Skip to main content
Glama
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`.