CLI Commands
CLI Reference
Section titled “CLI Reference”mcpfleet [command] [flags]Run mcpfleet <command> --help for the same information in your terminal.
Global flags
Section titled “Global flags”| Flag | Description |
|---|---|
-h, --help |
Show help for any command |
-v, --verbose |
Print debug logs to stderr (for example, which registry apply uses and which config file it writes). Without it, commands print only warnings and errors to stderr; results go to stdout |
--version |
Print the version, commit and build date, e.g. mcpfleet version 0.1.0 (commit abc1234, built 2026-11-05T10:00:00Z) |
Registry and credentials
Section titled “Registry and credentials”Every command that talks to the registry (list, apply, push, pull, delete) needs a stored token and a registry URL.
| What | Where it comes from |
|---|---|
| Registry URL | 1. MCPFLEET_REGISTRY_URL environment variable2. ~/.config/mcpfleet/registry_url (written by auth login --url)3. Default: https://registry.mcpfleet.dev |
| Auth token | ~/.config/mcpfleet/token (written by auth login, file mode 0600) |
Secrets for env and headers values |
~/.config/mcpfleet/vault.enc, encrypted with a key kept in the OS keyring |
No public registry answers at the default URL yet: point mcpfleet at your own registry (see Self-Hosting the Registry) with auth login --url or MCPFLEET_REGISTRY_URL. When nothing answers at the default URL, commands that talk to the registry fail with registry: request failed: … — no registry answers at the default URL https://registry.mcpfleet.dev; point mcpfleet at your registry with 'mcpfleet auth login --url <registry>' or MCPFLEET_REGISTRY_URL.
A trailing / on the registry URL is ignored. Without a stored token list, push, pull and delete fail with Error: registry client: registry: not authenticated — run 'mcpfleet auth login' first, and apply fails with Error: registry: not authenticated — run 'mcpfleet auth login' first.
mcpfleet
Section titled “mcpfleet”Without a subcommand, mcpfleet opens a terminal UI with three tabs:
- Dashboard: the number of servers in the registry and of supported agents
- Servers: the servers stored in the registry
- Adapters: every supported agent and the config file mcpfleet writes for it
Keys: tab switches tabs, 1–3 jump to a tab, q or ctrl+c quits.
The tabs stay empty until you log in with mcpfleet auth login.
mcpfleet auth
Section titled “mcpfleet auth”mcpfleet auth login
Section titled “mcpfleet auth login”Store the registry URL and the auth token.
mcpfleet auth login [--url <registry-url>] [--token <token>]| Flag | Description |
|---|---|
--url <url> |
Registry URL, saved to ~/.config/mcpfleet/registry_url for later commands |
--token <token> |
Auth token for non-interactive use (scripts, CI) |
Without --token, an interactive form asks for the registry URL and the token. With --token, no form is shown.
- The URL must be an absolute
http://orhttps://URL with a host. An invalid URL fails before anything is saved. - An empty URL keeps the previously saved one (or the default).
MCPFLEET_REGISTRY_URL, when set, still wins over the saved URL.- Login does not contact the registry. A wrong token shows up on the next command as
registry: token invalid or expired.
# Interactivemcpfleet auth login
# Non-interactive (self-hosted registry)mcpfleet auth login --url http://localhost:8080 --token mcp_0123abcd...mcpfleet auth logout
Section titled “mcpfleet auth logout”Delete the stored token. The saved registry URL stays. Prints Not logged in. when there is no token.
mcpfleet auth logoutmcpfleet auth status
Section titled “mcpfleet auth status”Show whether a token is stored, with the token masked, and the registry URL later commands use, with where it came from: MCPFLEET_REGISTRY_URL, ~/.config/mcpfleet/registry_url or default (see Registry and credentials). The Registry: line is printed also when you are not logged in. This command only reads local files and environment and does not contact the registry.
mcpfleet auth status✓ Logged in (token: mcp_************beae)Registry: https://registry.example.com (from MCPFLEET_REGISTRY_URL)Not logged in.Registry: https://registry.mcpfleet.dev (from default)mcpfleet list
Section titled “mcpfleet list”List all MCP servers in the registry. Alias: ls.
mcpfleet list [--json]| Flag | Description |
|---|---|
--json |
Print the servers as a JSON array instead of the table |
MCP Servers
NAME TRANSPORT TARGET---- --------- ------filesystem stdio npx -y @modelcontextprotocol/server-filesystem '/home/me/My Projects'github stdio npx -y @modelcontextprotocol/server-githubremote-api http https://example.com/mcpTRANSPORT is stdio, http or sse; a server stored without a transport shows as stdio. TARGET is the command with its arguments for a stdio server and the url for an http or sse server. A server with no command or URL shows -.
The command and each argument in TARGET are quoted like words in a POSIX shell, so an argument with a space reads as one argument: /home/me/My Projects shows as '/home/me/My Projects', an empty argument as '', and it's as 'it'\''s'. A word that holds only letters, digits and @ % + = : , . / _ - is printed as is. Characters such as $ and ~ are quoted too, because the agent passes arguments literally, without expanding them.
An empty registry prints No servers registered.
JSON output
Section titled “JSON output”With --json, list prints a JSON array with one object per server, using the same keys as a file for push — push reads JSON as well as YAML, so the output works as a backup you can push back:
mcpfleet list --json > servers.jsonmcpfleet push servers.json[ { "name": "github", "description": "GitHub MCP server", "transport": "stdio", "install": { "type": "npx", "package": "@modelcontextprotocol/server-github" }, "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-github" ], "env": { "GITHUB_TOKEN": { "secret": "github_token" } }, "tags": [ "dev" ] }, { "name": "remote-api", "transport": "http", "install": { "type": "", "package": "" }, "command": "", "url": "https://example.com/mcp", "headers": { "Authorization": { "secret": "example_auth" } } }]- Secrets appear only as references (
{"secret": "<name>"}), never as values:listdoes not read your local vault. Literal values stored in the registry ({"value": "…"}) are printed as stored. - The registry’s
id,created_atandupdated_atfields are not included. - An empty registry prints
[], with no header or message, so scripts can always parse the output. - Characters such as
&in URLs are printed as is, not escaped.
For example, to print the names of the servers tagged dev with jq:
mcpfleet list --json | jq -r '.[] | select(.tags // [] | index("dev")) | .name'filesystem stdio npx -y @modelcontextprotocol/server-filesystem /home/me/projects github stdio npx -y @modelcontextprotocol/server-github remote-api http https://example.com/mcp
`TRANSPORT` is `stdio`, `http` or `sse`; a server stored without a transport shows as `stdio`. `TARGET` is the command with its arguments for a `stdio` server and the `url` for an `http` or `sse` server. A server with no command or URL shows `-`.
An empty registry prints `No servers registered.`
---
## `mcpfleet apply`
Write the registry's server definitions into one agent's config file.
```bashmcpfleet apply <agent> [--tag <tag>]...<agent> is exactly one of: claude-code, claude-desktop, crush, cursor, windsurf, zed. See Agents for the file each one writes and how the merge works.
| Flag | Description |
|---|---|
--tag <tag> |
Apply only servers that have this tag. Repeat the flag (or pass a comma-separated list) to apply servers that have any of the tags. Without --tag, all servers are applied |
Before writing, env entries of a local server and headers entries of a remote server that reference a secret ({"secret": "<name>"}) are replaced by the value stored under that name in the local vault (store it with mcpfleet secret set). If a referenced secret is not in the vault, apply stops with an error that names every missing secret, with its server and variable or header, and writes nothing:
Error: missing secrets in vault: github_token (server github, env GITHUB_TOKEN), example_auth (server remote-api, header Authorization); set them with: mcpfleet secret set <name>The env of a remote server is not written to any agent, so its secrets are not read.
If the vault cannot be opened (for example the OS keyring is locked), apply also stops before writing and shows the vault error. The vault is opened only when an applied server references a secret, so apply without secret references never asks for the keyring.
Remote servers (transport: http or sse) are written in the format each agent reads. A server the agent’s config file cannot hold (an http or sse server for claude-desktop, an sse server for zed), or a remote server without a url, is skipped with a warning on stderr; the other servers are still written and the Applied count leaves the skipped ones out. A skipped server’s secrets are not read from the vault. See Remote servers.
warning: skipping linear: claude-desktop does not support http servers in its config filemcpfleet apply cursormcpfleet apply --tag dev cursormcpfleet apply --tag dev --tag vcs claude-codemcpfleet apply claude-desktop✓ Applied 2 MCP server(s) to claude-codemcpfleet push
Section titled “mcpfleet push”Create or update servers in the registry from a YAML file.
mcpfleet push <file>The file is a YAML list of servers (the same format pull writes):
- name: filesystem description: Read and write files in ~/projects command: npx args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/me/projects"] tags: [dev]- name: github command: npx args: ["-y", "@modelcontextprotocol/server-github"] env: GITHUB_TOKEN: secret: github_token # resolved from the local vault on apply LOG_LEVEL: value: debug tags: [dev, vcs]- name: remote-api description: Remote MCP server over HTTP transport: http url: https://example.com/mcp headers: Authorization: secret: example_auth # the whole value, e.g. "Bearer <token>"| Field | Description |
|---|---|
name |
Unique server name (required) |
description |
Free text |
transport |
stdio, sse or http; the registry stores stdio when empty |
install |
type (npx, uvx, docker, binary, go), package, version |
command, args |
The command the agent starts; command is required for stdio and must be left out for sse and http |
url |
Address of a remote server, an absolute http:// or https:// URL; required for sse and http, left out for stdio |
env |
Map of variable name to {value: ...} or {secret: ...} |
headers |
sse and http only: map of HTTP header name to {value: ...} or {secret: ...}. Authorization, Proxy-Authorization and Cookie need a secret (see header rules) |
tags |
Labels used by apply --tag |
platforms |
linux, darwin, windows |
For each server, push looks the name up in the registry: an existing server is replaced as a whole (fields missing from the file are cleared), a new one is created.
created filesystemupdated githubThe registry checks each server before storing it (transport rules, header rules). A server that breaks a rule stops the push with the field and the reason, e.g.:
Error: create server "remote-api": registry: validation failed: body.url: url is required for transport sseError: create server "remote-api": registry: validation failed: body.headers.Authorization: use {"secret": ...} for credential headers; the registry does not store secret valuesServers earlier in the file are already stored at that point; fix the file and run push again.
mcpfleet pull
Section titled “mcpfleet pull”Write all servers from the registry to a YAML file. An existing file is overwritten.
mcpfleet pull <file>pulled 2 server(s) -> servers.yamlSecret references stay references: pull never writes secret values.
mcpfleet delete
Section titled “mcpfleet delete”Remove a server from the registry by name. Alias: rm.
mcpfleet delete <name>Server "github" removed from registry.When no server has that name, delete fails with exit code 1:
Error: server "github" not found in registryThis needs a registry that answers 404 for an unknown server; an older registry answers 204, and delete then reports success. delete does not touch agent config files: remove the entry there by hand if you no longer want it.
mcpfleet secret
Section titled “mcpfleet secret”Manage the secrets in the local vault (~/.config/mcpfleet/vault.enc, encrypted with AES-256-GCM, key in the OS keyring). Registry entries refer to them by name (env: GITHUB_TOKEN: {secret: github_token}), and apply fills in the values. Secrets never leave your machine.
mcpfleet secret set
Section titled “mcpfleet secret set”Store a secret, or replace the value of an existing one.
mcpfleet secret set <name> [--stdin]| Flag | Description |
|---|---|
--stdin |
Read the value from standard input instead of the hidden prompt. One trailing newline (\n or \r\n) is dropped, everything else is kept |
The value is never taken from an argument, so it does not end up in your shell history. Without --stdin, a prompt asks for the value and does not show what you type; when standard input is not a terminal, the command fails with stdin is not a terminal; pipe the value with --stdin. An empty value is rejected. The name can be any non-empty string without leading or trailing spaces; use the name the registry entry references.
mcpfleet secret set github_tokenprintf '%s' "$GITHUB_TOKEN" | mcpfleet secret set github_token --stdin✓ Saved secret github_tokenReplacing an existing secret prints ✓ Updated secret github_token.
mcpfleet secret list
Section titled “mcpfleet secret list”Print the names of the stored secrets, one per line, sorted. Values are never printed.
mcpfleet secret listgithub_tokenslack_tokenWith no secrets stored, nothing goes to stdout and a hint goes to stderr.
mcpfleet secret rm
Section titled “mcpfleet secret rm”Remove a secret from the vault.
mcpfleet secret rm <name>✓ Removed secret github_tokenA name that is not in the vault fails with secret "<name>" not found.
mcpfleet completion
Section titled “mcpfleet completion”Generate a shell completion script (bash, zsh, fish or powershell).
mcpfleet completion zsh > "${fpath[1]}/_mcpfleet"Errors and exit codes
Section titled “Errors and exit codes”Errors go to stderr as Error: <message>, for example:
Error: unknown agent "nope" (supported: claude-code, claude-desktop, crush, cursor, windsurf, zed)| Code | Meaning |
|---|---|
0 |
Success |
1 |
Any error |