---
slug: "pi-mcp-bridge"
source_type: "readme"
source_url: "https://cdn.jsdelivr.net/gh/tmonk/pi-mcp-bridge@main/README.md"
repo: "https://github.com/tmonk/pi-mcp-bridge"
source_file: "README.md"
branch: "main"
---
# pi-mcp-bridge

A minimal MCP client extension for [pi](https://github.com/earendil-works/pi-coding-agent).

Attach any [MCP](https://modelcontextprotocol.io) server to pi. The extension spawns the server as a persistent subprocess, discovers its tools via the standard MCP handshake, and registers them so the pi agent can call them directly — no per-call startup overhead, no stubs.

## Install

```bash
# From pi.dev gallery
pi install https://github.com/tmonk/pi-mcp-bridge
```

```bash
# Or try without installing
MCP_SERVER_CMD="python -m my_mcp_server" pi -e https://github.com/tmonk/pi-mcp-bridge "Run my tool"
```

## Usage

```bash
# Load with an MCP server
MCP_SERVER_CMD="python -m my_mcp_server" pi "Run a query with my MCP tool"

# With a working directory and extra args
MCP_SERVER_DIR=~/projects/my-server MCP_SERVER_CMD="node server.js" MCP_SERVER_ARGS='["--port", "8080"]' pi "..."

# With pi's isolation flags
MCP_SERVER_DIR=~/projects/my-server pi -p --no-extensions --no-skills "Use the registered tool"
```

## How it works

1. **On load** — spawns the MCP server as a persistent subprocess and completes the initialization handshake (`initialize` → `notifications/initialized`).
2. **Discovery** — issues `tools/list`, then calls `pi.registerTool()` for each discovered tool with dynamically converted TypeBox parameter schemas.
3. **Execution** — when the agent calls a tool, sends `tools/call` over the persistent connection and returns the result. No subprocess spawned per call.
4. **Cleanup** — on `session_shutdown`, gracefully shuts down the server (SIGTERM → SIGKILL after 2s).

## Configuration

| Variable | Description |
|---|---|
| `MCP_SERVER_CMD` | Command to run the MCP server **(required)** |
| `MCP_SERVER_DIR` | Working directory for the server (optional) |
| `MCP_SERVER_ARGS` | JSON array of extra CLI arguments (optional) |

## Features

- **Persistent connection** — single subprocess for all tool calls (10x+ faster for warm calls vs. spawn-per-call)
- **Dynamic schemas** — MCP `inputSchema` → TypeBox conversion gives the LLM proper parameter types for each tool
- **Concurrent requests** — JSON-RPC ID-based promise matching handles overlapping tool calls
- **Graceful shutdown** — protocol-level shutdown + SIGTERM + SIGKILL fallback
- **Timeout protection** — per-request timeout (default 30s) prevents hanging on unresponsive servers
- **Stderr forwarding** — server diagnostics are forwarded to pi's stderr

## Development

```bash
git clone https://github.com/tmonk/pi-mcp-bridge
cd pi-mcp-bridge
npm install
npm test
```

The extension is a single `index.ts` file. Pi loads it via jiti — no build step.

## Test

```bash
npm test            # 35 tests (unit + integration + e2e)
npm run test:watch  # watch mode
npm run test:coverage
```

## License

MIT
