Metadata-Version: 2.4
Name: plane-mcp-server-pro
Version: 0.2.9
Summary: An unofficial Pro-enhanced Model Context Protocol server for Plane integration
Author: RenderCoder
License-Expression: MIT
Keywords: mcp,plane,fastmcp,ai,automation,pro
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp==3.2.0
Requires-Dist: plane-sdk==0.2.13
Requires-Dist: py-key-value-aio[redis]<0.5.0,>=0.4.4
Requires-Dist: mcp==1.26.0
Requires-Dist: PyJWT>=2.12.0
Requires-Dist: authlib>=1.6.9
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: ruff>=0.1.0; extra == "dev"
Dynamic: license-file

# Plane MCP Server Pro

[中文文档](./README.zh-CN.md)

An unofficial Pro-enhanced Model Context Protocol (MCP) server for Plane integration. This server provides tools and resources for interacting with Plane through AI agents.

This repository keeps the default MCP tool surface compatible with the official Plane MCP server. It also contains an optional enhanced patch for faster read-only task lookup through a separate Pro backend. The enhanced tools are disabled by default and are registered only when `PLANE_ENABLE_PRO_TASK_API=true`.

## Features

* 🔧 **Plane Integration**: Interact with Plane APIs and services
* 🔌 **Multiple Transports**: Supports stdio, SSE, and streamable HTTP transports
* 🌐 **Remote & Local**: Works both locally and as a remote service
* 🛠️ **Extensible**: Easy to add new tools and resources
* ⚙️ **Optional Enhanced Task API**: Can expose extra read-only `plane_task_*` tools when a Pro backend is deployed and explicitly enabled

## Usage

The server supports three transport methods. **We recommend using `uvx`** as it doesn't require installation.

**Requirements**:
- **Python 3.10+** (for stdio transport, via `uvx`)
- **Node.js 22+** (for remote transports, via `npx`)

### 1. Stdio Transport (for local use)

**MCP Client Configuration** (using uvx - recommended):

```json
{
  "mcpServers": {
    "plane-pro": {
      "command": "uvx",
      "args": ["plane-mcp-server-pro", "stdio"],
      "env": {
        "PLANE_API_KEY": "<your-api-key>",
        "PLANE_WORKSPACE_SLUG": "<your-workspace-slug>",
        "PLANE_BASE_URL": "https://api.plane.so"
      }
    }
  }
}
```

### 2. Remote HTTP Transport with OAuth

Connect to the hosted Plane MCP server using OAuth authentication.

**URL**: `https://mcp.plane.so/http/mcp`

**MCP Client Configuration** (for tools like Claude Desktop without native remote MCP support):

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

**Note**: OAuth authentication will be handled automatically when connecting to the remote server.

### 3. Remote HTTP Transport using PAT Token

Connect to the hosted Plane MCP server using a Personal Access Token (PAT).

**URL**: `https://mcp.plane.so/http/api-key/mcp`

**Headers**:
- `Authorization: Bearer <PAT_TOKEN>`
- `X-Workspace-slug: <SLUG>`

**MCP Client Configuration** (for tools like Claude Desktop without native remote MCP support):

```json
{
  "mcpServers": {
    "plane": {
      "command": "npx",
      "args": ["mcp-remote@latest", "https://mcp.plane.so/http/api-key/mcp"],
      "headers": {
        "Authorization": "Bearer <PAT_TOKEN>",
        "X-Workspace-slug": "<SLUG>"
      }
    }
  }
}
```

### 4. SSE Transport (Legacy)

⚠️ **Legacy Transport**: SSE (Server-Sent Events) transport is maintained for backward compatibility. New implementations should use the HTTP transport (sections 2 or 3) instead.

Connect to the hosted Plane MCP server using OAuth authentication via Server-Sent Events.

**URL**: `https://mcp.plane.so/sse`

**MCP Client Configuration** (for tools that support SSE transport):

```json
{
  "mcpServers": {
    "plane": {
      "command": "npx",
      "args": ["mcp-remote@latest", "https://mcp.plane.so/sse"]
    }
  }
}
```

**Note**: OAuth authentication will be handled automatically when connecting to the remote server. This transport is deprecated in favor of the HTTP transport.


## Configuration

### Backends and Authentication

This MCP server can talk to two Plane-related backends:

1. The standard Plane API for the existing SDK-backed tools such as projects, work items, cycles, modules, comments, and writes.
2. The optional Pro Task API for the read-only `plane_task_*` tools. This backend is an enhanced patch optimized for AI task lookup and digest queries.

By default, only the standard Plane API tools are registered, matching the official Plane MCP behavior. The Pro Task API tools are added only when `PLANE_ENABLE_PRO_TASK_API=true`.

The standard Plane API uses these settings:

- `PLANE_BASE_URL`: Base URL for Plane API (default: `https://api.plane.so`) - Optional
- `PLANE_API_KEY`: API key for authentication (required for stdio transport)
- `PLANE_WORKSPACE_SLUG`: Workspace slug identifier (required for stdio transport)
- `PLANE_ACCESS_TOKEN`: Access token for authentication (alternative to API key)

The Pro Task API uses these separate settings:

- `PLANE_ENABLE_PRO_TASK_API`: Set to `true` to register the enhanced read-only `plane_task_*` tools. Defaults to disabled.
- `PLANE_PRO_BASE_URL`: Pro service URL for the read-only Plane Task API tools.
- `PLANE_PRO_PERSONAL_TOKEN`: Plane personal token sent to Pro Task API as `X-Api-Key`.

**Default example** (official-compatible stdio transport):
```bash
export PLANE_BASE_URL="https://api.plane.so"
export PLANE_API_KEY="your-api-key"
export PLANE_WORKSPACE_SLUG="your-workspace-slug"
```

**Enhanced Task API example** (requires a deployed Pro backend):
```bash
export PLANE_ENABLE_PRO_TASK_API=true
export PLANE_PRO_BASE_URL="https://your-pro-host.example"
export PLANE_PRO_PERSONAL_TOKEN="your-plane-personal-token"
```

**Note**: For remote HTTP transports (OAuth or PAT), core Plane API authentication is handled via the connection method (OAuth flow or PAT headers). The enhanced Task API tools still require server-side `PLANE_ENABLE_PRO_TASK_API=true`, `PLANE_PRO_BASE_URL`, and `PLANE_PRO_PERSONAL_TOKEN` because they call the separate Pro backend.

If you only need the official-compatible Plane SDK-backed tools, configure the standard Plane API variables. If you want the faster read-only task search, person digest, or issue detail tools, deploy the Pro backend and enable the enhanced variables as well.

## Available Tools

The server provides comprehensive tools for interacting with Plane. The core Plane tools use Pydantic models from the Plane SDK for type safety and validation. By default, only these official-compatible tools are registered. When `PLANE_ENABLE_PRO_TASK_API=true`, the server also registers enhanced read-only Task API tools backed by Pro.

### Projects

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

### Work Items

| Tool Name | Description |
|-----------|-------------|
| `list_work_items` | List all work items in a project with optional filtering and pagination |
| `create_work_item` | Create a new work item with name, assignees, labels, and other attributes |
| `retrieve_work_item` | Retrieve a work item by ID with optional field expansion |
| `retrieve_work_item_by_identifier` | Retrieve a work item by project identifier and issue sequence number |
| `update_work_item` | Update a work item with partial data |
| `delete_work_item` | Delete a work item by ID |
| `search_work_items` | Search work items across a workspace with query string |

### Cycles

| Tool Name | Description |
|-----------|-------------|
| `list_cycles` | List all cycles in a project |
| `create_cycle` | Create a new cycle with name, dates, and owner |
| `retrieve_cycle` | Retrieve a cycle by ID |
| `update_cycle` | Update a cycle with partial data |
| `delete_cycle` | Delete a cycle by ID |
| `list_archived_cycles` | List archived cycles in a project |
| `add_work_items_to_cycle` | Add work items to a cycle |
| `remove_work_item_from_cycle` | Remove a work item from a cycle |
| `list_cycle_work_items` | List work items in a cycle |
| `transfer_cycle_work_items` | Transfer work items from one cycle to another |
| `archive_cycle` | Archive a cycle |
| `unarchive_cycle` | Unarchive a cycle |

### Modules

| Tool Name | Description |
|-----------|-------------|
| `list_modules` | List all modules in a project |
| `create_module` | Create a new module with name, dates, status, and members |
| `retrieve_module` | Retrieve a module by ID |
| `update_module` | Update a module with partial data |
| `delete_module` | Delete a module by ID |
| `list_archived_modules` | List archived modules in a project |
| `add_work_items_to_module` | Add work items to a module |
| `remove_work_item_from_module` | Remove a work item from a module |
| `list_module_work_items` | List work items in a module |
| `archive_module` | Archive a module |
| `unarchive_module` | Unarchive a module |

### Initiatives

| Tool Name | Description |
|-----------|-------------|
| `list_initiatives` | List all initiatives in a workspace |
| `create_initiative` | Create a new initiative with name, dates, state, and lead |
| `retrieve_initiative` | Retrieve an initiative by ID |
| `update_initiative` | Update an initiative with partial data |
| `delete_initiative` | Delete an initiative by ID |

### Intake Work Items

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

### Work Item Properties

| Tool Name | Description |
|-----------|-------------|
| `list_work_item_properties` | List work item properties for a work item type |
| `create_work_item_property` | Create a new work item property with type, settings, and validation rules |
| `retrieve_work_item_property` | Retrieve a work item property by ID |
| `update_work_item_property` | Update a work item property with partial data |
| `delete_work_item_property` | Delete a work item property by ID |

### Epics

| Tool Name | Description |
|-----------|-------------|
| `list_epics` | List all epics in a project |
| `create_epic` | Create a new epic |
| `retrieve_epic` | Retrieve an epic by ID |
| `update_epic` | Update an epic by ID |
| `delete_epic` | Delete an epic by ID |

### Milestones

| Tool Name | Description |
|-----------|-------------|
| `list_milestones` | List all milestones in a project |
| `create_milestone` | Create a new milestone |
| `retrieve_milestone` | Retrieve a milestone by ID |
| `update_milestone` | Update a milestone by ID |
| `delete_milestone` | Delete a milestone by ID |
| `add_work_items_to_milestone` | Add work items to a milestone |
| `remove_work_items_from_milestone` | Remove work items from a milestone |
| `list_milestone_work_items` | List work items in a milestone |

### Labels

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

### States

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

### Work Item Comments

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

### Work Item Links

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

### Work Item Types

| Tool Name | Description |
|-----------|-------------|
| `list_work_item_types` | List all work item types in a project |
| `create_work_item_type` | Create a new work item type |
| `retrieve_work_item_type` | Retrieve a work item type by ID |
| `update_work_item_type` | Update a work item type by ID |
| `delete_work_item_type` | Delete a work item type by ID |

### Work Item Relations

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

### Work Item Activities

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

### Work Logs

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

### Pages

| Tool Name | Description |
|-----------|-------------|
| `retrieve_workspace_page` | Retrieve a workspace page by ID |
| `retrieve_project_page` | Retrieve a project page by ID |
| `create_workspace_page` | Create a workspace page |
| `create_project_page` | Create a project page |

### Workspaces

| Tool Name | Description |
|-----------|-------------|
| `get_workspace_members` | Get all members of the current workspace |
| `get_workspace_features` | Get features of the current workspace |
| `update_workspace_features` | Update features of the current workspace |

### Users

| Tool Name | Description |
|-----------|-------------|
| `get_me` | Get current authenticated user information |

### Task API

These enhanced read-only tools are not part of the default official-compatible tool surface. They are registered only when `PLANE_ENABLE_PRO_TASK_API=true`.

They call Pro `/task-api/*` endpoints using `PLANE_PRO_BASE_URL` and send `PLANE_PRO_PERSONAL_TOKEN` as `X-Api-Key`.
They do not create, update, or delete Plane data.

| Tool Name | Description |
|-----------|-------------|
| `plane_task_context` | Get current token user, readable projects, optional member aliases, and coverage |
| `plane_person_digest` | Get attention, recently updated, and recently completed tasks for a person |
| `plane_task_search` | Search readable tasks by key, project identifier, title, description, and optional comments |
| `plane_task_detail` | Get one readable issue by key with optional latest or all comments |

Suggested use:

- Start with `plane_task_context` when the assistant needs readable project coverage or member aliases.
- Use `plane_person_digest` for "my tasks" or "what is this person working on" questions.
- Use `plane_task_search` for natural-language task lookup, Chinese keywords, project identifiers, or issue keys.
- Use `plane_task_detail` before summarizing a specific issue, description, status, assignees, or recent comments.

**Total Tools**: 100+ tools across 20 categories by default; 21 categories when the enhanced Pro Task API is enabled.

## Development

### Running Tests

```bash
uv sync --extra dev
uv run pytest
```

### Code Formatting

```bash
uv run ruff format .
uv run ruff check .
```

## License

MIT License - see LICENSE for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Deprecation Notice

⚠️ **The Node.js-based `plane-mcp-server` is deprecated and no longer maintained.**

This repository represents the new Python+FastMCP based implementation of the Plane MCP server. If you were using the previous Node.js version, please migrate to this Python-based version for continued support and updates.

The new implementation offers:
- Better type safety with Pydantic models
- Improved performance with FastMCP
- Enhanced tool coverage
- Active maintenance and development

For migration assistance, please refer to the configuration examples in this README or open an issue for support.

**Old Node.js Configuration (Deprecated):**

If you were using the previous Node.js-based `@makeplane/plane-mcp-server`, your configuration looked like this:

```json
{
  "mcpServers": {
    "plane": {
      "command": "npx",
      "args": [
        "-y",
        "@makeplane/plane-mcp-server"
      ],
      "env": {
        "PLANE_API_KEY": "<YOUR_API_KEY>",
        "PLANE_API_HOST_URL": "<HOST_URL_FOR_SELF_HOSTED>",
        "PLANE_WORKSPACE_SLUG": "<YOUR_WORKSPACE_SLUG>"
      }
    }
  }
}
```

**Please migrate to the new Python-based configuration shown in the Usage section above.**
