Tools
MISSIN CLI
Run MISSIN from your terminal with @missin/cli: log in once, run any tool as a command, script with --json and exit codes, and start a local MCP server.
@missin/cli installs the missin command. Every tool an AI agent can use is also a command, so the terminal can do what the MCP server can do, at the same access level.
Install and log in
-
Install the package. It needs Node 22.13 or later: that is the version it is built and tested on. The Claude Desktop extension runs the same code with the Node that ships inside Desktop, and declares an older floor (18.20) because that is what Desktop supplies and where it was tested.
bashnpm install -g @missin/cli -
Create a secret key in , then log in. The key is read from a hidden prompt, or from a pipe.
bashmissin login printf '%s' "$MISSIN_KEY" | missin login --key-stdin -
Check what the key can do.
bashmissin whoami missin tools --toolset partners
There is no --key flag, because a key on the command line lands in your shell history. missin login checks the key with the API before it stores anything, so a rejected key is never saved (exit code 4). Only secret sk_live_ keys log in.
Where the key lives
- The CLI stores the key in your system keychain. Where there is none, such as a headless Linux machine, it writes
~/.config/missin/credentials(under$XDG_CONFIG_HOME/missinif that is set), readable only by you. The folder is mode 0700 and the file 0600. MISSIN_API_KEYin the environment always wins over a stored key.missin loginandmissin logoutboth warn you while it is set.missin logoutremoves the key from the keychain and the file, and says which it removed.
What a key can reach
missin tools lists the commands your key can run, each with its access level. A command above the key's level is refused with exit code 7 and the server's sentence.
| Level | Reaches |
|---|---|
| Read | Looking things up, and getting a capture quote |
| Write | Also creating and changing partners, campaigns, posts, discounts and forms, and starting captures |
| Admin | Also changing connections, integration settings, the brand and workspace settings |
No level creates or revokes keys or members: do that in the app. A key acts as the member who created it, and its level is capped by that member's role.
Commands
Commands are named missin <domain> <action>, from the same names the SDK uses. Workspace-wide tools sit at the top, as missin whoami, missin find and missin toolsets.
missin partners list --first 10
missin partners save --name "Test 11" --handle instagram:test11 --handle tiktok:test11
missin campaigns listRun missin <domain> --help for a domain's commands and missin <domain> <action> --help for one command's flags.
- Flags are the tool's inputs, in kebab-case:
maxPerPartneris--max-per-partner. - Repeat a flag to pass a list, as
--handleabove. A pair isnetwork:handle. - Names work where ids do.
--partner @test11and--campaign springare resolved by the CLI, which looks the name up through the API before it makes the call. When a name matches several records, or none, the command prints the candidates and exits with code 3. Run it again with one id. --argspasses all the arguments as one JSON object:--args '{"first":10}',--args ./args.json, or--args -for stdin. Flags you give as well override it.
Output
On a terminal you get a table. When stdout is piped, or with --json, you get JSON: the data on success, and on a failure the whole result with its kind. Failures go to stderr, so missin partners list | jq never mixes the two; a needs_choice answer is the exception, because it asks you a question, and goes to stdout. No output contains your key.
Exit codes
Scripts can react to the code without reading the message.
| Code | Meaning |
|---|---|
0 | Done |
1 | Anything else: a usage mistake, not logged in, a server fault, a spend that was not confirmed |
2 | The API returned userErrors; nothing was written. They are printed to stderr |
3 | needs_choice: a name matched zero or several records. The candidates are printed |
4 | The key was rejected or cannot be used. Log in again |
5 | Rate limited. Wait, then run it again |
6 | The request timed out. A write may have happened, so check before you repeat it |
7 | forbidden: the key is valid but below the access level the command needs |
130 | You pressed Ctrl-C at a prompt |
Spending credits
Some commands spend capture credits. They never do it silently: the CLI shows what it will spend, asks y/N with No as the default, and only then runs it. Off a terminal, with no --yes, such a command is refused before it calls anything.
| Command | What you are shown | --yes |
|---|---|---|
missin capture start | The quote, in credits and pounds | Allowed: the quoted price is sent with the call, and a moved price is never accepted for you |
missin capture dispatch-hashtag | The exact total the server checks | Allowed, same pinning |
missin capture dispatch-partner | A price for display only. With no partner ids it says it will read every watched handle | Only with --quoted-credits, which the server checks |
missin capture rerun-run, missin capture resync-run, missin partners resync-profile, missin posts fetch-twitter-replies (retired) | No price: the server has none to check | Refused: answer the prompt in a terminal |
missin capture save-schedule, missin capture save-integration-setting, missin posts set-partner-settings with --enabled, and missin partners set-handle-watched with "watched": true in --body | That this commits recurring spend: every scheduled run that follows spends credits, with no price | Allowed |
If the price moves between the quote and the start, a terminal is shown the new price and asked again. With --yes the command stops with exit code 2 and the new price. A capture that started on some platforms and not others says which started and which did not.
The API address
The CLI talks to the public API unless you set --base-url <url> or MISSIN_BASE_URL. Your key is sent to that address, so it must be https; plain http is accepted only for localhost and 127.0.0.1. Any address other than the default is announced on stderr.
--api-version <id> (or MISSIN_API_VERSION) sends a different API version than the one this CLI was built for; latest follows the current version. Versions and stability says how long an older version keeps working.
Run a local MCP server
MISSIN_API_KEY=sk_live_... npx -y @missin/cli mcp --toolsets partners,campaignsmissin mcp runs the same tools as the hosted server at https://api.missin.co.uk/mcp, over stdio, for any client that starts a command. It reads the key like every other command, from MISSIN_API_KEY or the login. Choose which tools load with --toolsets or MISSIN_TOOLSETS: core is the default and all loads everything. Names are checked the way the hosted server checks ?toolsets=. See Connect Claude to add it to Claude.
Standard output carries only the protocol; everything else goes to stderr. With no key the command exits with code 1 before it speaks MCP.