MCP Servers
MCP (Model Context Protocol) servers give the agent tools beyond the built-ins, such as querying your issue tracker or searching internal documentation. pw code connects to configured servers at startup, local processes or remote endpoints, and offers their tools to the agent alongside the built-in ones. Servers can also expose reusable prompts, which appear as slash commands.
Managing Servers from the CLI
The pw code mcp command group manages server configuration:
# Add a stdio server (the command goes after --)
pw code mcp add -e API_KEY=secret everything -- npx -y @modelcontextprotocol/server-everything
# Add a remote HTTP server to the shared <workspace>/.mcp.json
pw code mcp add --transport http -H "Authorization: Bearer token" --scope project context7 https://mcp.context7.com/mcp
# Fill in every value interactively
pw code mcp add
# Inspect configuration
pw code mcp list
pw code mcp get <name>
# Remove a server
pw code mcp remove <name>add takes the server name, then a URL for http/sse servers or a command after -- for stdio servers. Run it with no arguments to be prompted for each value.
| Flag | Meaning |
|---|---|
--transport | Server transport: stdio, http, or sse |
-e/--env KEY=VALUE | Environment variable for the server process (repeatable, stdio only) |
-H/--header "Key: Value" | Header sent on every request (repeatable, http/sse only) |
--timeout | Connection timeout for this server |
--scope | Config file the entry is written to (local, agents, project, or user) |
--force | Overwrite an existing entry with the same name |
The other subcommands:
list(aliasls) shows every configured server across all config files, marking which file is active and which are shadowed. Use-o jsonfor machine-readable output.get <name>prints one server's configuration (JSON by default,-o textfor a summary).remove <name>(aliasrm) deletes a server; if the name is defined in more than one file, you choose which one (or pass--scope).
See the CLI reference for the full flag list.
Where Servers Are Configured
Servers live in an mcpServers map, the same shape as Claude Desktop and Claude Code, so existing server configs paste in unchanged. Four files can hold the map, from highest to lowest precedence:
| Scope | File | Typical use |
|---|---|---|
local | <workspace>/.agents/settings.local.json | Personal, git-ignored (default for add) |
agents | <workspace>/.agents/settings.json | Project settings, shared via version control |
project | <workspace>/.mcp.json | The cross-tool standard MCP file |
user | ~/.config/pw/code.json | Global, every workspace |
Files replace, not merge
The runtime server set comes from one file only: the highest-precedence file with a non-empty mcpServers map supplies the entire set. A higher-precedence file replaces the whole map below it rather than adding to it, so servers defined in a shadowed file are inactive. pw code mcp add warns when a write lands in (or creates) a shadowing situation, and pw code mcp list shows which file is active.
The three workspace files are part of the configuration pw code asks you to approve at launch; until you approve, their servers do not load. See Workspace Trust.
Configuration Format
All four files use the same top-level shape. The type field ("stdio", "http", or "sse") is optional. When omitted, the transport is inferred: stdio if command is set, HTTP if url is set.
{
"mcpServers": {
"local-tools": {
"command": "uvx",
"args": ["some-mcp-server"],
"env": { "API_KEY": "${MY_KEY}" }
},
"remote": {
"type": "http",
"url": "https://mcp.example.com/mcp",
"headers": { "Authorization": "Bearer ${TOKEN}" }
}
}
}- stdio servers are spawned as a local process from
command+argsand speak MCP over stdin/stdout. Optionalenvadds environment variables. The server must keep stdout clean for the protocol and log to stderr only. - http and sse servers are remote endpoints reached via
url. Optionalheadersare sent on every request (the place for auth tokens).
${VAR} in env values and headers is expanded from your environment, so secrets can stay out of config files.
Connection Timeout
Each connect attempt is bounded so a dead server cannot hang the session. The timeout is resolved in this order: a per-server timeout in the server's config, then the MCP_TIMEOUT environment variable, then a 30-second default. Both accept a bare number of milliseconds (60000) or a duration string ("60s", "2m").
Tools and Permissions
Each discovered tool is exposed to the model as mcp__<server>__<tool>: a server named github with a list_prs tool becomes mcp__github__list_prs. MCP tools ask for confirmation before each call, like shell commands. To pre-approve a tool and skip the prompt, add it to your allow rules:
/permissions add mcp__github__list_prsor start the session with --allowedTools mcp__github__list_prs. MCP tools are not available in plan mode; in read-only mode only pre-approved tools can run, and in bypass-permissions mode they run without prompting. See Permissions.
Connection Behavior
In interactive sessions, servers connect in the background so startup is never blocked. Each server is announced in the transcript as it comes online, and a server that fails its first attempt is retried with backoff, useful for servers that download packages on first run. Run /mcp at any time to see each server's status (connected, connecting, or failed) and the tools it exposes.
In non-interactive mode (--prompt), there is only a single turn, so servers connect synchronously before it runs.
Prompts as Slash Commands
Servers can also expose prompts: reusable prompt templates. Each discovered prompt becomes a slash command named /mcp__<server>__<prompt>, shown in the command palette (type /) with a usage hint built from the prompt's declared arguments.
Arguments are space-separated and map positionally onto the prompt's declared arguments; quote a value to keep multiple words together, and extra trailing words fold into the last argument:
/mcp__github__pr_review 456
/mcp__jira__create_issue "Bug in login flow" highRunning the command renders the prompt on the server and sends the result as a normal agent turn. A missing required argument, an unknown prompt, or a server-side failure is reported in the transcript instead.
Related Documentation
- pw code Overview: Feature overview and quick start
- pw code mcp CLI reference: Full command and flag reference
- Permissions: Permission modes and allow rules
- Slash Commands: Built-in and custom commands
- Settings: Other
pw codeconfiguration - Non-Interactive Mode: Running with
--prompt