MCP servers
Keep one list of MCP servers, give it to every connected tool, and keep their tokens in the vault rather than in each tool's config.Why a library
Every coding tool keeps its own list of MCP servers in its own format, so the same server ends up configured three times, and its token sits in plaintext in three files. Synapse keeps one list instead. Each server is a small TOML file in the Synapse data directory, and its secrets are held as references into the vault rather than as values.
What a tool is given is not the server itself. It is synapse mcp run <name>, written through that tool's own mcp add. When the tool starts it, Synapse reads the library, fetches the secrets from the vault, and replaces itself with the real server. Nothing is proxied: the tool talks to the server directly and keeps everything its own client does, and Synapse is gone from the path the moment the server starts.
Adding a server
Describe it once. Everything after the bare -- is the command, so its own flags are never read as Synapse's:
synapse mcp add github -- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
synapse mcp show github
synapse mcp edit github
The file it writes has a command, its args, plain settings under [env], and secrets under [secrets]. A value can only be written under [env], which is what keeps a token out of it: the [secrets] table holds nothing but references.
command = "docker"
args = ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"]
[secrets]
GITHUB_PERSONAL_ACCESS_TOKEN = "mcp-github.github-personal-access-token"
Secrets
A secret is entered at a prompt or piped in, never passed as an argument, the same as every other secret Synapse holds:
synapse mcp secret github GITHUB_PERSONAL_ACCESS_TOKEN
Each server gets a vault of its own, named mcp-<server>, because a vault holds one secret per environment variable and two servers wanting GITHUB_TOKEN is ordinary. In the app, a server that still needs a secret shows a Set button beside it, and the value goes from the field straight into the vault.
A server is not started while anything is missing — a secret with no value, a setting left empty, or an argument still written as a <placeholder>. It is refused with a line saying what to fill in, rather than starting half-configured and failing somewhere less obvious.
Installing
synapse mcp install # every server, every tool that can hold one
synapse mcp install github --tool codex
synapse mcp status
synapse mcp uninstall github
Claude Code, Codex, and Ainz can each be given library servers. pi has no MCP client of its own, so it gets no row. A tool somebody describes can take them too by adding a [servers] section to its descriptor with the add, remove, and at templates.
What each state means
| State | Meaning |
|---|---|
| installed | The tool starts this server through Synapse, from this binary. |
| update available | Through Synapse, but from a binary that has moved. install rewrites it. |
| not ours | The tool already has its own server by this name. It is left alone unless you say to replace it. |
| not installed | The tool does not have it. |
Whether an entry is Synapse's is read from the entry itself — synapse mcp run <its own name> — so there is no record to drift from what the file says. synapse disconnect and synapse uninstall take every such entry back out; a reset does not, because fixing a connection is no reason to lose a tool's servers.
Adopting what you already have
A server a tool already has can move into the library. Every value its entry carries goes into the vault — all of them, not only the ones whose names look secret, because a value misjudged as harmless would sit in plaintext in the library.
synapse mcp adopt github --tool claude
synapse mcp install github --tool claude --replace
Adopting does not touch the tool. Its own entry still holds the token until you install over it with --replace, which swaps it for the run line and takes the plaintext out. In the app, that is the Swap button, offered only for the tool the server was adopted from.
Finding servers
synapse mcp search asks the official MCP Registry, and synapse mcp get turns an entry into a library server: an npm package becomes npx, a PyPI one uvx, a container image docker run. Whatever the entry needs and gives no value for is left for you to fill in.
synapse mcp search postgres
synapse mcp get io.github.owner/server-name
synapse mcp install server-name
The official registry is one source among any you add: an organisation's own registry, or a GitHub repository holding server.json files. See Sources.
Limits
- Remote servers, which a tool reaches over HTTP rather than starting, are not kept here. Add those in each tool directly.
- A server's secrets are handed to it whenever a tool starts it, from any folder. The mapping you set up is the permission; there is no per-project scope for library servers.
- Deleting a server with
synapse mcp delete <name> --confirmtakes it out of every tool Synapse gave it to and forgets its vault. A tool's own entry by the same name is left alone.