Skip to main content

Unofficial MCP server for self-hosted Plane (Community Edition)

Project description

plane-ce-mcp

Unofficial MCP server for self-hosted Plane (Community Edition).

A Model Context Protocol server exposing Plane's project management API as MCP tools, built for people who run Plane themselves. Based on makeplane/plane-mcp-server (MIT). Not affiliated with Plane / makeplane.

Why this exists

The upstream server targets Plane Cloud. Run it against a self-hosted Community Edition instance and you hit missing "lite" endpoints, raw SDK stack traces on every 404, and no pages support. This project fixes what upstream didn't:

  • Central compatibility layer (plane_mcp/compat.py): every Plane API error becomes an actionable message - missing endpoint vs missing resource vs auth vs timeout. No raw SDK exceptions reach the MCP client.
  • Transparent endpoint fallbacks: lite endpoints absent on CE fall back to the full endpoints (projects, cycles, modules, project/workspace members), with the fallback logged for diagnosability.
  • PAT-only HTTP mode: the HTTP transport runs without any OAuth configuration - header auth alone (/http/api-key/mcp).
  • Pages tools on CE: list/retrieve/search/create pages via Plane's internal API (CE has no public pages API), with content truncation for LLM-sized outputs.
  • Documented CE vs Cloud differences: docs/plane-api-compat.md.

May still work against Plane Cloud - untested, unmaintained, not a goal.

Quick start

Requirements: Python 3.10+ and uv. No clone, no install - uvx runs the server straight from GitHub.

1. Get your credentials from Plane:

  • API key: Plane → Workspace Settings → API tokens → create token
  • Workspace slug: the part of your Plane URL after the host (https://plane.your-domain.tld/<slug>/)

2. Smoke-test the server (optional, confirms connectivity):

PLANE_API_KEY=<your-api-key> \
PLANE_WORKSPACE_SLUG=<your-workspace-slug> \
PLANE_BASE_URL=https://plane.your-domain.tld \
uvx --from git+https://github.com/Bl4nk44/plane-ce-mcp plane-ce-mcp stdio

Server starts and waits for MCP messages on stdin - Ctrl+C to exit. Errors at this point mean wrong URL or key, not a client problem.

3. Add to your MCP client (Claude Code, Claude Desktop, Cursor, ...):

{
  "mcpServers": {
    "plane": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/Bl4nk44/plane-ce-mcp", "plane-ce-mcp", "stdio"],
      "env": {
        "PLANE_API_KEY": "<your-api-key>",
        "PLANE_WORKSPACE_SLUG": "<your-workspace-slug>",
        "PLANE_BASE_URL": "https://plane.your-domain.tld"
      }
    }
  }
}

For Claude Code that's one command:

claude mcp add plane \
  -e PLANE_API_KEY=<your-api-key> \
  -e PLANE_WORKSPACE_SLUG=<your-workspace-slug> \
  -e PLANE_BASE_URL=https://plane.your-domain.tld \
  -- uvx --from git+https://github.com/Bl4nk44/plane-ce-mcp plane-ce-mcp stdio

PLANE_BASE_URL must point at your instance's API - the default is Plane Cloud (https://api.plane.so), so self-host setups must set it.

Run from source

git clone https://github.com/Bl4nk44/plane-ce-mcp.git
cd plane-ce-mcp
uv pip install -e .
PLANE_API_KEY=... PLANE_WORKSPACE_SLUG=... PLANE_BASE_URL=... python -m plane_mcp stdio

HTTP transport (self-hosted, PAT auth)

Run the server next to your Plane instance (port 8211):

PLANE_BASE_URL=https://plane.your-domain.tld python -m plane_mcp http

Connect with a Personal Access Token - no OAuth setup required:

URL: http://<server>:8211/http/api-key/mcp

Headers:

  • Authorization: Bearer <PAT_TOKEN> (or x-api-key: <PAT_TOKEN>)
  • X-Workspace-slug: <SLUG>
{
  "mcpServers": {
    "plane": {
      "command": "npx",
      "args": ["mcp-remote@latest", "http://<server>:8211/http/api-key/mcp"],
      "headers": {
        "Authorization": "Bearer <PAT_TOKEN>",
        "X-Workspace-slug": "<SLUG>"
      }
    }
  }
}

An OAuth endpoint (/oauth/mcp) and a legacy SSE transport also exist for setups with a configured Plane OAuth app - see Configuration. Deployment recipes (Docker Compose, Caddy, Tailscale) live in deploy/ and docs/tailscale-deployment.md.

Configuration

Variable Required for Purpose
PLANE_BASE_URL all (self-host: required) Your Plane API URL (default: https://api.plane.so = Cloud)
PLANE_API_KEY stdio API key (workspace settings → API tokens)
PLANE_WORKSPACE_SLUG stdio Target workspace
PLANE_INTERNAL_BASE_URL http/sse (optional) Internal URL for server-to-server calls (e.g. http://plane-api:8000 inside Docker)
PLANE_INTERNAL_API_EMAIL / PLANE_INTERNAL_API_PASSWORD pages tools Plane account used by the internal-API adapter (CE has no public pages API); the account needs membership in the relevant projects
PLANE_TOOLSETS optional (default: all) Comma-separated tool groups to register: core,comments,pages,types,planning,admin,pql (or all). Loads fewer tool definitions into the client's context - e.g. core is the daily-driver set (~64 tools vs ~142). Call list_toolsets to see active/available groups.
PLANE_MAX_RESPONSE_KB optional (default: 1024) Size cap for list_work_items / list_archived_work_items responses. Over the limit the tool returns an actionable error instead of the payload, to protect the client's context window. 0 disables.
PLANE_MAX_RETRIES optional (default: 2) Retries after the first attempt for transient Plane API failures (429/503 for any call; 502/504/timeouts for read-only calls only, to avoid duplicate writes). 0 disables.
PLANE_RETRY_BASE_DELAY optional (default: 0.5) Base seconds for exponential backoff with jitter between retries (capped at 10s).
PLANE_PAGES_MAX_CONTENT_LENGTH optional Default truncation for retrieve_page content
REDIS_HOST / REDIS_PORT http/sse (optional) Token storage (falls back to in-memory)
PLANE_OAUTH_PROVIDER_* http/sse OAuth only OAuth client credentials and base URL
PLANE_OAUTH_ALLOWED_REDIRECT_URIS http/sse OAuth (optional) Comma-separated redirect URI patterns appended to the built-in allowlist
LOG_USER_INFO optional (default: false) When true, include user display name (PII) in logs alongside the opaque user id
LOG_PAYLOADS optional (default: false) When true, include tool-call payloads (may contain PII / full descriptions) in structured logs. Off by default; enable only for debugging.

Logging

The server emits structured JSON logs. Each tool call is logged with its tool name, duration, status, and (when available) the opaque user id and workspace slug. Endpoint fallbacks are logged when they trigger (which endpoint failed, which was used instead), so CE quirks are diagnosable from logs.

Health check

In HTTP mode the server exposes an unauthenticated GET /healthz returning {"status": "ok", "server_version": ...}. It reports the server's own liveness and does not call Plane, so a Plane outage never marks the MCP server unhealthy. The Docker image ships a HEALTHCHECK against it.

Available Tools

All tools use Pydantic models from the Plane SDK for type safety and validation.

Projects

Tool Name Description
list_projects List all projects in a workspace with optional pagination and filtering
create_project Create a new project with name, identifier, and optional configuration
retrieve_project Retrieve a project by ID
update_project Update a project with partial data
delete_project Delete a project by ID
get_project_worklog_summary Get work log summary for a project
get_project_members Get all members of a project
update_project_features Update features configuration of a project
manage_project_archive Archive or unarchive a project

Work Items

Tool Name Description
list_work_items List all work items in a project with optional filtering and pagination
create_work_item Create a new work item with name, assignees, labels, and other attributes
retrieve_work_item Retrieve a work item by ID with optional field expansion
retrieve_work_item_by_identifier Retrieve a work item by project identifier and issue sequence number
update_work_item Update a work item with partial data
delete_work_item Delete a work item by ID
search_work_items Search work items across a workspace with query string
count_work_items Count work items across the workspace with optional grouping
list_archived_work_items List archived work items in a project with optional PQL filtering
manage_work_item_archive Archive or unarchive a work item
manage_work_item_assignee Add or remove a single assignee without replacing the full list
manage_work_item_label Add or remove a single label without replacing the full list

Cycles

Tool Name Description
list_cycles List cycles in a project (set archived=true for archived)
create_cycle Create a new cycle with name, dates, and owner
retrieve_cycle Retrieve a cycle by ID
update_cycle Update a cycle with partial data
delete_cycle Delete a cycle by ID
manage_cycle_work_items Add and/or remove work items on a cycle
list_cycle_work_items List work items in a cycle
transfer_cycle_work_items Transfer work items from one cycle to another
manage_cycle_archive Archive or unarchive a cycle
complete_cycle Complete (close) a cycle by setting its end date to today

Modules

Tool Name Description
list_modules List modules in a project (set archived=true for archived)
create_module Create a new module with name, dates, status, and members
retrieve_module Retrieve a module by ID
update_module Update a module with partial data
delete_module Delete a module by ID
manage_module_work_items Add and/or remove work items on a module
list_module_work_items List work items in a module
manage_module_archive Archive or unarchive a module

Initiatives

Tool Name Description
list_initiatives List all initiatives in a workspace
create_initiative Create a new initiative with name, dates, state, and lead
retrieve_initiative Retrieve an initiative by ID
update_initiative Update an initiative with partial data
delete_initiative Delete an initiative by ID
list_initiative_projects List projects linked to an initiative
manage_initiative_projects Link or unlink projects of an initiative

Intake Work Items

Tool Name Description
list_intake_work_items List all intake work items in a project with optional pagination
create_intake_work_item Create a new intake work item in a project
retrieve_intake_work_item Retrieve an intake work item by work item ID with optional field expansion
update_intake_work_item Update an intake work item with partial data
delete_intake_work_item Delete an intake work item by work item ID

Work Item Properties

Tool Name Description
list_work_item_properties List work item properties for a work item type
create_work_item_property Create a new work item property with type, settings, and validation rules
retrieve_work_item_property Retrieve a work item property by ID
update_work_item_property Update a work item property with partial data
delete_work_item_property Delete a work item property by ID
list_work_item_property_options List options for a work item property
create_work_item_property_option Create an option on a work item property
retrieve_work_item_property_option Retrieve a single option from a work item property
update_work_item_property_option Update an option on a work item property
delete_work_item_property_option Delete an option from a work item property
get_work_item_property_value Get the value(s) of a custom property on a work item
set_work_item_property_value Set (create or update) the value of a custom property on a work item
delete_work_item_property_value Delete the value(s) of a custom property on a work item

Milestones

Tool Name Description
list_milestones List all milestones in a project
create_milestone Create a new milestone
retrieve_milestone Retrieve a milestone by ID
update_milestone Update a milestone by ID
delete_milestone Delete a milestone by ID
manage_milestone_work_items Add and/or remove work items on a milestone
list_milestone_work_items List work items in a milestone

Labels

Tool Name Description
list_labels List all labels in a project
create_label Create a new label
retrieve_label Retrieve a label by ID
update_label Update a label by ID
delete_label Delete a label by ID

States

Tool Name Description
list_states List all states in a project
create_state Create a new state
retrieve_state Retrieve a state by ID
update_state Update a state by ID
delete_state Delete a state by ID

Work Item Comments

Tool Name Description
list_work_item_comments List comments for a work item
retrieve_work_item_comment Retrieve a specific comment for a work item
create_work_item_comment Create a comment for a work item
update_work_item_comment Update a comment for a work item
delete_work_item_comment Delete a comment for a work item

Work Item Links

Tool Name Description
list_work_item_links List links for a work item
retrieve_work_item_link Retrieve a specific link for a work item
create_work_item_link Create a link for a work item
update_work_item_link Update a link for a work item
delete_work_item_link Delete a link for a work item

Work Item Types

Tool Name Description
list_work_item_types List all work item types in a project
create_work_item_type Create a new work item type
retrieve_work_item_type Retrieve a work item type by ID
update_work_item_type Update a work item type by ID
delete_work_item_type Delete a work item type by ID
import_work_item_types_to_project Bulk-link workspace-level work item types to a project
resolve_work_item_type Find or create a named type for a project, auto-handling workspace vs project scope and import
manage_work_item_type_properties Attach or detach properties on a work item type in a single call

Work Item Relations

Tool Name Description
list_work_item_relations List relations for a work item
create_work_item_relation Create relations for a work item
remove_work_item_relation Remove a relation from a work item

Work Item Relation Definitions

Tool Name Description
list_work_item_relation_definitions List workspace custom relation definitions
create_work_item_relation_definition Create a workspace relation definition
update_work_item_relation_definition Update a relation definition
delete_work_item_relation_definition Delete a relation definition

Work Item Activities

Tool Name Description
list_work_item_activities List activities for a work item
retrieve_work_item_activity Retrieve a specific activity for a work item

Work Logs

Tool Name Description
list_work_logs List work logs for a work item
create_work_log Create a work log for a work item
update_work_log Update a work log for a work item
delete_work_log Delete a work log for a work item

Pages

Tool Name Description
list_pages List pages - metadata only (workspace, or a project's if project_id given)
retrieve_page Retrieve a page incl. content; optional max_length truncation (env default PLANE_PAGES_MAX_CONTENT_LENGTH)
search_pages Search pages by title, optionally inside content (client-side, case-insensitive)
create_page Create a workspace or project page
attach_page_to_work_item Link a page to a work item
detach_page_from_work_item Remove a page link from a work item
list_work_item_pages List all pages linked to a work item

Work Item Attachments

Tool Name Description
list_work_item_attachments List all attachments for a work item
get_work_item_attachment_download_url Get a presigned download URL for a work item attachment
read_work_item_attachment Fetch an attachment's content so the LLM can read or analyze it
upload_work_item_attachment_from_url Fetch a file from a public URL and attach it to a work item
delete_work_item_attachment Delete an attachment from a work item

Estimates

Tool Name Description
get_project_estimate Get the estimate configuration for a project
create_project_estimate Create a new estimate for a project
update_project_estimate Update the estimate for a project
delete_project_estimate Delete the estimate for a project
link_estimate_to_project Link an estimate to a project, making it the active estimate system
list_project_estimate_points List all valid estimate points for a project
create_project_estimate_points Create estimate points for a project estimate
update_project_estimate_point Update a single estimate point
delete_project_estimate_point Delete a single estimate point

Roles

Tool Name Description
list_roles List role definitions in the workspace
retrieve_role Retrieve a role definition by ID

PQL

Tool Name Description
get_pql_reference Return the Plane Query Language (PQL) syntax reference (also exposed as the resource://pql-reference MCP resource)

Workspaces

Tool Name Description
get_workspace_members Get all members of the current workspace
get_features Get feature flags (workspace, or a project's if project_id given)
update_workspace_features Update features of the current workspace

Users

Tool Name Description
get_me Get current authenticated user information

Instance

Tool Name Description
get_instance_info Get edition/version of the connected Plane instance and its known API limitations (e.g. Community Edition)
list_toolsets List the tool groups (toolsets) this server supports and which are active

Total Tools: 142 tools across 24 categories (scripts/check_tool_docs.py keeps these tables in sync)

Development

# Install (uses uv)
uv pip install -e ".[dev]"

# Tests
pytest

# Format + lint
ruff format plane_mcp/
ruff check plane_mcp/

Integration tests run against a live Plane instance - copy .env.test to .env.test.local with real values, then export $(cat .env.test.local | xargs) && pytest tests/ -v.

Attribution & License

MIT License - see LICENSE.

Based on makeplane/plane-mcp-server (MIT, © 2025 Plane MCP Server Contributors). This is an independent, unofficial project: not affiliated with, endorsed by, or supported by Plane / makeplane. "Plane" is a trademark of its respective owner.

Contributing

Contributions welcome - especially fixes for self-hosted Community Edition quirks. See CONTRIBUTING.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

plane_ce_mcp-1.1.0.tar.gz (91.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

plane_ce_mcp-1.1.0-py3-none-any.whl (92.6 kB view details)

Uploaded Python 3

File details

Details for the file plane_ce_mcp-1.1.0.tar.gz.

File metadata

  • Download URL: plane_ce_mcp-1.1.0.tar.gz
  • Upload date:
  • Size: 91.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for plane_ce_mcp-1.1.0.tar.gz
Algorithm Hash digest
SHA256 0b17ab754424a0066644c9c2b34a097de73085940819e385a9f78cdc4921929b
MD5 7e009d0e0997890423d0862c6f7019c9
BLAKE2b-256 afb8f5b040bde4c14099a16de5dd9c6eafaec16cf1807823a88bd357efce2ffc

See more details on using hashes here.

File details

Details for the file plane_ce_mcp-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: plane_ce_mcp-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 92.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.20

File hashes

Hashes for plane_ce_mcp-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 925e07089cd1af07650ed5411c226e9c85e0e82c48958035adbad04aa04589ad
MD5 df2851144826e3ec18e544c2655c8ee0
BLAKE2b-256 810e44581a998593eea4ee7a2cbf9811e4d151bbf6333c37050735217e6db102

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page