- Python 100%
| plane_mcp | ||
| .gitignore | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
plane-mcp-server-selfhosted
Patched fork of makeplane/plane-mcp-server 0.2.10,
fixed to work against self-hosted Plane instances that don't yet expose the
Cloud-only "-lite" endpoints.
Why this exists
The official plane-mcp-server (as of 0.2.10, pinned to plane-sdk==0.2.19) calls a handful of
endpoints that only exist on Plane Cloud (app.plane.so), not on self-hosted / Community Edition
instances:
GET /workspaces/{slug}/projects-lite/GET /workspaces/{slug}/members-lite/GET /workspaces/{slug}/projects/{id}/project-members-lite/GET /workspaces/{slug}/projects/{id}/cycles-lite/GET /workspaces/{slug}/projects/{id}/modules-lite/
Against a self-hosted instance these all 404, which breaks these MCP tools:
list_projects, get_workspace_members, get_project_members, list_cycles, list_modules.
What was changed
Four files under plane_mcp/tools/ were patched to call the equivalent non-lite endpoints
instead (/projects/, /members/, /project-members/, /cycles/, /modules/), which exist on
both Cloud and self-hosted:
| File | Tool | Before | After |
|---|---|---|---|
tools/projects.py |
list_projects |
client.projects.list_lite() |
client.projects.list() |
tools/projects.py |
get_project_members |
client.projects.get_members_lite() |
client.projects.get_members() |
tools/workspaces.py |
get_workspace_members |
client.workspaces.get_members_lite() |
client.workspaces.get_members() |
tools/cycles.py |
list_cycles |
client.cycles.list_lite() |
client.cycles.list() |
tools/modules.py |
list_modules |
client.modules.list_lite() |
client.modules.list() |
Return types changed accordingly — the non-lite endpoints return full objects (not the field-trimmed "lite" shape), and the member-listing ones return a bare list instead of a cursor-paginated envelope (the non-lite member endpoints aren't paginated).
Not patched / still unsupported on self-hosted: get_features, update_workspace_features,
and anything depending on custom work item types / Epics (resolve_work_item_type,
list_work_item_types, etc.). These call /workspaces/{slug}/features/ and
/workspaces/{slug}/projects/{id}/work-item-types/, which don't 404 because of a naming
mismatch — they genuinely don't exist on this edition of self-hosted Plane. There is no
non-lite equivalent to fall back to.
Everything else in the package is untouched, byte-for-byte identical to the upstream
plane-mcp-server==0.2.10 release.
Usage
On this machine
Already wired up — no action needed, this directory is only a backup/portable copy.
On a new machine / after a fresh install
Point your MCP client at this directory instead of the PyPI package name. In your MCP config
(e.g. .claude.json, claude_desktop_config.json, etc.), change:
{
"command": "uvx",
"args": ["plane-mcp-server", "stdio"] // <- pulls the unpatched package from PyPI
}
to:
{
"command": "uvx",
"args": ["--from", "/absolute/path/to/plane-mcp-server-selfhosted", "plane-mcp-server", "stdio"]
}
(On Windows, use a path like "C:/Users/you/Documents/plane-mcp-server-selfhosted" — forward
slashes work fine in JSON strings.)
env stays exactly the same as before (PLANE_API_KEY, PLANE_BASE_URL, PLANE_WORKSPACE_SLUG).
uv resolves the pinned dependencies from PyPI on first run and caches them, same as it does for
any normal package — you just need uv/uvx installed and internet access once.
From a git remote (GitHub / your own Gitea)
uvx --from also accepts a git URL, so once this is pushed you don't need to copy the folder
around at all:
{
"command": "uvx",
"args": ["--from", "git+https://github.com/<you>/plane-mcp-server-selfhosted", "plane-mcp-server", "stdio"]
}
or, for a self-hosted Gitea:
{
"command": "uvx",
"args": ["--from", "git+https://gitea.example.com/<you>/plane-mcp-server-selfhosted", "plane-mcp-server", "stdio"]
}
Pin to a specific commit/tag for stability with git+https://.../repo@<tag-or-sha>.
Publishing it
This is safe to push to a public or private GitHub/Gitea repo as-is — there are no secrets baked
in anywhere (API keys/tokens are only ever supplied at runtime via the PLANE_API_KEY env var in
your MCP client config, never stored in this repo). It's a legitimate fork/patch of an MIT-licensed
open source project (see LICENSE), so redistributing it is fine; consider also opening an issue
or PR upstream at makeplane/plane-mcp-server so
this gets fixed properly for everyone on self-hosted.
cd plane-mcp-server-selfhosted
git init
git add .
git commit -m "Patch -lite endpoint calls for self-hosted Plane compatibility"
git remote add origin https://github.com/<you>/plane-mcp-server-selfhosted.git
git push -u origin main
Re-syncing with upstream
If makeplane/plane-mcp-server ships a new version, the cleanest way to update is: install the
new version fresh via uvx plane-mcp-server@<new-version> stdio once (to populate uv's cache),
diff the new plane_mcp/tools/{projects,workspaces,cycles,modules}.py against upstream, and
reapply the same four patches (swap *_lite calls for their non-lite equivalents) — then bump the
dependency pins in pyproject.toml to match the new release's METADATA.