Plane MCP¶
Official Plane MCP server — tickets, Kanban, cycles, comments.
How it runs¶
| Agent clients | scripts/mcp-run.sh plane — stdio, local throwaway container |
| Hosted service | mcp.${DOMAIN}, from plane/mcp/docker-compose.yml |
The hosted service stays up for HTTP clients and is monitored by Kuma, but local agents use the stdio launcher — see "Client configuration" below.
Auth: API key, not OAuth¶
The image exposes two HTTP mounts (plane_mcp/__main__.py):
| Mount | Auth | Usable here |
|---|---|---|
/http/mcp |
OAuth proxy to Plane | No |
/http/api-key/mcp |
x-api-key + x-workspace-slug headers |
Yes |
OAuth is unusable against the self-hosted instance: the proxy redirects to
${PLANE_BASE_URL}/auth/o/authorize-app/, and pm.* returns 404 for every
/auth/o/* route — that app-installation flow ships only on Plane Cloud.
Symptom is a browser landing on app.plane.so, or an invalid_request /
Page not found error after the consent screen.
API-key mode validates the key against ${PLANE_BASE_URL}/api/v1/users/me/,
so PLANE_BASE_URL must stay set on the container (bare host, no /api/v1).
Generate the key in Plane → profile → Personal access tokens.
Client configuration — stdio, via scripts/mcp-run.sh¶
.mcp.json runs the same image locally in stdio mode, like forgejo and
infra-ops:
"plane": { "command": "bash", "args": ["scripts/mcp-run.sh", "plane"] }
The launcher reads PLANE_API_KEY and PLANE_WORKSPACE_SLUG from local/.env
itself, so nothing needs exporting by hand and no secret reaches .mcp.json.
Talking to the hosted mcp.${DOMAIN} over HTTP also works, but only on the
api-key mount and only with the key as a bearer token — the mount reads the
key from Authorization, not from x-api-key, and takes the workspace from
x-workspace-slug. Since the client must inject both, stdio is simpler.
Image is pinned to v0.2.9¶
From v0.2.10 on, list_projects, list_cycles and list_modules request
/projects-lite/, /cycles-lite/ and /modules-lite/. Self-hosted Plane
v1.3.1 does not serve those routes and returns 404: Page not found, while
the ~174 other tools work. v0.2.9 uses the plain endpoints. Re-test those three
tools before bumping the pin or upgrading Plane.
Typical agent tasks¶
- Create issue: "Create BIOS-15 for adding docs site"
- Move Kanban card: "Move PORT-3 to In Review"
- Add comment: "Comment on BIOS-12 that CI passed"
- Search issues before coding
Workflow integration¶
Per project Kanban: Backlog → Ready → In Progress → In Review → CI Green → QA → Done
Branch naming: feature/{PREFIX}-{N}-description
Close on merge: fixes {PREFIX}-{N}
CI integration (separate from MCP)¶
Woodpecker posts CI status via REST API (notify-plane-ci.sh) when branch contains PREFIX-N. This is not the MCP server — both work together.
Troubleshooting¶
| Issue | Fix |
|---|---|
| MCP down | bash scripts/bootstrap-plane-platform.sh on VPS |
Login redirects to app.plane.so |
PLANE_BASE_URL missing in the container — it defaults to https://api.plane.so. Set in plane/mcp/docker-compose.yml, bare host, no /api/v1 |
| Client prompts to authenticate / OAuth errors | You are on /http/mcp. Switch to /http/api-key/mcp — see "Auth" above |
| 401 on tools | PLANE_API_KEY / PLANE_WORKSPACE_SLUG not exported into the client's environment, or the key was revoked |
See Monitoring — Kuma monitors mcp.*.