pi-mcp
by zhaob1n
README.md
# pi-mcp
MCP server that exposes [pi](https://github.com/earendil-works/pi) coding-agent tools:
`read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`
Built with Deno and `@modelcontextprotocol/server` v2. Serves both the 2026-07-28 era (`server/discover`) and 2025-era `initialize`.
## Requirements
- Deno >= 2.9
- `rg` and `fd` on `PATH` (used by `grep` / `find`; never downloaded by pi-mcp)
## Install
From a checkout:
```sh
deno install -g -A -n pi-mcp --config deno.json ./src/cli.ts
```
Passing `--config deno.json` makes the installed command use this project's Deno configuration instead of relying on auto-discovery during installation.
By default, Deno installs the launcher under `~/.deno/bin`. If that directory is not on your `PATH`, you can either add it or choose a different installation root.
For example, to install `pi-mcp` as `~/.local/bin/pi-mcp`:
```sh
deno install -g -A -n pi-mcp --config deno.json --root "$HOME/.local" ./src/cli.ts
```
Deno places global executables in the `bin` subdirectory of the installation root, so `--root "$HOME/.local"` means `~/.local/bin`.
You can also set `DENO_INSTALL_ROOT` instead of passing `--root` each time:
```sh
export DENO_INSTALL_ROOT="$HOME/.local"
deno install -g -A -n pi-mcp --config deno.json ./src/cli.ts
```
`-A` is intentional: the exposed tools can read/write files and execute commands, so the server needs the same broad local permissions as the tools it exposes.
## Usage
```sh
pi-mcp # stdio (default)
pi-mcp --http --port 3000 # Streamable HTTP
pi-mcp --cwd /path/to/project
pi-mcp --readonly # read, grep, find, ls
pi-mcp --tools read,grep,ls
pi-mcp --shell /bin/bash
```
| Flag | Meaning |
| --- | --- |
| `--stdio` | Serve over stdin/stdout (default) |
| `--http` | Serve Streamable HTTP |
| `--host <host>` | HTTP bind host (default `127.0.0.1`; implies HTTP) |
| `--port <port>` | HTTP bind port (default `3000`; implies HTTP) |
| `--cwd <dir>` | Tool working directory |
| `--readonly` | Register only read-only tools |
| `--tools <names>` | Comma-separated subset |
| `--shell <path>` | Bash executable for `bash` |
| `--allowed-hosts <h>` | Comma-separated `Host` names for HTTP DNS-rebinding protection |
`--stdio` cannot be combined with `--http` / `--host` / `--port`.
Log to stderr. stdout is the stdio protocol channel.
### Host config (stdio)
```json
{
"mcpServers": {
"pi": {
"command": "pi-mcp",
"args": ["--cwd", "/path/to/project"]
}
}
}
```
### HTTP
```sh
pi-mcp --http --host 127.0.0.1 --port 3000
```
POST JSON-RPC to the listener. Modern (2026-07-28) clients use `server/discover` plus the per-request `_meta` envelope and `Mcp-Method` / `MCP-Protocol-Version` headers. 2025 clients use `initialize`.
## Tools
| Tool | Role |
| --- | --- |
| `read` | Read a text file or image (`offset` / `limit` for large files) |
| `bash` | Run a shell command in `--cwd` |
| `edit` | Exact text replacement (same coercions as pi: JSON-string `edits`, single edit object, legacy `oldText`/`newText`) |
| `write` | Create/overwrite a file, creating parent directories |
| `grep` | Search file contents with `rg` |
| `find` | Glob files with `fd` |
| `ls` | List a directory |
Tool execution behavior is taken from pi's coding-agent tools, including image normalization/resizing. TUI rendering is not included. One deliberate difference is `rg` / `fd` discovery: pi-mcp only uses executables already present on `PATH` and never downloads them automatically.
The vendored tool/helper code in this checkout is based on pi commit `59a71b235dadb4ad0d67557a8abb0aaa093e68b4`.
## Development
```sh
deno install
deno task check
deno task start --help
```
Useful tasks: `deno task dev`, `deno task check`, `deno task lint`, and `deno task fmt`.
Runtime dependencies: `@modelcontextprotocol/server`, `@silvia-odwyer/photon-node`, `zod`, `diff`.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues