One terminal interface to find skills, install team skills, sync them across machines, and publish your own. Sign in with any web auth provider — browser handles the handoff. Works with Node 20+.
The CLI ships as the npm package @botdocs/cli. Install globally to get the botdocs binary on your PATH:
npm i -g @botdocs/cli # or pnpm add -g @botdocs/cli
One-off without installing globally:
npx @botdocs/cli --help
Verify the install:
botdocs --version
Most read operations are anonymous. Publishing, installing private bundles, and syncing your library all require a logged-in account.
botdocs login and botdocs sync are interactive and live by default — a gradient brand mark, animated polling, and per-file status icons that update in place. On a non-TTY shell (CI, piped output) the CLI falls back to plain line-by-line output automatically; pass --no-ink to force the plain renderer on a real terminal, or --json on sync for machine-readable output.
botdocs login
This opens your browser at /cli-auth with an unguessable session token in the URL. Sign in with whichever provider you prefer (GitHub, Google, or email-OTP), confirm “Authorize this terminal session?” on the page, and the CLI picks up the issued token and writes it to ~/.botdocs/auth.json. Delete that file to log out.
For CI or any headless environment where the browser flow doesn’t make sense, mint a token at /settings/tokens and pass it directly:
botdocs login --token bd_xxxxxxxx
To enable the personalized Library page (a synced view of every installed skill across your machines), pass --sync-library:
botdocs login --sync-library
Confirm who you are at any point:
botdocs whoami
Search the public registry by topic:
botdocs search "code review"
Add --json to any command for machine-readable output. Once you have a ref, install it with the next command (install handles every supported ecosystem automatically).
Skills are bundles of files that ship to specific destinations on disk (Claude skills, Cursor rules, Claude Code commands, Codex agents, ChatGPT GPTs). A bundle is a curated playlist of skills — typically one per team.
botdocs install @teamco/eng-skills
Files land in the right place automatically:
~/.claude/skills/<scope>/<slug>/ for Claude skills./.cursor/rules/ for Cursor rules (project-local)./.claude/commands/ for Claude Code slash commands (project-local)~/.codex/agents/<slug>/ for Codex agentsList what you have installed:
botdocs list
Remove an installed ref:
botdocs uninstall @teamco/eng-skills
If a file would be overwritten, Botdocs backs up the original to .botdocs-backup/<ts>/ first (or ~/.botdocs/backup/<ts>/ for global-scoped files like ~/.claude/skills/...). Pass --no-backup on install or sync to opt out in CI.
If you regret an overwrite, botdocs undo restores the most recent backup run. It's reversible — the current state is itself backed up before the restore, so running botdocs undo twice swaps the state back. For more control, the backups group browses, partial-restores, diffs, and prunes runs:
botdocs undo # restore the most recent backup botdocs backups list # every run, newest first botdocs backups list <ts> # files in a specific run botdocs backups restore <ts> # restore the full run botdocs backups restore <ts> --files a.mdc # restore a subset botdocs backups diff <ts> <relpath> # diff backup vs current botdocs backups clear --older-than 30d # prune runs > N days old
sync walks your lockfile, applies clean updates, and prompts before touching files you've edited locally (with a double confirmation).
botdocs sync # or sync a single ref botdocs sync @teamco/eng-skills
To check for pending updates without applying them:
botdocs check-updates
For a one-line notice on every new terminal, install the shell hook. Detects your shell (zsh / bash / fish) and writes a marker-delimited block to your rc file:
botdocs install-instructions --shell-hook
Silent when there's nothing to report. Remove with --remove-shell-hook.
Botdocs installs versioned copies of skills into each tool's expected location and tracks them in a lockfile (~/.botdocs/installed.json). When you run botdocs sync, the CLI compares each installed file's fingerprint against the registry's current version, applies clean updates, and prompts before touching anything you've edited locally.
A reasonable question — symlinks would mean “edit once, every tool sees the change,” and they're cheaper to set up. We use the versioned-copy approach instead because symlinks break under common real-world conditions:
.mdc with frontmatter, Claude's SKILL.md, Copilot's *.instructions.md, Windsurf's plain markdown, and so on are not interchangeable. Symlinking the same file into all paths works in one and breaks in the others. Botdocs's compile step generates the right file per tool from a canonical source.If your needs are simpler — one machine, one developer, one format — a symlink-based tool may serve you fine. Botdocs starts to earn its weight when you have multiple teammates, multiple machines, multiple tools, or any need to version and roll back.
A team is a curated library of skills shared across its members. Skills stay user-owned; teams pin skills (no copy, no fork). Members install/sync the pinned set automatically — every botdocs sync walks each team's pinned skills and applies them locally.
botdocs team list # which teams am I in? botdocs team show teamco # members + pinned skills botdocs team push teamco @alice/eng-skill # pin a skill (WRITE+) botdocs team push teamco @alice/eng --version 3 # pin to a specific version botdocs sync # pulls personal + team pins
Admin-only — create teams and manage membership:
botdocs team create teamco --name "Team Co" botdocs team add teamco @bob --role write botdocs team remove teamco @bob
Roles are ADMIN, WRITE, and READ. The team creator becomes the first ADMIN automatically. Pinning is curation, not access control — skills are public in v1.
Scaffold a new skill:
botdocs init my-skill
That creates ./my-skill/index.md and ./my-skill/botdocs.json. Edit the markdown, fill in the description and category in the manifest, then validate:
botdocs validate my-skill/
validate must pass with no errors before publishing (warnings are OK).
botdocs publish my-skill/
category in botdocs.json must be one of KNOWLEDGE_MANAGEMENT, DEV_WORKFLOW, AUTOMATION, AGENT_CONFIG, PROJECT_SCAFFOLD, or OTHER.
Already have a collection of skills lying around? Walk a directory and upload each detected skill as a draft for review. ingest recognizes all 11 supported ecosystems (claude, claude-code, claude-code-agents, cursor, chatgpt, codex, copilot, windsurf, gemini, antigravity, opencode) when files live in the canonical Botdocs layout. For nested ecosystems (claude/<slug>/SKILL.md, claude-code/agents/<slug>/AGENT.md), ingest also sweeps adjacent files (scripts/, templates/, reference docs) and preserves POSIX file modes so executable scripts survive the round-trip.
Per-skill caps: 64 KB per file, 512 KB total, 25 files. Binary files (null-byte sniff) are skipped with an inline warning. Cap violations warn and skip without failing the ingest.
botdocs ingest ./my-skills/
For real on-disk locations like ~/.claude/commands/ or .cursor/rules/, pass --from-tool=<ecosystem> so every matching file is uploaded as a draft for that ecosystem with the canonical filename:
botdocs ingest --from-tool=claude-code ~/.claude/commands/ botdocs ingest --from-tool=cursor .cursor/rules/
Or run with no arguments — the CLI scans your machine across every known on-disk location (~/.claude/commands/, ~/.claude/skills/, .cursor/rules/, .github/instructions/, ~/.gemini/instructions/, etc.) and presents an interactive selection. Pass --auto to skip the prompt and ingest everything discovery finds.
botdocs ingest # interactive selection botdocs ingest --auto # one-shot, no prompts botdocs ingest --dry-run # list discoveries, don't upload
ingest and edit both create drafts — hidden from /explore, 404 for everyone but the author. To flip a draft live from the terminal, pass the ref (not a path) to publish:
botdocs publish @me/my-skill # ✓ Published @me/my-skill
botdocs publish @me/my-skill --json # {"ok":true,"ref":"@me/my-skill","status":"published"}publish overloads by argument shape: a local path runs the upload flow above; a @user/slug ref toggles the publish flag via the API.
To hide a published skill again:
botdocs unpublish @me/my-skill # prompts to confirm botdocs unpublish @me/my-skill --yes # skip the prompt (scripts/CI) botdocs unpublish @me/my-skill --json # implies --yes, emits JSON
Unpublishing is idempotent server-side — calling it on something already a draft is a no-op.
To delete a skill entirely:
botdocs delete @me/my-skill # state-aware confirm prompt botdocs delete @me/my-skill --yes # skip the prompt (scripts/CI) botdocs delete @me/my-skill --json # implies --yes, emits JSON
delete is state-aware. Drafts are hard-deleted — the row and all children (files, version history, bundle pins, team pins) are removed and the confirm is a single yes/no. Published skills are soft-deleted — deletedAtis set, version history is preserved, the public URL 404s, and the confirm requires typing the full ref. JSON output is {ok, ref, mode} where mode is "hard" or "soft".
Authors write a skill once in their preferred ecosystem (Claude Code, Cursor, etc.) and use their own LLM key to generate the other formats locally. The Botdocs server never runs inference — your file content stays on your machine.
export BOTDOCS_ANTHROPIC_KEY=sk-ant-... # or export BOTDOCS_OPENAI_KEY=sk-...
Scaffold a multi-ecosystem skill:
botdocs init my-skill --canonical # edit claude-code/commands/my-skill.md botdocs compile my-skill/ # generates claude/, cursor/, chatgpt/, codex/, copilot/, windsurf/, gemini/, antigravity/, opencode/ drafts botdocs publish my-skill/ # auto-compiles if stale; --no-compile to skip
To revise a published file later, in plain English:
botdocs edit @you/my-skill --ecosystem cursor
compile and edit both prefer BOTDOCS_ANTHROPIC_KEY (Claude Haiku) when set, otherwise fall back to BOTDOCS_OPENAI_KEY (GPT-4o mini). Use --key-env <NAME> to point at a different env var.
Run once in any project to drop a managed AGENTS.md block that teaches any agent that reads AGENTS.md (Claude Code, Cursor, Codex, Copilot, Windsurf, Gemini CLI, Antigravity, OpenCode) how to invoke the CLI:
botdocs install-instructions
If AGENTS.md already exists with markers from a prior run, the block is refreshed in place. Use --print to dump the snippet to stdout instead of writing.
Environment variables the CLI reads:
| Variable | Default | Purpose |
|---|---|---|
BOTDOCS_API_URL | https://botdocs.ai | Override the registry API endpoint (useful for local development). |
BOTDOCS_ANTHROPIC_KEY | — | Anthropic key for `compile` and `edit` (BYOK). Preferred when set. |
BOTDOCS_OPENAI_KEY | — | OpenAI key for `compile` and `edit` (BYOK). Used when no Anthropic key is set. |
Auth is stored at ~/.botdocs/auth.json after login. Delete that file to log out.
Every command accepts --json. Run botdocs <command> --help for full flags.
| Command | Purpose |
|---|---|
init [name] | Scaffold a new skill directory. `--canonical` for a multi-ecosystem skill. |
compile <path> | Generate per-ecosystem skill drafts from a canonical source (BYOK). |
edit <ref> | LLM-assisted revision of a published skill ecosystem file (BYOK). |
validate <source> | Pre-publish structural check on a directory or file. |
search <query> | Search the public registry. |
publish <source> | Publish from a file, directory, or zip archive — or pass `@user/slug` to mark an existing draft live. |
unpublish <ref> | Hide a published skill from /explore (sets the `draft` flag back; prompts unless `--yes`). |
delete <ref> | Delete a skill — drafts are hard-deleted with cascade, published skills are soft-deleted (hidden, version history preserved). |
install <ref> | Install a skill or bundle (auto-detects destinations). |
sync [ref] | Check installed skills/bundles for updates and apply. |
uninstall <ref> | Remove an installed skill or bundle. |
list | Show installed skills and bundles. |
ingest [path] | Scan your system (zero-arg) or walk a directory, detect existing skills, upload as drafts. |
team list / show / create | List teams, show members + pinned skills, or create a new team. |
team add / remove | Manage team membership (ADMIN only; or self-leave). |
team push / unpush | Pin or unpin a skill to a team (WRITE+). |
check-updates | Check installed refs for available updates (1-hour cached). |
install-instructions [target] | Write/refresh `AGENTS.md` (or install a shell hook with `--shell-hook`). |
login | Authenticate by opening your browser; pass `--token bd_xxx` for headless/CI. `--sync-library` enables `/library`. |
whoami | Show the currently authenticated user. |