diff --git a/packages/coding-agent/docs/mcp.md b/packages/coding-agent/docs/mcp.md index ea200d204..50d8832a1 100644 --- a/packages/coding-agent/docs/mcp.md +++ b/packages/coding-agent/docs/mcp.md @@ -1,10 +1,37 @@ # MCP Servers -Pi connects to [Model Context Protocol](https://modelcontextprotocol.io) servers over stdio or streamable HTTP and makes their tools available to the model. +Pi connects to [Model Context Protocol](https://modelcontextprotocol.io) servers over stdio or streamable HTTP and makes their tools and resources available to the model. + +## Quick setup + +Add a local stdio server, check the connection, then start Pi: + +```bash +pi mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem . +pi mcp list +pi +``` + +For a remote server: + +```bash +pi mcp add docs --url https://example.com/mcp --bearer-token-env-var DOCS_TOKEN +pi mcp list +``` + +These commands add user-level servers by default. Add `--local` or `-l` to write the project configuration instead: + +```bash +pi mcp add -l tools --env API_KEY='${TOOLS_KEY}' -- uvx tools-mcp +``` + +Use `/mcp` inside an interactive session to inspect connections, sign in, reconnect, change exposure, or enable and disable servers. Run `/reload` after adding, removing, or changing a server outside the session. ## Configure servers -Add servers to `~/.pi/agent/mcp.json`, or to `.pi/mcp.json` in a project. The format matches other MCP clients, so existing `mcpServers` entries can be copied over: +Pi reads user-level servers from `~/.pi/agent/mcp.json` and project servers from `.pi/mcp.json`. Project configuration is read only after [project trust](security.md#understand-project-trust) is granted. A project entry replaces a user-level entry with the same name. + +The format matches other MCP clients: ```json { @@ -22,71 +49,59 @@ Add servers to `~/.pi/agent/mcp.json`, or to `.pi/mcp.json` in a project. The fo } ``` -- stdio servers take `command`, `args`, `env`, and `cwd`. Relative `cwd` resolves against the session directory. A leading `~/` in `command`, an argument, or `cwd` names the home directory. -- HTTP servers take `url`, `headers`, and `oauth` (see [Sign in with OAuth](#sign-in-with-oauth)). The legacy SSE transport is not supported. -- `env` and `headers` values can reference environment variables (`${NAME}`) or commands (`!command`), like provider API keys. -- `timeout` sets the per-request timeout in seconds (default 60). Progress notifications from the server reset it. -- `enabled: false` keeps an entry without connecting to it. +Stdio servers use `command`, `args`, `env`, and `cwd`. Relative `cwd` values resolve against the session directory. A leading `~/` in `command`, an argument, or `cwd` names the home directory. -Project entries replace global entries with the same name. A project `mcp.json` is only read after the project is trusted, because stdio servers run commands. +HTTP servers use `url`, `headers`, and `oauth` (see [Authenticate with OAuth](#authenticate-with-oauth)). The legacy SSE transport is not supported. -`pi mcp add` and `pi mcp remove` edit the file from a shell (see [MCP commands](cli.md#mcp-commands)): +Both server types support: -```bash -pi mcp add filesystem -- npx -y @modelcontextprotocol/server-filesystem . -pi mcp add docs --url https://example.com/mcp --bearer-token-env-var DOCS_TOKEN --exposure direct -pi mcp add -l tools --env API_KEY='${TOOLS_KEY}' -- uvx tools-mcp -pi mcp remove docs -``` +- `timeout`: per-request timeout in seconds (default 60). Progress notifications reset it. +- `enabled: false`: keep the entry without connecting to it. +- `exposure` and `toolExposure`: control how tools reach the model (see [Control tool exposure](#control-tool-exposure)). -Rules that are easy to get wrong: +Keep personal servers and servers with credentials in the user-level file. Use the project file only for servers the project requires, and only in trusted projects. -- Server names may only contain letters, digits, `_`, and `-`. Tools are named `mcp____`. -- `type` is optional: a `command` makes a stdio server and a `url` a streamable HTTP server. When present, it must be `stdio`, `http`, or `streamable-http`. `sse` is rejected; most servers that document an SSE endpoint also serve streamable HTTP, often at `/mcp` instead of `/sse`. -- `command` is a single executable and `args` its arguments, not one shell string. -- Keep secrets out of the file: use `${NAME}` for environment variables, as in `"Authorization": "Bearer ${GITHUB_TOKEN}"`, or `!command` to run a command. A command must make up the whole value, so it has to print the header value itself: `"Authorization": "!echo Bearer $(gh auth token)"`. -- Invalid entries are skipped and reported; the other servers still connect. +### Configuration rules -## Set up servers +- Server names may contain only letters, digits, `_`, and `-`. Tools are named `mcp____`. +- `type` is optional. A `command` selects stdio and a `url` selects streamable HTTP. When present, `type` must be `stdio`, `http`, or `streamable-http`. +- `sse` is rejected. Servers that document an SSE endpoint often also provide streamable HTTP, commonly at `/mcp` instead of `/sse`. +- `command` is one executable and `args` contains its arguments. It is not a shell command string. +- `env` and `headers` values can use environment variables such as `${GITHUB_TOKEN}`. They can also run a command with `!command`, but the command must make up the whole value, for example `"Authorization": "!echo Bearer $(gh auth token)"`. +- Invalid entries are reported and skipped without preventing other servers from connecting. -When asked to add an MCP server, the agent should: +`pi mcp add` and `pi mcp remove` cover common changes from a shell. See [MCP commands](cli.md#mcp-commands) for their options. -1. Add simple servers with `pi mcp add` (add `-l` for the project file), or edit `mcp.json` directly for settings the command does not cover. Put personal servers and servers with credentials in `~/.pi/agent/mcp.json`. Use the project `.pi/mcp.json` only for servers the project itself needs, and only in trusted projects. -2. Convert entries written for other clients: - - Claude Desktop, Claude Code, and Cursor use the same `mcpServers` shape; copy the entry. - - VS Code uses a top-level `servers` object and `inputs` prompts; move the entry under `mcpServers` and replace `${input:...}` with `${NAME}` environment variables. - - Codex uses TOML (`[mcp_servers.]` with `command`, `args`, `env`, or `url`); write the same fields as JSON. - - opencode uses `"type": "local"` with `command` as an array (split it into `command` and `args`), `"type": "remote"` for URLs, `environment` for `env`, and `{env:NAME}` for `${NAME}`. -3. Run `pi mcp list` to check the entry. It connects to every enabled server and prints the state, the tools, and errors such as the stderr of a stdio server that failed to start. It exits with 1 while anything is wrong. -4. For a server that needs a sign-in, run `pi mcp login `. It opens the authorization page in the user's browser and waits until the user approves access; tell the user to approve it. A running session uses the new credentials on its next turn. -5. Tell the user to run `/reload` (or start a new session) so the running session connects to added or changed servers. +### Inspect or change a server -Pi connects when a session starts. The first prompt waits up to 10 seconds for startup connections; the tools of servers that take longer become available once they connect. HTTP connections that fail with a network error or a transient status (408, 429, 5xx) are retried twice. A server that drops its connection shows as disconnected and is reconnected on the next call. When a server announces that its tool list changed, new tools are added and withdrawn tools become unreachable until the server offers them again. +`/mcp` lists configured servers with their state, tool count, exposure, and configuration source. Servers that need attention appear first. Select a server to inspect its tools and connection details, reconnect, sign in or out, change exposure, or enable and disable it. -Config errors, servers that failed to connect, and servers that need a sign-in are reported once after startup. +Exposure and enabled-state changes are saved to the file that defines the server without replacing unrelated content. Disabled servers remain listed. Outside the interactive TUI, `/mcp` prints server status; `/mcp login `, `/mcp logout `, and `/mcp reconnect ` perform those actions directly. -Log messages servers send with MCP logging notifications are appended to `~/.pi/agent/mcp.log` as `