# MCP Servers

> Source: https://parallelworks.com/docs/ai/code/mcp

# MCP Servers

MCP ([Model Context Protocol](https://modelcontextprotocol.io)) 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:

```bash
# 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` (alias `ls`) shows every configured server across all config files, marking which file is active and which are shadowed. Use `-o json` for machine-readable output.
- `get <name>` prints one server's configuration (JSON by default, `-o text` for a summary).
- `remove <name>` (alias `rm`) deletes a server; if the name is defined in more than one file, you choose which one (or pass `--scope`).

See the [CLI reference](/docs/cli/pw/code/mcp) 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 |

:::warning 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](/docs/ai/code/settings#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.

```json
{
  "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` + `args` and speak MCP over stdin/stdout. Optional `env` adds 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`. Optional `headers` are 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:

```text
/permissions add mcp__github__list_prs
```

or 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](/docs/ai/code/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:

```text
/mcp__github__pr_review 456
/mcp__jira__create_issue "Bug in login flow" high
```

Running 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](/docs/ai/code): Feature overview and quick start
- [pw code mcp CLI reference](/docs/cli/pw/code/mcp): Full command and flag reference
- [Permissions](/docs/ai/code/permissions): Permission modes and allow rules
- [Slash Commands](/docs/ai/code/slash-commands): Built-in and custom commands
- [Settings](/docs/ai/code/settings): Other `pw code` configuration
- [Non-Interactive Mode](/docs/ai/code/non-interactive): Running with `--prompt`
