Symbol Docs

Symbol CLI

Read, search and write capsules from a terminal with the symbol command, on any Symbol server, with the same write rules as the Symbol MCP.

What It Is

The Symbol CLI is a command named symbol for working with your capsules from a terminal. It lists, reads and searches capsules, reads a Type's guidance, and creates and edits capsules and log entries. It works the same for a person typing commands and for an agent running them, and the server applies the same write rules to it as to the Symbol MCP: guidance first, valid field values, and only the scopes you approved.

It talks to whichever Symbol server you point it at, including a local development server, and it has no built-in server, so it never writes to production unless you choose it.

The CLI is not published to npm yet. Today you run it from a checkout of the Symbol repository, as shown below.

Running It From the Repository

The CLI needs Node.js 20.19 or later and nothing else: it has no third-party dependencies.

# From the repository root
node packages/cli/bin/symbol.mjs --help

# Or, after npm ci at the root, through the workspace bin
npx symbol --help

The rest of this page writes symbol for either form.

Choosing a Server

Every command talks to one server, chosen in this order:

  1. --server <name|url> on the command
  2. the SYMBOL_SERVER environment variable
  3. the default saved by symbol server use

With none of these, the command stops with exit code 2 and tells you how to pick one.

CommandWhat it does
symbol server add <name> <url>Save a server under a short name, such as staging
symbol server use <name|url>Make a saved name or a URL the default
symbol server listList saved servers; the default is marked
symbol server remove <name>Forget a saved name

A server URL must use https://. Plain http:// is accepted only for localhost, names ending in .localhost, 127.0.0.1 and [::1], because a token sent over plain http to another machine can be read on the way.

Signing In

Start the sign-in

symbol login --server https://symbol.chat

The CLI prints a web address and an eight-character code such as BCDF-GHJK, then waits. It never asks for your password.

Approve it in a browser

Open the address in any browser where you are signed in to Symbol, on this machine or another one (a phone works), and enter the code. Check that the code matches the one your terminal shows, choose the workspaces the CLI may use, and approve. Only approve a code you started yourself.

Check who you are

symbol whoami

This prints the account, the server, the scopes you approved, and the entry this sign-in has in Connected Apps:

account: ana@example.com
server: https://symbol.chat
credential: oauth
scopes: read create update
connected app: Symbol CLI (on "ana-laptop")

symbol login flags:

FlagMeaning
--scopes <list>Comma-separated scopes to request. The default is read,create,update.
--device-name <name>Name this sign-in in Connected Apps. The default is this machine's hostname.
--openAlso open the approval page in a browser on this machine.
--with-tokenStore an API key instead of using a code (see below).

The first successful sign-in also saves that server as your default.

Each sign-in is its own entry under Settings → Connected Apps, named after the device, for example "Symbol CLI (on "ana-laptop")", with its own Last used date and request count. symbol login and symbol whoami print that entry name, so you can tell which entry belongs to which machine. Each sign-in keeps only the workspaces you approved for it, whatever you approve for another one.

The device name defaults to this machine's hostname. It is shown in your Connected Apps and to Symbol support. Pass --device-name to choose another.

Revoking an entry signs out that sign-in alone, and symbol logout removes its own entry. Signing in again in the same CLI home, for the same server, replaces the earlier sign-in, so one machine keeps one entry.

With an API key

For CI or an agent that already holds a key, pipe the key in on stdin. The CLI never takes a key as a command argument, where it would land in your shell history.

symbol login --with-token --server https://symbol.chat < key.txt

You can also set SYMBOL_TOKEN in the environment. It overrides the stored sign-in for that run and is never written to disk.

Prefer symbol login over an organization API key. A code sign-in acts as you, limited to the scopes and workspaces you approved, and you can revoke it in Connected Apps.

Signing out

symbol logout

symbol logout revokes the stored tokens on the server and forgets them. If the server cannot be reached, the CLI still forgets them and exits 1, warning that the token may stay live until it expires. For a stored API key, logout only forgets it: the key stays valid until you revoke it in Settings.

The CLI keeps its files in ~/.symbol/cli (config.json, credentials.json and state.json). The credentials and state files are readable only by your user. Set SYMBOL_CLI_HOME to use a different directory.

Commands

Every command accepts these global flags:

FlagMeaning
--server <name|url>Server to talk to
--workspace <name|id>Workspace: personal, a workspace id, or an exact workspace name
--jsonWrite one JSON document to stdout
--helpShow help for the command
--versionPrint the CLI version

symbol --help lists every command, and symbol <command> --help lists every flag of that command.

Workspaces

symbol workspace list

--workspace takes personal, a workspace id, or the workspace's exact name (letter case does not matter). A partial name such as Acme for "Acme Research" is refused with exit 2 and the list of your real workspaces, so a write never lands in a workspace you did not mean.

Types

symbol type list
symbol type show notes

symbol type list lists your Types. symbol type show <type> prints a Type's guidance and its fields, and remembers the guidance token that writes to that Type need (see Write Rules below). A Type can be named by its slug, its exact name, or its id.

Listing and reading capsules

symbol capsule list --type notes --limit 20
symbol capsule list --collection reading --cursor <cursor>
symbol capsule get @notes/3
symbol capsule get @notes/launch-plan

symbol capsule list flags:

FlagMeaning
--type <type>Only capsules of this Type
--collection <collection>Only capsules in this collection (its alias, its id, or its name together with --type)
--project <project>Only capsules in this project (exact name, slug or id)
--limit <n>Page size, 1 to 100
--cursor <cursor>Continue from the cursor the previous page printed
--archivedList archived capsules instead of active ones

symbol capsule get takes @type/3, @type/<alias> or a capsule id, and prints the title, reference, Type, field values and body.

Searching

symbol search "launch plan"
symbol search budget --type notes --sort newest

symbol search returns the same capsules in the same order as the search page in the web app.

FlagMeaning
--type <type>Only capsules of this Type
--limit <n>How many capsules to return (default 20, as on the web)
--offset <n>Skip this many results, for the next page
--sort <best|newest|oldest>Result order (default best)

Creating a capsule

symbol type show notes
symbol capsule create --type notes --title "Launch plan" \
  --summary "What ships on Friday and who owns it." \
  --content-file plan.md --field status=draft --tag launch
FlagMeaning
--type <type>Type to create the capsule in (required)
--title <title>Capsule title (required)
--summary <summary>One or two sentences saying what the capsule is about (required)
--content-file <path|->Read the body from a file, or from stdin with -
--field <name=value>Set a field value; repeat for more fields
--fields-file <path|->Read field values from a JSON object
--slug <alias>A short alias, so the capsule is also @type/<alias>
--tag <tag>Add a tag; repeat for more
--collection <collection>Add the new capsule to a collection
--project <project>Attach the new capsule to a project
--guidance-token <token>Send this guidance token instead of the remembered one

--field values are read by the Type's field schema: numbers and true or false become numbers and booleans, and a value that starts with [ or { is read as JSON, for lists. The server checks every value and refuses invalid ones with its own message.

Editing a capsule

symbol capsule edit @notes/3 --replace "Friday" --with "Monday" \
  --summary "Launch moved to Monday."
symbol capsule edit @notes/3 --field status=final
FlagMeaning
--title <title>New title
--summary <summary>New summary (the server asks for one when the body changes)
--content-file <path|->Replace the whole body
--field <name=value>Change a field value; repeat for more
--fields-file <path|->Read field values to change from a JSON object
--replace <old>Exact text to replace; it must appear exactly once across the body and the text fields
--with <new>The replacement for the --replace in the same position
--guidance-token <token>Send this guidance token instead of the remembered one

symbol capsule edit reads the capsule fresh before writing, and the server refuses the write if someone else changed the capsule in between. If any --replace text is missing or appears more than once, nothing is written.

Appending to a log

symbol type show standup
symbol log append --type standup --field mood=good --field hours=6
symbol log append @projects/atlas --field note="Shipped the beta"

symbol log append takes an owner capsule (a capsule whose Type keeps a log) or --type <log type> for a dated log. An entry is its field values: there is no body.

FlagMeaning
--type <log type>Append to this log Type instead of an owner capsule
--field <name=value>Set an entry field; repeat for more
--fields-file <path|->Read entry fields from a JSON object
--guidance-token <token>Send this guidance token instead of the remembered one

Write Rules

The CLI declares itself to the server as an assistant client, so the server applies the same rules as for the Symbol MCP, for people and agents alike:

  • Read the Type first. Run symbol type show <type> before writing to a Type that has guidance. The CLI remembers the guidance token it returns and sends it with capsule create, capsule edit and log append. Without it, the server refuses the write and the CLI adds a line telling you which command to run.
  • Field values are checked against the Type's fields.
  • Scopes apply. A sign-in approved for read only cannot write.
  • A summary is expected when a body changes.

The CLI never decides these on its own: it relays the server's answer, with the same reason the MCP gets.

Encrypted Capsules

The CLI cannot decrypt end-to-end encrypted capsules. symbol capsule get on one stops with exit code 1 and the message "This capsule is end-to-end encrypted. The CLI cannot decrypt it. Open it in the web app or in Symbol Bridge." In lists and search results, an encrypted capsule appears with its title and "encrypted": true, never with its encrypted body.

To read encrypted capsules from an assistant, use Symbol Bridge.

JSON Output

With --json, a command writes exactly one JSON document to stdout: the server's response for data commands, or a small object for local commands such as symbol server list. Errors go to stderr as one JSON object:

{"error":{"code":"guidance_token_required","message":"...","status":422}}

Without --json, errors read error: <reason> (<code>, HTTP <status>). Either way, a failed command writes nothing to stdout, so a pipe never receives half a result.

Exit Codes

CodeMeaning
0Success
1The server refused the request, or it failed
2Usage error: a wrong flag, a missing argument, an unknown or partial name, or no server chosen
4Not signed in, or the server refused the token. Run symbol login.

When a sign-in expires, the CLI renews it once on its own. If the server refuses the renewal (for example because you revoked the grant in Connected Apps), the CLI forgets the sign-in and exits 4 with Signed out: run "symbol login".

If the server warns that this version of the API is being retired, the CLI prints one warning naming the date. If the server no longer serves it, commands exit 1 asking you to update the CLI.

On this page