From 8a6880f5d5ae62dc71ae79f0c29014333bd1bc36 Mon Sep 17 00:00:00 2001 From: danciaclara Date: Mon, 18 May 2026 16:43:47 +0530 Subject: [PATCH 1/4] Updated the MCP Server --- docs/dev-tools/mcp-server.md | 1414 +++++++++++++++++++++++++++++++--- 1 file changed, 1288 insertions(+), 126 deletions(-) diff --git a/docs/dev-tools/mcp-server.md b/docs/dev-tools/mcp-server.md index 867d8a63..5cd3837b 100644 --- a/docs/dev-tools/mcp-server.md +++ b/docs/dev-tools/mcp-server.md @@ -6,175 +6,323 @@ keywords: plane, developer tools, integrations, extensions, mcp server, protocol # MCP server -The [Model Context Protocol](https://modelcontextprotocol.io/overview) (MCP) is a -standardized interface that enables AI models to communicate with external tools and -services. The Plane MCP Server enables AI agents to interact with Plane's project -management capabilities through multiple transport methods. +The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard that defines how AI applications discover and call external tools. Any client that speaks MCP can talk to any server that speaks MCP. -The Plane MCP Server is open source and available on [GitHub](https://github.com/makeplane/plane-mcp-server). +The Plane MCP Server is a bridge that lets AI models interact with Plane. It exposes Plane's full API surface as MCP tools, so your AI tool can create work items, manage sprints, track time, and organise work without you leaving your editor or chat interface. - -Beta -The Plane MCP Server is currently in **Beta**. Some aspects of the API may change. -While MCP is standardized, it is also rapidly evolving. The Plane MCP Server aims to -provide a stable implementation for developers to build robust AI-powered -applications. Please send any issues to support@plane.so. - +## Transport modes -## Transport methods +The server supports four transport modes. The right one depends on your deployment and usecase. -The Plane MCP Server supports multiple transport methods to accommodate different deployment scenarios: +| Transport | For | Auth method | How to start | +|-----------|----------|-------------|--------------| +| HTTP with OAuth | Plane Cloud users, simplest setup | Browser-based OAuth flow | `plane-mcp-server http` | +| HTTP with PAT Token | Automated workflows, CI/CD | API key in request headers | `plane-mcp-server http` | +| Local Stdio | Local dev, self-hosted Plane | Environment variables | `plane-mcp-server stdio` | +| SSE (Legacy) | Existing integrations | Browser-based OAuth flow | `plane-mcp-server http` | -| Transport | Best for | Authentication | -| -------------------------------------------------- | --------------------------- | --------------------- | -| [HTTP with OAuth](#remote-http-with-oauth) | Cloud users, simplest setup | Browser-based OAuth | -| [HTTP with PAT Token](#remote-http-with-pat-token) | Automated workflows, CI/CD | API key in headers | -| [Local Stdio](#local-stdio-transport) | Self-hosted Plane instances | Environment variables | -| [SSE (Legacy)](#sse-transport-legacy) | Existing integrations | Browser-based OAuth | +## Authentication model -## Remote HTTP with OAuth +The server has three authentication mechanisms, one per transport variant. -The recommended method for connecting to Plane Cloud. Uses browser-based OAuth for authentication. +### OAuth auth (HTTP with OAuth, SSE) + +For cloud deployments, the server acts as an **OAuth proxy** to Plane's OAuth system: + +1. The MCP client redirects the user to the Plane OAuth authorization page +2. The user logs into Plane and grants access +3. Plane returns an OAuth token which the server validates by calling `/api/v1/users/me/` +4. Subsequent MCP requests carry this token, from which the server extracts the workspace slug + +The server supports OAuth redirect URIs for all major MCP clients: +- `http://localhost:*` (dynamic ports from desktop clients) +- `cursor://`, `vscode://`, `vscode-insiders://`, `windsurf://`, `claude://` + +### Header auth (HTTP with PAT Token) + +For automated workflows, the MCP client sends two headers with every request: +- `x-api-key` - a Plane API token +- `x-workspace-slug` - the workspace identifier + +The server validates the API key against Plane's `/api/v1/users/me/` endpoint on each request. No browser interaction required. + +### Environment variable auth (stdio) + +For stdio mode, credentials are read from environment variables at startup: +- `PLANE_API_KEY` - your Plane API token +- `PLANE_WORKSPACE_SLUG` - your workspace identifier +- `PLANE_BASE_URL` - API URL for self-hosted instances (defaults to `https://api.plane.so`) + +## Identifier system + +Plane uses two kinds of identifiers for work items. + +- **Readable identifier** - human-friendly, e.g., `ENG-42` + - Composed of the project identifier (`ENG`) and a sequence number (`42`) + - Used in URLs, UI, and team communication + +- **UUID** - machine-friendly, e.g., `3fa85f64-5717-4562-b3fc-2c963f66afa6` + - Used by all other tools for `project_id`, `work_item_id`, `cycle_id`, etc. + - Returned by every API response + +--- + +## How-to guides ### Prerequisites -- **Node.js**: Version 22 or later -- **npx**: Comes bundled with npm +**For all modes:** +- A Plane account with access to at least one workspace + +**For stdio mode (local and self-hosted deployments)** +- Python 3.10+ installed (`python --version`) +- `uv` package manager (recommended). See [Installing uv](https://docs.astral.sh/uv/getting-started/installation/) -### Claude.ai +#### Get your API key (required for stdio and PAT token modes) -1. Open **Settings** from the sidebar on the web or desktop app. -2. Scroll to the **Integrations** section and click **Add more**. -3. Enter the Integration URL: `https://mcp.plane.so/http/mcp` -4. Click **Connect** to link your Plane workspace. +1. Open Plane and go to your workspace. +2. Generate a token. You can use either: + - **Personal Access Token** - go to **Profile Settings → API Tokens**. + - **Workspace Access Token** - go to **Workspace Settings → Access Tokens**. +3. Click **Add access token**, name it (e.g., "MCP Server"), click **Generate token**. +4. Copy the token as it will not be shown again. + +#### Get your workspace slug + +The slug is the short identifier in your Plane URL. For: +``` +https://app.plane.so/acme-corp/ +``` +the slug is `acme-corp`. ### Claude Desktop -Add to your `claude_desktop_config.json`: +Config file: `/claude_desktop_config.json`. + +Quit Claude Desktop before editing, then relaunch and click the hammer icon (🔨) to confirm Plane tools are listed. + +#### Stdio + +Spawns the server as a local subprocess. Credentials come from environment variables. ```json { "mcpServers": { "plane": { - "command": "npx", - "args": ["mcp-remote@latest", "https://mcp.plane.so/http/mcp"] + "command": "uvx", + "args": ["plane-mcp-server", "stdio"], + "env": { + "PLANE_API_KEY": "your_api_key_here", + "PLANE_WORKSPACE_SLUG": "your-workspace-slug", + "PLANE_BASE_URL": "https://plane.yourcompany.com" + } } } } ``` -### Cursor +#### HTTP with OAuth -Add to your Cursor MCP configuration: +Connects to a remote MCP server. Claude Desktop opens a browser window for the Plane OAuth flow on first use. ```json { "mcpServers": { "plane": { - "command": "npx", - "args": ["mcp-remote@latest", "https://mcp.plane.so/http/mcp"] + "url": "https://your-mcp-server.com/http/mcp", + "type": "http" } } } ``` -### VSCode +#### HTTP with PAT Token -Add to your `.vscode/mcp.json` file: +Connects to the PAT endpoint using API key headers. No browser interaction required - suitable for shared team setups where users authenticate via their own API key. ```json { - "servers": { + "mcpServers": { "plane": { - "command": "npx", - "args": ["mcp-remote@latest", "https://mcp.plane.so/http/mcp"] + "url": "https://your-mcp-server.com/http/api-key/mcp", + "type": "http", + "headers": { + "x-api-key": "your_api_key_here", + "x-workspace-slug": "your-workspace-slug" + } } } } ``` -### Windsurf +#### SSE (Legacy) -1. Press `Ctrl/Cmd + ,` to open Windsurf settings -2. Navigate to **Cascade** > **MCP servers** -3. Select **Add Server** > **Add custom server** -4. Add the following configuration: +For existing integrations already using the SSE transport. ```json { "mcpServers": { "plane": { - "command": "npx", - "args": ["-y", "mcp-remote@latest", "https://mcp.plane.so/http/mcp"] + "url": "https://your-mcp-server.com/sse", + "type": "sse" } } } ``` -### Zed +--- -1. Press `Cmd + ,` to open Zed settings -2. Add the following configuration: +### Claude Code (CLI) + +Claude Code manages MCP servers via `claude mcp add` or a settings file. + +#### Stdio + +```bash +claude mcp add plane \ + -e PLANE_API_KEY=your_api_key_here \ + -e PLANE_WORKSPACE_SLUG=your-workspace-slug \ + -e PLANE_BASE_URL=https://plane.yourcompany.com \ + -- uvx plane-mcp-server stdio +``` + +Settings file (`.claude/settings.json` for project scope, `~/.claude/settings.json` for user scope): ```json { - "context_servers": { + "mcpServers": { "plane": { - "source": "custom", - "command": "npx", - "args": ["-y", "mcp-remote@latest", "https://mcp.plane.so/http/mcp"], - "env": {} + "command": "uvx", + "args": ["plane-mcp-server", "stdio"], + "env": { + "PLANE_API_KEY": "your_api_key_here", + "PLANE_WORKSPACE_SLUG": "your-workspace-slug" + } } } } ``` -## Remote HTTP with PAT Token +#### HTTP with OAuth + +```bash +claude mcp add plane \ + --transport http \ + --url https://your-mcp-server.com/http/mcp +``` -Use this method when you need header-based authentication, such as in automated workflows or CI/CD pipelines. +Claude Code will open a browser for the Plane OAuth flow. Settings file equivalent: -### Prerequisites +```json +{ + "mcpServers": { + "plane": { + "url": "https://your-mcp-server.com/http/mcp", + "type": "http" + } + } +} +``` -- **Node.js**: Version 22 or later -- **npx**: Comes bundled with npm -- **Plane API Key**: Generate from your Plane workspace settings +#### HTTP with PAT Token -### Configuration +```bash +claude mcp add plane \ + --transport http \ + --url https://your-mcp-server.com/http/api-key/mcp \ + --header "x-api-key: your_api_key_here" \ + --header "x-workspace-slug: your-workspace-slug" +``` + +Settings file equivalent: ```json { "mcpServers": { "plane": { - "command": "npx", - "args": ["mcp-remote@latest", "https://mcp.plane.so/http/api-key/mcp"], + "url": "https://your-mcp-server.com/http/api-key/mcp", + "type": "http", "headers": { - "Authorization": "Bearer ", - "X-Workspace-slug": "" + "x-api-key": "your_api_key_here", + "x-workspace-slug": "your-workspace-slug" } } } } ``` -Replace `` with your Plane API key and `` with your workspace slug. +#### SSE (Legacy) -## Local Stdio transport +```bash +claude mcp add plane \ + --transport sse \ + --url https://your-mcp-server.com/sse +``` -Use this method to connect to a self-hosted Plane instance. The Stdio transport runs locally and communicates directly with your Plane API. +Settings file equivalent: -### Prerequisites +```json +{ + "mcpServers": { + "plane": { + "url": "https://your-mcp-server.com/sse", + "type": "sse" + } + } +} +``` -- **Python**: Version 3.10 or later -- **uvx**: Comes bundled with [uv](https://docs.astral.sh/uv/getting-started/installation/) +Verify any configuration with: -You can verify your installation by running: +```bash +claude mcp list +``` + +#### Using Plane in Claude Code sessions ```bash -python --version -uvx --version +claude + +> Look up work item ENG-42 and implement what it describes. + +> After fixing the bug, mark ENG-42 as done and log 90 minutes of work. + +> Create work items for each TODO in src/auth.ts and add them to the current sprint. ``` -### Configuration +--- + +### Claude.ai / Claude Chat (Web) + +Claude.ai supports remote MCP servers for eligible plans. Because it runs in a browser it cannot spawn local processes, stdio is not available here. + +#### HTTP with OAuth + +1. Go to **Settings → Integrations** in Claude.ai. +2. Click **Add Integration**. +3. Enter the server URL: `https://your-mcp-server.com/http/mcp` +4. Claude.ai redirects you through the Plane OAuth flow. + +#### HTTP with PAT Token + +If your Claude.ai plan supports custom headers in integrations: + +- URL: `https://your-mcp-server.com/http/api-key/mcp` +- Headers: `x-api-key: your_api_key_here`, `x-workspace-slug: your-workspace-slug` + +#### SSE (Legacy) + +- URL: `https://your-mcp-server.com/sse` + +--- + +### Cursor + +Config file: `~/.cursor/mcp.json` + +Open Cursor → **Settings** → search **MCP** → open the config file. Restart Cursor (`Cmd/Ctrl + Shift + P → Reload Window`) after saving. + +#### Stdio ```json { @@ -183,104 +331,1118 @@ uvx --version "command": "uvx", "args": ["plane-mcp-server", "stdio"], "env": { - "PLANE_API_KEY": "", - "PLANE_WORKSPACE_SLUG": "", - "PLANE_BASE_URL": "https://your-plane-instance.com/api" + "PLANE_API_KEY": "your_api_key_here", + "PLANE_WORKSPACE_SLUG": "your-workspace-slug", + "PLANE_BASE_URL": "https://plane.yourcompany.com" } } } } ``` -### Environment variables - -| Variable | Required | Description | -| ---------------------- | -------- | ---------------------------------------------------------------------- | -| `PLANE_API_KEY` | Yes | Your Plane API key | -| `PLANE_WORKSPACE_SLUG` | Yes | Your workspace slug | -| `PLANE_BASE_URL` | No | API URL for self-hosted instances (defaults to `https://api.plane.so`) | +#### HTTP with OAuth -## SSE transport (Legacy) +The `cursor://` redirect URI is registered natively in the OAuth provider. - -The SSE transport is maintained for backward compatibility. For new integrations, we recommend using the [HTTP with OAuth](#remote-http-with-oauth) transport. - +```json +{ + "mcpServers": { + "plane": { + "url": "https://your-mcp-server.com/http/mcp", + "type": "http" + } + } +} +``` -### Prerequisites +#### HTTP with PAT Token -- **Node.js**: Version 22 or later -- **npx**: Comes bundled with npm +```json +{ + "mcpServers": { + "plane": { + "url": "https://your-mcp-server.com/http/api-key/mcp", + "type": "http", + "headers": { + "x-api-key": "your_api_key_here", + "x-workspace-slug": "your-workspace-slug" + } + } + } +} +``` -### Configuration +#### SSE (Legacy) ```json { "mcpServers": { "plane": { - "command": "npx", - "args": ["mcp-remote@latest", "https://mcp.plane.so/sse"] + "url": "https://your-mcp-server.com/sse", + "type": "sse" } } } ``` -## Activating the Plane MCP Server +--- -After setup, when activating the server with OAuth-based transports (HTTP with OAuth or SSE), you will be prompted in your browser to connect your Plane workspace to the MCP server. +### VS Code -When prompted to authorize, click **Approve**. +VS Code supports MCP through GitHub Copilot (requires a Copilot subscription). Open the Copilot chat panel (`Ctrl+Alt+I`), switch to **Agent** mode. The `vscode://` and `vscode-insiders://` redirect URIs are registered in the OAuth provider. -Next, choose the workspace you want to connect, review the permissions, and click **Accept**. +Config can be set at workspace level (`.vscode/mcp.json`) or user level (VS Code `settings.json` under the `"mcp"` key). Examples below use `.vscode/mcp.json`. -## Troubleshooting +#### Stdio + +```json +{ + "servers": { + "plane": { + "command": "uvx", + "args": ["plane-mcp-server", "stdio"], + "env": { + "PLANE_API_KEY": "your_api_key_here", + "PLANE_WORKSPACE_SLUG": "your-workspace-slug", + "PLANE_BASE_URL": "https://plane.yourcompany.com" + } + } + } +} +``` -### Common issues +#### HTTP with OAuth -**Authentication errors** +```json +{ + "servers": { + "plane": { + "url": "https://your-mcp-server.com/http/mcp", + "type": "http" + } + } +} +``` -If you encounter authentication issues with OAuth transports, clear saved auth tokens: +#### HTTP with PAT Token -```bash -rm -rf ~/.mcp-auth +```json +{ + "servers": { + "plane": { + "url": "https://your-mcp-server.com/http/api-key/mcp", + "type": "http", + "headers": { + "x-api-key": "your_api_key_here", + "x-workspace-slug": "your-workspace-slug" + } + } + } +} +``` + +#### SSE (Legacy) + +```json +{ + "servers": { + "plane": { + "url": "https://your-mcp-server.com/sse", + "type": "sse" + } + } +} +``` + +--- + +### Windsurf + +Config file: `~/.codeium/windsurf/mcp_config.json` + +Restart Windsurf after saving, then open the Cascade panel. The `windsurf://` redirect URI is registered in the OAuth provider. + +#### Stdio + +```json +{ + "mcpServers": { + "plane": { + "command": "uvx", + "args": ["plane-mcp-server", "stdio"], + "env": { + "PLANE_API_KEY": "your_api_key_here", + "PLANE_WORKSPACE_SLUG": "your-workspace-slug", + "PLANE_BASE_URL": "https://plane.yourcompany.com" + } + } + } +} ``` -**Connection timeouts** +#### HTTP with OAuth + +```json +{ + "mcpServers": { + "plane": { + "url": "https://your-mcp-server.com/http/mcp", + "type": "http" + } + } +} +``` -- Ensure you have a stable internet connection -- Check if your firewall or proxy is blocking MCP connections -- Verify your Plane instance is accessible +#### HTTP with PAT Token -**WSL on Windows** +```json +{ + "mcpServers": { + "plane": { + "url": "https://your-mcp-server.com/http/api-key/mcp", + "type": "http", + "headers": { + "x-api-key": "your_api_key_here", + "x-workspace-slug": "your-workspace-slug" + } + } + } +} +``` -If you're using WSL on Windows and encountering errors with remote transports: +#### SSE (Legacy) ```json { "mcpServers": { "plane": { - "command": "wsl", - "args": ["npx", "-y", "mcp-remote@latest", "https://mcp.plane.so/http/mcp"] + "url": "https://your-mcp-server.com/sse", + "type": "sse" + } + } +} +``` + +--- + +### Zed + +Config file: `~/.config/zed/settings.json` under `"context_servers"`. Zed uses a different schema from other clients - the stdio command goes inside a `"command"` object with `"path"` instead of `"command"`. + +#### Stdio + +```json +{ + "context_servers": { + "plane-mcp-server": { + "command": { + "path": "uvx", + "args": ["plane-mcp-server", "stdio"], + "env": { + "PLANE_API_KEY": "your_api_key_here", + "PLANE_WORKSPACE_SLUG": "your-workspace-slug", + "PLANE_BASE_URL": "https://plane.yourcompany.com" + } + }, + "settings": {} + } + } +} +``` + +#### HTTP with OAuth + +```json +{ + "context_servers": { + "plane-mcp-server": { + "url": "https://your-mcp-server.com/http/mcp", + "settings": {} + } + } +} +``` + +#### HTTP with PAT Token + +```json +{ + "context_servers": { + "plane-mcp-server": { + "url": "https://your-mcp-server.com/http/api-key/mcp", + "headers": { + "x-api-key": "your_api_key_here", + "x-workspace-slug": "your-workspace-slug" + }, + "settings": {} + } + } +} +``` + +#### SSE (Legacy) + +```json +{ + "context_servers": { + "plane-mcp-server": { + "url": "https://your-mcp-server.com/sse", + "settings": {} } } } ``` -**Node.js version** +Open the AI panel (`Cmd + Shift + A`) to use Plane tools in conversation. + +## Self-hosted Plane deployments + +Set `PLANE_BASE_URL` to the public URL of your Plane instance (e.g., https://plane.yourcompany.com). This is used for user-facing OAuth redirects and API calls in stdio mode. + +In HTTP/SSE mode, the server also makes internal server-to-server calls to Plane for token validation. If your infrastructure routes internal traffic differently from public traffic (e.g., via a private network, service mesh, or internal load balancer), set `PLANE_INTERNAL_BASE_URL` to the internal address. When set, all server-to-server calls use this URL and only OAuth redirects use `PLANE_BASE_URL`. + +If `PLANE_INTERNAL_BASE_URL` is not set, it falls back to PLANE_BASE_URL for all calls. + +Before connecting a client, verify your credentials reach the instance: + +```bash +curl -H "x-api-key: YOUR_API_KEY" \ + "https://plane.yourcompany.com/api/v1/users/me/" +``` + +A `200` response confirms the API key and URL are correct. + +--- + +## Reference + +### Transport modes + +#### HTTP with OAuth + +| Property | Value | +|----------|-------| +| Start command | `plane-mcp-server http` | +| MCP endpoint | `http://host:8211/http/mcp` | +| Auth | Browser OAuth flow via Plane | +| Token storage | Redis (recommended) or in-memory | +| OAuth redirect URIs | `cursor://`, `vscode://`, `windsurf://`, `claude://`, `http://localhost:*` | +| Required env vars | `PLANE_OAUTH_PROVIDER_CLIENT_ID`, `PLANE_OAUTH_PROVIDER_CLIENT_SECRET`, `PLANE_OAUTH_PROVIDER_BASE_URL`, `PLANE_BASE_URL` | + +#### HTTP with PAT Token + +| Property | Value | +|----------|-------| +| Start command | `plane-mcp-server http` (same process) | +| MCP endpoint | `http://host:8211/http/api-key/mcp` | +| Auth | `x-api-key` + `x-workspace-slug` HTTP headers | +| Token storage | None (stateless) | +| Required env vars | None (credentials come from request headers) | + +The PAT endpoint validates the API key against Plane's `/api/v1/users/me/` on each request. + +#### Local Stdio + +| Property | Value | +|----------|-------| +| Start command | `plane-mcp-server stdio` | +| Transport | stdin/stdout (JSON-RPC 2.0) | +| Auth | `PLANE_API_KEY` + `PLANE_WORKSPACE_SLUG` env vars | +| Process lifecycle | One process per client session | +| Required env vars | `PLANE_API_KEY`, `PLANE_WORKSPACE_SLUG` | + +#### SSE (Legacy) + +| Property | Value | +|----------|-------| +| Start command | `plane-mcp-server http` (same process) | +| MCP endpoint | `http://host:8211/sse` | +| Auth | Browser OAuth flow via Plane | +| Token storage | Redis (recommended) or in-memory | +| Required env vars | Same as HTTP with OAuth | + +Use SSE only for clients that require it. New integrations should prefer streamable HTTP. + +--- + +### Tool reference + +The server exposes 100+ tools across 20 modules. All tools are registered identically regardless of transport mode. The same tools are available via stdio, HTTP/OAuth, HTTP/PAT, and SSE. + +#### Users + +##### `get_me` +Returns the profile of the currently authenticated user. No parameters. + +--- + +#### Workspaces + +##### `get_workspace_members` +Returns all members of the workspace. + +##### `get_workspace_features` +Returns enabled features for the workspace. + +##### `update_workspace_features` +Updates workspace-level feature flags. + +--- + +#### Projects + +##### `list_projects` +Returns all projects the current user is a member of. + +##### `create_project` +Creates a new project. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `name` | string | **Yes** | Project display name | +| `identifier` | string | **Yes** | Short uppercase code, max 12 chars (e.g., `ENG`) | +| `description` | string | No | Project description | +| `network` | string | No | `0` (secret) or `2` (public) | + +##### `retrieve_project` +Returns details of a single project. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `update_project` +Updates project fields. All fields are optional. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| other fields | partial | No | + +##### `delete_project` +Deletes a project. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `get_project_worklog_summary` +Returns time-tracking summary for a project. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `get_project_members` +Returns all members of a project. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `get_project_features` +Returns the feature configuration for a project (modules, cycles, pages, etc.). + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `update_project_features` +Updates which features are enabled on a project. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| feature fields | partial | No | + +--- + +#### Work Items + +##### `list_work_items` +Lists work items in a project, or searches across the workspace when filters are provided. + +When any filter parameter is set, the tool uses Plane's advanced search endpoint (supports workspace-wide search). Without filters it uses the standard paginated list endpoint. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | Conditional | Required when no filters are provided | +| `query` | string | No | Free-text search across name and description | +| `assignee_ids` | UUID[] | No | Filter by assignee | +| `state_ids` | UUID[] | No | Filter by state | +| `state_groups` | string[] | No | `backlog` · `unstarted` · `started` · `completed` · `cancelled` | +| `priorities` | string[] | No | `urgent` · `high` · `medium` · `low` · `none` | +| `label_ids` | UUID[] | No | Filter by label | +| `type_ids` | UUID[] | No | Filter by work item type | +| `cycle_ids` | UUID[] | No | Filter by cycle | +| `module_ids` | UUID[] | No | Filter by module | +| `is_archived` | boolean | No | Filter by archived status | +| `created_by_ids` | UUID[] | No | Filter by creator | +| `workspace_search` | boolean | No | Search across all projects (requires filters) | +| `limit` | integer | No | Max results when using filters | +| `cursor` | string | No | Pagination cursor (list mode) | +| `per_page` | integer | No | Results per page, 1–100 (list mode) | +| `expand` | string | No | Comma-separated fields to expand | +| `fields` | string | No | Comma-separated fields to include | +| `order_by` | string | No | Sort field | + +##### `create_work_item` +Creates a new work item in a project. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | Target project | +| `name` | string | **Yes** | Work item title | +| `description_html` | string | No | HTML body | +| `state_id` | UUID string | No | Initial state | +| `priority` | string | No | `urgent` · `high` · `medium` · `low` · `none` | +| `assignee_ids` | UUID[] | No | Assigned members | +| `label_ids` | UUID[] | No | Labels | +| `type_id` | UUID string | No | Work item type | +| `parent_id` | UUID string | No | Parent work item (sub-item) | +| `start_date` | string | No | `YYYY-MM-DD` | +| `due_date` | string | No | `YYYY-MM-DD` | + +##### `retrieve_work_item` +Returns a single work item by UUID. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `retrieve_work_item_by_identifier` +Returns a work item using its human-readable identifier (e.g., `ENG-42`). + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_identifier` | string | **Yes** | Project prefix, e.g., `ENG` | +| `work_item_identifier` | string | **Yes** | Issue number, e.g., `42` | + +##### `update_work_item` +Updates one or more fields on a work item. Only supplied fields are changed. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| other fields | partial | No | + +##### `delete_work_item` +Permanently deletes a work item. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `search_work_items` +Searches work items by text query within a project. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `query` | string | **Yes** | Search text | + +--- + +#### Work Item Activities + +##### `list_work_item_activities` +Returns the activity log (history of changes) for a work item. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `retrieve_work_item_activity` +Returns a single activity entry. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `activity_id` | UUID string | **Yes** | + +--- + +#### Work Item Comments + +##### `list_work_item_comments` +Returns all comments on a work item. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `retrieve_work_item_comment` +Returns a single comment. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `comment_id` | UUID string | **Yes** | + +##### `create_work_item_comment` +Adds a comment to a work item. Comments are stored as HTML. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | | +| `comment_html` | string | **Yes** | HTML content, e.g., `

Fixed in commit abc123

` | + +##### `update_work_item_comment` +Updates a comment's content. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `comment_id` | UUID string | **Yes** | +| `comment_html` | string | **Yes** | + +##### `delete_work_item_comment` +Deletes a comment. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `comment_id` | UUID string | **Yes** | + +--- + +#### Work Item Links + +External URLs attached to a work item (e.g., Figma designs, PRs, docs). + +##### `list_work_item_links` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `retrieve_work_item_link` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `link_id` | UUID string | **Yes** | + +##### `create_work_item_link` +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | | +| `url` | string | **Yes** | External URL | +| `title` | string | No | Display title for the link | + +##### `update_work_item_link` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `link_id` | UUID string | **Yes** | +| `url` / `title` | string | No | + +##### `delete_work_item_link` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `link_id` | UUID string | **Yes** | + +--- + +#### Work Item Relations + +Relations between work items (e.g., "blocks", "is blocked by", "duplicate of"). + +##### `list_work_item_relations` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `create_work_item_relation` +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | Source work item | +| `related_work_item_id` | UUID string | **Yes** | Target work item | +| `relation_type` | string | **Yes** | `blocking` · `blocked_by` · `duplicate_of` · `duplicate` · `relates_to` | + +##### `remove_work_item_relation` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `relation_id` | UUID string | **Yes** | + +--- + +#### Work Item Properties + +Custom fields defined per project. + +##### `list_work_item_properties` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `create_work_item_property` +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `name` | string | **Yes** | Property name | +| `property_type` | string | **Yes** | Type of the custom field | + +##### `retrieve_work_item_property` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `property_id` | UUID string | **Yes** | + +##### `update_work_item_property` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `property_id` | UUID string | **Yes** | + +##### `delete_work_item_property` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `property_id` | UUID string | **Yes** | + +--- + +#### Work Item Types + +Custom work item type definitions (e.g., Bug, Feature, Task, Epic). + +##### `list_work_item_types` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `create_work_item_type` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description` | string | No | +| `is_active` | boolean | No | + +##### `retrieve_work_item_type` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `type_id` | UUID string | **Yes** | + +##### `update_work_item_type` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `type_id` | UUID string | **Yes** | + +##### `delete_work_item_type` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `type_id` | UUID string | **Yes** | + +--- + +#### Worklogs + +Time tracking for work items. All durations are in **minutes**. + +##### `list_work_logs` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `create_work_log` +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | | +| `duration` | integer | **Yes** | Minutes logged (≥ 0) | +| `description` | string | No | What was done | + +##### `update_work_log` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `work_log_id` | UUID string | **Yes** | +| `duration` / `description` | - | No | + +##### `delete_work_log` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `work_log_id` | UUID string | **Yes** | + +--- + +#### States + +Workflow states for a project's work items. + +##### `list_states` / `create_state` / `retrieve_state` / `update_state` / `delete_state` + +All state tools accept `project_id`. Create and update accept: + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `name` | string | **Yes** (create) | Display name | +| `color` | string | **Yes** (create) | Hex color code, e.g., `#FF5733` | +| `group` | string | **Yes** (create) | `backlog` · `unstarted` · `started` · `completed` · `cancelled` | +| `description` | string | No | | + +--- + +#### Labels + +Tags for work items. + +##### `list_labels` / `create_label` / `retrieve_label` / `update_label` / `delete_label` + +All label tools accept `project_id`. Create and update accept: + +| Field | Type | Required | +|-------|------|----------| +| `name` | string | **Yes** (create) | +| `color` | string | **Yes** (create) | +| `parent` | UUID string | No | + +--- + +#### Cycles + +Time-boxed iterations (sprints). + +##### `list_cycles` +Returns all cycles in a project including upcoming, active, and completed. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `list_archived_cycles` +Returns archived cycles only. + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `create_cycle` +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `name` | string | **Yes** | Cycle name | +| `start_date` | string | No | `YYYY-MM-DD` | +| `end_date` | string | No | `YYYY-MM-DD` | +| `description` | string | No | | + +##### `retrieve_cycle` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | + +##### `update_cycle` / `delete_cycle` +Accept `project_id` and `cycle_id`. + +##### `add_work_items_to_cycle` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | + +##### `remove_work_item_from_cycle` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `list_cycle_work_items` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | + +##### `transfer_cycle_work_items` +Moves all incomplete work items from one cycle to another. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `project_id` | UUID string | **Yes** | | +| `cycle_id` | UUID string | **Yes** | Source cycle | +| `new_cycle_id` | UUID string | **Yes** | Target cycle | + +--- + +#### Modules + +Feature groupings within a project. + +##### `list_modules` / `list_archived_modules` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `create_module` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description` | string | No | +| `start_date` | string | No | +| `target_date` | string | No | +| `lead` | UUID string | No | +| `members` | UUID[] | No | + +##### `retrieve_module` / `update_module` / `delete_module` / `archive_module` +Accept `project_id` and `module_id`. + +##### `add_work_items_to_module` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `module_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | + +##### `remove_work_item_from_module` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `module_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | + +##### `list_module_work_items` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `module_id` | UUID string | **Yes** | + +--- + +#### Epics + +Large work items that group related items. The server resolves the Epic work item type automatically. + +##### `list_epics` / `create_epic` / `retrieve_epic` / `update_epic` / `delete_epic` + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `epic_id` | UUID string | Varies by operation | +| name, description, etc. | - | Varies | + +--- + +#### Milestones + +Point-in-time goals within a project. + +##### `list_milestones` / `create_milestone` / `retrieve_milestone` / `update_milestone` / `delete_milestone` + +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | Varies | +| `name` | string | **Yes** (create) | + +##### `add_work_items_to_milestone` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | + +##### `remove_work_items_from_milestone` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | + +##### `list_milestone_work_items` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | **Yes** | + +--- + +#### Initiatives + +Workspace-scoped strategic goals that span multiple projects. + +##### `list_initiatives` / `create_initiative` / `retrieve_initiative` / `update_initiative` / `delete_initiative` + +Initiatives are workspace-scoped - no `project_id` required. `retrieve_initiative`, `update_initiative`, and `delete_initiative` accept an `initiative_id` UUID. + +--- + +#### Intake + +Triage queue for incoming work items before they enter a project. + +##### `list_intake_work_items` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | + +##### `create_intake_work_item` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description_html` | string | No | + +##### `retrieve_intake_work_item` / `update_intake_work_item` / `delete_intake_work_item` +Accept `project_id` and `work_item_id`. + +--- + +#### Pages + +Wiki-style documents. Pages can be workspace-scoped or project-scoped. + +##### `retrieve_workspace_page` +| Parameter | Type | Required | +|-----------|------|----------| +| `page_id` | UUID string | **Yes** | + +##### `retrieve_project_page` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `page_id` | UUID string | **Yes** | + +##### `create_workspace_page` +| Parameter | Type | Required | +|-----------|------|----------| +| `name` | string | **Yes** | +| `description_html` | string | No | + +##### `create_project_page` +| Parameter | Type | Required | +|-----------|------|----------| +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description_html` | string | No | + +--- + +## Common Workflows + +### Look up a work item by ID + +``` +What is work item ENG-42 about? +``` + +Model calls `retrieve_work_item_by_identifier` with `project_identifier="ENG"` and `work_item_identifier="42"`. + +### Create a work item + +``` +Create a high-priority bug in the ENG project called "Login times out on Safari". +Description: The OAuth callback redirects to a blank page on Safari 17+. +Assign it to me. +``` + +Model calls `list_projects` → `retrieve_work_item_by_identifier` (or `get_me` to resolve "me") → `create_work_item`. + +### Update work item state + +``` +Mark ENG-88 as done and add a comment: "Fixed in commit abc1234, needs QA." +``` + +Model resolves the UUID, calls `list_states` to find the Done state UUID, calls `update_work_item` and `create_work_item_comment`. + +### Sprint planning + +``` +Create a cycle called "Sprint 15" in ENG starting 2025-06-02, ending 2025-06-15. +Then move all incomplete issues from Sprint 14 into it. +``` + +Model calls `create_cycle` then `list_cycles` to find Sprint 14's UUID, then `transfer_cycle_work_items`. + +### Log time + +``` +Log 90 minutes on ENG-42: "Implemented retry logic for the upload endpoint." +``` + +### Search across the workspace + +``` +Show me all high-priority bugs assigned to me that are still in progress. +``` + +Model calls `list_work_items` with filters `priorities=["high"]`, `state_groups=["started"]`, and the current user's UUID as `assignee_ids`. + +### Manage a module + +``` +Add ENG-55, ENG-56, and ENG-57 to the "Checkout Redesign" module. +``` + +Model calls `list_modules` to find the UUID, then `add_work_items_to_module` with the resolved work item UUIDs. + +--- + +## Troubleshooting + +The server propagates errors from the Plane SDK as MCP tool errors. -Ensure you have Node.js 22 or later installed for remote transports. +| Scenario | HTTP Status | Cause | Resolution | +|----------|-------------|-------|------------| +| Invalid API key | 401 | `PLANE_API_KEY` is wrong or revoked | Regenerate the token in Plane settings | +| Invalid OAuth token | 401 | Token expired or revoked | Re-authorise through OAuth flow | +| Missing `x-workspace-slug` header | - | Header auth missing workspace | Include `x-workspace-slug` header | +| Wrong workspace slug | 404 | Slug doesn't exist | Check the exact slug in your Plane URL | +| Insufficient permissions | 403 | User role too low | Check your role in the workspace/project | +| Resource not found | 404 | UUID or identifier doesn't exist | Verify the ID; check if resource was deleted | +| Validation error | 400 | Required field missing or invalid value | Check required fields and value constraints | +| Redis unavailable | - | Token storage down | Set `REDIS_HOST`/`REDIS_PORT` or omit for in-memory | +| Network error | - | Cannot reach Plane API | Verify `PLANE_BASE_URL` and connectivity | -**Python version** +**Verify connectivity (stdio/PAT):** -Ensure you have Python 3.10 or later installed for the local Stdio transport. +```bash +curl -H "x-api-key: YOUR_KEY" \ + "https://api.plane.so/api/v1/users/me/" +``` -### Getting help +**Run stdio mode manually to debug startup:** -If you continue to experience issues: +```bash +PLANE_API_KEY=your_key PLANE_WORKSPACE_SLUG=your-slug plane-mcp-server stdio +``` -1. Verify your authentication credentials -2. Contact support at support@plane.so for Plane-specific issues -3. Check the [MCP community forums](https://modelcontextprotocol.io) for general MCP issues +**Test the HTTP server is running:** -## Congrats! +```bash +curl http://localhost:8211/http/mcp +# Should return MCP protocol response or 401 +``` +--- -You have successfully connected your Plane workspace to the MCP server! +*Plane MCP Server is open source and licensed under MIT. Source at [github.com/makeplane/plane-mcp-server](https://github.com/makeplane/plane-mcp-server).* From d06d42ceeaf3f5a7f6c5b694d5aeab7999caeade Mon Sep 17 00:00:00 2001 From: danciaclara Date: Mon, 18 May 2026 16:44:53 +0530 Subject: [PATCH 2/4] formatting fixes --- docs/dev-tools/mcp-server.md | 862 +++++++++++++++++++---------------- 1 file changed, 472 insertions(+), 390 deletions(-) diff --git a/docs/dev-tools/mcp-server.md b/docs/dev-tools/mcp-server.md index 5cd3837b..adb941e4 100644 --- a/docs/dev-tools/mcp-server.md +++ b/docs/dev-tools/mcp-server.md @@ -14,12 +14,12 @@ The Plane MCP Server is a bridge that lets AI models interact with Plane. It exp The server supports four transport modes. The right one depends on your deployment and usecase. -| Transport | For | Auth method | How to start | -|-----------|----------|-------------|--------------| -| HTTP with OAuth | Plane Cloud users, simplest setup | Browser-based OAuth flow | `plane-mcp-server http` | -| HTTP with PAT Token | Automated workflows, CI/CD | API key in request headers | `plane-mcp-server http` | -| Local Stdio | Local dev, self-hosted Plane | Environment variables | `plane-mcp-server stdio` | -| SSE (Legacy) | Existing integrations | Browser-based OAuth flow | `plane-mcp-server http` | +| Transport | For | Auth method | How to start | +| ------------------- | --------------------------------- | -------------------------- | ------------------------ | +| HTTP with OAuth | Plane Cloud users, simplest setup | Browser-based OAuth flow | `plane-mcp-server http` | +| HTTP with PAT Token | Automated workflows, CI/CD | API key in request headers | `plane-mcp-server http` | +| Local Stdio | Local dev, self-hosted Plane | Environment variables | `plane-mcp-server stdio` | +| SSE (Legacy) | Existing integrations | Browser-based OAuth flow | `plane-mcp-server http` | ## Authentication model @@ -35,12 +35,14 @@ For cloud deployments, the server acts as an **OAuth proxy** to Plane's OAuth sy 4. Subsequent MCP requests carry this token, from which the server extracts the workspace slug The server supports OAuth redirect URIs for all major MCP clients: + - `http://localhost:*` (dynamic ports from desktop clients) - `cursor://`, `vscode://`, `vscode-insiders://`, `windsurf://`, `claude://` ### Header auth (HTTP with PAT Token) For automated workflows, the MCP client sends two headers with every request: + - `x-api-key` - a Plane API token - `x-workspace-slug` - the workspace identifier @@ -49,6 +51,7 @@ The server validates the API key against Plane's `/api/v1/users/me/` endpoint on ### Environment variable auth (stdio) For stdio mode, credentials are read from environment variables at startup: + - `PLANE_API_KEY` - your Plane API token - `PLANE_WORKSPACE_SLUG` - your workspace identifier - `PLANE_BASE_URL` - API URL for self-hosted instances (defaults to `https://api.plane.so`) @@ -72,9 +75,11 @@ Plane uses two kinds of identifiers for work items. ### Prerequisites **For all modes:** + - A Plane account with access to at least one workspace **For stdio mode (local and self-hosted deployments)** + - Python 3.10+ installed (`python --version`) - `uv` package manager (recommended). See [Installing uv](https://docs.astral.sh/uv/getting-started/installation/) @@ -90,9 +95,11 @@ Plane uses two kinds of identifiers for work items. #### Get your workspace slug The slug is the short identifier in your Plane URL. For: + ``` https://app.plane.so/acme-corp/ ``` + the slug is `acme-corp`. ### Claude Desktop @@ -462,7 +469,7 @@ Config file: `~/.codeium/windsurf/mcp_config.json` Restart Windsurf after saving, then open the Cascade panel. The `windsurf://` redirect URI is registered in the OAuth provider. -#### Stdio +#### Stdio ```json { @@ -620,46 +627,46 @@ A `200` response confirms the API key and URL are correct. #### HTTP with OAuth -| Property | Value | -|----------|-------| -| Start command | `plane-mcp-server http` | -| MCP endpoint | `http://host:8211/http/mcp` | -| Auth | Browser OAuth flow via Plane | -| Token storage | Redis (recommended) or in-memory | -| OAuth redirect URIs | `cursor://`, `vscode://`, `windsurf://`, `claude://`, `http://localhost:*` | -| Required env vars | `PLANE_OAUTH_PROVIDER_CLIENT_ID`, `PLANE_OAUTH_PROVIDER_CLIENT_SECRET`, `PLANE_OAUTH_PROVIDER_BASE_URL`, `PLANE_BASE_URL` | +| Property | Value | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------- | +| Start command | `plane-mcp-server http` | +| MCP endpoint | `http://host:8211/http/mcp` | +| Auth | Browser OAuth flow via Plane | +| Token storage | Redis (recommended) or in-memory | +| OAuth redirect URIs | `cursor://`, `vscode://`, `windsurf://`, `claude://`, `http://localhost:*` | +| Required env vars | `PLANE_OAUTH_PROVIDER_CLIENT_ID`, `PLANE_OAUTH_PROVIDER_CLIENT_SECRET`, `PLANE_OAUTH_PROVIDER_BASE_URL`, `PLANE_BASE_URL` | #### HTTP with PAT Token -| Property | Value | -|----------|-------| -| Start command | `plane-mcp-server http` (same process) | -| MCP endpoint | `http://host:8211/http/api-key/mcp` | -| Auth | `x-api-key` + `x-workspace-slug` HTTP headers | -| Token storage | None (stateless) | -| Required env vars | None (credentials come from request headers) | +| Property | Value | +| ----------------- | --------------------------------------------- | +| Start command | `plane-mcp-server http` (same process) | +| MCP endpoint | `http://host:8211/http/api-key/mcp` | +| Auth | `x-api-key` + `x-workspace-slug` HTTP headers | +| Token storage | None (stateless) | +| Required env vars | None (credentials come from request headers) | The PAT endpoint validates the API key against Plane's `/api/v1/users/me/` on each request. #### Local Stdio -| Property | Value | -|----------|-------| -| Start command | `plane-mcp-server stdio` | -| Transport | stdin/stdout (JSON-RPC 2.0) | -| Auth | `PLANE_API_KEY` + `PLANE_WORKSPACE_SLUG` env vars | -| Process lifecycle | One process per client session | -| Required env vars | `PLANE_API_KEY`, `PLANE_WORKSPACE_SLUG` | +| Property | Value | +| ----------------- | ------------------------------------------------- | +| Start command | `plane-mcp-server stdio` | +| Transport | stdin/stdout (JSON-RPC 2.0) | +| Auth | `PLANE_API_KEY` + `PLANE_WORKSPACE_SLUG` env vars | +| Process lifecycle | One process per client session | +| Required env vars | `PLANE_API_KEY`, `PLANE_WORKSPACE_SLUG` | #### SSE (Legacy) -| Property | Value | -|----------|-------| -| Start command | `plane-mcp-server http` (same process) | -| MCP endpoint | `http://host:8211/sse` | -| Auth | Browser OAuth flow via Plane | -| Token storage | Redis (recommended) or in-memory | -| Required env vars | Same as HTTP with OAuth | +| Property | Value | +| ----------------- | -------------------------------------- | +| Start command | `plane-mcp-server http` (same process) | +| MCP endpoint | `http://host:8211/sse` | +| Auth | Browser OAuth flow via Plane | +| Token storage | Redis (recommended) or in-memory | +| Required env vars | Same as HTTP with OAuth | Use SSE only for clients that require it. New integrations should prefer streamable HTTP. @@ -672,6 +679,7 @@ The server exposes 100+ tools across 20 modules. All tools are registered identi #### Users ##### `get_me` + Returns the profile of the currently authenticated user. No parameters. --- @@ -679,12 +687,15 @@ Returns the profile of the currently authenticated user. No parameters. #### Workspaces ##### `get_workspace_members` + Returns all members of the workspace. ##### `get_workspace_features` + Returns enabled features for the workspace. ##### `update_workspace_features` + Updates workspace-level feature flags. --- @@ -692,227 +703,250 @@ Updates workspace-level feature flags. #### Projects ##### `list_projects` + Returns all projects the current user is a member of. ##### `create_project` + Creates a new project. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `name` | string | **Yes** | Project display name | -| `identifier` | string | **Yes** | Short uppercase code, max 12 chars (e.g., `ENG`) | -| `description` | string | No | Project description | -| `network` | string | No | `0` (secret) or `2` (public) | +| Parameter | Type | Required | Description | +| ------------- | ------ | -------- | ------------------------------------------------ | +| `name` | string | **Yes** | Project display name | +| `identifier` | string | **Yes** | Short uppercase code, max 12 chars (e.g., `ENG`) | +| `description` | string | No | Project description | +| `network` | string | No | `0` (secret) or `2` (public) | ##### `retrieve_project` + Returns details of a single project. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `update_project` + Updates project fields. All fields are optional. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| other fields | partial | No | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| other fields | partial | No | ##### `delete_project` + Deletes a project. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `get_project_worklog_summary` + Returns time-tracking summary for a project. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `get_project_members` + Returns all members of a project. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `get_project_features` + Returns the feature configuration for a project (modules, cycles, pages, etc.). -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `update_project_features` + Updates which features are enabled on a project. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| feature fields | partial | No | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| feature fields | partial | No | --- #### Work Items ##### `list_work_items` + Lists work items in a project, or searches across the workspace when filters are provided. When any filter parameter is set, the tool uses Plane's advanced search endpoint (supports workspace-wide search). Without filters it uses the standard paginated list endpoint. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | Conditional | Required when no filters are provided | -| `query` | string | No | Free-text search across name and description | -| `assignee_ids` | UUID[] | No | Filter by assignee | -| `state_ids` | UUID[] | No | Filter by state | -| `state_groups` | string[] | No | `backlog` · `unstarted` · `started` · `completed` · `cancelled` | -| `priorities` | string[] | No | `urgent` · `high` · `medium` · `low` · `none` | -| `label_ids` | UUID[] | No | Filter by label | -| `type_ids` | UUID[] | No | Filter by work item type | -| `cycle_ids` | UUID[] | No | Filter by cycle | -| `module_ids` | UUID[] | No | Filter by module | -| `is_archived` | boolean | No | Filter by archived status | -| `created_by_ids` | UUID[] | No | Filter by creator | -| `workspace_search` | boolean | No | Search across all projects (requires filters) | -| `limit` | integer | No | Max results when using filters | -| `cursor` | string | No | Pagination cursor (list mode) | -| `per_page` | integer | No | Results per page, 1–100 (list mode) | -| `expand` | string | No | Comma-separated fields to expand | -| `fields` | string | No | Comma-separated fields to include | -| `order_by` | string | No | Sort field | +| Parameter | Type | Required | Description | +| ------------------ | ----------- | ----------- | --------------------------------------------------------------- | +| `project_id` | UUID string | Conditional | Required when no filters are provided | +| `query` | string | No | Free-text search across name and description | +| `assignee_ids` | UUID[] | No | Filter by assignee | +| `state_ids` | UUID[] | No | Filter by state | +| `state_groups` | string[] | No | `backlog` · `unstarted` · `started` · `completed` · `cancelled` | +| `priorities` | string[] | No | `urgent` · `high` · `medium` · `low` · `none` | +| `label_ids` | UUID[] | No | Filter by label | +| `type_ids` | UUID[] | No | Filter by work item type | +| `cycle_ids` | UUID[] | No | Filter by cycle | +| `module_ids` | UUID[] | No | Filter by module | +| `is_archived` | boolean | No | Filter by archived status | +| `created_by_ids` | UUID[] | No | Filter by creator | +| `workspace_search` | boolean | No | Search across all projects (requires filters) | +| `limit` | integer | No | Max results when using filters | +| `cursor` | string | No | Pagination cursor (list mode) | +| `per_page` | integer | No | Results per page, 1–100 (list mode) | +| `expand` | string | No | Comma-separated fields to expand | +| `fields` | string | No | Comma-separated fields to include | +| `order_by` | string | No | Sort field | ##### `create_work_item` + Creates a new work item in a project. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | Target project | -| `name` | string | **Yes** | Work item title | -| `description_html` | string | No | HTML body | -| `state_id` | UUID string | No | Initial state | -| `priority` | string | No | `urgent` · `high` · `medium` · `low` · `none` | -| `assignee_ids` | UUID[] | No | Assigned members | -| `label_ids` | UUID[] | No | Labels | -| `type_id` | UUID string | No | Work item type | -| `parent_id` | UUID string | No | Parent work item (sub-item) | -| `start_date` | string | No | `YYYY-MM-DD` | -| `due_date` | string | No | `YYYY-MM-DD` | +| Parameter | Type | Required | Description | +| ------------------ | ----------- | -------- | --------------------------------------------- | +| `project_id` | UUID string | **Yes** | Target project | +| `name` | string | **Yes** | Work item title | +| `description_html` | string | No | HTML body | +| `state_id` | UUID string | No | Initial state | +| `priority` | string | No | `urgent` · `high` · `medium` · `low` · `none` | +| `assignee_ids` | UUID[] | No | Assigned members | +| `label_ids` | UUID[] | No | Labels | +| `type_id` | UUID string | No | Work item type | +| `parent_id` | UUID string | No | Parent work item (sub-item) | +| `start_date` | string | No | `YYYY-MM-DD` | +| `due_date` | string | No | `YYYY-MM-DD` | ##### `retrieve_work_item` + Returns a single work item by UUID. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `retrieve_work_item_by_identifier` + Returns a work item using its human-readable identifier (e.g., `ENG-42`). -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_identifier` | string | **Yes** | Project prefix, e.g., `ENG` | -| `work_item_identifier` | string | **Yes** | Issue number, e.g., `42` | +| Parameter | Type | Required | Description | +| ---------------------- | ------ | -------- | --------------------------- | +| `project_identifier` | string | **Yes** | Project prefix, e.g., `ENG` | +| `work_item_identifier` | string | **Yes** | Issue number, e.g., `42` | ##### `update_work_item` + Updates one or more fields on a work item. Only supplied fields are changed. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| other fields | partial | No | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| other fields | partial | No | ##### `delete_work_item` + Permanently deletes a work item. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `search_work_items` + Searches work items by text query within a project. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `query` | string | **Yes** | Search text | +| Parameter | Type | Required | Description | +| ------------ | ----------- | -------- | ----------- | +| `project_id` | UUID string | **Yes** | | +| `query` | string | **Yes** | Search text | --- #### Work Item Activities ##### `list_work_item_activities` + Returns the activity log (history of changes) for a work item. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `retrieve_work_item_activity` + Returns a single activity entry. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `activity_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `activity_id` | UUID string | **Yes** | --- #### Work Item Comments ##### `list_work_item_comments` + Returns all comments on a work item. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `retrieve_work_item_comment` + Returns a single comment. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `comment_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `comment_id` | UUID string | **Yes** | ##### `create_work_item_comment` + Adds a comment to a work item. Comments are stored as HTML. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `work_item_id` | UUID string | **Yes** | | -| `comment_html` | string | **Yes** | HTML content, e.g., `

Fixed in commit abc123

` | +| Parameter | Type | Required | Description | +| -------------- | ----------- | -------- | --------------------------------------------------- | +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | | +| `comment_html` | string | **Yes** | HTML content, e.g., `

Fixed in commit abc123

` | ##### `update_work_item_comment` + Updates a comment's content. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `comment_id` | UUID string | **Yes** | -| `comment_html` | string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `comment_id` | UUID string | **Yes** | +| `comment_html` | string | **Yes** | ##### `delete_work_item_comment` + Deletes a comment. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `comment_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `comment_id` | UUID string | **Yes** | --- @@ -921,40 +955,45 @@ Deletes a comment. External URLs attached to a work item (e.g., Figma designs, PRs, docs). ##### `list_work_item_links` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `retrieve_work_item_link` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `link_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `link_id` | UUID string | **Yes** | ##### `create_work_item_link` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `work_item_id` | UUID string | **Yes** | | -| `url` | string | **Yes** | External URL | -| `title` | string | No | Display title for the link | + +| Parameter | Type | Required | Description | +| -------------- | ----------- | -------- | -------------------------- | +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | | +| `url` | string | **Yes** | External URL | +| `title` | string | No | Display title for the link | ##### `update_work_item_link` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `link_id` | UUID string | **Yes** | -| `url` / `title` | string | No | + +| Parameter | Type | Required | +| --------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `link_id` | UUID string | **Yes** | +| `url` / `title` | string | No | ##### `delete_work_item_link` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `link_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `link_id` | UUID string | **Yes** | --- @@ -963,25 +1002,28 @@ External URLs attached to a work item (e.g., Figma designs, PRs, docs). Relations between work items (e.g., "blocks", "is blocked by", "duplicate of"). ##### `list_work_item_relations` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `create_work_item_relation` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `work_item_id` | UUID string | **Yes** | Source work item | -| `related_work_item_id` | UUID string | **Yes** | Target work item | -| `relation_type` | string | **Yes** | `blocking` · `blocked_by` · `duplicate_of` · `duplicate` · `relates_to` | + +| Parameter | Type | Required | Description | +| ---------------------- | ----------- | -------- | ----------------------------------------------------------------------- | +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | Source work item | +| `related_work_item_id` | UUID string | **Yes** | Target work item | +| `relation_type` | string | **Yes** | `blocking` · `blocked_by` · `duplicate_of` · `duplicate` · `relates_to` | ##### `remove_work_item_relation` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `relation_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `relation_id` | UUID string | **Yes** | --- @@ -990,34 +1032,39 @@ Relations between work items (e.g., "blocks", "is blocked by", "duplicate of"). Custom fields defined per project. ##### `list_work_item_properties` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `create_work_item_property` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `name` | string | **Yes** | Property name | -| `property_type` | string | **Yes** | Type of the custom field | + +| Parameter | Type | Required | Description | +| --------------- | ----------- | -------- | ------------------------ | +| `project_id` | UUID string | **Yes** | | +| `name` | string | **Yes** | Property name | +| `property_type` | string | **Yes** | Type of the custom field | ##### `retrieve_work_item_property` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `property_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `property_id` | UUID string | **Yes** | ##### `update_work_item_property` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `property_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `property_id` | UUID string | **Yes** | ##### `delete_work_item_property` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `property_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `property_id` | UUID string | **Yes** | --- @@ -1026,35 +1073,40 @@ Custom fields defined per project. Custom work item type definitions (e.g., Bug, Feature, Task, Epic). ##### `list_work_item_types` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `create_work_item_type` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `name` | string | **Yes** | -| `description` | string | No | -| `is_active` | boolean | No | + +| Parameter | Type | Required | +| ------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description` | string | No | +| `is_active` | boolean | No | ##### `retrieve_work_item_type` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `type_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `type_id` | UUID string | **Yes** | ##### `update_work_item_type` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `type_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `type_id` | UUID string | **Yes** | ##### `delete_work_item_type` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `type_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `type_id` | UUID string | **Yes** | --- @@ -1063,33 +1115,37 @@ Custom work item type definitions (e.g., Bug, Feature, Task, Epic). Time tracking for work items. All durations are in **minutes**. ##### `list_work_logs` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `create_work_log` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `work_item_id` | UUID string | **Yes** | | -| `duration` | integer | **Yes** | Minutes logged (≥ 0) | -| `description` | string | No | What was done | + +| Parameter | Type | Required | Description | +| -------------- | ----------- | -------- | -------------------- | +| `project_id` | UUID string | **Yes** | | +| `work_item_id` | UUID string | **Yes** | | +| `duration` | integer | **Yes** | Minutes logged (≥ 0) | +| `description` | string | No | What was done | ##### `update_work_log` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `work_log_id` | UUID string | **Yes** | -| `duration` / `description` | - | No | + +| Parameter | Type | Required | +| -------------------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `work_log_id` | UUID string | **Yes** | +| `duration` / `description` | - | No | ##### `delete_work_log` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | -| `work_log_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | +| `work_log_id` | UUID string | **Yes** | --- @@ -1101,12 +1157,12 @@ Workflow states for a project's work items. All state tools accept `project_id`. Create and update accept: -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `name` | string | **Yes** (create) | Display name | -| `color` | string | **Yes** (create) | Hex color code, e.g., `#FF5733` | -| `group` | string | **Yes** (create) | `backlog` · `unstarted` · `started` · `completed` · `cancelled` | -| `description` | string | No | | +| Field | Type | Required | Description | +| ------------- | ------ | ---------------- | --------------------------------------------------------------- | +| `name` | string | **Yes** (create) | Display name | +| `color` | string | **Yes** (create) | Hex color code, e.g., `#FF5733` | +| `group` | string | **Yes** (create) | `backlog` · `unstarted` · `started` · `completed` · `cancelled` | +| `description` | string | No | | --- @@ -1118,11 +1174,11 @@ Tags for work items. All label tools accept `project_id`. Create and update accept: -| Field | Type | Required | -|-------|------|----------| -| `name` | string | **Yes** (create) | -| `color` | string | **Yes** (create) | -| `parent` | UUID string | No | +| Field | Type | Required | +| -------- | ----------- | ---------------- | +| `name` | string | **Yes** (create) | +| `color` | string | **Yes** (create) | +| `parent` | UUID string | No | --- @@ -1131,65 +1187,74 @@ All label tools accept `project_id`. Create and update accept: Time-boxed iterations (sprints). ##### `list_cycles` + Returns all cycles in a project including upcoming, active, and completed. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `list_archived_cycles` + Returns archived cycles only. -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `create_cycle` -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `name` | string | **Yes** | Cycle name | -| `start_date` | string | No | `YYYY-MM-DD` | -| `end_date` | string | No | `YYYY-MM-DD` | -| `description` | string | No | | + +| Parameter | Type | Required | Description | +| ------------- | ----------- | -------- | ------------ | +| `project_id` | UUID string | **Yes** | | +| `name` | string | **Yes** | Cycle name | +| `start_date` | string | No | `YYYY-MM-DD` | +| `end_date` | string | No | `YYYY-MM-DD` | +| `description` | string | No | | ##### `retrieve_cycle` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `cycle_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | ##### `update_cycle` / `delete_cycle` + Accept `project_id` and `cycle_id`. ##### `add_work_items_to_cycle` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `cycle_id` | UUID string | **Yes** | -| `work_item_ids` | UUID[] | **Yes** | + +| Parameter | Type | Required | +| --------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | ##### `remove_work_item_from_cycle` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `cycle_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `list_cycle_work_items` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `cycle_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `cycle_id` | UUID string | **Yes** | ##### `transfer_cycle_work_items` + Moves all incomplete work items from one cycle to another. -| Parameter | Type | Required | Description | -|-----------|------|----------|-------------| -| `project_id` | UUID string | **Yes** | | -| `cycle_id` | UUID string | **Yes** | Source cycle | -| `new_cycle_id` | UUID string | **Yes** | Target cycle | +| Parameter | Type | Required | Description | +| -------------- | ----------- | -------- | ------------ | +| `project_id` | UUID string | **Yes** | | +| `cycle_id` | UUID string | **Yes** | Source cycle | +| `new_cycle_id` | UUID string | **Yes** | Target cycle | --- @@ -1198,43 +1263,49 @@ Moves all incomplete work items from one cycle to another. Feature groupings within a project. ##### `list_modules` / `list_archived_modules` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `create_module` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `name` | string | **Yes** | -| `description` | string | No | -| `start_date` | string | No | -| `target_date` | string | No | -| `lead` | UUID string | No | -| `members` | UUID[] | No | + +| Parameter | Type | Required | +| ------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description` | string | No | +| `start_date` | string | No | +| `target_date` | string | No | +| `lead` | UUID string | No | +| `members` | UUID[] | No | ##### `retrieve_module` / `update_module` / `delete_module` / `archive_module` + Accept `project_id` and `module_id`. ##### `add_work_items_to_module` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `module_id` | UUID string | **Yes** | -| `work_item_ids` | UUID[] | **Yes** | + +| Parameter | Type | Required | +| --------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `module_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | ##### `remove_work_item_from_module` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `module_id` | UUID string | **Yes** | -| `work_item_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `module_id` | UUID string | **Yes** | +| `work_item_id` | UUID string | **Yes** | ##### `list_module_work_items` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `module_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `module_id` | UUID string | **Yes** | --- @@ -1244,11 +1315,11 @@ Large work items that group related items. The server resolves the Epic work ite ##### `list_epics` / `create_epic` / `retrieve_epic` / `update_epic` / `delete_epic` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `epic_id` | UUID string | Varies by operation | -| name, description, etc. | - | Varies | +| Parameter | Type | Required | +| ----------------------- | ----------- | ------------------- | +| `project_id` | UUID string | **Yes** | +| `epic_id` | UUID string | Varies by operation | +| name, description, etc. | - | Varies | --- @@ -1258,31 +1329,34 @@ Point-in-time goals within a project. ##### `list_milestones` / `create_milestone` / `retrieve_milestone` / `update_milestone` / `delete_milestone` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `milestone_id` | UUID string | Varies | -| `name` | string | **Yes** (create) | +| Parameter | Type | Required | +| -------------- | ----------- | ---------------- | +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | Varies | +| `name` | string | **Yes** (create) | ##### `add_work_items_to_milestone` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `milestone_id` | UUID string | **Yes** | -| `work_item_ids` | UUID[] | **Yes** | + +| Parameter | Type | Required | +| --------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | ##### `remove_work_items_from_milestone` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `milestone_id` | UUID string | **Yes** | -| `work_item_ids` | UUID[] | **Yes** | + +| Parameter | Type | Required | +| --------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | **Yes** | +| `work_item_ids` | UUID[] | **Yes** | ##### `list_milestone_work_items` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `milestone_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| -------------- | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `milestone_id` | UUID string | **Yes** | --- @@ -1301,18 +1375,21 @@ Initiatives are workspace-scoped - no `project_id` required. `retrieve_initiativ Triage queue for incoming work items before they enter a project. ##### `list_intake_work_items` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | ##### `create_intake_work_item` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `name` | string | **Yes** | -| `description_html` | string | No | + +| Parameter | Type | Required | +| ------------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description_html` | string | No | ##### `retrieve_intake_work_item` / `update_intake_work_item` / `delete_intake_work_item` + Accept `project_id` and `work_item_id`. --- @@ -1322,28 +1399,32 @@ Accept `project_id` and `work_item_id`. Wiki-style documents. Pages can be workspace-scoped or project-scoped. ##### `retrieve_workspace_page` -| Parameter | Type | Required | -|-----------|------|----------| -| `page_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| --------- | ----------- | -------- | +| `page_id` | UUID string | **Yes** | ##### `retrieve_project_page` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `page_id` | UUID string | **Yes** | + +| Parameter | Type | Required | +| ------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `page_id` | UUID string | **Yes** | ##### `create_workspace_page` -| Parameter | Type | Required | -|-----------|------|----------| -| `name` | string | **Yes** | -| `description_html` | string | No | + +| Parameter | Type | Required | +| ------------------ | ------ | -------- | +| `name` | string | **Yes** | +| `description_html` | string | No | ##### `create_project_page` -| Parameter | Type | Required | -|-----------|------|----------| -| `project_id` | UUID string | **Yes** | -| `name` | string | **Yes** | -| `description_html` | string | No | + +| Parameter | Type | Required | +| ------------------ | ----------- | -------- | +| `project_id` | UUID string | **Yes** | +| `name` | string | **Yes** | +| `description_html` | string | No | --- @@ -1412,17 +1493,17 @@ Model calls `list_modules` to find the UUID, then `add_work_items_to_module` wit The server propagates errors from the Plane SDK as MCP tool errors. -| Scenario | HTTP Status | Cause | Resolution | -|----------|-------------|-------|------------| -| Invalid API key | 401 | `PLANE_API_KEY` is wrong or revoked | Regenerate the token in Plane settings | -| Invalid OAuth token | 401 | Token expired or revoked | Re-authorise through OAuth flow | -| Missing `x-workspace-slug` header | - | Header auth missing workspace | Include `x-workspace-slug` header | -| Wrong workspace slug | 404 | Slug doesn't exist | Check the exact slug in your Plane URL | -| Insufficient permissions | 403 | User role too low | Check your role in the workspace/project | -| Resource not found | 404 | UUID or identifier doesn't exist | Verify the ID; check if resource was deleted | -| Validation error | 400 | Required field missing or invalid value | Check required fields and value constraints | -| Redis unavailable | - | Token storage down | Set `REDIS_HOST`/`REDIS_PORT` or omit for in-memory | -| Network error | - | Cannot reach Plane API | Verify `PLANE_BASE_URL` and connectivity | +| Scenario | HTTP Status | Cause | Resolution | +| --------------------------------- | ----------- | --------------------------------------- | --------------------------------------------------- | +| Invalid API key | 401 | `PLANE_API_KEY` is wrong or revoked | Regenerate the token in Plane settings | +| Invalid OAuth token | 401 | Token expired or revoked | Re-authorise through OAuth flow | +| Missing `x-workspace-slug` header | - | Header auth missing workspace | Include `x-workspace-slug` header | +| Wrong workspace slug | 404 | Slug doesn't exist | Check the exact slug in your Plane URL | +| Insufficient permissions | 403 | User role too low | Check your role in the workspace/project | +| Resource not found | 404 | UUID or identifier doesn't exist | Verify the ID; check if resource was deleted | +| Validation error | 400 | Required field missing or invalid value | Check required fields and value constraints | +| Redis unavailable | - | Token storage down | Set `REDIS_HOST`/`REDIS_PORT` or omit for in-memory | +| Network error | - | Cannot reach Plane API | Verify `PLANE_BASE_URL` and connectivity | **Verify connectivity (stdio/PAT):** @@ -1443,6 +1524,7 @@ PLANE_API_KEY=your_key PLANE_WORKSPACE_SLUG=your-slug plane-mcp-server stdio curl http://localhost:8211/http/mcp # Should return MCP protocol response or 401 ``` + --- -*Plane MCP Server is open source and licensed under MIT. Source at [github.com/makeplane/plane-mcp-server](https://github.com/makeplane/plane-mcp-server).* +_Plane MCP Server is open source and licensed under MIT. Source at [github.com/makeplane/plane-mcp-server](https://github.com/makeplane/plane-mcp-server)._ From 9318d5d196385be63040273c44e24f5a8311df08 Mon Sep 17 00:00:00 2001 From: danciaclara Date: Mon, 18 May 2026 17:00:10 +0530 Subject: [PATCH 3/4] minor updates --- docs/dev-tools/mcp-server.md | 251 ++++++++++++++--------------------- 1 file changed, 100 insertions(+), 151 deletions(-) diff --git a/docs/dev-tools/mcp-server.md b/docs/dev-tools/mcp-server.md index adb941e4..297fcc94 100644 --- a/docs/dev-tools/mcp-server.md +++ b/docs/dev-tools/mcp-server.md @@ -621,92 +621,41 @@ A `200` response confirms the API key and URL are correct. --- -## Reference - -### Transport modes - -#### HTTP with OAuth - -| Property | Value | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------- | -| Start command | `plane-mcp-server http` | -| MCP endpoint | `http://host:8211/http/mcp` | -| Auth | Browser OAuth flow via Plane | -| Token storage | Redis (recommended) or in-memory | -| OAuth redirect URIs | `cursor://`, `vscode://`, `windsurf://`, `claude://`, `http://localhost:*` | -| Required env vars | `PLANE_OAUTH_PROVIDER_CLIENT_ID`, `PLANE_OAUTH_PROVIDER_CLIENT_SECRET`, `PLANE_OAUTH_PROVIDER_BASE_URL`, `PLANE_BASE_URL` | - -#### HTTP with PAT Token - -| Property | Value | -| ----------------- | --------------------------------------------- | -| Start command | `plane-mcp-server http` (same process) | -| MCP endpoint | `http://host:8211/http/api-key/mcp` | -| Auth | `x-api-key` + `x-workspace-slug` HTTP headers | -| Token storage | None (stateless) | -| Required env vars | None (credentials come from request headers) | - -The PAT endpoint validates the API key against Plane's `/api/v1/users/me/` on each request. - -#### Local Stdio - -| Property | Value | -| ----------------- | ------------------------------------------------- | -| Start command | `plane-mcp-server stdio` | -| Transport | stdin/stdout (JSON-RPC 2.0) | -| Auth | `PLANE_API_KEY` + `PLANE_WORKSPACE_SLUG` env vars | -| Process lifecycle | One process per client session | -| Required env vars | `PLANE_API_KEY`, `PLANE_WORKSPACE_SLUG` | - -#### SSE (Legacy) - -| Property | Value | -| ----------------- | -------------------------------------- | -| Start command | `plane-mcp-server http` (same process) | -| MCP endpoint | `http://host:8211/sse` | -| Auth | Browser OAuth flow via Plane | -| Token storage | Redis (recommended) or in-memory | -| Required env vars | Same as HTTP with OAuth | - -Use SSE only for clients that require it. New integrations should prefer streamable HTTP. - ---- - -### Tool reference +## Tool reference The server exposes 100+ tools across 20 modules. All tools are registered identically regardless of transport mode. The same tools are available via stdio, HTTP/OAuth, HTTP/PAT, and SSE. -#### Users +### Users -##### `get_me` +#### `get_me` Returns the profile of the currently authenticated user. No parameters. --- -#### Workspaces +### Workspaces -##### `get_workspace_members` +#### `get_workspace_members` Returns all members of the workspace. -##### `get_workspace_features` +#### `get_workspace_features` Returns enabled features for the workspace. -##### `update_workspace_features` +#### `update_workspace_features` Updates workspace-level feature flags. --- -#### Projects +### Projects -##### `list_projects` +#### `list_projects` Returns all projects the current user is a member of. -##### `create_project` +#### `create_project` Creates a new project. @@ -717,7 +666,7 @@ Creates a new project. | `description` | string | No | Project description | | `network` | string | No | `0` (secret) or `2` (public) | -##### `retrieve_project` +#### `retrieve_project` Returns details of a single project. @@ -725,7 +674,7 @@ Returns details of a single project. | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `update_project` +#### `update_project` Updates project fields. All fields are optional. @@ -734,7 +683,7 @@ Updates project fields. All fields are optional. | `project_id` | UUID string | **Yes** | | other fields | partial | No | -##### `delete_project` +#### `delete_project` Deletes a project. @@ -742,7 +691,7 @@ Deletes a project. | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `get_project_worklog_summary` +#### `get_project_worklog_summary` Returns time-tracking summary for a project. @@ -750,7 +699,7 @@ Returns time-tracking summary for a project. | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `get_project_members` +#### `get_project_members` Returns all members of a project. @@ -758,7 +707,7 @@ Returns all members of a project. | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `get_project_features` +#### `get_project_features` Returns the feature configuration for a project (modules, cycles, pages, etc.). @@ -766,7 +715,7 @@ Returns the feature configuration for a project (modules, cycles, pages, etc.). | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `update_project_features` +#### `update_project_features` Updates which features are enabled on a project. @@ -777,9 +726,9 @@ Updates which features are enabled on a project. --- -#### Work Items +### Work Items -##### `list_work_items` +#### `list_work_items` Lists work items in a project, or searches across the workspace when filters are provided. @@ -807,7 +756,7 @@ When any filter parameter is set, the tool uses Plane's advanced search endpoint | `fields` | string | No | Comma-separated fields to include | | `order_by` | string | No | Sort field | -##### `create_work_item` +#### `create_work_item` Creates a new work item in a project. @@ -825,7 +774,7 @@ Creates a new work item in a project. | `start_date` | string | No | `YYYY-MM-DD` | | `due_date` | string | No | `YYYY-MM-DD` | -##### `retrieve_work_item` +#### `retrieve_work_item` Returns a single work item by UUID. @@ -834,7 +783,7 @@ Returns a single work item by UUID. | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `retrieve_work_item_by_identifier` +#### `retrieve_work_item_by_identifier` Returns a work item using its human-readable identifier (e.g., `ENG-42`). @@ -843,7 +792,7 @@ Returns a work item using its human-readable identifier (e.g., `ENG-42`). | `project_identifier` | string | **Yes** | Project prefix, e.g., `ENG` | | `work_item_identifier` | string | **Yes** | Issue number, e.g., `42` | -##### `update_work_item` +#### `update_work_item` Updates one or more fields on a work item. Only supplied fields are changed. @@ -853,7 +802,7 @@ Updates one or more fields on a work item. Only supplied fields are changed. | `work_item_id` | UUID string | **Yes** | | other fields | partial | No | -##### `delete_work_item` +#### `delete_work_item` Permanently deletes a work item. @@ -862,7 +811,7 @@ Permanently deletes a work item. | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `search_work_items` +#### `search_work_items` Searches work items by text query within a project. @@ -873,9 +822,9 @@ Searches work items by text query within a project. --- -#### Work Item Activities +### Work Item Activities -##### `list_work_item_activities` +#### `list_work_item_activities` Returns the activity log (history of changes) for a work item. @@ -884,7 +833,7 @@ Returns the activity log (history of changes) for a work item. | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `retrieve_work_item_activity` +#### `retrieve_work_item_activity` Returns a single activity entry. @@ -896,9 +845,9 @@ Returns a single activity entry. --- -#### Work Item Comments +### Work Item Comments -##### `list_work_item_comments` +#### `list_work_item_comments` Returns all comments on a work item. @@ -907,7 +856,7 @@ Returns all comments on a work item. | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `retrieve_work_item_comment` +#### `retrieve_work_item_comment` Returns a single comment. @@ -917,7 +866,7 @@ Returns a single comment. | `work_item_id` | UUID string | **Yes** | | `comment_id` | UUID string | **Yes** | -##### `create_work_item_comment` +#### `create_work_item_comment` Adds a comment to a work item. Comments are stored as HTML. @@ -927,7 +876,7 @@ Adds a comment to a work item. Comments are stored as HTML. | `work_item_id` | UUID string | **Yes** | | | `comment_html` | string | **Yes** | HTML content, e.g., `

Fixed in commit abc123

` | -##### `update_work_item_comment` +#### `update_work_item_comment` Updates a comment's content. @@ -938,7 +887,7 @@ Updates a comment's content. | `comment_id` | UUID string | **Yes** | | `comment_html` | string | **Yes** | -##### `delete_work_item_comment` +#### `delete_work_item_comment` Deletes a comment. @@ -950,18 +899,18 @@ Deletes a comment. --- -#### Work Item Links +### Work Item Links External URLs attached to a work item (e.g., Figma designs, PRs, docs). -##### `list_work_item_links` +#### `list_work_item_links` | Parameter | Type | Required | | -------------- | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `retrieve_work_item_link` +#### `retrieve_work_item_link` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -969,7 +918,7 @@ External URLs attached to a work item (e.g., Figma designs, PRs, docs). | `work_item_id` | UUID string | **Yes** | | `link_id` | UUID string | **Yes** | -##### `create_work_item_link` +#### `create_work_item_link` | Parameter | Type | Required | Description | | -------------- | ----------- | -------- | -------------------------- | @@ -978,7 +927,7 @@ External URLs attached to a work item (e.g., Figma designs, PRs, docs). | `url` | string | **Yes** | External URL | | `title` | string | No | Display title for the link | -##### `update_work_item_link` +#### `update_work_item_link` | Parameter | Type | Required | | --------------- | ----------- | -------- | @@ -987,7 +936,7 @@ External URLs attached to a work item (e.g., Figma designs, PRs, docs). | `link_id` | UUID string | **Yes** | | `url` / `title` | string | No | -##### `delete_work_item_link` +#### `delete_work_item_link` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -997,18 +946,18 @@ External URLs attached to a work item (e.g., Figma designs, PRs, docs). --- -#### Work Item Relations +### Work Item Relations Relations between work items (e.g., "blocks", "is blocked by", "duplicate of"). -##### `list_work_item_relations` +#### `list_work_item_relations` | Parameter | Type | Required | | -------------- | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `create_work_item_relation` +#### `create_work_item_relation` | Parameter | Type | Required | Description | | ---------------------- | ----------- | -------- | ----------------------------------------------------------------------- | @@ -1017,7 +966,7 @@ Relations between work items (e.g., "blocks", "is blocked by", "duplicate of"). | `related_work_item_id` | UUID string | **Yes** | Target work item | | `relation_type` | string | **Yes** | `blocking` · `blocked_by` · `duplicate_of` · `duplicate` · `relates_to` | -##### `remove_work_item_relation` +#### `remove_work_item_relation` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -1027,17 +976,17 @@ Relations between work items (e.g., "blocks", "is blocked by", "duplicate of"). --- -#### Work Item Properties +### Work Item Properties Custom fields defined per project. -##### `list_work_item_properties` +#### `list_work_item_properties` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `create_work_item_property` +#### `create_work_item_property` | Parameter | Type | Required | Description | | --------------- | ----------- | -------- | ------------------------ | @@ -1045,21 +994,21 @@ Custom fields defined per project. | `name` | string | **Yes** | Property name | | `property_type` | string | **Yes** | Type of the custom field | -##### `retrieve_work_item_property` +#### `retrieve_work_item_property` | Parameter | Type | Required | | ------------- | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `property_id` | UUID string | **Yes** | -##### `update_work_item_property` +#### `update_work_item_property` | Parameter | Type | Required | | ------------- | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `property_id` | UUID string | **Yes** | -##### `delete_work_item_property` +#### `delete_work_item_property` | Parameter | Type | Required | | ------------- | ----------- | -------- | @@ -1068,17 +1017,17 @@ Custom fields defined per project. --- -#### Work Item Types +### Work Item Types Custom work item type definitions (e.g., Bug, Feature, Task, Epic). -##### `list_work_item_types` +#### `list_work_item_types` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `create_work_item_type` +#### `create_work_item_type` | Parameter | Type | Required | | ------------- | ----------- | -------- | @@ -1087,21 +1036,21 @@ Custom work item type definitions (e.g., Bug, Feature, Task, Epic). | `description` | string | No | | `is_active` | boolean | No | -##### `retrieve_work_item_type` +#### `retrieve_work_item_type` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `type_id` | UUID string | **Yes** | -##### `update_work_item_type` +#### `update_work_item_type` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `type_id` | UUID string | **Yes** | -##### `delete_work_item_type` +#### `delete_work_item_type` | Parameter | Type | Required | | ------------ | ----------- | -------- | @@ -1110,18 +1059,18 @@ Custom work item type definitions (e.g., Bug, Feature, Task, Epic). --- -#### Worklogs +### Worklogs Time tracking for work items. All durations are in **minutes**. -##### `list_work_logs` +#### `list_work_logs` | Parameter | Type | Required | | -------------- | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `create_work_log` +#### `create_work_log` | Parameter | Type | Required | Description | | -------------- | ----------- | -------- | -------------------- | @@ -1130,7 +1079,7 @@ Time tracking for work items. All durations are in **minutes**. | `duration` | integer | **Yes** | Minutes logged (≥ 0) | | `description` | string | No | What was done | -##### `update_work_log` +#### `update_work_log` | Parameter | Type | Required | | -------------------------- | ----------- | -------- | @@ -1139,7 +1088,7 @@ Time tracking for work items. All durations are in **minutes**. | `work_log_id` | UUID string | **Yes** | | `duration` / `description` | - | No | -##### `delete_work_log` +#### `delete_work_log` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -1149,11 +1098,11 @@ Time tracking for work items. All durations are in **minutes**. --- -#### States +### States Workflow states for a project's work items. -##### `list_states` / `create_state` / `retrieve_state` / `update_state` / `delete_state` +#### `list_states` / `create_state` / `retrieve_state` / `update_state` / `delete_state` All state tools accept `project_id`. Create and update accept: @@ -1166,11 +1115,11 @@ All state tools accept `project_id`. Create and update accept: --- -#### Labels +### Labels Tags for work items. -##### `list_labels` / `create_label` / `retrieve_label` / `update_label` / `delete_label` +#### `list_labels` / `create_label` / `retrieve_label` / `update_label` / `delete_label` All label tools accept `project_id`. Create and update accept: @@ -1182,11 +1131,11 @@ All label tools accept `project_id`. Create and update accept: --- -#### Cycles +### Cycles Time-boxed iterations (sprints). -##### `list_cycles` +#### `list_cycles` Returns all cycles in a project including upcoming, active, and completed. @@ -1194,7 +1143,7 @@ Returns all cycles in a project including upcoming, active, and completed. | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `list_archived_cycles` +#### `list_archived_cycles` Returns archived cycles only. @@ -1202,7 +1151,7 @@ Returns archived cycles only. | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `create_cycle` +#### `create_cycle` | Parameter | Type | Required | Description | | ------------- | ----------- | -------- | ------------ | @@ -1212,18 +1161,18 @@ Returns archived cycles only. | `end_date` | string | No | `YYYY-MM-DD` | | `description` | string | No | | -##### `retrieve_cycle` +#### `retrieve_cycle` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `cycle_id` | UUID string | **Yes** | -##### `update_cycle` / `delete_cycle` +#### `update_cycle` / `delete_cycle` Accept `project_id` and `cycle_id`. -##### `add_work_items_to_cycle` +#### `add_work_items_to_cycle` | Parameter | Type | Required | | --------------- | ----------- | -------- | @@ -1231,7 +1180,7 @@ Accept `project_id` and `cycle_id`. | `cycle_id` | UUID string | **Yes** | | `work_item_ids` | UUID[] | **Yes** | -##### `remove_work_item_from_cycle` +#### `remove_work_item_from_cycle` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -1239,14 +1188,14 @@ Accept `project_id` and `cycle_id`. | `cycle_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `list_cycle_work_items` +#### `list_cycle_work_items` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `cycle_id` | UUID string | **Yes** | -##### `transfer_cycle_work_items` +#### `transfer_cycle_work_items` Moves all incomplete work items from one cycle to another. @@ -1258,17 +1207,17 @@ Moves all incomplete work items from one cycle to another. --- -#### Modules +### Modules Feature groupings within a project. -##### `list_modules` / `list_archived_modules` +#### `list_modules` / `list_archived_modules` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `create_module` +#### `create_module` | Parameter | Type | Required | | ------------- | ----------- | -------- | @@ -1280,11 +1229,11 @@ Feature groupings within a project. | `lead` | UUID string | No | | `members` | UUID[] | No | -##### `retrieve_module` / `update_module` / `delete_module` / `archive_module` +#### `retrieve_module` / `update_module` / `delete_module` / `archive_module` Accept `project_id` and `module_id`. -##### `add_work_items_to_module` +#### `add_work_items_to_module` | Parameter | Type | Required | | --------------- | ----------- | -------- | @@ -1292,7 +1241,7 @@ Accept `project_id` and `module_id`. | `module_id` | UUID string | **Yes** | | `work_item_ids` | UUID[] | **Yes** | -##### `remove_work_item_from_module` +#### `remove_work_item_from_module` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -1300,7 +1249,7 @@ Accept `project_id` and `module_id`. | `module_id` | UUID string | **Yes** | | `work_item_id` | UUID string | **Yes** | -##### `list_module_work_items` +#### `list_module_work_items` | Parameter | Type | Required | | ------------ | ----------- | -------- | @@ -1309,11 +1258,11 @@ Accept `project_id` and `module_id`. --- -#### Epics +### Epics Large work items that group related items. The server resolves the Epic work item type automatically. -##### `list_epics` / `create_epic` / `retrieve_epic` / `update_epic` / `delete_epic` +#### `list_epics` / `create_epic` / `retrieve_epic` / `update_epic` / `delete_epic` | Parameter | Type | Required | | ----------------------- | ----------- | ------------------- | @@ -1323,11 +1272,11 @@ Large work items that group related items. The server resolves the Epic work ite --- -#### Milestones +### Milestones Point-in-time goals within a project. -##### `list_milestones` / `create_milestone` / `retrieve_milestone` / `update_milestone` / `delete_milestone` +#### `list_milestones` / `create_milestone` / `retrieve_milestone` / `update_milestone` / `delete_milestone` | Parameter | Type | Required | | -------------- | ----------- | ---------------- | @@ -1335,7 +1284,7 @@ Point-in-time goals within a project. | `milestone_id` | UUID string | Varies | | `name` | string | **Yes** (create) | -##### `add_work_items_to_milestone` +#### `add_work_items_to_milestone` | Parameter | Type | Required | | --------------- | ----------- | -------- | @@ -1343,7 +1292,7 @@ Point-in-time goals within a project. | `milestone_id` | UUID string | **Yes** | | `work_item_ids` | UUID[] | **Yes** | -##### `remove_work_items_from_milestone` +#### `remove_work_items_from_milestone` | Parameter | Type | Required | | --------------- | ----------- | -------- | @@ -1351,7 +1300,7 @@ Point-in-time goals within a project. | `milestone_id` | UUID string | **Yes** | | `work_item_ids` | UUID[] | **Yes** | -##### `list_milestone_work_items` +#### `list_milestone_work_items` | Parameter | Type | Required | | -------------- | ----------- | -------- | @@ -1360,27 +1309,27 @@ Point-in-time goals within a project. --- -#### Initiatives +### Initiatives Workspace-scoped strategic goals that span multiple projects. -##### `list_initiatives` / `create_initiative` / `retrieve_initiative` / `update_initiative` / `delete_initiative` +#### `list_initiatives` / `create_initiative` / `retrieve_initiative` / `update_initiative` / `delete_initiative` Initiatives are workspace-scoped - no `project_id` required. `retrieve_initiative`, `update_initiative`, and `delete_initiative` accept an `initiative_id` UUID. --- -#### Intake +### Intake Triage queue for incoming work items before they enter a project. -##### `list_intake_work_items` +#### `list_intake_work_items` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | -##### `create_intake_work_item` +#### `create_intake_work_item` | Parameter | Type | Required | | ------------------ | ----------- | -------- | @@ -1388,37 +1337,37 @@ Triage queue for incoming work items before they enter a project. | `name` | string | **Yes** | | `description_html` | string | No | -##### `retrieve_intake_work_item` / `update_intake_work_item` / `delete_intake_work_item` +#### `retrieve_intake_work_item` / `update_intake_work_item` / `delete_intake_work_item` Accept `project_id` and `work_item_id`. --- -#### Pages +### Pages Wiki-style documents. Pages can be workspace-scoped or project-scoped. -##### `retrieve_workspace_page` +#### `retrieve_workspace_page` | Parameter | Type | Required | | --------- | ----------- | -------- | | `page_id` | UUID string | **Yes** | -##### `retrieve_project_page` +#### `retrieve_project_page` | Parameter | Type | Required | | ------------ | ----------- | -------- | | `project_id` | UUID string | **Yes** | | `page_id` | UUID string | **Yes** | -##### `create_workspace_page` +#### `create_workspace_page` | Parameter | Type | Required | | ------------------ | ------ | -------- | | `name` | string | **Yes** | | `description_html` | string | No | -##### `create_project_page` +#### `create_project_page` | Parameter | Type | Required | | ------------------ | ----------- | -------- | From 39bfb3cac6ec18ecdfd802defb8bb90f77e97cfe Mon Sep 17 00:00:00 2001 From: danciaclara Date: Mon, 18 May 2026 22:41:32 +0530 Subject: [PATCH 4/4] minor updates --- docs/dev-tools/mcp-server.md | 60 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/dev-tools/mcp-server.md b/docs/dev-tools/mcp-server.md index 297fcc94..7b18d427 100644 --- a/docs/dev-tools/mcp-server.md +++ b/docs/dev-tools/mcp-server.md @@ -35,9 +35,7 @@ For cloud deployments, the server acts as an **OAuth proxy** to Plane's OAuth sy 4. Subsequent MCP requests carry this token, from which the server extracts the workspace slug The server supports OAuth redirect URIs for all major MCP clients: - -- `http://localhost:*` (dynamic ports from desktop clients) -- `cursor://`, `vscode://`, `vscode-insiders://`, `windsurf://`, `claude://` +`cursor://`, `vscode://`, `vscode-insiders://`, `windsurf://`, `claude://` ### Header auth (HTTP with PAT Token) @@ -72,6 +70,8 @@ Plane uses two kinds of identifiers for work items. ## How-to guides +Plane hosts the MCP server for you at **`https://mcp.plane.so`**. If you run your own instance of the MCP server, replace `https://mcp.plane.so` with your own server's public URL (e.g., `https://mcp.yourcompany.com`) in all client config examples below. + ### Prerequisites **For all modes:** @@ -136,7 +136,7 @@ Connects to a remote MCP server. Claude Desktop opens a browser window for the P { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/mcp", + "url": "https://mcp.plane.so/http/mcp", "type": "http" } } @@ -151,7 +151,7 @@ Connects to the PAT endpoint using API key headers. No browser interaction requi { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/api-key/mcp", + "url": "https://mcp.plane.so/http/api-key/mcp", "type": "http", "headers": { "x-api-key": "your_api_key_here", @@ -170,7 +170,7 @@ For existing integrations already using the SSE transport. { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/sse", + "url": "https://mcp.plane.so/sse", "type": "sse" } } @@ -215,7 +215,7 @@ Settings file (`.claude/settings.json` for project scope, `~/.claude/settings.js ```bash claude mcp add plane \ --transport http \ - --url https://your-mcp-server.com/http/mcp + --url https://mcp.plane.so/http/mcp ``` Claude Code will open a browser for the Plane OAuth flow. Settings file equivalent: @@ -224,7 +224,7 @@ Claude Code will open a browser for the Plane OAuth flow. Settings file equivale { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/mcp", + "url": "https://mcp.plane.so/http/mcp", "type": "http" } } @@ -236,7 +236,7 @@ Claude Code will open a browser for the Plane OAuth flow. Settings file equivale ```bash claude mcp add plane \ --transport http \ - --url https://your-mcp-server.com/http/api-key/mcp \ + --url https://mcp.plane.so/http/api-key/mcp \ --header "x-api-key: your_api_key_here" \ --header "x-workspace-slug: your-workspace-slug" ``` @@ -247,7 +247,7 @@ Settings file equivalent: { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/api-key/mcp", + "url": "https://mcp.plane.so/http/api-key/mcp", "type": "http", "headers": { "x-api-key": "your_api_key_here", @@ -263,7 +263,7 @@ Settings file equivalent: ```bash claude mcp add plane \ --transport sse \ - --url https://your-mcp-server.com/sse + --url https://mcp.plane.so/sse ``` Settings file equivalent: @@ -272,7 +272,7 @@ Settings file equivalent: { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/sse", + "url": "https://mcp.plane.so/sse", "type": "sse" } } @@ -305,21 +305,21 @@ Claude.ai supports remote MCP servers for eligible plans. Because it runs in a b #### HTTP with OAuth -1. Go to **Settings → Integrations** in Claude.ai. -2. Click **Add Integration**. -3. Enter the server URL: `https://your-mcp-server.com/http/mcp` +1. Go to **Customize → Connectors ** in Claude.ai. +2. Click **Add custom connector**. +3. Enter the server URL: `https://mcp.plane.so/http/mcp` 4. Claude.ai redirects you through the Plane OAuth flow. #### HTTP with PAT Token If your Claude.ai plan supports custom headers in integrations: -- URL: `https://your-mcp-server.com/http/api-key/mcp` +- URL: `https://mcp.plane.so/http/api-key/mcp` - Headers: `x-api-key: your_api_key_here`, `x-workspace-slug: your-workspace-slug` #### SSE (Legacy) -- URL: `https://your-mcp-server.com/sse` +- URL: `https://mcp.plane.so/sse` --- @@ -355,7 +355,7 @@ The `cursor://` redirect URI is registered natively in the OAuth provider. { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/mcp", + "url": "https://mcp.plane.so/http/mcp", "type": "http" } } @@ -368,7 +368,7 @@ The `cursor://` redirect URI is registered natively in the OAuth provider. { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/api-key/mcp", + "url": "https://mcp.plane.so/http/api-key/mcp", "type": "http", "headers": { "x-api-key": "your_api_key_here", @@ -385,7 +385,7 @@ The `cursor://` redirect URI is registered natively in the OAuth provider. { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/sse", + "url": "https://mcp.plane.so/sse", "type": "sse" } } @@ -424,7 +424,7 @@ Config can be set at workspace level (`.vscode/mcp.json`) or user level (VS Code { "servers": { "plane": { - "url": "https://your-mcp-server.com/http/mcp", + "url": "https://mcp.plane.so/http/mcp", "type": "http" } } @@ -437,7 +437,7 @@ Config can be set at workspace level (`.vscode/mcp.json`) or user level (VS Code { "servers": { "plane": { - "url": "https://your-mcp-server.com/http/api-key/mcp", + "url": "https://mcp.plane.so/http/api-key/mcp", "type": "http", "headers": { "x-api-key": "your_api_key_here", @@ -454,7 +454,7 @@ Config can be set at workspace level (`.vscode/mcp.json`) or user level (VS Code { "servers": { "plane": { - "url": "https://your-mcp-server.com/sse", + "url": "https://mcp.plane.so/sse", "type": "sse" } } @@ -493,7 +493,7 @@ Restart Windsurf after saving, then open the Cascade panel. The `windsurf://` re { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/mcp", + "url": "https://mcp.plane.so/http/mcp", "type": "http" } } @@ -506,7 +506,7 @@ Restart Windsurf after saving, then open the Cascade panel. The `windsurf://` re { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/http/api-key/mcp", + "url": "https://mcp.plane.so/http/api-key/mcp", "type": "http", "headers": { "x-api-key": "your_api_key_here", @@ -523,7 +523,7 @@ Restart Windsurf after saving, then open the Cascade panel. The `windsurf://` re { "mcpServers": { "plane": { - "url": "https://your-mcp-server.com/sse", + "url": "https://mcp.plane.so/sse", "type": "sse" } } @@ -563,7 +563,7 @@ Config file: `~/.config/zed/settings.json` under `"context_servers"`. Zed uses a { "context_servers": { "plane-mcp-server": { - "url": "https://your-mcp-server.com/http/mcp", + "url": "https://mcp.plane.so/http/mcp", "settings": {} } } @@ -576,7 +576,7 @@ Config file: `~/.config/zed/settings.json` under `"context_servers"`. Zed uses a { "context_servers": { "plane-mcp-server": { - "url": "https://your-mcp-server.com/http/api-key/mcp", + "url": "https://mcp.plane.so/http/api-key/mcp", "headers": { "x-api-key": "your_api_key_here", "x-workspace-slug": "your-workspace-slug" @@ -593,7 +593,7 @@ Config file: `~/.config/zed/settings.json` under `"context_servers"`. Zed uses a { "context_servers": { "plane-mcp-server": { - "url": "https://your-mcp-server.com/sse", + "url": "https://mcp.plane.so/sse", "settings": {} } } @@ -1377,7 +1377,7 @@ Wiki-style documents. Pages can be workspace-scoped or project-scoped. --- -## Common Workflows +## Common workflows ### Look up a work item by ID