Install the CLI and sign in
`npm install -g @letterstory/cli`, then `letterstory login`. Every platform tool becomes a terminal command.
The CLI is a thin client over the same tools the MCP server exposes. It needs Node 20 or newer and nothing else.
Install
npm install -g @letterstory/cli
This puts two commands on your path that do the same thing: letterstory, and phantom (a ghost-branded alias for demos). Run either with --help. To try it without installing:
npx -p @letterstory/cli letterstory --help
(The -p matters; the package ships two commands, so npx needs to be told which.)
Sign in
Two ways, pick the one that fits:
In your browser: best on your own machine:
letterstory login
Your browser opens to app.letterstory.com, you approve the CLI, and it comes back with a session that refreshes itself. No key to copy.
With an API key: for CI, servers, or scoped-down access:
letterstory login --key ls_your_key
Either way, confirm with:
letterstory whoami
It prints which key or session resolved and the organization it belongs to. (A key-based login needs provisioning:read for this, because whoami reads the organization profile.) Credentials are saved to ~/.letterstory/config.json (readable only by you). letterstory logout forgets them.
The commands you'll use most
letterstory phantom-onboard acme.com # preview a phantom site for a client (creates nothing)
letterstory phantom-onboard acme.com --accept # …then build it
letterstory phantom-onboard domain --about "…" --watch # onboard your own domain end to end: import the blog, set strategy, stand up a phantom
letterstory phantom list # every site: status, address, and the collection behind it
letterstory phantom rebuild <phantom-id>
letterstory phantom config <phantom-id> # the site's settings joined to its collection's file
letterstory phantom balance # hosted sites you may keep live at once
letterstory collections list
letterstory posts new --title "…" --collection <id> --body "…"
letterstory kernel list
letterstory kernel write <endpoint-id> --article <id> --kernel <id> # write into a post, from its own content
letterstory kernel status <job-id>
letterstory arena run --topic "…" --article <id>
letterstory arena run-status <run-id>
letterstory enhance run <article-id> --pass internal_links # re-run one Enhance pass on a post
letterstory collection run --collection <id> --topic "…"
letterstory collection run-status <run-id>
letterstory seers run <seer-id> --dry-run
letterstory shredder run <endpoint-id> --file post.md
letterstory published show --id <article-id> --format md
Choose the beat and the name before anything is created
propose and mastheads are the two decisions the platform would otherwise make for you, as
separate steps. Neither creates anything or spends anything: the domain checks are read-only.
# One: the beat. Omit the domain to use your own. Save it, so the chosen plan can travel.
letterstory phantom-onboard propose acme.com --json > proposal.json
# Two: the name. Candidate mastheads for one plan, each with its own priced domains.
letterstory phantom-onboard mastheads acme.com --plan-file proposal.json --plan-id plan-2
# Then onboard with the plan, the masthead, and the domain you picked.
letterstory phantom-onboard acme.com --plan-file proposal.json --plan-id plan-2 \
--name "The Compliance Wire" --domain compliancewire.com --domain-mode buy_now
Passing --plan-file with --plan-id pins both the plan's direction and its content areas, so
the site is built on exactly the angle you approved rather than one re-derived at build time. An
explicit --about still wins on direction.
Every tool is reachable even without a named command:
letterstory tools list # every tool
letterstory tools show run_kernel
letterstory call run_kernel --args '{"endpoint_id":"…","article_id":"…","kernel_id":"…"}'
Add --json to any command for machine-readable output, --verbose to see the HTTP traffic.
Print your MCP config
letterstory mcp # the config block for Claude Desktop / Cursor, and the claude mcp add line
letterstory mcp --print-key # …with your real key inlined
Updating
The CLI checks npm once a day and prints a one-line nudge when a newer version exists. Upgrade with npm install -g @letterstory/cli@latest. Set LETTERSTORY_NO_UPDATE_CHECK=1 to silence the check in CI.