CLI reference

Every finch command, grouped by what you do with it. finch runs on macOS and Linux. Run finch on its own for the list of commands, and finch help <command> (or finch <command> -h) for one command's usage, flags and an example.

Driving finch with an agent? Point it at /agents.md, a step-by-step guide written for agents (the installed binary prints a copy with finch guide). Every command below takes --json, so the only step that needs you is approving the login. One paste does it: “Read https://finchmcp.com/agents.md and use finch to publish my MCP server on http://127.0.0.1:8000 as notes. Show me the sign-in link when you get it. Run it as a background service, check it with finch test, then connect it to this agent.”

By hand, start to finish

finch login                                     # opens the sign-in page and waits
finch add notes --service http://127.0.0.1:8000   # prints the public URL
finch service install                           # keep it running in the background
finch test notes                                # does it answer through finch?
finch connect notes --client claude-code        # add it to your MCP client

Set up

CommandWhat it does
finch loginLog this machine in to your account. Prints a link and a short code, opens the link in your browser and waits until you approve it. You can approve on any device, such as your phone. --headless skips the local browser (use it over SSH). --hub URL logs in to another finch hub.
finch add <name> --service <url>Publish the local app at <url> as <name>: add it to your account and to finch.yml, and print its public URL (JSON field url). The name becomes the URL segment, <account address>.finchmcp.com/<name>/, lowercased and with each run of other characters turned into - (My_API.v1 is published as my-api-v1; see names). Running it again for a name this machine already serves updates that service's local URL instead of adding a second service, and restarts the background service if it is running.
  --publicLet anyone with the URL in, with no key. Change it later with finch auth.
  --forward-allForward every path under /<name>/ to the app, for a web app or REST API. Without it finch forwards only /<name>/mcp. See Web apps and REST APIs.
finch service installRun finch in the background: it starts at login and restarts if it exits. A launchd LaunchAgent (~/Library/LaunchAgents/com.finchmcp.finch.plist) on macOS, a systemd user unit (finch.service) on Linux. Safe to run again, and running it again is how you apply changes to finch.yml. It waits for every service to connect and exits 1 if finch does not come up or a service has not connected within about 20 seconds; the unit stays installed and the message says why. On a headless Linux machine, sudo loginctl enable-linger $USER keeps it running after you log out.
finch service status / uninstallSay whether the background service is installed and running, or stop and remove it. uninstall exits 1 and keeps the unit if finch could not be stopped.
finch run [--config finch.yml]Serve every service in finch.yml in the foreground, until you press Ctrl-C.

Log in from a script or agent

Plain finch login waits for you and has no --json form. Scripts and agents split it in two, so they can show you the link and keep working:

CommandWhat it does
finch login --startStart a login and return at once. Prints the sign-in link and code (JSON: user_code, verification_uri_complete, expires_in, interval) and saves the pending login to ~/.finch/login-pending.json (mode 0600).
finch login --pollCheck the pending login once. Exit 0 when approved, 10 while it waits, 11 once the code has expired. JSON: {"status":"approved"|"pending"|"expired"}. Until it resolves, every other command reports APPROVAL_PENDING, even when an older login is saved.
finch login --cancelDrop a login started with --start. The saved login, if any, works again. JSON: {"cancelled":true|false}.
finch login --token -Log in with a token from finch token, read from stdin (or set FINCH_CLI_TOKEN). A token passed as an argument works but warns: it lands in the process list and shell history.

Connect a client

CommandWhat it does
finch connect <name> --client claude-codeMakes a finch_ key scoped to the service, saves it to ~/.finch/connect/<name>.claude-code.json (mode 0600), and adds the server to the current directory's Claude Code project with claude mcp add-json. The entry's headersHelper reads the key from that file, so the key never appears in a command line. Claude Code runs the helper only in a trusted workspace. Needs the claude CLI on PATH.
finch connect <name> --client cursorMakes a key and adds the server to ~/.cursor/mcp.json, keeping every other entry.
finch connect <name> --client codexMakes a key and writes [mcp_servers.<name>] into ~/.codex/config.toml, keeping the rest of the file.
finch connect <name> --client jsonMakes a key and prints an mcpServers JSON snippet for any other client. This is the only mode that prints the key.

Each connect makes its own key, labelled with the client and machine, so you can revoke one client with finch keys revoke <id> without touching the others. The client is checked before a key is made, and a key whose setup fails is revoked again. A public service gets no key. Running connect again for Claude Code, Cursor or Codex replaces the entry and revokes the key the old entry used (listed as revoked_key_ids in --json), so re-running it rotates the key. Every Claude Code project on the machine connected to the same service shares the one key file, so they all move to the new key.

See what's happening

CommandWhat it does
finch statusThis machine at a glance: whether you are logged in (logged_in; loggedIn is kept for older scripts) or a login is waiting for approval (login_pending), which services its finch.yml serves and their public URLs (url, when logged in and finch answers), and whether the background service is installed and running. It always exits 0; read the fields.
finch fleetEvery service on your account, with its state (online, offline, pending) and public URL (url). Alias: finch ls.
finch logs <name>Recent calls to a service: time, route, caller, status and duration. --limit N sets how many. This is the whole call record finch keeps; request and response bodies are never stored (see Privacy).
finch versionThe installed version and platform.
finch guidePrint the step-by-step guide for agents.

Test a service

CommandWhat it does
finch test <name>Open an MCP session with the service through finch and list its tools. Exits non-zero when that fails, and the message says which part failed. If your server refuses the session with HTTP 406, or a 400 that mentions the session, it starts with “the server rejected the MCP handshake” and quotes the answer. Other refusals name the status or the error, as “<name> answered tools/list with HTTP <status>” or “<name> answered tools/list with an MCP error” followed by the answer, even when it was the opening handshake your server refused. A 401 says your MCP server asks for its own credentials, and a 5xx reads “<name> did not answer through finch”.
finch call <name> <tool> [--args '{...}']Call one MCP tool through finch. --args takes a JSON object. A tool that reports an error exits 1.
finch test notes
notes — 2 tool(s):
  • search           Search notes
  • read             Read one note
finch call notes search --args '{"q":"finch"}'

Keys and tokens

CommandWhat it does
finch keys mint <label> --service <name>Make a finch_ key for a client, scoped to one service. The key prints once. --all scopes it to every service instead.
finch keys listList client keys (id and label).
finch keys revoke <id>Revoke a client key. Access stops immediately.
finch token [--login]Make a fresh login token on a logged-in machine, to set up another machine without a browser. --login prints a ready-to-run finch login command that feeds the token on stdin.
finch revoke-tokensLog out every machine, including the one you run it on.
Two kinds of credentials. The login token (about 30 days) is what a machine uses to manage your account: add services, make keys, revoke access. finch_ keys are what clients present to reach your services. See Keys & auth.

Manage

CommandWhat it does
finch auth <name> public|keyChoose whether callers need a finch_ key (or OAuth sign-in). public lets anyone in.
finch rm <name>Remove a service: from your account, from this machine's finch.yml, and its credential on this machine.
finch update [--force]Update finch to the latest version and restart the background service on it. When you already have the latest it says so (“finch 1.8.0 is already the latest”) and downloads nothing; --force reinstalls anyway. --restart auto|service|self|none controls the restart.
finch domain lsList custom hostnames on your account; finch domain add <hostname> and finch domain rm <hostname> manage them. Custom hostnames don't serve traffic yet; see Domains.

Remove finch

finch uninstall

finch uninstall takes finch off this machine and prints each step as it goes. It:

It never deletes the finch binary itself; it prints the command that does. Your account and services stay; finch rm <name> removes a service, and finch revoke-tokens logs out every other machine. With --json it reports each step.

Less common

CommandWhat it does
finch enroll <name> --ticket -On a machine with no login: trade a one-time ticket (stdin, or FINCH_TICKET) for a credential that serves one service. A logged-in machine uses finch add instead.
finch approve <name>Approve a service that a machine enrolled with a ticket, which waits as pending until you do. Run it from a logged-in machine. Services you add with finch add never need it.

JSON output and exit codes

Every command takes --json. Success payloads go to stdout and carry "schema_version":1. Lists are wrapped in an object: finch fleet --json prints {"schema_version":1,"services":[…]}. Field names are snake_case. Errors go to stderr as one line:

{"schema_version":1,"error":{"code":"NOT_LOGGED_IN","message":"not logged in","next":"finch login --start"}}

When next is present, it is the command to run next. Exit codes are the same everywhere:

ExitMeaningError codes
0OK
1ErrorNOT_FOUND, UPSTREAM (finch or your server failed), INTERNAL (a local problem)
2Usage: the command line was wrongUSAGE
10Waiting for login approvalAPPROVAL_PENDING
11The login code expiredEXPIRED
12Not logged in, or the login was revokedNOT_LOGGED_IN
finch status --json
{"schema_version":1,"account":"you@example.com","config":"/Users/you/.finch/finch.yml",
 "hub":"https://finchmcp.com","hub_reachable":true,
 "ingress":[{"app_path":"notes","service":"http://127.0.0.1:8000",
   "url":"https://sunny-wren-42.finchmcp.com/notes/mcp"}],
 "loggedIn":true,"logged_in":true,"login_pending":false,
 "service":{"installed":true,"manager":"launchd","running":true,…},
 "version":"1.8.0",…}

finch.yml

finch add writes this file (at ~/.finch/finch.yml unless the current directory has a finch.yml). It holds no secrets; credentials are saved separately under ~/.finch/.

hub: https://finchmcp.com
box: studio                          # this machine's name
ingress:
  - app_path: notes                  # the service name: sunny-wren-42.finchmcp.com/notes/
    service: http://127.0.0.1:8000
  - app_path: demo
    service: http://127.0.0.1:3000
    forward_all: true                # set by --forward-all