One small patch in plane-mcp to make it talk to Plane Community Edition
The /dependencies/ route 404s on CE self-hosted. A small fallback to the old /relations/ route fixes it.
TL;DR
The MCP link tool returned a bare 404 though the work items existed, because its cloud route is missing in Community Edition. The patch detects a missing-route 404 versus missing data and falls back to the older CE route with adjusted payloads. This keeps upstream merges simple and is validated by a live smoke test creating and linking real items.
I ran the MCP tool to link two work items, and all I got back was one cold line: 404 Not Found. No extra message, no hint about a wrong configuration. Just empty.
My first guess: a 404 means the item I was looking for does not exist. I spent time double-checking work item IDs, hunting for typos, even restarting the local server. The items were there, and they were valid.
Not bad data, a missing route
Digging deeper, the problem was never the data, it was the route itself. I found issue #185 on the plane-mcp-server repository, which describes this exact situation. The official SDK calls a /dependencies/ endpoint to create relations, and that route 404s on a self-hosted Community Edition. The reporter even attached curl output showing the older /relations/ route on the same instance answering with a clean 201 Created.
The only difference is the body shape: the old route expects an issues key, not the work_item_ids key of the newer cloud route. The same issue also names the root cause: the SDK targets cloud routes that never landed on CE, the same pattern as the earlier -lite issue family. One detail makes it worse: the docstring of the list_work_item_relation_definitions tool tells you to call definitions first before creating a relation, and the definitions endpoint itself 404s on CE. The documented workflow breaks at step one.
A fallback based on response shape
My fix in commit a9769dd (140 insertions, 32 deletions in workitem_relation.py) comes down to one principle: do not guess, discriminate the 404s. The _endpoint_missing() function checks whether a 404 means "Page not found" (the route is absent in this edition) or "item not found" (the route exists, the data does not). These two cases deserve different treatment: the first is a sensible fallback trigger, the second must still surface as missing data.
When the route is detected as absent, the call switches to _ce_relations_path(), a URL with the same shape the SDK builds, only a different leaf segment. Listing relations returns a single grouped GET with a ce_fallback: true flag plus a note that entries carry an issue_id rather than full work items. Creating posts {"relation_type", "issues"}. Relation definitions, which have no CE endpoint at all, get answered with a static built-in list, and relation deletion, which on CE is only possible through the UI, returns an explicit error saying so instead of failing silently.
Why not a hard fork
I could have forked plane-mcp-server entirely and stripped out every cloud path. But the upstream code in my repo is vendored whole so upgrades stay easy, and a heavy fork turns every upstream release into a merge conflict. Shape-based detection keeps the upstream code intact; the fallback only attaches at the points where CE differs.
The same reasoning reaches beyond relations: CE has no PQL support, and the Pages, issue-types, and custom-properties endpoints are also absent on self-hosted. Every deviation is written down in CE-COMPAT.md, so the patch decisions leave a written trail instead of tribal knowledge.
The maintenance ritual
The cost of this pattern: every time I replace plane_mcp/ with a new upstream tag, the fallback blocks have to be re-applied. The procedure is already mechanical: grep CE-FALLBACK on the old tree, copy the blocks into the new tree, then run the smoke test.
That smoke test is not a mock test. It drives the real MCP server over HTTP: initialize with header auth, create two throwaway work items through the workitem tool, then call list_definitions, list, and create a relation between them, and clean up. If all of that passes, the fallback genuinely works on the edition that needs it.
It sounds like extra work. But compared with waiting for cloud routes to land on CE with no announced date, this small, measured bridge is the only path that lets AI agents use work item relations on self-hosted today.