Skip to main content
Glama

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 stdio

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

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

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

For Claude Code that's one command:

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

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

Run from source

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

HTTP transport (self-hosted, PAT auth)

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

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

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

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

Headers:

  • Authorization: Bearer <PAT_TOKEN> (or x-api-key: <PAT_TOKEN>)

  • X-Workspace-slug: <SLUG>

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

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

Configuration

Variable

Required for

Purpose

PLANE_BASE_URL

all (self-host: required)

Your Plane API URL (default: https://api.plane.so = Cloud)

PLANE_API_KEY

stdio

API key (workspace settings → API tokens)

PLANE_WORKSPACE_SLUG

stdio

Target workspace

PLANE_INTERNAL_BASE_URL

http/sse (optional)

Internal URL for server-to-server calls (e.g. http://plane-api:8000 inside Docker)

PLANE_INTERNAL_API_EMAIL / PLANE_INTERNAL_API_PASSWORD

pages tools

Plane account used by the internal-API adapter (CE has no public pages API); the account needs membership in the relevant projects

PLANE_TOOLSETS

optional (default: all)

Comma-separated tool groups to register: core,comments,pages,types,planning,admin,pql (or all). Loads fewer tool definitions into the client's context - e.g. core is the daily-driver set (~64 tools vs ~142). Call list_toolsets to see active/available groups.

PLANE_MAX_RESPONSE_KB

optional (default: 1024)

Size cap for list_work_items / list_archived_work_items responses. Over the limit the tool returns an actionable error instead of the payload, to protect the client's context window. 0 disables.

PLANE_MAX_RETRIES

optional (default: 2)

Retries after the first attempt for transient Plane API failures (429/503 for any call; 502/504/timeouts for read-only calls only, to avoid duplicate writes). 0 disables.

PLANE_RETRY_BASE_DELAY

optional (default: 0.5)

Base seconds for exponential backoff with jitter between retries (capped at 10s).

PLANE_PAGES_MAX_CONTENT_LENGTH

optional

Default truncation for retrieve_page content

REDIS_HOST / REDIS_PORT

http/sse (optional)

Token storage (falls back to in-memory)

PLANE_OAUTH_PROVIDER_*

http/sse OAuth only

OAuth client credentials and base URL

PLANE_OAUTH_ALLOWED_REDIRECT_URIS

http/sse OAuth (optional)

Comma-separated redirect URI patterns appended to the built-in allowlist

LOG_USER_INFO

optional (default: false)

When true, include user display name (PII) in logs alongside the opaque user id

LOG_PAYLOADS

optional (default: false)

When true, include tool-call payloads (may contain PII / full descriptions) in structured logs. Off by default; enable only for debugging.

Logging

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

Health check

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

Available Tools

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

Projects

Tool Name

Description

list_projects

List all projects in a workspace with optional pagination and filtering

create_project

Create a new project with name, identifier, and optional configuration

retrieve_project

Retrieve a project by ID

update_project

Update a project with partial data

delete_project

Delete a project by ID

get_project_worklog_summary

Get work log summary for a project

get_project_members

Get all members of a project

update_project_features

Update features configuration of a project

manage_project_archive

Archive or unarchive a project

Work Items

Tool Name

Description

list_work_items

List all work items in a project with optional filtering and pagination

create_work_item

Create a new work item with name, assignees, labels, and other attributes

retrieve_work_item

Retrieve a work item by ID with optional field expansion

retrieve_work_item_by_identifier

Retrieve a work item by project identifier and issue sequence number

update_work_item

Update a work item with partial data

delete_work_item

Delete a work item by ID

search_work_items

Search work items across a workspace with query string

count_work_items

Count work items across the workspace with optional grouping

list_archived_work_items

List archived work items in a project with optional PQL filtering

manage_work_item_archive

Archive or unarchive a work item

manage_work_item_assignee

Add or remove a single assignee without replacing the full list

manage_work_item_label

Add or remove a single label without replacing the full list

Cycles

Tool Name

Description

list_cycles

List cycles in a project (set archived=true for archived)

create_cycle

Create a new cycle with name, dates, and owner

retrieve_cycle

Retrieve a cycle by ID

update_cycle

Update a cycle with partial data

delete_cycle

Delete a cycle by ID

manage_cycle_work_items

Add and/or remove work items on a cycle

list_cycle_work_items

List work items in a cycle

transfer_cycle_work_items

Transfer work items from one cycle to another

manage_cycle_archive

Archive or unarchive a cycle

complete_cycle

Complete (close) a cycle by setting its end date to today

Modules

Tool Name

Description

list_modules

List modules in a project (set archived=true for archived)

create_module

Create a new module with name, dates, status, and members

retrieve_module

Retrieve a module by ID

update_module

Update a module with partial data

delete_module

Delete a module by ID

manage_module_work_items

Add and/or remove work items on a module

list_module_work_items

List work items in a module

manage_module_archive

Archive or unarchive a module

Initiatives

Tool Name

Description

list_initiatives

List all initiatives in a workspace

create_initiative

Create a new initiative with name, dates, state, and lead

retrieve_initiative

Retrieve an initiative by ID

update_initiative

Update an initiative with partial data

delete_initiative

Delete an initiative by ID

list_initiative_projects

List projects linked to an initiative

manage_initiative_projects

Link or unlink projects of an initiative

Intake Work Items

Tool Name

Description

list_intake_work_items

List all intake work items in a project with optional pagination

create_intake_work_item

Create a new intake work item in a project

retrieve_intake_work_item

Retrieve an intake work item by work item ID with optional field expansion

update_intake_work_item

Update an intake work item with partial data

delete_intake_work_item

Delete an intake work item by work item ID

Work Item Properties

Tool Name

Description

list_work_item_properties

List work item properties for a work item type

create_work_item_property

Create a new work item property with type, settings, and validation rules

retrieve_work_item_property

Retrieve a work item property by ID

update_work_item_property

Update a work item property with partial data

delete_work_item_property

Delete a work item property by ID

list_work_item_property_options

List options for a work item property

create_work_item_property_option

Create an option on a work item property

retrieve_work_item_property_option

Retrieve a single option from a work item property

update_work_item_property_option

Update an option on a work item property

delete_work_item_property_option

Delete an option from a work item property

get_work_item_property_value

Get the value(s) of a custom property on a work item

set_work_item_property_value

Set (create or update) the value of a custom property on a work item

delete_work_item_property_value

Delete the value(s) of a custom property on a work item

Milestones

Tool Name

Description

list_milestones

List all milestones in a project

create_milestone

Create a new milestone

retrieve_milestone

Retrieve a milestone by ID

update_milestone

Update a milestone by ID

delete_milestone

Delete a milestone by ID

manage_milestone_work_items

Add and/or remove work items on a milestone

list_milestone_work_items

List work items in a milestone

Labels

Tool Name

Description

list_labels

List all labels in a project

create_label

Create a new label

retrieve_label

Retrieve a label by ID

update_label

Update a label by ID

delete_label

Delete a label by ID

States

Tool Name

Description

list_states

List all states in a project

create_state

Create a new state

retrieve_state

Retrieve a state by ID

update_state

Update a state by ID

delete_state

Delete a state by ID

Work Item Comments

Tool Name

Description

list_work_item_comments

List comments for a work item

retrieve_work_item_comment

Retrieve a specific comment for a work item

create_work_item_comment

Create a comment for a work item

update_work_item_comment

Update a comment for a work item

delete_work_item_comment

Delete a comment for a work item

Tool Name

Description

list_work_item_links

List links for a work item

retrieve_work_item_link

Retrieve a specific link for a work item

create_work_item_link

Create a link for a work item

update_work_item_link

Update a link for a work item

delete_work_item_link

Delete a link for a work item

Work Item Types

Tool Name

Description

list_work_item_types

List all work item types in a project

create_work_item_type

Create a new work item type

retrieve_work_item_type

Retrieve a work item type by ID

update_work_item_type

Update a work item type by ID

delete_work_item_type

Delete a work item type by ID

import_work_item_types_to_project

Bulk-link workspace-level work item types to a project

resolve_work_item_type

Find or create a named type for a project, auto-handling workspace vs project scope and import

manage_work_item_type_properties

Attach or detach properties on a work item type in a single call

Work Item Relations

Tool Name

Description

list_work_item_relations

List relations for a work item

create_work_item_relation

Create relations for a work item

remove_work_item_relation

Remove a relation from a work item

Work Item Relation Definitions

Tool Name

Description

list_work_item_relation_definitions

List workspace custom relation definitions

create_work_item_relation_definition

Create a workspace relation definition

update_work_item_relation_definition

Update a relation definition

delete_work_item_relation_definition

Delete a relation definition

Work Item Activities

Tool Name

Description

list_work_item_activities

List activities for a work item

retrieve_work_item_activity

Retrieve a specific activity for a work item

Work Logs

Tool Name

Description

list_work_logs

List work logs for a work item

create_work_log

Create a work log for a work item

update_work_log

Update a work log for a work item

delete_work_log

Delete a work log for a work item

Pages

Tool Name

Description

list_pages

List pages - metadata only (workspace, or a project's if project_id given)

retrieve_page

Retrieve a page incl. content; optional max_length truncation (env default PLANE_PAGES_MAX_CONTENT_LENGTH)

search_pages

Search pages by title, optionally inside content (client-side, case-insensitive)

create_page

Create a workspace or project page

attach_page_to_work_item

Link a page to a work item

detach_page_from_work_item

Remove a page link from a work item

list_work_item_pages

List all pages linked to a work item

Work Item Attachments

Tool Name

Description

list_work_item_attachments

List all attachments for a work item

get_work_item_attachment_download_url

Get a presigned download URL for a work item attachment

read_work_item_attachment

Fetch an attachment's content so the LLM can read or analyze it

upload_work_item_attachment_from_url

Fetch a file from a public URL and attach it to a work item

delete_work_item_attachment

Delete an attachment from a work item

Estimates

Tool Name

Description

get_project_estimate

Get the estimate configuration for a project

create_project_estimate

Create a new estimate for a project

update_project_estimate

Update the estimate for a project

delete_project_estimate

Delete the estimate for a project

link_estimate_to_project

Link an estimate to a project, making it the active estimate system

list_project_estimate_points

List all valid estimate points for a project

create_project_estimate_points

Create estimate points for a project estimate

update_project_estimate_point

Update a single estimate point

delete_project_estimate_point

Delete a single estimate point

Roles

Tool Name

Description

list_roles

List role definitions in the workspace

retrieve_role

Retrieve a role definition by ID

PQL

Tool Name

Description

get_pql_reference

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

Workspaces

Tool Name

Description

get_workspace_members

Get all members of the current workspace

get_features

Get feature flags (workspace, or a project's if project_id given)

update_workspace_features

Update features of the current workspace

Users

Tool Name

Description

get_me

Get current authenticated user information

Instance

Tool Name

Description

get_instance_info

Get edition/version of the connected Plane instance and its known API limitations (e.g. Community Edition)

list_toolsets

List the tool groups (toolsets) this server supports and which are active

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

Development

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

# Tests
pytest

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

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

Attribution & License

MIT License - see LICENSE.

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

Contributing

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

Available Tools

142 tools
attach_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_itemsA
Read-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_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_cycleC
DestructiveIdempotent

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_initiativeA
DestructiveIdempotent

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_itemB
DestructiveIdempotent

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_labelB
DestructiveIdempotent

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_milestoneA
DestructiveIdempotent

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_moduleC
DestructiveIdempotent

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_projectC
DestructiveIdempotent

Delete a project by ID.

Args: workspace_slug: The workspace slug identifier project_id: UUID of the project

Inputs: project_id (required).

delete_project_estimateB
DestructiveIdempotent

Delete the estimate for a project.

Args: project_id: UUID of the project

Inputs: project_id (required).

delete_project_estimate_pointB
DestructiveIdempotent

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_stateC
DestructiveIdempotent

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_itemC
DestructiveIdempotent

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_attachmentA
DestructiveIdempotent

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_commentA
DestructiveIdempotent

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_propertyA
DestructiveIdempotent

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_optionA
DestructiveIdempotent

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_valueA
DestructiveIdempotent

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_definitionA
DestructiveIdempotent

Delete a workspace relation definition.

Args: definition_id: UUID of the relation definition to delete.

Inputs: definition_id (required).

delete_work_item_typeA
DestructiveIdempotent

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_logC
DestructiveIdempotent

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_itemA
DestructiveIdempotent

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_featuresA
Read-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_infoA
Read-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_meA
Read-only

Get current user information.

Returns: UserLite object containing current user information

Inputs: no named parameters. Returns: Lite user information.

get_pql_referenceA
Read-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_estimateA
Read-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_membersA
Read-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_summaryC
Read-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_urlA
Read-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_valueA
Read-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_membersA
Read-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).

list_archived_work_itemsA
Read-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_cyclesA
Read-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_itemsA
Read-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_projectsA
Read-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_initiativesA
Read-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_itemsB
Read-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_labelsA
Read-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_milestonesA
Read-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_itemsC
Read-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_modulesA
Read-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_itemsA
Read-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_pagesA
Read-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_pointsA
Read-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_projectsA
Read-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_rolesA
Read-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_statesA
Read-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_toolsetsA
Read-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_activitiesB
Read-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_attachmentsA
Read-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_commentsB
Read-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_pagesA
Read-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_propertiesA
Read-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):

  1. list_work_item_properties() → all workspace properties, one call

  2. find the property by display_name in-memory → property.id

  3. list_work_items(pql='cf["<property.id>"] = "<option.id>"')

Inputs: params, project_id, work_item_type_id. Returns: result

list_work_item_property_optionsA
Read-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_definitionsA
Read-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_relationsA
Read-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_itemsA
Read-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_typesA
Read-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_logsA
Read-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_attachmentA
Read-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_relationA
DestructiveIdempotent

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_cycleB
Read-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_initiativeA
Read-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_itemB
Read-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_labelA
Read-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_milestoneA
Read-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_moduleC
Read-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_pageA
Read-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_projectC
Read-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_roleB
Read-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_stateA
Read-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_itemB
Read-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_activityA
Read-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_identifierA
Read-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_commentA
Read-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_propertyA
Read-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_optionA
Read-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_typeA
Read-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_pagesA
Read-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_itemsA
Read-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_valueA
Idempotent

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_cycleB
Idempotent

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_initiativeA
Idempotent

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_itemA
Idempotent

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_labelA
Idempotent

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_milestoneB
Idempotent

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_moduleA
Idempotent

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_projectB
Idempotent

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_estimateA
Idempotent

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_pointA
Idempotent

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_featuresA
Idempotent

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_stateB
Idempotent

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_itemA
Idempotent

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_commentA
Idempotent

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_propertyA
Idempotent

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_optionA
Idempotent

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_definitionA
Idempotent

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_typeA
Idempotent

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_logA
Idempotent

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_featuresA
Idempotent

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

    B3.4/5.0

    Scored across 142 tools

    Disambiguation4/5

    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.

    Naming Consistency4/5

    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.

    Tool Count2/5

    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.

    Completeness5/5

    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

    ActivityNo data
    ResponsivenessSyncing

    Related MCP Connectors

    Related MCP Servers