plane-mcp-rs
by ninerf
README.md
# plane-mcp-rs
A fast, single-binary [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server for
[Plane](https://plane.so) project management. It lets AI agents such as Claude, Cursor and Codex work with
Plane work items, comments, cycles, modules, pages and more.
It is a Rust port of the MIT-licensed Python [`plane-mcp-server`](https://github.com/makeplane/plane-mcp-server):
the same 30 tools and tool schemas, about 16x less memory, no Python runtime.
> **Unofficial.** A community project, not affiliated with or endorsed by Plane.
MCP Registry name: `mcp-name: io.github.ninerf/plane-mcp-rs`
## Install
Download a binary from [Releases](https://github.com/ninerf/plane-mcp-rs/releases/latest) and put it on your `PATH`.
Clients that support MCP bundles can install `plane-mcp-rs.mcpb` from the same page. Or build it with Rust:
```bash
cargo install --git https://github.com/ninerf/plane-mcp-rs
```
## Configure
| Variable | Required | Meaning |
|---|---|---|
| `PLANE_API_KEY` | yes | Plane API key (Profile → Personal Access Tokens) |
| `PLANE_WORKSPACE_SLUG` | yes | Workspace slug from your Plane URL |
| `PLANE_BASE_URL` | no | Self-hosted URL; defaults to `https://api.plane.so` |
### Claude Code
```bash
claude mcp add plane -e PLANE_API_KEY=your-key -e PLANE_WORKSPACE_SLUG=your-slug -- plane-mcp-rs --stdio
```
### Cursor, Claude Desktop and other JSON-configured clients
```json
{
"mcpServers": {
"plane": {
"command": "plane-mcp-rs",
"args": ["--stdio"],
"env": { "PLANE_API_KEY": "your-key", "PLANE_WORKSPACE_SLUG": "your-slug" }
}
}
}
```
### Shared HTTP server
One process can serve every agent on a machine. It binds to `127.0.0.1` only and has no authentication of its own, so
don't expose the port.
```bash
plane-mcp-rs --port 8096
```
The endpoint is `http://127.0.0.1:8096/servers/plane/mcp`.
## Tools
`workitem`, `workitem_comment`, `workitem_activity`, `workitem_link`, `workitem_relation`, `workitem_attachment`,
`workitem_type`, `workitem_property`, `work_log`, `project`, `project_estimate`, `state`, `label`, `member`,
`workspace`, `module`, `cycle`, `milestone`, `intake`, `page`, `collection`, `template`, `initiative`, `customer`,
`customer_property`, `customer_request`, `release`, `release_label`, `release_tag`, `get_pql_reference`.
The upstream server's retired tool names (169 aliases such as `create_work_item`) still work.
### Differences from the Python server
- `workitem list` leaves out descriptions unless you pass `fields`, which roughly halves its output. Use `retrieve`
for the full item.
- Results are sent once as text, with no duplicate `structuredContent` copy.
- Plane's raw response is passed through, so null placeholder fields the Python models add are absent.
- Empty lists come back as `[]`.
- `upload_from_url` checks every resolved address and every redirect against private networks.
- API-key login only: no OAuth or hosted mode.
## Performance
Measured on one Windows 11 workstation against one self-hosted Plane instance, with `plane-mcp-server` 0.3.3 already
tuned for a fair comparison (one server process, no `mcp-proxy`, payload logging off, the same lean `workitem list`).
A stock install uses more. Your numbers will differ.
| | Rust | Python | |
|---|---|---|---|
| Memory, idle (working set) | 7.6 MB | 127.9 MB | 17x less |
| Memory, after load | 12.8 MB | 135.8 MB | 11x less |
| Cold start to listening¹ | about 0.5 s | about 7.2 s | 14x faster |
| Local tool call, p50 | 1.09 ms | 16.82 ms | 15x faster |
| `tools/list`, p50 | 2.78 ms | 8.9 ms | 3x faster |
| `workitem list` (20 items), p50² | about 686 ms | about 728 ms | about the same |
| `workitem list` (20 items), response | 8.6 KB | 16.5 KB | 48% smaller |
| Install size | 1.7 MB, 1 file | 109.8 MB, 8,769 files | |
| Tool schemas sent to the client | 66.5 KB | 66.5 KB | identical |
¹ Includes the measuring loop's own overhead, so the Rust figure is an upper bound.
² Most of this is Plane itself, so Rust can't speed it up much. Measured with paced calls; the pacing delay is
subtracted.
Rust doesn't reduce the tool schema cost, because the schemas are deliberately identical. Reproduce the latency and
size numbers with [`bench/bench.py`](bench/bench.py).
## Compatibility and test status
Tested against self-hosted Plane 1.4.2:
- **Read and validation:** 77 calls across all 30 tools compared with the Python server, with no behaviour differences
beyond those listed above. This covers each tool, not every action.
- **Writes, end to end:** work items, comments including mentions, links, attachments, labels and states.
- **Same 404 from both servers on this Plane version:** work item relations and archive. Your edition may differ.
- **Not exercised end to end:** write actions for other tools, including customers, releases, initiatives, pages,
cycles, modules, templates and work logs. They follow the upstream SDK's routes. Please open an issue if one fails.
Linux and macOS builds are compiled and unit-tested in CI. The end-to-end testing above ran on Windows only.
## Credits
Tool schemas, descriptions and PQL reference text come from
[`plane-mcp-server`](https://github.com/makeplane/plane-mcp-server) (MIT). See [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues