Command-line
The anchorify CLI is a small Bun/Node program that wraps the REST API. Every share is one HTTP request; the CLI mostly exists so you can pipe a file path on the command line and get a URL on stdout.
This page is the reference. For an overview, see Getting started.
Install
npm install -g anchorify-cli
# or
bun install -g anchorify-cli
The npm package is anchorify-cli (suffixed because anchorify was
already taken on the registry by an unrelated utility); the binary it
ships is anchorify. A justforwarded alias keeps working through the
rebrand transition. Run anchorify help to see the top-level usage, or anchorify help <cmd> (equivalently anchorify <cmd> --help) for one subcommand — the built-in help is generated from the same source as this page, so it never drifts from the binary you have installed.
Log in
anchorify login
login prompts on the TTY for a token (no echo). The token comes from your dashboard at https://anchorify.io/dashboard — see CLI tokens. After verifying the token against /api/me, the CLI writes host and token to ~/.config/anchorify/auth.json (mode 600).
Flags:
--host <url>— server URL. Default:https://anchorify.io.--token <token>— pass the token non-interactively.
Examples:
anchorify login
anchorify login --host https://anchorify.io --token jf_...
Log out
anchorify logout
Removes ~/.config/anchorify/auth.json. Does not invalidate the token on the server. Idempotent: prints not logged in if there's nothing to remove.
Publish or update a file
The bare invocation is the primary entry point:
anchorify path/to/report.md
Behaviour:
- If the file's absolute path is in
~/.config/anchorify/published.json, the CLI updates the existing share at the recorded id. - Otherwise the CLI inserts a new share at a random 8-character base36 id.
- Prints the share URL on stdout. Nothing else. (Errors go to stderr.)
Flags on the bare invocation:
--slug <slug>— publish at a chosen slug. Returns409if taken; the CLI surfaces the error and you pick another.--id <id>— explicit update at this id (works for both random ids and chosen slugs).--new— force a new random id, ignoring the local mapping.--type <type>— override content type. One ofmarkdown,code,json,yaml,csv,tsv,html,html_embed. Default is detected server-side from the file extension.--access <tier>—restricted,view,comment, orsuggest. Default for new shares iscomment. See Access and passwords.--index/--no-index— list the share publicly (on /discover and in the sitemap) or keep it hidden. Default is--no-index. Mutually exclusive; ignored for--access restricted, which is never indexed.--password <pw>— set a password. Only valid on a hidden, link-reachable share (--accessaboverestricted, no--index).--project <slug>— publish into a specific project in your home org. Defaults to the project the file's mapping entry already points at, oruntitledfor new shares.
Examples:
anchorify path/to/report.md
anchorify path/to/report.md --slug q1-report
anchorify path/to/report.md --type code
anchorify path/to/report.md --access view
anchorify path/to/report.md --access suggest --index
anchorify path/to/report.md --access restricted
anchorify path/to/report.md --project q1-acme
anchorify path/to/report.md --new
anchorify update
anchorify update <file> [flags]
Strict, explicit form of the bare invocation. Errors out if the file is not already in the local mapping, instead of silently inserting a new share. Identity-changing flags (--slug, --id, --new) are rejected — use rename for that.
Flags:
--password <pw>— set a password.--no-password— remove an existing password.--access <tier>—restricted,view,comment, orsuggest. Omit to leave the current tier alone.--index/--no-index— flip public listing on or off. Omit to leave it alone.--type <type>— override content type.
Examples:
anchorify update path/to/report.md
anchorify update path/to/report.md --password sekret
anchorify update path/to/report.md --no-password --access comment --index
anchorify update path/to/report.md --access restricted
anchorify list
anchorify list
# aliases: anchorify --list, anchorify -l
Lists every share owned by the authenticated user. Output is tab-separated: <url>\t<filename>\t<source-path-or-em-dash>. Sorted by most recently updated.
The source path comes from the local mapping. Items published from another machine show as —.
anchorify list | grep deliverable
anchorify view
anchorify view <slug-or-id> [--user <username>]
Prints a share's raw source content to stdout. Auth required (your own shares). With --user <username>, fetches a public share owned by another user — no auth needed.
anchorify view my-share
anchorify view some-slug --user alice
anchorify view abc12345 > /tmp/share.md
anchorify comments
anchorify comments <slug-or-id-or-url> [--json] [--limit N]
Lists the comments on a share, newest first. Inline comments carry their anchor context (the quoted span the comment was attached to), so an agent reading this can tell what a reviewer was pointing at, not just what they said. Accepts a slug, a share id, or a full share URL.
Default output is flat text. --json emits the same payload the API returns (items + next_cursor), which is the shape to parse from a script.
Flags:
--json— raw API JSON instead of the text format.--limit N— how many comments to fetch. Default 50; the server caps at 200.
anchorify comments my-deliverable
anchorify comments https://anchorify.io/alice/untitled/x --json
anchorify comments abc12345 --limit 100
See Comments and reactions for the data model.
anchorify delete
anchorify delete <file-path>
anchorify delete --slug <slug>
anchorify delete --id <id>
Identify the share by file path (resolved via the local mapping), explicit slug, or explicit id. On success, removes the matching mapping entry. Auth required.
anchorify delete path/to/report.md
anchorify delete --slug old-deliverable
anchorify delete --id abc12345
anchorify rename
anchorify rename <slug-or-id> <new-slug>
Changes a share's slug — the id stays the same; only the URL changes. The CLI updates the local mapping so re-publishing the same path shows the new URL in list.
anchorify rename old-slug new-slug
anchorify rename abc12345 new-slug
anchorify access
anchorify access <slug-or-id> restricted|view|comment|suggest [--index|--no-index] [--force]
Set a share's access rung plus the orthogonal public-listing flag. The rung says what someone holding the link can do:
restricted— the link grants nothing. Only org admins, project members, per-share editors, and org viewers can read; everyone else gets404.view— anyone with the link can read.comment— read, plus signed-in users can comment and react. This is the default for new shares.suggest— read, comment, react, plus signed-in users can submit suggested edits.
--index lists the share on /discover and puts it in sitemap-shares.xml; --no-index (the default) keeps it hidden, reachable only by its URL. restricted is never indexed regardless of the flags.
A password is only valid on a hidden, link-reachable share, so switching to restricted or to --index clears any password — which needs --force. Without it the server returns 400 and the CLI prints a hint. Making a hidden share indexed can also be refused with 403 index_forbidden on a new or unverified account; the share stays live at its link.
anchorify access my-share view
anchorify access my-share comment --index
anchorify access my-share restricted
anchorify access my-share comment --index --force
See Access and passwords for the full model.
anchorify downloads
anchorify downloads <slug-or-id> on|off
Turns the share's download affordances on or off. With downloads off: the Download button and PDF export disappear from the share toolbar, /download and the ?raw=1 raw-file URL both 404, blob shares (images, PDFs, other binaries) lose their download CTA, and the CSV grid loses its Export CSV button.
The page still renders. This is friction, not DRM — a reader can copy the text, print the page, or view the source. Use it when a deliverable is meant to be read at the link (a draft under review, a pre-signature scope). To actually restrict who can read it, use anchorify access <slug> restricted.
New shares default to on. The gate is checked independently of the password gate, so a share with downloads off 404s on /download even for a visitor who has entered the password. Download counts on the analytics page are kept either way — turning downloads off doesn't erase what already happened.
anchorify downloads my-share off
anchorify downloads my-share on
anchorify --version
anchorify --version
Prints the CLI version on stdout (e.g. 0.2.2) and exits. Stamped at build time from package.json so it always reflects the binary you have installed. The Claude Code skill references this command to verify CLI compatibility (requires-cli: ">=0.2.2").
anchorify skill install
anchorify skill install [--force]
anchorify skill update [--force] # alias
Installs or refreshes the bundled Claude Code skill at ~/.claude/skills/anchorify/SKILL.md. Fetches the canonical version from https://anchorify.io/docs/anchorify-skill.md — no auth required.
Refuses to overwrite when the local file differs from the canonical version (assumes user edits); pass --force to overwrite. The skill version is pinned to the CLI version, so re-run whenever you upgrade the CLI.
npm install -g anchorify-cli@latest && anchorify skill install --force
anchorify mcp
anchorify mcp
Runs a stdio Model Context Protocol server exposing Anchorify's verbs as tools — publish, update, list, view, delete, set-access, set-password, rename, move, comments, versions, suggestions. Point any MCP client (Claude Desktop, Claude Code, Cursor, Zed) at it and the agent can manage shares directly instead of shelling out.
It's a pure client of the HTTP API, authenticated from the environment. No flags — configure with ANCHORIFY_TOKEN and (optionally) ANCHORIFY_HOST.
{
"mcpServers": {
"anchorify": {
"command": "anchorify",
"args": ["mcp"],
"env": { "ANCHORIFY_TOKEN": "your-token" }
}
}
}
See MCP server for the full setup.
anchorify lint
anchorify lint <file> [--type <type>]
Pre-publish format check. Calls POST /api/v1/lint with the file's content and (optionally) an explicit type override, then prints warnings to stderr. --type here accepts the render types above plus slides_marp and slides_reveal, so you can lint a deck as a deck before publishing it.
- Exit 0 with
ok — <file> lints clean as <type>when there are no issues, or when the issues are onlyinfo/warn-severity. - Exit 1 when at least one
error-severity issue is present (file will look broken to recipients).
anchorify lint deck.md
anchorify lint data.txt --type csv
See Lint API for the warning catalog and the full HTTP shape.
anchorify type
anchorify type <slug-or-id> <type>
Changes how a share is rendered. <type> is one of markdown, code, json, yaml, csv, tsv, html, html_embed (html is sanitized in place; html_embed renders inside a sandboxed iframe). Content is untouched; only the renderer changes.
anchorify type my-share code
anchorify type my-share json
anchorify type my-share markdown
anchorify password
anchorify password set <slug-or-id> [--password <pw>]
anchorify password clear <slug-or-id>
set without --password prompts on the TTY (no echo) or reads the first line from stdin (non-TTY). clear removes any existing password.
anchorify password set my-share
anchorify password set my-share --password sekret
echo sekret | anchorify password set my-share
anchorify password clear my-share
anchorify move
anchorify move <slug-or-id> --to <project>
Move a share into a different project in your home org. The canonical URL changes; the old URL 301s to the new one (slug redirect history is preserved per project).
anchorify move my-share --to q1-acme
anchorify move abc12345 --to retainer
anchorify org
anchorify org show [--json]
anchorify org rename <new-slug> [--yes]
Inspect or rename your home org. show prints slug, name, plan, and member/project counts. rename changes the org slug — every existing share URL at the old slug 301s to the new slug, and the old slug is permanently retired (tombstoned). Type-to-confirm the old slug unless --yes is passed.
anchorify org show
anchorify org show --json
anchorify org rename my-new-slug
anchorify org rename my-new-slug --yes
anchorify project
anchorify project list
anchorify project create <slug> [--name "..."]
anchorify project rename <old-slug> <new-slug>
anchorify project delete <slug> [--yes]
anchorify project visibility <slug> <private|unlisted|public>
anchorify project password <slug> [<password>|--clear]
anchorify project logo <slug> [--domain <domain> | --image <url> | --clear]
Manage projects inside your home org.
list— every project in your home org with slug, name, and its logo (the image URL, else the favicon domain, else—).--jsonreturns the raw API payload includingshare_count.create— new project.--namedefaults to the slug.rename— change a project slug. Old URLs301viaproject_redirects.delete— delete an empty project. Blocked if it still contains shares (move them first) or if it is the last project in the org. Type-to-confirm unless--yes.visibility— set the project's own visibility.publicandunlistedturn on the/<org>/<project>deliverable-index page;privatekeeps it admin-only.password— set or clear the project-level password gate on that index page. Applies on top ofunlisted/public.logo— set the project's visual identity, shown on the dashboard project card.--domain <d>displays that site's favicon,--image <url>uses an explicit image (and wins over--domain),--cleardrops both back to the initial-letter avatar. Exactly one of the three per call. The domain is normalized server-side, and the command prints what was actually stored.
Two different things called "visibility." A project's visibility (
private/unlisted/public, above) governs the project index page — the bundle URL you send a client so they can see every deliverable in one place. A share's reachability is the separateaccessladder plus theindexedflag (anchorify access, Access and passwords). Setting a project public does not change any share's access, and vice versa.
Flags:
--name "<name>"— (create) human-readable name; defaults to the slug.--yes/-y— (delete) skip the type-to-confirm prompt.--clear— (password) remove the existing password; (logo) remove both the domain and the image.--domain <domain>/--image <url>— (logo) the two ways to give a project an avatar.
anchorify project list
anchorify project create q1-acme --name "Q1 — Acme"
anchorify project rename q1-acme acme-q1
anchorify project delete old-project
anchorify project visibility q1-acme public
anchorify project password q1-acme swordfish
anchorify project password q1-acme --clear
anchorify project logo q1-acme --domain acme.com
anchorify project logo q1-acme --image https://acme.com/logo.png
anchorify project logo q1-acme --clear
anchorify upload-folder
anchorify upload-folder <local-dir> [--project <slug>] [--access <tier>] [--index|--no-index] [--dry-run]
Recursively walk a local directory and publish every file as its own share. Slugs are derived from each file's relative path (subdir slashes become hyphens). One URL is printed per file to stdout. With --dry-run, the planned slugs/URLs are listed without hitting the server.
Flags:
--project <slug>— target project. Defaults tountitled.--access <tier>—restricted,view,comment, orsuggest, applied to every file in the batch. Default iscomment.--index/--no-index— public listing for the whole batch. Default is--no-index.--dry-run— list planned URLs without publishing.
anchorify upload-folder ./deliverables
anchorify upload-folder ./deliverables --project q1-acme
anchorify upload-folder ./deliverables --access restricted --dry-run
anchorify admin
anchorify admin upgrade-org <slug> --plan free|pro
Operator-only. Requires the legacy operator bearer token (REPO_SHARE_TOKEN), not a per-user CLI token. Flips an org's plan tier — pro unlocks custom-domain affordances; free is the default. There is no self-serve upgrade path yet.
anchorify admin upgrade-org acme --plan pro
anchorify admin upgrade-org acme --plan free
anchorify notifications
anchorify notifications [--unread] [--limit N]
List your in-app notifications, newest first. Tab-separated output:
<id>\t<kind>\t<created_at_iso>\t<title>\t<link>
Use --unread to filter to unread rows only; --limit sets page size (default 50, max 200). See Notifications for the kinds.
anchorify versions
anchorify versions <slug-or-id>
anchorify versions restore <slug-or-id> <version-id>
versions <slug> lists every version of a share, newest first:
<version-id>\t<created_at_iso>\t<source>\t<author>\t<status>
versions restore <slug> <vid> rolls the share back to that version. The restore is itself versioned (a new rollback-source row is appended). Prints ok on success. See Version history.
anchorify audit
anchorify audit [--org <slug>] [--limit N] [--action <name>]
Lists audit events for an org, newest first. --org defaults to your home org. --action filters to a single event type (e.g. share.delete, share.visibility, org.member.add). Tab-separated output:
<created_at_iso>\t<action>\t<actor>\t<target_type>:<target_id>
See Audit log for the action catalog.
anchorify suggestions
anchorify suggestions <slug-or-id> # owner-only: open suggestions on a share
anchorify suggestions mine # your own submitted suggestions
mine output: <version-id>\t<share-url>\t<status>\t<created_at_iso>. Approve and reject from the web dashboard — the CLI only lists. See Suggest changes.
anchorify report-bug
anchorify report-bug "<summary>" [--body "<details>"] [--file <path>] [--context '{"key":"value"}'] [--surface cli|api|agent]
Files a bug report against Anchorify. Works without auth; when you're logged in the report is tied to your account so we can follow up. Prints the new report id on stdout and nothing else.
Flags:
--body "<details>"— the long-form description.--file <path>— read the body from a file instead (mutually exclusive with--bodyin practice;--bodywins).--context '{...}'— a JSON object of agent-side breadcrumbs (the command that failed, the response code, whatever you have). Invalid JSON or a non-object exits1rather than silently sending a string.--surface <name>— where the bug was hit. Defaults tocli.
anchorify report-bug "slides render blank on Safari"
anchorify report-bug "publish 500s on large CSV" --file ./repro.md
anchorify report-bug "agent got a 403" --context '{"cmd":"anchorify x.md --index","status":403}'
Environment variables
ANCHORIFY_CONFIG_DIR— override the config directory. Default:~/.config/anchorify. Redirects bothauth.jsonandpublished.json. Useful for sandboxed testing, so a logged-in session does not accidentally publish to prod. The legacyJF_CONFIG_DIRis still honored as a fallback.ANCHORIFY_HOST— server URL. When set together withANCHORIFY_TOKEN, these overrideauth.json. (A one-line stderr notice is printed ifauth.jsonexists and the env vars are taking precedence.) The legacyREPO_SHARE_HOSTis still honored as a fallback.ANCHORIFY_TOKEN— bearer token. Both env vars must be set for the override to fire; setting only one falls back toauth.json. The legacyREPO_SHARE_TOKENis still honored as a fallback.
Local mapping
The CLI stores a per-machine file-to-slug mapping at ~/.config/anchorify/published.json:
{
"/abs/path/to/file.md": {
"id": "chosen-or-random-slug",
"url": "https://anchorify.io/you/chosen-or-random-slug",
"filename": "file.md",
"last_published_at": "2026-05-06T07:19:38.781Z"
}
}
Plain JSON, mode 644. Rebuilt by re-publishing files; not yet auto-synced from the server. Items published from another machine or before the mapping existed show as — in anchorify list.
Next steps
- Web dashboard — the same actions in the browser.
- REST API — the underlying HTTP surface.
- Slug rules — the slug regex.