Skip to content

MCP server

Use Plane from the AI tool you already work in to create work items, plan cycles, and query projects in natural language. The server is open source under the MIT license.

Hosted server

Connect to https://mcp.plane.so/http/mcp and sign in with your Plane account.

TIP

Just want to connect your AI tool? Use the short setup guide.

How it works

Model Context Protocol (MCP) is an open standard for how AI clients discover and call external tools. The Plane MCP server sits between your client and Plane's REST API, then acts as the signed-in user.

Version 0.3.0 exposes 28 tools, one per resource, covering 183 actions. Pass action to select an operation:

python
workitem(action="create", project_id=..., name="Fix login")
workitem(action="list", project_id=..., pql='stateGroup = "started"')
cycle(action="archive", project_id=..., cycle_id=...)

Every tool description lists its actions and marks parameters as required or optional. Tools also carry MCP readOnlyHint and destructiveHint annotations derived from their actions.

Hosted or self-hosted

Plane Cloud users can connect to mcp.plane.so. For self-hosted Plane, run locally with PLANE_BASE_URL set to your instance, or deploy your own server.

What you can do

  • Work items: create, update, search, comment, attach, link, relate, nest, and log time.
  • Types, properties, and estimates: manage types, custom properties, and estimates.
  • Planning: plan cycles, modules, milestones, and initiatives.
  • Releases: manage tags, labels, work items, and changelogs.
  • Projects and workspace: manage projects, states, labels, members, pages, features, and intake.
  • Customers: manage customers, requests, properties, and linked work.
  • Query: retrieve the PQL language reference before composing filters.

Query with PQL

workitem list, workitem list_archived, workitem count, cycle list_workitems, and module list_workitems accept pql. UUID-backed fields require UUIDs, so resolve names first. Call get_pql_reference with detail="brief" or detail="full"; see Plane Query Language.

There are no separate epic tools. Follow the epics recipe.

Endpoints and authentication

EndpointAuthUse it for
https://mcp.plane.so/http/mcpOAuthStreamable HTTP; recommended for interactive use
https://mcp.plane.so/http/api-key/mcpPAT headersAutomations, CI, headless agents, shared team setups
uvx plane-mcp-server stdioEnvironment variablesSelf-hosted Plane and local or offline development
https://mcp.plane.so/sseOAuthDeprecated clients that still require HTTP+SSE

OAuth

Your client redirects you to Plane, where you sign in and choose a workspace. The server validates the resulting token with /api/v1/users/me/, and the connection stays bound to that workspace.

The default redirect allowlist covers Cursor, VS Code, Antigravity, Claude.ai, ChatGPT, and localhost callbacks. A self-hosted server can add other clients through PLANE_OAUTH_ALLOWED_REDIRECT_URIS.

Re-authenticate from your client's connector controls. In Claude Code, run /mcp; with mcp-remote, clear its cache:

bash
rm -rf ~/.mcp-auth

This removes cached OAuth credentials for every mcp-remote server, not only Plane. To keep Plane's cache separate, set MCP_REMOTE_CONFIG_DIR in that server's env and remove that directory instead.

Personal access token

Send both headers on every request to the PAT endpoint:

HeaderValue
AuthorizationBearer <PAT>
x-workspace-slug<workspace-slug>

Changed

Earlier versions of this page showed an x-api-key header. The server reads the standard Authorization: Bearer header; update existing configs.

Get a token

Create a personal access token under Profile Settings → Personal Access Tokens and copy it when shown. For automations, you can instead create a workspace access token under Workspace Settings → Access Tokens.

Find your workspace slug

The slug is the segment after app.plane.so/ in your Plane URL. In https://app.plane.so/acme-corp/, it is acme-corp.

Local (stdio)

Local mode requires Python 3.10+ and uv. On macOS or Linux:

bash
curl -LsSf https://astral.sh/uv/install.sh | sh

On Windows:

powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
VariableRequiredDescription
PLANE_API_KEYYesYour Plane personal or workspace access token
PLANE_WORKSPACE_SLUGYesThe workspace slug
PLANE_BASE_URLNoDefaults to https://api.plane.so; set it to your self-hosted Plane instance URL

Prefer stdio when the client runs on the same machine, you need a self-hosted or private Plane instance, or you do not want to expose an MCP HTTP service.

SSE (deprecated)

The MCP specification deprecated the older HTTP+SSE transport. Keep https://mcp.plane.so/sse only for an existing client that cannot use Streamable HTTP, and migrate when that client supports it.

Connect a client

Replace mcp.plane.so with your own host if you self-host the server. Tabs stay in sync across this page.

General

These are the common shapes. Some clients use serverUrl, servers, or context_servers; use the client-specific schema below.

json
{
  "mcpServers": {
    "plane": {
      "url": "https://mcp.plane.so/http/mcp"
    }
  }
}

Claude

On Claude Desktop or claude.ai:

  1. Open Settings → Connectors → Add custom connector.
  2. Paste https://mcp.plane.so/http/mcp, select Add, then Connect.
  3. Sign in to Plane. In a chat, choose + → Connectors to enable Plane.

Free plans allow one custom connector. On Team or Enterprise, an Owner adds it under Organization settings → Connectors, then members select Connect.

Claude Code

bash
claude mcp add --transport http plane https://mcp.plane.so/http/mcp
# In a session, run /mcp and authenticate (or run: claude mcp login plane).
claude mcp list

Use --scope local|project|user; project scope writes a shareable .mcp.json with mcpServers, type: "http", and url. PAT entries add headers, and ${PLANE_PAT} expands from the environment. Claude Code's SSE transport is deprecated.

ChatGPT

ChatGPT supports OAuth on Plus, Pro, Business, Enterprise, and Edu plans:

  1. Open Settings → Security and login and turn on Developer mode. Business, Enterprise, and Edu workspaces require an admin to allow it.
  2. Open chatgpt.com/plugins, select +, name the connection "Plane", enter https://mcp.plane.so/http/mcp under Connection, select Create, then sign in to Plane.
  3. In a chat, open + → Developer mode and enable Plane.

The exact menu names may differ by workspace. ChatGPT does not accept custom headers, so use OAuth.

Codex

The CLI, IDE extension, and ChatGPT desktop app share ~/.codex/config.toml.

bash
codex mcp add plane --url https://mcp.plane.so/http/mcp
codex mcp login plane
codex mcp list

You can also run /mcp inside Codex. No experimental flag is required.

Cursor

Use ~/.cursor/mcp.json globally or .cursor/mcp.json in a project.

Install in Cursor

Or add the server manually:

json
{
  "mcpServers": {
    "plane": {
      "url": "https://mcp.plane.so/http/mcp"
    }
  }
}

Cursor shows Login or Needs authentication and completes OAuth. Manage servers from Customize.

Remote entries use url and must not include a type key.

VS Code

Use .vscode/mcp.json for a workspace, or run MCP: Open User Configuration for the user file.

Install in VS Code

Install in VS Code Insiders, or add it from the CLI:

bash
code --add-mcp '{"name":"plane","type":"http","url":"https://mcp.plane.so/http/mcp"}'

Trust the server on first start, verify it with MCP: List Servers, and use Copilot Chat in Agent mode. Copilot Business and Enterprise organizations must enable the "MCP servers in Copilot" policy.

Windsurf

Current vendor docs call Windsurf Devin Desktop. Its configuration remains at ~/.codeium/windsurf/mcp_config.json; open Cascade's MCPs → Manage MCPs or Settings → Cascade → MCP Servers.

json
{
  "mcpServers": {
    "plane": {
      "serverUrl": "https://mcp.plane.so/http/mcp"
    }
  }
}

If the OAuth sign-in does not complete, use the access-token configuration instead.

Remote entries use serverUrl. Refresh the server list after saving.

Zed

Use Settings → AI → MCP Servers → Add Server, or edit ~/.config/zed/settings.json.

json
{
  "context_servers": {
    "plane": {
      "url": "https://mcp.plane.so/http/mcp"
    }
  }
}

Zed prompts for OAuth through an allowlisted loopback callback.

Zed uses this flat schema; the old nested command.path and source: custom shape is outdated.

Antigravity

The IDE and CLI share ~/.gemini/config/mcp_config.json globally or .agents/mcp_config.json in a workspace.

json
{
  "mcpServers": {
    "plane": {
      "serverUrl": "https://mcp.plane.so/http/mcp"
    }
  }
}

OAuth is automatic. In the IDE, open … → MCP Servers → Manage MCP Servers. In Antigravity 2.0, use Settings → Customizations → Installed MCP Servers → Add MCP; in the CLI, run /mcp.

Remote entries require serverUrl; url and httpUrl are unsupported.

Other clients

For a stdio-only client, use mcp-remote with Node.js 22+ recommended. A client with native remote-MCP support only needs the OAuth URL.

json
{
  "mcpServers": {
    "plane": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.plane.so/http/mcp"]
    }
  }
}

mcp-remote reads headers from its --header arguments; a headers key on this stdio entry is ignored. Keep the header values in env and write the arguments without spaces around the colon: on Windows, spaces inside args can be mangled by some clients. To reset cached OAuth state, remove ~/.mcp-auth (or the directory MCP_REMOTE_CONFIG_DIR points to).

Common workflows

What's on my plate

text
List work items assigned to me that are in progress or overdue, grouped by project.

Trace: member meworkitem list without project_id, using pql='assignee = currentUser() AND (stateGroup = "started" OR isOverdue())'.

File a bug

text
Create a high-priority bug in ENG called "Login times out on Safari 17". Description: the OAuth callback lands on a blank page. Assign it to me and add the "auth" label.

Trace: project listmember melabel listworkitem create.

Roll over a sprint

text
Create Sprint 15 in ENG from June 2 to June 15, move everything unfinished from Sprint 14 into it, and give me a count by priority.

Trace: cycle create with owned_bycycle list to find Sprint 14 → cycle transfer_workitemsworkitem count with pql and group_by="priority".

Close the loop

text
Log 90 minutes on ENG-42 with the note "Implemented retry logic", mark it Done, and comment "Fixed in abc1234, needs QA".

Trace: workitem retrieve_by_identifierwork_log createstate listworkitem updateworkitem_comment create.

Permissions and sessions

  • The server acts as the authenticated user. Plane enforces workspace and project roles, so a Guest cannot do more through MCP.
  • OAuth requests read and write scopes. The workspace chosen at consent binds that connection; reconnect to switch workspaces.
  • A PAT connection is scoped by x-workspace-slug.
  • Hosted OAuth tokens are stored server-side in Redis or Valkey. A self-hosted server without Redis falls back to in-memory storage.
  • Revoke access by disconnecting the connector in your client, deleting a PAT in Plane, or clearing the mcp-remote cache.

Security best practices

  • Use only https://mcp.plane.so or your own trusted host, and check the URL on Plane's consent screen.
  • Treat work item titles, descriptions, comments, and attachments as untrusted model input. Prefer clients that confirm writes; destructive actions are flagged with destructiveHint.
  • Keep PATs out of shared or committed configs. Use environment variables or ${input:...}, and never commit a token in a project-scoped .mcp.json.
  • Use a workspace access token with the minimum role needed for automations.
  • Revoke tokens in Plane settings and audit API token events in the workspace audit log.
  • Server logs are structured JSON with tool name, duration, status, opaque user ID, and workspace slug. Display names are logged only when LOG_USER_INFO=true, because they are PII.

Self-hosted Plane

The hosted mcp.plane.so service cannot reach private Plane instances. In stdio mode, set PLANE_BASE_URL to your instance URL, then test the token against Plane's REST API. Read the key into a shell variable first so it stays out of your command history:

bash
read -rs PLANE_API_KEY   # paste the key and press Enter; nothing is echoed
curl -H "x-api-key: $PLANE_API_KEY" \
  "https://plane.yourcompany.com/api/v1/users/me/"

A 200 response confirms the key and URL. That header is the Plane REST API header, not the MCP PAT header.

Running your own MCP server?

Follow the self-hosting guide for Docker, Helm, OAuth, storage, and operations. The OAuth transport needs Plane's OAuth application registration, which is available on Plane Cloud and Plane Commercial Edition; on Community Edition, use stdio mode.

Upgrading

From per-operation tools (0.2.x → 0.3.0)

The 177 per-operation tools became 28 resource tools. Of the 177 names, 169 still resolve as hidden aliases and keep their original parameter names, so saved prompts and scripts continue to work; get_pql_reference is unchanged; and seven cannot be mapped and return a message naming their replacement. See retired tool names.

project list is now paginated by default. Follow next_cursor or pass per_page. Archive actions now return an explicit status object.

From the Node.js server

The @makeplane/plane-mcp-server npm package is deprecated. Update environment variables, then use the stdio configuration shown above:

Node.js serverPython server
PLANE_API_KEYPLANE_API_KEY
PLANE_API_HOST_URLPLANE_BASE_URL
PLANE_WORKSPACE_SLUGPLANE_WORKSPACE_SLUG

Replace the old Node.js command and args with uvx plane-mcp-server stdio.

Troubleshooting

SymptomCauseFix
401 with PATToken is wrong, revoked, or uses old headerUse Authorization: Bearer <PAT> instead of x-api-key
401 with OAuthToken expiredRe-authenticate from the client
"workspace slug missing"PAT config omits the workspace headerAdd x-workspace-slug
404Workspace slug or resource ID is wrongCheck the slug or ID
403Your Plane role is too lowAsk for the required workspace or project role
400An argument is missing or invalidRead the error; permitted enum values are in the tool description
"not available on your plan" or 402The Plane plan does not include the featureEnable the feature or use an available action
mcp-remote fails to startNode.js is too oldUse Node.js 22+ and run npx -y mcp-remote@latest
Server is not listedJSON or client schema is invalidRemove trailing commas; apply the client-specific schema notes above
Only the first page of projectsproject list is paginatedFollow next_cursor or pass per_page
Tools look stale or out of orderPinned tool order or client cache is staleRestart the client after upgrades

For a server that is not listed, remember that Claude Desktop's JSON file cannot contain url, Windsurf and Antigravity require serverUrl, and a Cursor remote entry must not contain type.

Debug with:

bash
claude --debug
claude mcp list

PLANE_API_KEY=<your-api-key> PLANE_WORKSPACE_SLUG=<workspace-slug> uvx plane-mcp-server stdio

curl -X POST http://localhost:8211/http/mcp

rm -rf ~/.mcp-auth

The local HTTP request should return either 401 or an MCP response.

FAQ

Which Plane plans work?

The server follows your Plane plan and role. A plan-gated action returns a message naming the unavailable feature.

Is the server free?

The MIT-licensed server is free to use. The Plane features it can access follow your Plane plan.

Does it work with self-hosted Plane?

Yes. Use stdio with PLANE_BASE_URL, or deploy your own MCP server.

Is there a read-only mode?

There is no separate read-only endpoint. Use your client's tool allow-list; read-only tools are annotated with readOnlyHint.

Can I limit which tools are available?

Yes. Use the client's tool allow-list or deny-list.

How do epics work?

An epic is a work item whose type is "Epic". Follow the epics recipe.

Does it use Plane AI credits?

No. The MCP server calls Plane's API directly; the AI model belongs to your MCP client.

Where does my data go?

The hosted server proxies requests to api.plane.so. Self-host the MCP server if you need full infrastructure control.

See also