MCP Servers
pi-config does not ship an MCP client. Since pi 0.99.0, MCP is built into pi itself
(builtin:mcp), so servers are configured in mcp.json and managed with /mcp.
There is no external MCP binary to install and no separate bridge process.
Configuration
Servers live in mcp.json under a mcpServers key. pi reads the user-level file at
~/.pi/agent/mcp.json and a project-level mcp.json once the project is trusted.
{
"mcpServers": {
"local-jenkins": {
"command": "npx",
"args": ["-y", "mcp-jenkins"],
"env": { "JENKINS_URL": "https://jenkins.internal" }
},
"docs": {
"url": "https://mcp.example.com/mcp",
"headers": { "Authorization": "Bearer ${DOCS_TOKEN}" }
}
}
}
pi infers the transport from the keys present: command/args/env/cwd means stdio,
url/headers/oauth means streamable HTTP. The legacy SSE transport is not supported.
${VAR} in a value expands from the environment.
After editing mcp.json, run /mcp to reconnect, or restart pi.
Upgrading from the mcpc bridge
Before pi 0.99, pi-config reached MCP through the external mcpc binary, which read
~/.pi/pi-config/mcp.json. builtin:mcp reads ~/.pi/agent/mcp.json instead, so an
existing install would upgrade to a pi that finds no servers at all — silently, with no
error to look for.
pi-config copies the file across for you at startup, and only when
~/.pi/agent/mcp.json does not already exist. Your existing ~/.pi/agent/mcp.json is
never overwritten, and the old file is left in place for you to delete whenever you
like. The copy is logged to ~/.pi/logs/mcp-config-migration/; if it fails, the reason
is in there and you can copy the file by hand.
Managing servers
| Command | Purpose |
|---|---|
/mcp |
Interactive manager: state, tool count, exposure, and the config file each server came from |
/mcp reconnect |
Reconnect after editing mcp.json |
/mcp login / /mcp logout |
Manage OAuth for a server |
pi mcp list |
List configured servers from the shell |
pi mcp add / pi mcp remove |
Add or remove a server from the shell |
Outside the TUI, /mcp prints status.
How tools reach the model
An MCP server can expose dozens of tools. Declaring all of them on every request would
bloat the context window, so each server has an exposure that decides when its tools
become visible. The default is codemode, and it is the right choice for almost every
server.
| Exposure | Behaviour | Cost when unused |
|---|---|---|
codemode (default) |
Not declared to the model. Reached from codemode scripts, which find tools with searchTools(). |
0 |
codemode-deferred |
As above, and the tool list is not even in the codemode description — only the server name and tool count. |
0 |
deferred |
Not declared until the tool_search tool loads them, then called directly. |
0 |
direct |
Declared to the model like built-in tools. | Full schema, every request |
hidden |
Registered but not callable. | 0 |
The codemode description has its own budget, codemode.inlineBudget (default 3000
tokens). Tools that do not fit are found with searchTools(), so the cost of a large
server is bounded rather than proportional to its tool count.
Set a server's exposure, and per-tool overrides, in the same mcp.json:
{
"mcpServers": {
"jira": {
"command": "npx",
"args": ["-y", "mcp-jira"],
"exposure": "codemode"
},
"github": {
"url": "https://mcp.githubcopilot.com/mcp/",
"exposure": "deferred",
"toolExposure": {
"search_code": "direct",
"delete_*": "hidden"
}
}
}
}
toolExposure keys are tool names as the server offers them, or patterns where *
matches any characters. An exact name beats a pattern; among patterns the first match
wins. pi mcp list marks tools whose exposure differs from their server's.
Reserve direct for the one or two tools you reach for constantly. A server set to
direct costs tokens whether or not the task needs it.
Calling a tool
With codemode or deferred exposure, the agent writes a codemode script or lets
tool_search load the tool — there is no shell round-trip and no separate discovery
step. Tools loaded by tool_search are recorded in the transcript and stay declared on
that branch.
To confirm a server is healthy, run /mcp and check its state and tool count. pi logs
MCP activity to ~/.pi/agent/mcp.log.
Resources
Servers offering MCP resources gain list_mcp_resources, read_mcp_resource, and
list_mcp_resource_templates automatically. They reach every server whose exposure is
not hidden, and take the widest exposure among them.