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. Returns 409 if 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 of markdown, code, json, yaml, csv, tsv, html, html_embed. Default is detected server-side from the file extension.
  • --access <tier>restricted, view, comment, or suggest. Default for new shares is comment. 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 (--access above restricted, 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, or untitled for 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, or suggest. 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 gets 404.
  • 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 only info/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 ). --json returns the raw API payload including share_count.
  • create — new project. --name defaults to the slug.
  • rename — change a project slug. Old URLs 301 via project_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. public and unlisted turn on the /<org>/<project> deliverable-index page; private keeps it admin-only.
  • password — set or clear the project-level password gate on that index page. Applies on top of unlisted / 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), --clear drops 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 separate access ladder plus the indexed flag (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 to untitled.
  • --access <tier>restricted, view, comment, or suggest, applied to every file in the batch. Default is comment.
  • --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 --body in practice; --body wins).
  • --context '{...}' — a JSON object of agent-side breadcrumbs (the command that failed, the response code, whatever you have). Invalid JSON or a non-object exits 1 rather than silently sending a string.
  • --surface <name> — where the bug was hit. Defaults to cli.
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 both auth.json and published.json. Useful for sandboxed testing, so a logged-in session does not accidentally publish to prod. The legacy JF_CONFIG_DIR is still honored as a fallback.
  • ANCHORIFY_HOST — server URL. When set together with ANCHORIFY_TOKEN, these override auth.json. (A one-line stderr notice is printed if auth.json exists and the env vars are taking precedence.) The legacy REPO_SHARE_HOST is 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 to auth.json. The legacy REPO_SHARE_TOKEN is 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