plane-ce-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@plane-ce-mcp list all tasks in the current cycle"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
plane-ce-mcp
Unofficial MCP server for self-hosted Plane (Community Edition).
A Model Context Protocol server exposing Plane's project management API as MCP tools, built for people who run Plane themselves. Based on makeplane/plane-mcp-server (MIT). Not affiliated with Plane / makeplane.
Why this exists
The upstream server targets Plane Cloud. Run it against a self-hosted Community Edition instance and you hit missing "lite" endpoints, raw SDK stack traces on every 404, and no pages support. This project fixes what upstream didn't:
Central compatibility layer (plane_mcp/compat.py): every Plane API error becomes an actionable message - missing endpoint vs missing resource vs auth vs timeout. No raw SDK exceptions reach the MCP client.
Transparent endpoint fallbacks: lite endpoints absent on CE fall back to the full endpoints (projects, cycles, modules, project/workspace members), with the fallback logged for diagnosability.
PAT-only HTTP mode: the HTTP transport runs without any OAuth configuration - header auth alone (
/http/api-key/mcp).Pages tools on CE: list/retrieve/search/create pages via Plane's internal API (CE has no public pages API), with content truncation for LLM-sized outputs.
Documented CE vs Cloud differences: docs/plane-api-compat.md.
May still work against Plane Cloud - untested, unmaintained, not a goal.
Related MCP server: plane-mcp-server
Quick start
Requirements: Python 3.10+ and uv. No clone, no
install - uvx runs the server straight from GitHub.
1. Get your credentials from Plane:
API key: Plane → Workspace Settings → API tokens → create token
Workspace slug: the part of your Plane URL after the host (
https://plane.your-domain.tld/<slug>/)
2. Smoke-test the server (optional, confirms connectivity):
PLANE_API_KEY=<your-api-key> \
PLANE_WORKSPACE_SLUG=<your-workspace-slug> \
PLANE_BASE_URL=https://plane.your-domain.tld \
uvx --from git+https://github.com/Bl4nk44/plane-ce-mcp plane-ce-mcp stdioServer starts and waits for MCP messages on stdin - Ctrl+C to exit. Errors at this point mean wrong URL or key, not a client problem.
3. Add to your MCP client (Claude Code, Claude Desktop, Cursor, ...):
{
"mcpServers": {
"plane": {
"command": "uvx",
"args": ["--from", "git+https://github.com/Bl4nk44/plane-ce-mcp", "plane-ce-mcp", "stdio"],
"env": {
"PLANE_API_KEY": "<your-api-key>",
"PLANE_WORKSPACE_SLUG": "<your-workspace-slug>",
"PLANE_BASE_URL": "https://plane.your-domain.tld"
}
}
}
}For Claude Code that's one command:
claude mcp add plane \
-e PLANE_API_KEY=<your-api-key> \
-e PLANE_WORKSPACE_SLUG=<your-workspace-slug> \
-e PLANE_BASE_URL=https://plane.your-domain.tld \
-- uvx --from git+https://github.com/Bl4nk44/plane-ce-mcp plane-ce-mcp stdioPLANE_BASE_URL must point at your instance's API - the default is Plane Cloud
(https://api.plane.so), so self-host setups must set it.
Run from source
git clone https://github.com/Bl4nk44/plane-ce-mcp.git
cd plane-ce-mcp
uv pip install -e .
PLANE_API_KEY=... PLANE_WORKSPACE_SLUG=... PLANE_BASE_URL=... python -m plane_mcp stdioHTTP transport (self-hosted, PAT auth)
Run the server next to your Plane instance (port 8211):
PLANE_BASE_URL=https://plane.your-domain.tld python -m plane_mcp httpConnect with a Personal Access Token - no OAuth setup required:
URL: http://<server>:8211/http/api-key/mcp
Headers:
Authorization: Bearer <PAT_TOKEN>(orx-api-key: <PAT_TOKEN>)X-Workspace-slug: <SLUG>
{
"mcpServers": {
"plane": {
"command": "npx",
"args": ["mcp-remote@latest", "http://<server>:8211/http/api-key/mcp"],
"headers": {
"Authorization": "Bearer <PAT_TOKEN>",
"X-Workspace-slug": "<SLUG>"
}
}
}
}An OAuth endpoint (/oauth/mcp) and a legacy SSE transport also exist for setups
with a configured Plane OAuth app - see Configuration. Deployment
recipes (Docker Compose, Caddy, Tailscale) live in deploy/ and
docs/tailscale-deployment.md.
Configuration
Variable | Required for | Purpose |
| all (self-host: required) | Your Plane API URL (default: |
| stdio | API key (workspace settings → API tokens) |
| stdio | Target workspace |
| http/sse (optional) | Internal URL for server-to-server calls (e.g. |
| pages tools | Plane account used by the internal-API adapter (CE has no public pages API); the account needs membership in the relevant projects |
| optional (default: | Comma-separated tool groups to register: |
| optional (default: | Size cap for |
| optional (default: | Retries after the first attempt for transient Plane API failures (429/503 for any call; 502/504/timeouts for read-only calls only, to avoid duplicate writes). |
| optional (default: | Base seconds for exponential backoff with jitter between retries (capped at 10s). |
| optional | Default truncation for |
| http/sse (optional) | Token storage (falls back to in-memory) |
| http/sse OAuth only | OAuth client credentials and base URL |
| http/sse OAuth (optional) | Comma-separated redirect URI patterns appended to the built-in allowlist |
| optional (default: | When |
| optional (default: | When |
Logging
The server emits structured JSON logs. Each tool call is logged with its tool name, duration, status, and (when available) the opaque user id and workspace slug. Endpoint fallbacks are logged when they trigger (which endpoint failed, which was used instead), so CE quirks are diagnosable from logs.
Health check
In HTTP mode the server exposes an unauthenticated GET /healthz returning
{"status": "ok", "server_version": ...}. It reports the server's own liveness
and does not call Plane, so a Plane outage never marks the MCP server unhealthy.
The Docker image ships a HEALTHCHECK against it.
Available Tools
All tools use Pydantic models from the Plane SDK for type safety and validation.
Projects
Tool Name | Description |
| List all projects in a workspace with optional pagination and filtering |
| Create a new project with name, identifier, and optional configuration |
| Retrieve a project by ID |
| Update a project with partial data |
| Delete a project by ID |
| Get work log summary for a project |
| Get all members of a project |
| Update features configuration of a project |
| Archive or unarchive a project |
Work Items
Tool Name | Description |
| List all work items in a project with optional filtering and pagination |
| Create a new work item with name, assignees, labels, and other attributes |
| Retrieve a work item by ID with optional field expansion |
| Retrieve a work item by project identifier and issue sequence number |
| Update a work item with partial data |
| Delete a work item by ID |
| Search work items across a workspace with query string |
| Count work items across the workspace with optional grouping |
| List archived work items in a project with optional PQL filtering |
| Archive or unarchive a work item |
| Add or remove a single assignee without replacing the full list |
| Add or remove a single label without replacing the full list |
Cycles
Tool Name | Description |
| List cycles in a project (set |
| Create a new cycle with name, dates, and owner |
| Retrieve a cycle by ID |
| Update a cycle with partial data |
| Delete a cycle by ID |
| Add and/or remove work items on a cycle |
| List work items in a cycle |
| Transfer work items from one cycle to another |
| Archive or unarchive a cycle |
| Complete (close) a cycle by setting its end date to today |
Modules
Tool Name | Description |
| List modules in a project (set |
| Create a new module with name, dates, status, and members |
| Retrieve a module by ID |
| Update a module with partial data |
| Delete a module by ID |
| Add and/or remove work items on a module |
| List work items in a module |
| Archive or unarchive a module |
Initiatives
Tool Name | Description |
| List all initiatives in a workspace |
| Create a new initiative with name, dates, state, and lead |
| Retrieve an initiative by ID |
| Update an initiative with partial data |
| Delete an initiative by ID |
| List projects linked to an initiative |
| Link or unlink projects of an initiative |
Intake Work Items
Tool Name | Description |
| List all intake work items in a project with optional pagination |
| Create a new intake work item in a project |
| Retrieve an intake work item by work item ID with optional field expansion |
| Update an intake work item with partial data |
| Delete an intake work item by work item ID |
Work Item Properties
Tool Name | Description |
| List work item properties for a work item type |
| Create a new work item property with type, settings, and validation rules |
| Retrieve a work item property by ID |
| Update a work item property with partial data |
| Delete a work item property by ID |
| List options for a work item property |
| Create an option on a work item property |
| Retrieve a single option from a work item property |
| Update an option on a work item property |
| Delete an option from a work item property |
| Get the value(s) of a custom property on a work item |
| Set (create or update) the value of a custom property on a work item |
| Delete the value(s) of a custom property on a work item |
Milestones
Tool Name | Description |
| List all milestones in a project |
| Create a new milestone |
| Retrieve a milestone by ID |
| Update a milestone by ID |
| Delete a milestone by ID |
| Add and/or remove work items on a milestone |
| List work items in a milestone |
Labels
Tool Name | Description |
| List all labels in a project |
| Create a new label |
| Retrieve a label by ID |
| Update a label by ID |
| Delete a label by ID |
States
Tool Name | Description |
| List all states in a project |
| Create a new state |
| Retrieve a state by ID |
| Update a state by ID |
| Delete a state by ID |
Work Item Comments
Tool Name | Description |
| List comments for a work item |
| Retrieve a specific comment for a work item |
| Create a comment for a work item |
| Update a comment for a work item |
| Delete a comment for a work item |
Work Item Links
Tool Name | Description |
| List links for a work item |
| Retrieve a specific link for a work item |
| Create a link for a work item |
| Update a link for a work item |
| Delete a link for a work item |
Work Item Types
Tool Name | Description |
| List all work item types in a project |
| Create a new work item type |
| Retrieve a work item type by ID |
| Update a work item type by ID |
| Delete a work item type by ID |
| Bulk-link workspace-level work item types to a project |
| Find or create a named type for a project, auto-handling workspace vs project scope and import |
| Attach or detach properties on a work item type in a single call |
Work Item Relations
Tool Name | Description |
| List relations for a work item |
| Create relations for a work item |
| Remove a relation from a work item |
Work Item Relation Definitions
Tool Name | Description |
| List workspace custom relation definitions |
| Create a workspace relation definition |
| Update a relation definition |
| Delete a relation definition |
Work Item Activities
Tool Name | Description |
| List activities for a work item |
| Retrieve a specific activity for a work item |
Work Logs
Tool Name | Description |
| List work logs for a work item |
| Create a work log for a work item |
| Update a work log for a work item |
| Delete a work log for a work item |
Pages
Tool Name | Description |
| List pages - metadata only (workspace, or a project's if |
| Retrieve a page incl. content; optional |
| Search pages by title, optionally inside content (client-side, case-insensitive) |
| Create a workspace or project page |
| Link a page to a work item |
| Remove a page link from a work item |
| List all pages linked to a work item |
Work Item Attachments
Tool Name | Description |
| List all attachments for a work item |
| Get a presigned download URL for a work item attachment |
| Fetch an attachment's content so the LLM can read or analyze it |
| Fetch a file from a public URL and attach it to a work item |
| Delete an attachment from a work item |
Estimates
Tool Name | Description |
| Get the estimate configuration for a project |
| Create a new estimate for a project |
| Update the estimate for a project |
| Delete the estimate for a project |
| Link an estimate to a project, making it the active estimate system |
| List all valid estimate points for a project |
| Create estimate points for a project estimate |
| Update a single estimate point |
| Delete a single estimate point |
Roles
Tool Name | Description |
| List role definitions in the workspace |
| Retrieve a role definition by ID |
PQL
Tool Name | Description |
| Return the Plane Query Language (PQL) syntax reference (also exposed as the |
Workspaces
Tool Name | Description |
| Get all members of the current workspace |
| Get feature flags (workspace, or a project's if |
| Update features of the current workspace |
Users
Tool Name | Description |
| Get current authenticated user information |
Instance
Tool Name | Description |
| Get edition/version of the connected Plane instance and its known API limitations (e.g. Community Edition) |
| List the tool groups (toolsets) this server supports and which are active |
Total Tools: 142 tools across 24 categories (scripts/check_tool_docs.py keeps these tables in sync)
Development
# Install (uses uv)
uv pip install -e ".[dev]"
# Tests
pytest
# Format + lint
ruff format plane_mcp/
ruff check plane_mcp/Integration tests run against a live Plane instance - copy .env.test to
.env.test.local with real values, then export $(cat .env.test.local | xargs) && pytest tests/ -v.
Attribution & License
MIT License - see LICENSE.
Based on makeplane/plane-mcp-server (MIT, © 2025 Plane MCP Server Contributors). This is an independent, unofficial project: not affiliated with, endorsed by, or supported by Plane / makeplane. "Plane" is a trademark of its respective owner.
Contributing
Contributions welcome - especially fixes for self-hosted Community Edition quirks. See CONTRIBUTING.md.
Available Tools
142 toolsattach_page_to_work_itemB
Link a page to a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item page_id: UUID of the page to link
Returns: WorkItemPage link object
Inputs: page_id (required), project_id (required), work_item_id (required). Returns: Work item to page link.
complete_cycleA
Complete (close) a cycle by setting its end date to today.
Plane has no explicit "complete" action - a cycle is considered complete when its end_date is in the past. This tool sets end_date to today, effectively closing the cycle.
Args: project_id: UUID of the project cycle_id: UUID of the cycle to complete
Returns: Updated Cycle object
Inputs: cycle_id (required), project_id (required). Returns: Cycle model.
count_work_itemsARead-only
Count work items across the workspace with optional grouping.
Use this for analytics - "how many urgent items?", "distribution by state?" - without fetching full work item payloads.
Args: pql: PQL filter to scope the count (e.g. 'priority = "urgent"'). group_by: Dimension to group counts by. Supported values: state_id, state__group, priority, project_id, type_id, labels__id, assignees__id, issue_module__module_id, release_work_items__release_id, cycle_id, milestone_id, created_by, target_date, start_date. sub_group_by: Second dimension for nested grouping (requires group_by).
Returns: grouped_by: The group_by field used (null if none). sub_grouped_by: The sub_group_by field used (null if none). total_count: Total matching work items. grouped_counts: Dict of group_key → {count} or {count, sub_grouped_counts} when sub_group_by is set. Keys are UUIDs for FK fields, plain strings for priority/state__group, ISO dates for target_date/start_date, "None" for unset values.
Inputs: pql, group_by, sub_group_by. Returns: object
create_cycleB
Create a new cycle.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project name: Cycle name owned_by: UUID of the user who owns the cycle description: Cycle description start_date: Cycle start date (ISO 8601 format) end_date: Cycle end date (ISO 8601 format) external_source: External system source name external_id: External system identifier timezone: Cycle timezone
Returns: Created Cycle object
Inputs: name (required), owned_by (required), project_id (required), end_date, +5 more. Returns: Cycle model.
create_initiativeA
Create a new initiative in the workspace.
Args: name: Initiative name description_html: HTML description of the initiative start_date: Initiative start date (ISO 8601 format) end_date: Initiative end date (ISO 8601 format) logo_props: Logo properties dictionary state: Initiative state (DRAFT, PLANNED, ACTIVE, COMPLETED, CLOSED) lead: UUID of the user who leads the initiative
Returns: Created Initiative object
Raises: ToolError: if the workspace's initiatives feature is disabled. Native initiatives require the feature to be enabled in workspace settings. When disabled, create an "Initiative" work item instead - the error message gives the exact steps.
Inputs: name (required), lead, state, end_date, +3 more. Returns: Initiative model.
create_intake_work_itemB
Create a new intake work item in a project.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project data: Intake work item data as a dictionary
Returns: Created IntakeWorkItem object
Inputs: data (required), project_id (required). Returns: Intake work item model.
create_labelB
Create a new label.
Args: project_id: UUID of the project name: Label name color: Label color (hex color code) description: Label description parent: UUID of the parent label (for nested labels) sort_order: Sort order for the label external_source: External system source name external_id: External system identifier
Returns: Created Label object
Inputs: name (required), project_id (required), color, parent, +4 more. Returns: Label model.
create_milestoneB
Create a new milestone.
Args: project_id: UUID of the project title: Milestone title target_date: Target date for the milestone (ISO 8601 format) external_source: External system source name external_id: External system identifier
Returns: Created Milestone object
Inputs: title (required), project_id (required), external_id, target_date, +1 more. Returns: Milestone model.
create_moduleA
Create a new module.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project name: Module name description: Module description start_date: Module start date (ISO 8601 format) target_date: Module target/end date (ISO 8601 format) status: Module status (backlog, planned, in-progress, paused, completed, cancelled) lead: UUID of the user who leads the module members: List of user IDs who are members of the module external_source: External system source name external_id: External system identifier
Returns: Created Module object
Inputs: name (required), project_id (required), lead, status, +6 more. Returns: Module model.
create_pageA
Create a page.
Creates a project page if project_id is given, otherwise a workspace-level page.
Args: name: Page name description_html: Page content in HTML format project_id: UUID of the project. Omit to create a workspace page. access: Access level for the page (integer) color: Page color is_locked: Whether the page is locked archived_at: Archive timestamp (ISO 8601 format) view_props: View properties dictionary logo_props: Logo properties dictionary external_id: External system identifier external_source: External system source name
Returns: Created Page object
Inputs: name (required), description_html (required), color, access, +7 more. Returns: Page model.
create_projectB
Create a new project.
Args: workspace_slug: The workspace slug identifier name: Project name identifier: Project identifier (e.g., "MP" for "My Project") description: Project description project_lead: UUID of the project lead user default_assignee: UUID of the default assignee user emoji: Emoji for the project cover_image: Cover image URL or asset ID module_view: Enable module view cycle_view: Enable cycle view issue_views_view: Enable issue views view page_view: Enable page view intake_view: Enable intake view guest_view_all_features: Allow guests to view all features archive_in: Days until auto-archive close_in: Days until auto-close timezone: Project timezone external_source: External system source name external_id: External system identifier is_issue_type_enabled: Enable issue types
Returns: Created Project object
Inputs: name (required), identifier (required), emoji, close_in, +15 more. Returns: Project model.
create_project_estimateA
Create a new estimate for a project.
Args: project_id: UUID of the project name: Name of the estimate (e.g., "Story Points", "T-Shirt Sizes") type: Estimate type - "categories", "points", or "time" description: Optional description last_used: Whether this becomes the active estimate (default True) external_id: External system identifier external_source: External system source name
Returns: Created Estimate object
Inputs: name (required), project_id (required), type, last_used, +3 more. Returns: Estimate response model. Represents the sizing scale configured for a project (…
create_project_estimate_pointsA
Create estimate points for a project estimate.
Each point dict may have: value (required, max 20 chars), key (int), description, external_id, external_source.
Example: points=[ {"value": "1", "key": 0}, {"value": "2", "key": 1}, {"value": "3", "key": 2}, {"value": "5", "key": 3}, {"value": "8", "key": 4}, ]
Args: project_id: UUID of the project estimate_id: UUID of the estimate points: List of point definitions
Returns: List of created EstimatePoint objects
Inputs: points (required), project_id (required), estimate_id (required). Returns: result
create_stateA
Create a new state.
Args: project_id: UUID of the project name: State name color: State color (hex color code) description: State description sequence: State sequence order group: State group (e.g., backlog, unstarted, started, completed, cancelled) is_triage: Whether this is a triage state default: Whether this is the default state external_source: External system source name external_id: External system identifier
Returns: Created State object
Inputs: name (required), color (required), project_id (required), group, +6 more. Returns: State model.
create_work_itemA
Create a new work item.
Args: project_id: UUID of the project name: Work item name (required) assignees: List of user IDs to assign to the work item labels: List of label IDs to attach to the work item type_id: UUID of the work item type point: Story point value description_html: HTML description of the work item description_stripped: Plain text description. Convenience only - it is wrapped into HTML and stored as description_html (Plane derives description_stripped server-side). Ignored if description_html is set. priority: Priority level (urgent, high, medium, low, none) start_date: Start date (ISO 8601 format) target_date: Target/end date (ISO 8601 format) sort_order: Sort order value is_draft: Whether the work item is a draft external_source: External system source name external_id: External system identifier parent: UUID of the parent work item state: UUID of the state estimate_point: Estimate point value type: Work item type identifier
Returns: Created WorkItem object
Inputs: name (required), project_id (required), type, point, +15 more. Returns: Work item model.
create_work_item_commentB
Create a comment for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item comment_html: Comment content in HTML format comment_json: Comment content in JSON format access: Access level for the comment (INTERNAL or EXTERNAL) external_source: External system source name external_id: External system identifier
Returns: Created WorkItemComment object
Inputs: project_id (required), work_item_id (required), access, external_id, +3 more. Returns: Work item comment model.
create_work_item_linkB
Create a link for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item url: URL of the link
Returns: Created WorkItemLink object
Inputs: url (required), project_id (required), work_item_id (required). Returns: Work item link model.
create_work_item_propertyA
Create a new work item property.
Scope resolution:
project_id + work_item_type_id → type-scoped project property (legacy)
project_id only → project-level property (not yet linked to a type)
neither → workspace-level property
Args: display_name: Display name for the property property_type: TEXT | DATETIME | DECIMAL | BOOLEAN | OPTION | RELATION | URL | EMAIL | FILE | FORMULA project_id: UUID of the project. Omit for workspace-level property. work_item_type_id: UUID of the work item type - omit to create at project level relation_type: ISSUE | USER - required when property_type=RELATION description: Property description is_required: Whether the property is required default_value: Default value(s) for the property settings: Required for TEXT/DATETIME. TEXT: {"display_format": "single-line"|"multi-line"|"readonly"} DATETIME: {"display_format": "MMM dd, yyyy"|"dd/MM/yyyy"|"MM/dd/yyyy"|"yyyy/MM/dd"} is_active: Whether the property is active is_multi: Whether the property supports multiple values validation_rules: Validation rules dictionary external_source: External system source name external_id: External system identifier options: List of {name, color?, is_default?} dicts - for OPTION type
Returns: Created WorkItemProperty object
Inputs: display_name (required), property_type (required), options, is_multi, +11 more. Returns: Work item property model.
create_work_item_property_optionA
Create an option on a work item property.
Args: property_id: UUID of the work item property name: Display name for the option project_id: UUID of the project. Omit for workspace scope. description: Option description color: Hex color string e.g. "#FF5733" is_default: Whether this is the default option external_source: External system source name external_id: External system identifier
Returns: Created WorkItemPropertyOption object
Inputs: name (required), property_id (required), color, is_default, +4 more. Returns: Work item property option model.
create_work_item_relationA
Relate a work item to one or more targets.
Always call list_work_item_relation_definitions first and match the user's wording to an entry there. If it is a built_in_dependencies value, pass it as relation_type. If it is a custom_definitions entry, pass that definition's id as relation_definition_id and the matched outward/inward label as relation_definition_label (the label sets directionality).
Args: project_id: UUID of the project. work_item_id: UUID of the source work item. work_item_ids: UUIDs of the target work items. relation_type: A built_in_dependencies value, or None for a custom relation. relation_definition_id: UUID of the relation definition (custom relations). relation_definition_label: Definition's outward or inward label (custom relations).
Returns: List of created WorkItemWithRelationType objects.
Inputs: project_id (required), work_item_id (required), work_item_ids (required), relation_type, +2 more. Returns: result
create_work_item_relation_definitionA
Create a new workspace relation definition.
A relation definition describes a named relationship type with an outward label (how the source item describes the target) and an inward label (how the target item describes the source).
Args: name: Unique name for this relation definition. outward: Label describing the relation from the source item's perspective. inward: Label describing the relation from the target item's perspective. is_active: Whether this definition is active and available for use. color: Hex color code for UI display.
Returns: Created WorkItemRelationDefinition object.
Inputs: name (required), color, inward, outward, +1 more. Returns: Work item relation definition response model.
create_work_item_typeA
Create a new work item type.
To get a usable type for a project (e.g. "Epic"), prefer resolve_work_item_type, which finds-or-creates at the correct scope and never duplicates.
Args: name: Work item type name project_id: UUID of the project. Omit for workspace-level type. description: Work item type description project_ids: List of project IDs this type applies to is_active: Whether the type is active external_source: External system source name external_id: External system identifier
Returns: Created WorkItemType object
Inputs: name (required), is_active, project_id, description, +3 more. Returns: Work item type model.
create_work_logA
Create a work log for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item duration: Duration of work in minutes description: Description of the work performed
Returns: Created WorkItemWorkLog object
Inputs: project_id (required), work_item_id (required), duration, description. Returns: Work item work log model.
delete_cycleCDestructiveIdempotent
Delete a cycle by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project cycle_id: UUID of the cycle
Inputs: cycle_id (required), project_id (required).
delete_initiativeADestructiveIdempotent
Delete an initiative by ID.
Args: initiative_id: UUID of the initiative
Raises: ToolError: if the initiatives feature is disabled. When disabled, the initiative is an "Initiative" work item - the error gives the steps.
Inputs: initiative_id (required).
delete_intake_work_itemBDestructiveIdempotent
Delete an intake work item by work item ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project work_item_id: UUID of the work item (use the issue field from IntakeWorkItem response, not the intake work item ID)
Inputs: project_id (required), work_item_id (required).
delete_labelBDestructiveIdempotent
Delete a label by ID.
Args: project_id: UUID of the project label_id: UUID of the label
Inputs: label_id (required), project_id (required).
delete_milestoneADestructiveIdempotent
Delete a milestone by ID.
Args: project_id: UUID of the project milestone_id: UUID of the milestone
Inputs: project_id (required), milestone_id (required).
delete_moduleCDestructiveIdempotent
Delete a module by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project module_id: UUID of the module
Inputs: module_id (required), project_id (required).
delete_projectCDestructiveIdempotent
Delete a project by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project
Inputs: project_id (required).
delete_project_estimateBDestructiveIdempotent
Delete the estimate for a project.
Args: project_id: UUID of the project
Inputs: project_id (required).
delete_project_estimate_pointBDestructiveIdempotent
Delete a single estimate point.
Args: project_id: UUID of the project estimate_id: UUID of the estimate estimate_point_id: UUID of the estimate point to delete
Inputs: project_id (required), estimate_id (required), estimate_point_id (required).
delete_stateCDestructiveIdempotent
Delete a state by ID.
Args: project_id: UUID of the project state_id: UUID of the state
Inputs: state_id (required), project_id (required).
delete_work_itemCDestructiveIdempotent
Delete a work item by ID.
Args: project_id: UUID of the project work_item_id: UUID of the work item
Inputs: project_id (required), work_item_id (required).
delete_work_item_attachmentADestructiveIdempotent
Delete an attachment from a work item.
Use list_work_item_attachments to get the attachment_id.
Args: project_id: UUID of the project work_item_id: UUID of the work item attachment_id: UUID of the attachment to delete
Inputs: project_id (required), work_item_id (required), attachment_id (required).
delete_work_item_commentADestructiveIdempotent
Delete a comment for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item comment_id: UUID of the comment
Inputs: comment_id (required), project_id (required), work_item_id (required).
delete_work_item_linkBDestructiveIdempotent
Delete a link for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item link_id: UUID of the link
Inputs: link_id (required), project_id (required), work_item_id (required).
delete_work_item_propertyADestructiveIdempotent
Delete a work item property by ID.
Args: work_item_property_id: UUID of the property project_id: UUID of the project. Omit for workspace scope. work_item_type_id: UUID of the work item type - omit to use project-level endpoint
Inputs: work_item_property_id (required), project_id, work_item_type_id.
delete_work_item_property_optionADestructiveIdempotent
Delete an option from a work item property.
Args: property_id: UUID of the work item property option_id: UUID of the option project_id: UUID of the project. Omit for workspace scope.
Inputs: option_id (required), property_id (required), project_id.
delete_work_item_property_valueADestructiveIdempotent
Delete the value(s) of a custom property on a work item.
For multi-value properties, deletes all values for that property.
Args: project_id: UUID of the project work_item_id: UUID of the work item property_id: UUID of the work item property
Inputs: project_id (required), property_id (required), work_item_id (required).
delete_work_item_relation_definitionADestructiveIdempotent
Delete a workspace relation definition.
Args: definition_id: UUID of the relation definition to delete.
Inputs: definition_id (required).
delete_work_item_typeADestructiveIdempotent
Delete a work item type by ID.
Args: work_item_type_id: UUID of the work item type project_id: UUID of the project. Omit for workspace scope.
Inputs: work_item_type_id (required), project_id.
delete_work_logCDestructiveIdempotent
Delete a work log for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item work_log_id: UUID of the work log
Inputs: project_id (required), work_log_id (required), work_item_id (required).
detach_page_from_work_itemADestructiveIdempotent
Remove a page link from a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item work_item_page_id: UUID of the work item page link (not the page ID)
Inputs: project_id (required), work_item_id (required), work_item_page_id (required).
get_featuresARead-only
Get feature flags.
Returns a project's features if project_id is given, otherwise the workspace's features.
Args: project_id: UUID of the project. Omit for workspace features.
Returns: ProjectFeature when project_id is given, otherwise WorkspaceFeature.
Inputs: project_id. Returns: result
get_instance_infoARead-only
Get edition/version info and known API limitations of the connected Plane instance.
Use this to understand up-front which tool families are unavailable (e.g. pages, epics/work-item types, initiatives, estimates and milestones on Community Edition) instead of discovering them through 404 errors.
Returns: Dict with base_url, edition (e.g. "PLANE_COMMUNITY"), version, compat_reference, and - for Community Edition - unavailable_features.
Inputs: no named parameters. Returns: object
get_meARead-only
Get current user information.
Returns: UserLite object containing current user information
Inputs: no named parameters. Returns: Lite user information.
get_pql_referenceARead-only
Return the Plane Query Language (PQL) syntax reference.
Call this when composing the pql filter for list_work_items,
list_archived_work_items, list_cycle_work_items, list_module_work_items,
or count_work_items.
Args: detail: "full" (default) returns the comprehensive reference with all operators, functions, common mistakes, and worked examples. "brief" returns the compact field/operator/function quick reference (lighter payload for simple queries).
Returns:
Dict with detail (which version was returned) and reference
(the PQL syntax text).
Inputs: detail. Returns: object
get_project_estimateARead-only
Get the estimate configuration for a project.
Returns the active estimate system including its ID, which is required to call list_project_estimate_points.
Args: project_id: UUID of the project
Returns: Estimate object with id, name, and type fields
Inputs: project_id (required). Returns: Estimate response model. Represents the sizing scale configured for a project (…
get_project_membersARead-only
List members of a project (filterable, paginated).
Optional filters first_name/last_name/email/display_name (case-insensitive contains), role_slug (exact), is_active, is_bot - combined with AND.
Args: project_id: UUID of the project. cursor: Prior response's next_cursor; omit for first page. per_page: Results per page (1-1000, default 100). order_by: Sort field; prefix '-' for descending.
Returns: Paginated envelope: results (members incl. role, role_slug, is_active, is_bot) + total_count, next_cursor, next_page_results.
Inputs: project_id (required), email, cursor, is_bot, +7 more. Returns: Paginated response for the project members-lite endpoint.
get_project_worklog_summaryCRead-only
Get work log summary for a project.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project
Returns: List of ProjectWorklogSummary objects containing work item IDs and durations
Inputs: project_id (required). Returns: result
get_work_item_attachment_download_urlARead-only
Get a presigned download URL for a work item attachment.
Returns a time-limited URL (typically valid ~1 hour) that can be opened directly in a browser or downloaded with any HTTP client - no Plane authentication required on the URL itself.
Use list_work_item_attachments first to get attachment IDs and names.
Args: project_id: UUID of the project work_item_id: UUID of the work item attachment_id: UUID of the attachment
Returns: Dict with: download_url (presigned S3 URL), attachment_id, name.
Inputs: project_id (required), work_item_id (required), attachment_id (required). Returns: object
get_work_item_property_valueARead-only
Get the value(s) of a custom property on a work item.
Use list_work_item_properties to find the property_id for a given property name (e.g. "Acceptance Criteria").
Args: project_id: UUID of the project work_item_id: UUID of the work item property_id: UUID of the work item property
Returns: Single WorkItemPropertyValueDetail for non-multi properties, or list of WorkItemPropertyValueDetail for multi-value properties
Inputs: project_id (required), property_id (required), work_item_id (required). Returns: result
get_workspace_membersARead-only
List members of the current workspace (filterable, paginated).
Optional filters first_name/last_name/email/display_name (case-insensitive contains), role_slug (exact), is_active, is_bot - combined with AND.
Args: cursor: Prior response's next_cursor; omit for first page. per_page: Results per page (1-1000, default 100). order_by: Sort field; prefix '-' for descending.
Returns: Paginated envelope: results (members incl. role, role_slug, is_active, is_bot) + total_count, next_cursor, next_page_results.
Inputs: email, cursor, is_bot, order_by, +6 more. Returns: Paginated response for the workspace members-lite endpoint.
import_work_item_types_to_projectA
Bulk-link workspace-level work item types to a project.
Imports one or more workspace-scoped work item types into a project so that they become available for use within that project.
For the common case of getting one named type usable in a project, prefer resolve_work_item_type, which finds-or-creates and imports in one step.
Args: project_id: UUID of the project work_item_type_ids: List of workspace-level work item type UUIDs to import
Inputs: project_id (required), work_item_type_ids (required).
link_estimate_to_projectA
Link an estimate to a project, making it the active estimate system.
Args: project_id: UUID of the project estimate_id: UUID of the estimate to activate
Returns: Updated Project object
Inputs: project_id (required), estimate_id (required). Returns: Project model.
list_archived_work_itemsARead-only
List archived work items in a project with optional PQL filtering.
Args:
project_id: UUID of the project
pql: PQL filter expression. Omit to list all archived items.
order_by: Field to sort by; prefix with - for descending
(default -archived_at).
per_page: Results per page, 1-100 (default 100).
cursor: Pagination cursor from a previous response's next_cursor.
expand: Comma-separated related fields to expand.
fields: Comma-separated sparse fieldset.
Returns: Paginated envelope with results, total_count, next_cursor, prev_cursor.
Inputs: project_id (required), pql, cursor, expand, +3 more. Returns: object
list_cyclesARead-only
List cycles in a project. Active (non-archived) cycles by default.
Args: project_id: UUID of the project archived: Set True to list archived cycles instead of active ones. status: Filter active cycles by status - "current" (running now), "upcoming" (starts later), "completed" (ended), "draft" (no dates), or "incomplete" (not yet finished). Ignored when archived is True. cursor: Pagination cursor from a previous response's next_cursor (form "{per_page}:{page}:{offset}"). Omit for the first page. per_page: Number of results per page (1-1000, default and max 1000). order_by: Field to order results by. Prefix with '-' for descending.
Returns: Paginated envelope: results (lite cycles) + total_count, next_cursor, next_page_results.
Inputs: project_id (required), cursor, status, archived, +2 more. Returns: result
list_cycle_work_itemsARead-only
List work items in a cycle with optional PQL filtering.
Args:
project_id: UUID of the project
cycle_id: UUID of the cycle
pql: PQL filter expression. See field description for syntax.
Omit to list all items in the cycle.
order_by: Field to sort by; prefix with - for descending.
per_page: Results per page, 1-100 (default 25).
cursor: Pagination cursor from a previous response's next_cursor.
expand: Comma-separated related fields to expand.
fields: Comma-separated sparse fieldset.
Returns: Paginated envelope with results, total_count, next_cursor, prev_cursor.
Inputs: cycle_id (required), project_id (required), pql, cursor, +4 more. Returns: object
list_initiative_projectsARead-only
List projects linked to an initiative.
Args: initiative_id: UUID of the initiative params: Optional query parameters (e.g., per_page, cursor)
Returns: List of linked Project objects
Inputs: initiative_id (required), params. Returns: result
list_initiativesARead-only
List all initiatives in a workspace.
Args: params: Optional query parameters as a dictionary (e.g., per_page, cursor)
Returns: List of Initiative objects
Raises: ToolError: if the initiatives feature is disabled. When disabled, initiatives are "Initiative" work items - the error gives the steps.
Inputs: params. Returns: result
list_intake_work_itemsBRead-only
List all intake work items in a project.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project params: Optional query parameters as a dictionary (e.g., per_page, cursor)
Returns: List of IntakeWorkItem objects
Inputs: project_id (required), params. Returns: result
list_labelsARead-only
List all labels in a project.
Args: project_id: UUID of the project params: Optional query parameters as a dictionary
Returns: List of Label objects
Inputs: project_id (required), params. Returns: result
list_milestonesARead-only
List all milestones in a project.
Args: project_id: UUID of the project params: Optional query parameters as a dictionary
Returns: List of Milestone objects
Inputs: project_id (required), params. Returns: result
list_milestone_work_itemsCRead-only
List work items in a milestone.
Args: project_id: UUID of the project milestone_id: UUID of the milestone params: Optional query parameters as a dictionary
Returns: List of MilestoneWorkItem objects in the milestone
Inputs: project_id (required), milestone_id (required), params. Returns: result
list_modulesARead-only
List modules in a project.
Args: project_id: UUID of the project archived: Set True to list archived modules instead of active ones. cursor: Pagination cursor from a previous response's next_cursor (form "{per_page}:{page}:{offset}"). Omit for the first page. per_page: Number of results per page (1-1000, default and max 1000). order_by: Field to order results by. Prefix with '-' for descending.
Returns: Paginated envelope: results (lite modules) + total_count, next_cursor, next_page_results.
Inputs: project_id (required), cursor, archived, order_by, +1 more. Returns: result
list_module_work_itemsARead-only
List work items in a module with optional PQL filtering.
Args:
project_id: UUID of the project
module_id: UUID of the module
pql: PQL filter expression. See field description for syntax.
Omit to list all items in the module.
order_by: Field to sort by; prefix with - for descending.
per_page: Results per page, 1-100 (default 25).
cursor: Pagination cursor from a previous response's next_cursor.
expand: Comma-separated related fields to expand.
fields: Comma-separated sparse fieldset.
Returns: Paginated envelope with results, total_count, next_cursor, prev_cursor.
Inputs: module_id (required), project_id (required), pql, cursor, +4 more. Returns: object
list_pagesARead-only
List pages.
Lists a project's pages if project_id is given, otherwise workspace-level pages. The list contains metadata only - description_html is null here by design; fetch a page's content with retrieve_page.
Args: project_id: UUID of the project. Omit to list workspace pages. params: Optional query parameters as a dictionary (e.g., per_page, cursor)
Returns: List of Page objects (metadata only, no page content)
Inputs: params, project_id. Returns: result
list_project_estimate_pointsARead-only
List all valid estimate points for a project.
Use this to discover the available estimate point UUIDs before calling update_work_item with an estimate_point value. Each EstimatePoint has an id (UUID to pass to update_work_item) and a value (display label such as "1", "2", "3", "5", "8" or "XS", "S", "M", "L", "XL").
Workflow: 1. Call get_project_estimate to get the estimate_id 2. Call list_project_estimate_points with that estimate_id 3. Pick the EstimatePoint whose value matches the user's intent 4. Pass that EstimatePoint.id to update_work_item(estimate_point=...)
Args: project_id: UUID of the project estimate_id: UUID of the estimate (from get_project_estimate)
Returns: List of EstimatePoint objects, each with id and value fields
Inputs: project_id (required), estimate_id (required). Returns: result
list_projectsARead-only
List projects in a workspace (lite, paginated).
Trimmed fields: id, identifier, name, description, emoji, icon_prop, cover_image, cover_image_url, archived_at. For full detail use retrieve_project.
Args: cursor: Prior response's next_cursor; omit for first page. per_page: Results per page (1-1000, default 1000). order_by: Sort field; prefix '-' for descending.
Returns: Paginated envelope: results + total_count, next_cursor, next_page_results (page again while next_page_results is true).
Inputs: cursor, order_by, per_page. Returns: Paginated response for the projects-lite endpoint.
list_rolesARead-only
List role definitions in the workspace.
namespace="workspace" → Owner/Admin/Member/Guest; "project" → project-role defs shared across all projects (Admin/Contributor/Commenter/Guest); omit for both. slug is stable but NOT globally unique (admin/guest exist in both namespaces) - key by (namespace, slug).
Args: namespace: "workspace" or "project"; omit for both. per_page: Results per page (server default 20). cursor: Prior response's next_cursor.
Returns: Paginated envelope: results (name, slug, namespace) + pagination fields.
Inputs: cursor, per_page, namespace. Returns: Paginated response for workspace/project role definitions.
list_statesARead-only
List all states in a project.
Args: project_id: UUID of the project params: Optional query parameters as a dictionary
Returns: List of State objects
Inputs: project_id (required), params. Returns: result
list_toolsetsARead-only
List the tool groups (toolsets) this server knows and which are active.
Toolsets are selected with the PLANE_TOOLSETS env var (comma-separated, or "all"). A client that only needs a subset can set it to load fewer tool definitions into its context window.
Returns:
Dict with active (toolset names currently registered) and
available (every toolset name the server supports).
Inputs: no named parameters. Returns: object
list_work_item_activitiesBRead-only
List activities for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item params: Optional query parameters as a dictionary
Returns: List of WorkItemActivity objects
Inputs: project_id (required), work_item_id (required), params. Returns: result
list_work_item_attachmentsARead-only
List all attachments for a work item.
Returns metadata for each attachment. To get a downloadable link for a specific attachment, use get_work_item_attachment_download_url.
Args: project_id: UUID of the project work_item_id: UUID of the work item
Returns: List of attachments, each with: id, name, size, content_type, created_at, created_by.
Inputs: project_id (required), work_item_id (required). Returns: result
list_work_item_commentsBRead-only
List comments for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item params: Optional query parameters as a dictionary
Returns: List of WorkItemComment objects
Inputs: project_id (required), work_item_id (required), params. Returns: result
list_work_item_linksBRead-only
List links for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item params: Optional query parameters as a dictionary
Returns: List of WorkItemLink objects
Inputs: project_id (required), work_item_id (required), params. Returns: result
list_work_item_pagesARead-only
List all pages linked to a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item
Returns: List of WorkItemPage link objects
Inputs: project_id (required), work_item_id (required). Returns: result
list_work_item_propertiesARead-only
List custom work item properties.
Scope resolution (highest priority first):
no args → ALL workspace-level properties (one API call)
work_item_type_id only → workspace-level properties linked to that type
project_id only → all properties in that project (any type)
project_id + work_item_type_id → properties linked to that type in that project, falling back to project-flat then workspace if empty
For PQL filtering by name, prefer calling with NO args - one workspace-wide
fetch beats iterating every work item type. Each result includes the
display_name you can match in-memory before composing cf["<id>"] in PQL.
Each result includes:
id: property UUID - use as cf[""] in PQL filters
display_name: user-facing label (e.g. "Fed", "Acceptance Criteria")
property_type: TEXT | OPTION | DECIMAL | BOOLEAN | DATETIME | RELATION | URL | EMAIL
options: for OPTION type, each option has id + name; use option id in PQL
PQL workflow for filtering by custom property (efficient path):
list_work_item_properties() → all workspace properties, one call
find the property by display_name in-memory → property.id
list_work_items(pql='cf["<property.id>"] = "<option.id>"')
Inputs: params, project_id, work_item_type_id. Returns: result
list_work_item_property_optionsARead-only
List options for a work item property.
Args: property_id: UUID of the work item property project_id: UUID of the project. Omit for workspace scope. params: Optional query parameters
Returns: List of WorkItemPropertyOption objects
Inputs: property_id (required), params, project_id. Returns: result
list_work_item_relation_definitionsARead-only
List every relation type usable with create_work_item_relation.
Match the user's wording against an entry here before creating a relation. built_in_dependencies are fixed scheduling/blocking types; custom_definitions are workspace-specific, each with an outward and inward label. custom_definitions are also what create/update/delete_work_item_relation_definition manage.
Args: is_default: Filter custom definitions to default/non-default only. is_active: Filter custom definitions to active/inactive only.
Returns: built_in_dependencies: relation_type values for the dependency path. custom_definitions: workspace definitions; use the id plus the matched outward or inward label.
Inputs: is_active, is_default. Returns: object
list_work_item_relationsARead-only
List every relation for a work item.
Args: project_id: UUID of the project. work_item_id: UUID of the work item.
Returns: dependencies: Built-in dependencies grouped by the six directions. custom: Custom relations grouped by definition label.
Inputs: project_id (required), work_item_id (required). Returns: object
list_work_itemsARead-only
List work items with optional PQL filtering.
Omit project_id to list across the entire workspace. Pass project_id to scope results to a single project.
For UUID fields (assignee, state, label, cycle, module, type, milestone) call the relevant list tool first to get the UUID.
Args:
project_id: UUID of the project. Omit for workspace-wide results.
pql: PQL filter. See field description for syntax.
order_by: Sort field; prefix - for descending (e.g. -created_at).
per_page: 1-100, default 25.
cursor: From previous response's next_cursor.
expand: Comma-separated relations to expand (e.g. assignees,labels,state).
fields: Sparse fieldset - id, name, sequence_id, priority, state,
project, assignees, labels, type_id, description_html, start_date,
target_date, created_at, updated_at, created_by, is_draft. Use
project (not project_id) and description_html (there is no
description field). Any field you omit or misname comes back
null - a null here does NOT mean the item lacks that value; it
means it was not requested. To read the description, include
description_html; for the type, include type_id.
external_id / external_source: Filter by external system.
Returns: results: Paginated list of work items. total_count: True DB total, not page-bounded - use for counts. next_cursor: Cursor for the next page. prev_cursor: Cursor for the previous page.
Inputs: pql, cursor, expand, fields, +5 more. Returns: object
list_work_item_typesARead-only
List work item types. Omit project_id for workspace-level types.
Each result's id is the work_item_type_id needed by list_work_item_properties
to look up custom property and option UUIDs for PQL cf[] filters.
Inputs: params, project_id. Returns: result
list_work_logsARead-only
List work logs for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item params: Optional query parameters as a dictionary
Returns: List of WorkItemWorkLog objects
Inputs: project_id (required), work_item_id (required), params. Returns: result
manage_cycle_archiveA
Archive or unarchive a cycle.
Plane requires the cycle end_date to be in the past before archiving. When archive=True, this tool automatically sets end_date to today if the cycle is still active (end_date is missing or in the future), then archives it.
Args: project_id: UUID of the project cycle_id: UUID of the cycle archive: True to archive the cycle, False to unarchive it
Returns: True if the operation completed successfully
Inputs: archive (required), cycle_id (required), project_id (required). Returns: result
manage_cycle_work_itemsA
Add or remove work items on a cycle in a single call.
At least one of add_ids or remove_ids must be provided.
Args: project_id: UUID of the project cycle_id: UUID of the cycle add_ids: UUIDs of work items to add to the cycle remove_ids: UUIDs of work items to remove from the cycle
Inputs: cycle_id (required), project_id (required), add_ids, remove_ids.
manage_initiative_projectsA
Link or unlink projects of an initiative. Use list_initiative_projects to read.
Args: initiative_id: UUID of the initiative action: "add" to link the projects, "remove" to unlink them project_ids: Project UUIDs to link/unlink
Returns: The initiative's linked projects after the operation
Inputs: action (required), project_ids (required), initiative_id (required). Returns: result
manage_milestone_work_itemsA
Add or remove work items on a milestone in a single call.
At least one of add_ids or remove_ids must be provided.
Args: project_id: UUID of the project milestone_id: UUID of the milestone add_ids: UUIDs of work items to add to the milestone remove_ids: UUIDs of work items to remove from the milestone
Inputs: project_id (required), milestone_id (required), add_ids, remove_ids.
manage_module_archiveA
Archive or unarchive a module.
Args: project_id: UUID of the project module_id: UUID of the module archive: True to archive the module, False to unarchive it
Inputs: archive (required), module_id (required), project_id (required).
manage_module_work_itemsA
Add or remove work items on a module in a single call.
At least one of add_ids or remove_ids must be provided.
Args: project_id: UUID of the project module_id: UUID of the module add_ids: UUIDs of work items to add to the module remove_ids: UUIDs of work items to remove from the module
Inputs: module_id (required), project_id (required), add_ids, remove_ids.
manage_project_archiveA
Archive or unarchive a project.
Archived projects are hidden from active project lists but not deleted. All work items, cycles, and modules are preserved.
Args: project_id: UUID of the project archive: True to archive the project, False to unarchive it
Inputs: archive (required), project_id (required).
manage_work_item_archiveA
Archive or unarchive a work item.
Only work items in a completed or cancelled state can be archived. Archived work items no longer appear in active work item lists.
Args: project_id: UUID of the project work_item_id: UUID of the work item archive: True to archive the work item, False to unarchive it
Inputs: archive (required), project_id (required), work_item_id (required).
manage_work_item_assigneeA
Add or remove a single assignee on a work item without replacing the full list.
Provide add_user_id, remove_user_id, or both. If both are given the removal is applied first, then the addition. Already-assigned users in add_user_id are silently skipped.
Args: project_id: UUID of the project work_item_id: UUID of the work item add_user_id: UUID of the user to add as assignee remove_user_id: UUID of the user to remove from assignees
Returns: Updated WorkItem object
Inputs: project_id (required), work_item_id (required), add_user_id, remove_user_id. Returns: Work item model.
manage_work_item_labelA
Add or remove a single label on a work item without replacing the full list.
Provide add_label_id, remove_label_id, or both. If both are given the removal is applied first, then the addition. Already-attached labels in add_label_id are silently skipped.
Args: project_id: UUID of the project work_item_id: UUID of the work item add_label_id: UUID of the label to add remove_label_id: UUID of the label to remove
Returns: Updated WorkItem object
Inputs: project_id (required), work_item_id (required), add_label_id, remove_label_id. Returns: Work item model.
manage_work_item_type_propertiesA
Attach or detach properties on a work item type in a single call.
At least one of attach_ids or detach_ids must be provided. Detach does not delete the property - it only removes the association.
Args: project_id: UUID of the project work_item_type_id: UUID of the work item type attach_ids: Property UUIDs to attach to the type detach_ids: Property UUIDs to detach from the type
Returns: List of attached property UUIDs if attach_ids was provided, else None
Inputs: project_id (required), work_item_type_id (required), attach_ids, detach_ids. Returns: result
read_work_item_attachmentARead-only
Fetch an attachment's content so the LLM can read or analyze it.
Supported file types: Images (returned as vision-readable image, max 5 MB): PNG, JPEG, GIF, WEBP Text (returned as a string, max 1 MB): TXT, MD, CSV, HTML, XML, YAML, JSON
Not supported (use get_work_item_attachment_download_url instead): PDF - requires a text-extraction library (not installed) DOCX/XLSX/PPTX - binary Office formats, require extraction Audio / Video - non-textual binary formats Generic binary - executables, archives, etc.
Args: project_id: UUID of the project work_item_id: UUID of the work item attachment_id: UUID of the attachment
Returns: Image object for image files, plain string for text files.
Raises: ValueError: If the file type is unsupported or the file exceeds the size limit for its category.
Inputs: project_id (required), work_item_id (required), attachment_id (required).
remove_work_item_relationADestructiveIdempotent
Remove ONE relation between two work items.
A built-in dependency and a custom relation are removed independently - removing one leaves the other intact. Set is_dependency from the relation the user named (see list_work_item_relations): True for a built-in dependency (blocking, blocked_by, start/finish ordering), False for a custom relation.
Args: project_id: UUID of the project. work_item_id: UUID of the source work item. related_work_item_id: UUID of the related work item. is_dependency: True to remove a built-in dependency, False to remove a custom relation.
Inputs: project_id (required), work_item_id (required), is_dependency (required), related_work_item_id (required).
resolve_work_item_typeA
Find a work item type by name for a project, create it if missing, and guarantee it is usable inside that project. Use this to resolve the type_id for a typed work item such as an "Epic" or "Initiative" before calling create_work_item(type_id=...).
Handles workspace-level and project-level work item types automatically, so the caller never has to decide which mode the workspace is in:
If the workspace owns work item types, the type is found (or created) at the workspace level and imported into the project. Project-level creation is blocked in this mode, so importing is the only valid path.
Otherwise the type is found (or created) at the project level, enabling the project's work item types feature first if it is off.
Matching is exact (case-sensitive, whitespace-stripped); an existing type is never duplicated.
Prefer this over manually combining get_workspace_features, list_work_item_types, create_work_item_type, and import_work_item_types_to_project - it does all of that deterministically.
Args: project_id: UUID of the project the type must be usable in name: Work item type name, e.g. "Epic" or "Initiative"
Returns:
The WorkItemType. Its id is the type_id for create_work_item.
Inputs: name (required), project_id (required). Returns: Work item type model.
retrieve_cycleBRead-only
Retrieve a cycle by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project cycle_id: UUID of the cycle
Returns: Cycle object
Inputs: cycle_id (required), project_id (required). Returns: Cycle model.
retrieve_initiativeARead-only
Retrieve an initiative by ID.
Args: initiative_id: UUID of the initiative
Returns: Initiative object
Raises: ToolError: if the initiatives feature is disabled. When disabled, the initiative is an "Initiative" work item - the error gives the steps.
Inputs: initiative_id (required). Returns: Initiative model.
retrieve_intake_work_itemBRead-only
Retrieve an intake work item by work item ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project work_item_id: UUID of the work item (use the issue field from IntakeWorkItem response, not the intake work item ID) params: Optional query parameters as a dictionary (e.g., expand, fields)
Returns: IntakeWorkItem object
Inputs: project_id (required), work_item_id (required), params. Returns: Intake work item model.
retrieve_labelARead-only
Retrieve a label by ID.
Args: project_id: UUID of the project label_id: UUID of the label
Returns: Label object
Inputs: label_id (required), project_id (required). Returns: Label model.
retrieve_milestoneARead-only
Retrieve a milestone by ID.
Args: project_id: UUID of the project milestone_id: UUID of the milestone
Returns: Milestone object
Inputs: project_id (required), milestone_id (required). Returns: Milestone model.
retrieve_moduleCRead-only
Retrieve a module by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project module_id: UUID of the module
Returns: Module object
Inputs: module_id (required), project_id (required). Returns: Module model.
retrieve_pageARead-only
Retrieve a page by ID, including its content (description_html).
Retrieves a project page if project_id is given, otherwise a workspace page. Page bodies can be large; pass max_length (or set the server-side PLANE_PAGES_MAX_CONTENT_LENGTH env default) to bound the returned content.
Args: page_id: UUID of the page project_id: UUID of the project. Omit for a workspace page. max_length: Maximum number of characters of content to return. When the content is longer, the response carries content_truncated=true and total_content_length with the full size.
Returns: Page object; when truncation applies, a dict with the page fields plus content_truncated and total_content_length.
Inputs: page_id (required), max_length, project_id. Returns: result
retrieve_projectCRead-only
Retrieve a project by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project
Returns: Project object
Inputs: project_id (required). Returns: Project model.
retrieve_roleBRead-only
Retrieve a role definition by ID.
Args: role_id: UUID of the role.
Returns: Role (name, slug, namespace).
Inputs: role_id (required). Returns: Workspace or project role definition. The API returns additional fields (``id``…
retrieve_stateARead-only
Retrieve a state by ID.
Args: project_id: UUID of the project state_id: UUID of the state
Returns: State object
Inputs: state_id (required), project_id (required). Returns: State model.
retrieve_work_itemBRead-only
Retrieve a work item by ID.
Args: project_id: UUID of the project work_item_id: UUID of the work item expand: Comma-separated fields to expand (e.g., "assignees,labels,state") fields: Comma-separated fields to include in response external_id: External system identifier for filtering external_source: External system source name for filtering order_by: Field to order results by
Returns: WorkItemDetail object with expanded relationships
Inputs: project_id (required), work_item_id (required), expand, fields, +3 more. Returns: Detailed work item with expanded relationships.
retrieve_work_item_activityARead-only
Retrieve a specific activity for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item activity_id: UUID of the activity
Returns: WorkItemActivity object
Inputs: project_id (required), activity_id (required), work_item_id (required). Returns: Work item activity model.
retrieve_work_item_by_identifierARead-only
Retrieve a work item by its full identifier (project prefix + sequence number).
The identifier must be in PROJECT-N format where PROJECT is the project's identifier string and N is the sequence number. Both parts are required.
Valid sparse fields values include: id, name, sequence_id, priority,
state, project, workspace, parent, assignees, labels, type_id,
start_date, target_date, created_at, updated_at, created_by,
updated_by, is_draft, external_source, external_id, estimate_point.
Use project (not project_id) to get the project UUID.
If you need the project UUID from a short identifier like "SHO",
use list_projects() instead - it returns id and identifier
for every project.
Args: work_item_identifier: Full work item identifier in PROJECT-N format expand: Comma-separated fields to expand (e.g., "assignees,labels,state") fields: Comma-separated sparse fieldset (see valid values above) external_id: External system identifier for filtering external_source: External system source name for filtering order_by: Field to order results by
Returns: WorkItemDetail object with expanded relationships
Inputs: work_item_identifier (required), expand, fields, order_by, +2 more. Returns: Detailed work item with expanded relationships.
retrieve_work_item_commentARead-only
Retrieve a specific comment for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item comment_id: UUID of the comment
Returns: WorkItemComment object
Inputs: comment_id (required), project_id (required), work_item_id (required). Returns: Work item comment model.
retrieve_work_item_linkARead-only
Retrieve a specific link for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item link_id: UUID of the link
Returns: WorkItemLink object
Inputs: link_id (required), project_id (required), work_item_id (required). Returns: Work item link model.
retrieve_work_item_propertyARead-only
Retrieve a work item property by ID.
Args: work_item_property_id: UUID of the property project_id: UUID of the project. Omit for workspace scope. work_item_type_id: UUID of the work item type - omit to use project-level endpoint
Returns: WorkItemProperty object
Inputs: work_item_property_id (required), project_id, work_item_type_id. Returns: Work item property model.
retrieve_work_item_property_optionARead-only
Retrieve a single option from a work item property.
Args: property_id: UUID of the work item property option_id: UUID of the option project_id: UUID of the project. Omit for workspace scope.
Returns: WorkItemPropertyOption object
Inputs: option_id (required), property_id (required), project_id. Returns: Work item property option model.
retrieve_work_item_typeARead-only
Retrieve a work item type by ID.
Args: work_item_type_id: UUID of the work item type project_id: UUID of the project. Omit for workspace scope.
Returns: WorkItemType object
Inputs: work_item_type_id (required), project_id. Returns: Work item type model.
search_pagesARead-only
Search pages by title (and optionally content) with a simple case-insensitive substring match.
Plane has no server-side page search API, so this filters the page list client-side. With search_content=true each candidate page's content is fetched individually (capped at 30 pages) - slower but matches body text.
Args: query: Text to look for (case-insensitive substring). project_id: UUID of the project. Omit to search workspace pages (workspace pages are unavailable on Community Edition). search_content: Also search inside page content, not just titles. max_results: Maximum number of matches to return (default 20).
Returns: List of matches: id, name, project_id, match_field ("name" or "content") and a snippet of the surrounding text.
Inputs: query (required), project_id, max_results, search_content. Returns: result
search_work_itemsARead-only
Search work items by text across a workspace.
Matches on work item name, sequence id, and project identifier (not
description). For structured filtering (priority, state, assignee,
dates, etc.) use list_work_items with a PQL expression.
Args: query: Free-text string matched against name, sequence id, and project identifier expand: Comma-separated list of related fields to expand in response fields: Comma-separated list of fields to include in response external_id: External system identifier for filtering external_source: External system source name for filtering order_by: Field to order results by. Prefix with '-' for descending
Returns: WorkItemSearch object containing search results
Inputs: query (required), expand, fields, order_by, +2 more. Returns: Work item search results.
set_work_item_property_valueAIdempotent
Set (create or update) the value of a custom property on a work item.
Acts as an upsert - creates the value if it does not exist, updates it if it does. For multi-value properties (is_multi=True), replaces all existing values with the new ones.
Value types by property type: TEXT/URL/EMAIL/FILE: string DATETIME: string (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS) DECIMAL: int or float BOOLEAN: true or false OPTION/RELATION (single): UUID string OPTION/RELATION (multi, is_multi=True): list of UUID strings
Args: project_id: UUID of the project work_item_id: UUID of the work item property_id: UUID of the work item property value: The value to set (type depends on the property type - see above) external_id: Optional external identifier for syncing external_source: Optional external source name (e.g. "github", "jira")
Returns: Single WorkItemPropertyValueDetail for non-multi properties, or list of WorkItemPropertyValueDetail for multi-value properties
Inputs: value (required), project_id (required), property_id (required), work_item_id (required), +2 more. Returns: result
transfer_cycle_work_itemsC
Transfer work items from one cycle to another.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project cycle_id: UUID of the source cycle new_cycle_id: UUID of the target cycle to transfer issues to
Inputs: cycle_id (required), project_id (required), new_cycle_id (required).
update_cycleBIdempotent
Update a cycle by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project cycle_id: UUID of the cycle name: Cycle name description: Cycle description start_date: Cycle start date (ISO 8601 format) end_date: Cycle end date (ISO 8601 format) owned_by: UUID of the user who owns the cycle external_source: External system source name external_id: External system identifier timezone: Cycle timezone
Returns: Updated Cycle object
Inputs: cycle_id (required), project_id (required), name, end_date, +6 more. Returns: Cycle model.
update_initiativeAIdempotent
Update an initiative by ID.
Args: initiative_id: UUID of the initiative name: Initiative name description_html: HTML description of the initiative start_date: Initiative start date (ISO 8601 format) end_date: Initiative end date (ISO 8601 format) logo_props: Logo properties dictionary state: Initiative state (DRAFT, PLANNED, ACTIVE, COMPLETED, CLOSED) lead: UUID of the user who leads the initiative
Returns: Updated Initiative object
Raises: ToolError: if the initiatives feature is disabled. When disabled, the initiative is an "Initiative" work item - the error gives the steps.
Inputs: initiative_id (required), lead, name, state, +4 more. Returns: Initiative model.
update_intake_work_itemAIdempotent
Update an intake work item, including triage status.
Status values: -2 = pending (default/unreviewed) -1 = declined 0 = snoozed (requires snoozed_till date) 1 = accepted (converts intake item to active work item) 2 = duplicate (requires duplicate_to work item ID)
Args: project_id: UUID of the project work_item_id: UUID of the work item (use the issue field from IntakeWorkItem response, not the intake work item ID) status: Triage status (-2=pending, -1=declined, 0=snoozed, 1=accepted, 2=duplicate) snoozed_till: ISO 8601 date string, required when status=0 duplicate_to: UUID of the work item this duplicates, required when status=2 source: Source identifier source_email: Source email address
Returns: Updated IntakeWorkItem object
Inputs: project_id (required), work_item_id (required), source, status, +3 more. Returns: Intake work item model.
update_labelAIdempotent
Update a label by ID.
Args: project_id: UUID of the project label_id: UUID of the label name: Label name color: Label color (hex color code) description: Label description parent: UUID of the parent label (for nested labels) sort_order: Sort order for the label external_source: External system source name external_id: External system identifier
Returns: Updated Label object
Inputs: label_id (required), project_id (required), name, color, +5 more. Returns: Label model.
update_milestoneBIdempotent
Update a milestone by ID.
Args: project_id: UUID of the project milestone_id: UUID of the milestone title: Milestone title target_date: Target date for the milestone (ISO 8601 format) external_source: External system source name external_id: External system identifier
Returns: Updated Milestone object
Inputs: project_id (required), milestone_id (required), title, external_id, +2 more. Returns: Milestone model.
update_moduleAIdempotent
Update a module by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project module_id: UUID of the module name: Module name description: Module description start_date: Module start date (ISO 8601 format) target_date: Module target/end date (ISO 8601 format) status: Module status (backlog, planned, in-progress, paused, completed, cancelled) lead: UUID of the user who leads the module members: List of user IDs who are members of the module external_source: External system source name external_id: External system identifier
Returns: Updated Module object
Inputs: module_id (required), project_id (required), lead, name, +7 more. Returns: Module model.
update_projectBIdempotent
Update a project by ID.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project name: Project name description: Project description project_lead: UUID of the project lead user default_assignee: UUID of the default assignee user identifier: Project identifier emoji: Emoji for the project cover_image: Cover image URL or asset ID network: Project visibility (0=secret, 2=public) module_view: Enable module view cycle_view: Enable cycle view issue_views_view: Enable issue views view page_view: Enable page view intake_view: Enable intake view guest_view_all_features: Allow guests to view all features archive_in: Days until auto-archive close_in: Days until auto-close timezone: Project timezone external_source: External system source name external_id: External system identifier is_issue_type_enabled: Enable issue types is_time_tracking_enabled: Enable time tracking default_state: UUID of the default state estimate: Estimate configuration
Returns: Updated Project object
Inputs: project_id (required), name, emoji, network, +20 more. Returns: Project model.
update_project_estimateAIdempotent
Update the estimate for a project.
Args: project_id: UUID of the project name: New name for the estimate description: New description external_id: External system identifier external_source: External system source name
Returns: Updated Estimate object
Inputs: project_id (required), name, description, external_id, +1 more. Returns: Estimate response model. Represents the sizing scale configured for a project (…
update_project_estimate_pointAIdempotent
Update a single estimate point.
Args: project_id: UUID of the project estimate_id: UUID of the estimate estimate_point_id: UUID of the estimate point to update value: New display value (max 20 chars, e.g. "XL", "13") key: New sort key (integer) description: New description external_id: External system identifier external_source: External system source name
Returns: Updated EstimatePoint object
Inputs: project_id (required), estimate_id (required), estimate_point_id (required), key, +4 more. Returns: Estimate point response model. Represents an individual value within an estimat…
update_project_featuresAIdempotent
Update features of a project.
Args: workspace_slug: The workspace slug identifier project_id: UUID of the project modules: Enable/disable modules feature cycles: Enable/disable cycles feature views: Enable/disable views feature pages: Enable/disable pages feature intakes: Enable/disable intakes feature work_item_types: Enable/disable work item types feature
Returns: Updated ProjectFeature object
Inputs: project_id (required), pages, views, cycles, +3 more. Returns: Project feature model.
update_stateBIdempotent
Update a state by ID.
Args: project_id: UUID of the project state_id: UUID of the state name: State name color: State color (hex color code) description: State description sequence: State sequence order group: State group (e.g., backlog, unstarted, started, completed, cancelled) is_triage: Whether this is a triage state default: Whether this is the default state external_source: External system source name external_id: External system identifier
Returns: Updated State object
Inputs: state_id (required), project_id (required), name, color, +7 more. Returns: State model.
update_work_itemAIdempotent
Update a work item by ID.
Args: project_id: UUID of the project work_item_id: UUID of the work item name: Work item name assignees: List of user IDs to assign to the work item labels: List of label IDs to attach to the work item type_id: UUID of the work item type point: Story point value description_html: HTML description of the work item description_stripped: Plain text description. Convenience only - it is wrapped into HTML and stored as description_html (Plane derives description_stripped server-side). Ignored if description_html is set. priority: Priority level (urgent, high, medium, low, none) start_date: Start date (ISO 8601 format) target_date: Target/end date (ISO 8601 format) sort_order: Sort order value is_draft: Whether the work item is a draft external_source: External system source name external_id: External system identifier parent: UUID of the parent work item state: UUID of the state estimate_point: Estimate point value type: Work item type identifier
Returns: Updated WorkItem object
Inputs: project_id (required), work_item_id (required), name, type, +16 more. Returns: Work item model.
update_work_item_commentAIdempotent
Update a comment for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item comment_id: UUID of the comment comment_html: Comment content in HTML format comment_json: Comment content in JSON format access: Access level for the comment (INTERNAL or EXTERNAL) external_source: External system source name external_id: External system identifier
Returns: Updated WorkItemComment object
Inputs: comment_id (required), project_id (required), work_item_id (required), access, +4 more. Returns: Work item comment model.
update_work_item_linkAIdempotent
Update a link for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item link_id: UUID of the link url: Updated URL of the link
Returns: Updated WorkItemLink object
Inputs: link_id (required), project_id (required), work_item_id (required), url. Returns: Work item link model.
update_work_item_propertyAIdempotent
Update a work item property by ID.
Args: work_item_property_id: UUID of the property project_id: UUID of the project. Omit for workspace scope. work_item_type_id: UUID of the work item type - required when project_id is provided display_name: Display name for the property property_type: TEXT | DATETIME | DECIMAL | BOOLEAN | OPTION | RELATION | URL | EMAIL | FILE | FORMULA relation_type: ISSUE | USER - required when updating to RELATION description: Property description is_required: Whether the property is required default_value: Default value(s) for the property settings: Required when changing type to TEXT/DATETIME. TEXT: {"display_format": "single-line"|"multi-line"|"readonly"} DATETIME: {"display_format": "MMM dd, yyyy"|"dd/MM/yyyy"|"MM/dd/yyyy"|"yyyy/MM/dd"} is_active: Whether the property is active is_multi: Whether the property supports multiple values validation_rules: Validation rules dictionary external_source: External system source name external_id: External system identifier
Returns: Updated WorkItemProperty object
Inputs: work_item_property_id (required), is_multi, settings, is_active, +11 more. Returns: Work item property model.
update_work_item_property_optionAIdempotent
Update an option on a work item property.
Args: property_id: UUID of the work item property option_id: UUID of the option project_id: UUID of the project. Omit for workspace scope. name: Display name for the option description: Option description color: Hex color string e.g. "#FF5733" is_default: Whether this is the default option external_source: External system source name external_id: External system identifier
Returns: Updated WorkItemPropertyOption object
Inputs: option_id (required), property_id (required), name, color, +5 more. Returns: Work item property option model.
update_work_item_relation_definitionAIdempotent
Update an existing workspace relation definition.
Args: definition_id: UUID of the relation definition to update. name: New name for this definition. outward: Updated outward label. inward: Updated inward label. is_active: Updated active status. color: Updated hex color code.
Returns: Updated WorkItemRelationDefinition object.
Inputs: definition_id (required), name, color, inward, +2 more. Returns: Work item relation definition response model.
update_work_item_typeAIdempotent
Update a work item type by ID.
Args: work_item_type_id: UUID of the work item type project_id: UUID of the project. Omit for workspace scope. name: Work item type name description: Work item type description project_ids: List of project IDs this type applies to is_active: Whether the type is active external_source: External system source name external_id: External system identifier
Returns: Updated WorkItemType object
Inputs: work_item_type_id (required), name, is_active, project_id, +4 more. Returns: Work item type model.
update_work_logAIdempotent
Update a work log for a work item.
Args: project_id: UUID of the project work_item_id: UUID of the work item work_log_id: UUID of the work log duration: Duration of work in minutes description: Description of the work performed
Returns: Updated WorkItemWorkLog object
Inputs: project_id (required), work_log_id (required), work_item_id (required), duration, +1 more. Returns: Work item work log model.
update_workspace_featuresAIdempotent
Update features of the current workspace.
Args: project_grouping: Enable/disable project grouping feature initiatives: Enable/disable initiatives feature teams: Enable/disable teams feature customers: Enable/disable customers feature wiki: Enable/disable wiki feature pi: Enable/disable PI (Program Increment) feature
Returns: Updated WorkspaceFeature object
Inputs: pi, wiki, teams, customers, +2 more. Returns: Workspace feature model.
upload_work_item_attachment_from_urlA
Fetch a file from a public URL and attach it to a work item.
The MCP server downloads the file server-side and uploads it to Plane via the standard three-step presigned S3 flow. The source URL must be publicly accessible without authentication and must not resolve to a private/internal network address.
Args: project_id: UUID of the project work_item_id: UUID of the work item url: Publicly accessible URL of the file to attach (e.g. a GitHub raw URL, public S3 link, or direct download link) name: Override the filename. Defaults to the filename in the URL path.
Returns: Created attachment metadata: id, name, size, content_type.
Inputs: url (required), project_id (required), work_item_id (required), name. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 142 tools
Most tools target distinct entity-action pairs, with clear separation across projects, work items, states, cycles, modules, pages, and more. Minor overlap exists (e.g., manage_work_item_assignee vs update_work_item's assignees field) but descriptions clarify the differences.
Tool names predominantly follow a verb_noun snake_case pattern (e.g., list_projects, create_state, update_cycle). Some inconsistency occurs with get_ vs retrieve_, and set_ vs create_ for property values, but overall the pattern is predictable.
With 142 tools, the surface is overly large and likely overwhelming for most agents. While Plane is feature-rich, many tools could be consolidated (e.g., manage_X_work_items into update_cycle/module). The count far exceeds practical usability.
The tool set covers virtually all domain entities: projects, work items, states, labels, cycles, modules, pages, work item types, custom properties, relations, initiatives, milestones, intake items, work logs, and roles. Gaps are minimal given the Community Edition limitations.
Maintenance
Related MCP Connectors
MCP server for generating rough-draft project plans from natural-language prompts.
Official Todoist MCP server. Manage tasks and projects. Hosted, no API key needed.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Official Fibery MCP server: query and update your workspace from any AI client via OAuth.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server for the Plane project management platform that enables users to manage workspaces, projects, and work items. It supports full CRUD operations for issues while providing access to cycles, modules, labels, and workflow states.MIT
- AlicenseCqualityDmaintenanceMCP server for Plane integration, enabling AI agents to interact with Plane APIs and services for project management tasks.100MIT
- AlicenseBqualityDmaintenanceAn MCP server that enables LLMs to fully manage a Plane workspace, including projects, work items, states, labels, cycles, modules, comments, and members.38MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for integrating AI agents with the Plane project management platform, providing tools to manage projects, work items, cycles, modules, and more.MIT