plane-ce-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| REDIS_HOST | No | Redis host for token storage (optional, falls back to in-memory) | |
| REDIS_PORT | No | Redis port (optional) | |
| LOG_USER_INFO | No | When true, include user display name (PII) in logs | false |
| PLANE_API_KEY | Yes | API key (workspace settings → API tokens) | |
| PLANE_BASE_URL | Yes | Your Plane API URL (required for self-hosted instances) | https://api.plane.so |
| PLANE_WORKSPACE_SLUG | Yes | Target workspace slug | |
| PLANE_INTERNAL_BASE_URL | No | Internal URL for server-to-server calls (optional) | |
| PLANE_INTERNAL_API_EMAIL | No | Plane account email used by the internal-API adapter for pages tools | |
| PLANE_INTERNAL_API_PASSWORD | No | Plane account password used by the internal-API adapter for pages tools | |
| PLANE_PAGES_MAX_CONTENT_LENGTH | No | Default truncation for retrieve_page content (optional) |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_projectsA | 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). |
| 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 |
| retrieve_projectC | Retrieve a project by ID. Args: workspace_slug: The workspace slug identifier project_id: UUID of the project Returns: Project object |
| update_projectB | 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 |
| delete_projectC | Delete a project by ID. Args: workspace_slug: The workspace slug identifier project_id: UUID of the project |
| 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 |
| get_project_worklog_summaryC | 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 |
| get_project_membersA | 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. |
| update_project_featuresA | 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 |
| get_project_estimateA | 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 |
| list_project_estimate_pointsA | 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 |
| 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 |
| update_project_estimateA | 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 |
| delete_project_estimateB | Delete the estimate for a project. Args: project_id: UUID of the project |
| 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 |
| 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 |
| update_project_estimate_pointA | 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 |
| delete_project_estimate_pointB | 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 |
| list_work_itemsA | 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 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. |
| count_work_itemsA | 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. |
| 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 |
| retrieve_work_itemB | 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 |
| retrieve_work_item_by_identifierA | 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 If you need the project UUID from a short identifier like "SHO",
use 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 |
| update_work_itemA | 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 |
| delete_work_itemC | Delete a work item by ID. Args: project_id: UUID of the project work_item_id: UUID of the work item |
| 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 |
| 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 |
| list_archived_work_itemsA | 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 Returns: Paginated envelope with results, total_count, next_cursor, prev_cursor. |
| 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 |
| search_work_itemsA | 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 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 |
| list_statesA | 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 |
| 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 |
| retrieve_stateA | Retrieve a state by ID. Args: project_id: UUID of the project state_id: UUID of the state Returns: State object |
| update_stateB | 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 |
| delete_stateC | Delete a state by ID. Args: project_id: UUID of the project state_id: UUID of the state |
| list_labelsA | 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 |
| 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 |
| retrieve_labelA | Retrieve a label by ID. Args: project_id: UUID of the project label_id: UUID of the label Returns: Label object |
| update_labelA | 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 |
| delete_labelB | Delete a label by ID. Args: project_id: UUID of the project label_id: UUID of the label |
| list_cyclesA | 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. |
| 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 |
| retrieve_cycleB | 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 |
| update_cycleB | 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 |
| delete_cycleC | Delete a cycle by ID. Args: workspace_slug: The workspace slug identifier project_id: UUID of the project cycle_id: UUID of the cycle |
| 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 |
| list_cycle_work_itemsA | 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 Returns: Paginated envelope with results, total_count, next_cursor, prev_cursor. |
| 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 |
| 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 |
| 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 |
| list_modulesA | 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. |
| 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 |
| retrieve_moduleC | 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 |
| update_moduleA | 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 |
| delete_moduleC | Delete a module by ID. Args: workspace_slug: The workspace slug identifier project_id: UUID of the project module_id: UUID of the module |
| 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 |
| list_module_work_itemsA | 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 Returns: Paginated envelope with results, total_count, next_cursor, prev_cursor. |
| 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 |
| get_meA | Get current user information. Returns: UserLite object containing current user information |
| get_workspace_membersA | 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. |
| get_featuresA | 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. |
| update_workspace_featuresA | 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 |
| get_instance_infoA | 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. |
| list_toolsetsA | 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 |
| list_work_item_commentsB | 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 |
| retrieve_work_item_commentA | 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 |
| 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 |
| update_work_item_commentA | 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 |
| delete_work_item_commentA | 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 |
| list_work_item_linksB | 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 |
| retrieve_work_item_linkA | 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 |
| 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 |
| update_work_item_linkA | 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 |
| delete_work_item_linkB | 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 |
| list_work_item_attachmentsA | 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. |
| get_work_item_attachment_download_urlA | 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. |
| 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. |
| delete_work_item_attachmentA | 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 |
| read_work_item_attachmentA | 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. |
| list_work_item_activitiesB | 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 |
| retrieve_work_item_activityA | 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 |
| list_pagesA | 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) |
| 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 |
| list_work_item_pagesA | 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 |
| detach_page_from_work_itemA | 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) |
| retrieve_pageA | 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. |
| search_pagesA | 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. |
| 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 |
| list_work_item_typesA | List work item types. Omit project_id for workspace-level types. Each result's |
| 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 |
| 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 |
| 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:
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 |
| retrieve_work_item_typeA | 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 |
| update_work_item_typeA | 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 |
| delete_work_item_typeA | 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. |
| list_work_item_propertiesA | List custom work item properties. Scope resolution (highest priority first):
For PQL filtering by name, prefer calling with NO args - one workspace-wide
fetch beats iterating every work item type. Each result includes the
Each result includes:
PQL workflow for filtering by custom property (efficient path):
|
| create_work_item_propertyA | Create a new work item property. Scope resolution:
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 |
| retrieve_work_item_propertyA | 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 |
| update_work_item_propertyA | 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 |
| delete_work_item_propertyA | 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 |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| Plane Query Language (PQL) reference | Full PQL syntax for the `pql` filter on work-item list/count tools. |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Bl4nk44/plane-ce-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server