Adding one
-, starting with a letter or digit. The URL must
be https.
/mcp add always writes to your profile root, never to the project. Adding a server is a
personal action, and a project’s servers.yaml is a committable file. Writing a URL you typed in
a terminal into a file you might share is not seri’s call to make.
The panel
/mcp opens the panel. Each row is a server, grouped by scope with the project’s first, showing
its connection state and how many tools are cached for it.
Connect, then trust
A server you added is not yet a server the model can call. You connect it from the panel, which dials it and fetches its tool catalog, then you look at what it offers and trust it. That order is the point. The catalog is what you are actually approving, and a server nobody has looked at has no business putting tools in front of the model.Authenticating
/mcp auth <name> runs the OAuth flow for one server. Run it when the panel says the server
needs authentication, and run it again whenever you want to renew.
It only opens a browser when it has to. The first thing it does is ask for authorization with
whatever credentials are already stored. If the refresh token is still good, that call comes back
authorized and the command finishes without a browser, without a consent screen, and without you
doing anything. Re-running /mcp auth on a working server is therefore a cheap way to refresh it
rather than a fresh sign-in.
When it does need you, it opens your browser and also prints the URL, because a headless
machine, a broken xdg-open or a browser that opens in the wrong profile all leave that URL as
the only way through.
You have five minutes to finish. A consent screen can involve a password manager, a second device
and a scope list worth reading, and the only thing the wait costs is a bound loopback port.
There are five ways it can end, and each is one line in the transcript rather than a crash.
Credentials are stored one file per server, at
mcp/auth/<name>.json in your profile root, so two
servers have independent lifecycles.
A stored credential is bound to the URL it was minted against. Repoint a name in
servers.yaml at a different host and the old record stops counting as authentication, so the new
host gets its own authorization rather than the previous host’s bearer token.The file
A server can also be written by hand, at.seri/mcp/servers.yaml in the project or under your
profile root.
${env:VAR} is the only expansion, and it reads an environment variable. Nothing here spawns a
shell. $(…) and every other shell-looking syntax is left exactly as written, because config
that executes shell at load is an anti-pattern seri refuses by design.
A server whose name or shape does not parse is skipped with a warning at startup rather than
failing the session.
What the tools are called
The model gets one tool, namedmcp. Its description lists every trusted server tool as
mcp_<server>_<tool>, and a call names one of those in its input rather than being a tool of its
own. So search on a server named github is mcp_github_search.
One composite tool rather than one per remote tool keeps the model’s tool array stable when a
server is added mid-session.
That composed name is what the permission gate, the approval prompt, a stored grant and a hook
matcher all see. It is computed once and never parsed back apart, because - in a server name
folds to _ and mcp_my_server_x would be ambiguous to decompose. The server itself only ever
receives its own unprefixed name.
Permissions
An MCP tool is not in the gate’s read list, so it is classified as a write and prompts in every mode. That is deliberate. A third party’s tool is exactly the case where “seri has not heard of it” is not evidence that it is safe. A permanent approval for an MCP tool is stored asmcp_<server>_<tool>@<digest>, where the
digest fingerprints the tool’s name, description and input schema at the moment you approved it.
Change the tool on the server’s end and the digest stops matching, so seri asks again rather than
trusting your old answer about a tool you never saw. See Permissions.
Removing one
/mcp remove <name> deletes the server and clears any stored credential for it. Dropping the
credential is not tidiness. Reusing that name later must not inherit a live access token the
previous server was trusted with.
