Plate MCP Server
Quản lý dự án tối giản cho nhóm và tác nhân AI.
Tài liệu
← Docs
MCP Server
Manage your Plate tasks directly from AI assistants — Claude, Cursor, Windsurf, and any MCP-compatible client.
Endpoint https://plate.to/mcp
Setup
The Plate MCP server uses OAuth 2.0 — your AI client handles authentication automatically when you first connect. No API keys needed.
Add this to your MCP configuration file:
{ "mcpServers": { "plate": { "type": "http", "url": "https://plate.to/mcp" } } }
| Client | Config file location |
|---|---|
| Claude Code | .mcp.json in project root, or ~/.claude/.mcp.json globally |
| Claude Desktop | macOS: ~/Library/Application Support/Claude/claude_desktop_config.json |
| Cursor | Settings → Cursor Settings → MCP |
| Windsurf | Windsurf Settings → MCP Servers |
After adding the server, your client will prompt you to authorize via browser. Sign in with your Plate account and choose a scope. To revoke access, go to Workspace Settings → Apps in Plate.
Authentication
Plate uses OAuth 2.0 with PKCE. When you first use a Plate tool, your client opens a browser window where you sign into your Plate account and approve access. You receive an access token (valid 1 hour) and a refresh token (valid 30 days). Refresh is handled automatically — you won't be asked to re-authorize unless the refresh token expires.
Scopes
| Scope | Permissions |
|---|---|
| read | View workspaces, projects, tasks — no changes allowed |
| read write | Full access: view and create/update tasks, projects, and comments |
Tools
Read tools are always available. Write tools require the write scope.
list_workspaces read
Returns all Plate workspaces the authenticated user belongs to.
[{ "id": "ws_abc", "name": "Acme Corp", "urlId": "acme", "taskPrefix": "SCA" }]
list_projects read
Returns all projects in a workspace.
| Parameter | Type | Description |
|---|---|---|
| workspaceId* | string | Workspace ID from list_workspaces |
[{ "id": "proj_xyz", "name": "Backend", "description": null }]
list_sections read
Returns all sections in a project, ordered by position.
| Parameter | Type | Description |
|---|---|---|
| projectId* | string | Project ID from list_projects |
[{ "id": "list_abc", "name": "To Do", "order": 0 }]
list_tasks read
Returns tasks in a project. Excludes completed tasks by default. Also supports looking up a task by its public number (e.g. 42 from SCD-42) — pass workspaceId + number and omit projectId.
| Parameter | Type | Description |
|---|---|---|
| projectIdoptional | string | Project ID. Required unless number is provided. |
| workspaceIdoptional | string | Workspace ID. Required when using number. |
| numberoptional | number | Public task number (digits only — e.g. 42 from SCD-42). When provided, workspaceId is required and projectId is ignored. |
| statusIdoptional | string | Filter by status |
| listIdoptional | string | Filter by section |
| includeCompletedoptional | boolean | Include completed tasks (default: false) |
| limitoptional | number | Max tasks to return (default: 100, max: 500) |
[{ "id": "task_123", "number": 42, "name": "Fix login bug", "isCompleted": false, "statusId": "status_abc", "assigneeId": "user_xyz", "listId": "list_abc", "projectId": "proj_xyz", "workspaceId": "ws_abc", "createdAt": "2025-01-15T10:00:00.000Z" }]
get_task read
Returns full details of a single task, including its rich text description and label list. Accepts three lookup forms:
- Internal ID — pass
taskId(theidfield fromlist_tasks) - Prefixed reference — pass
taskId: "SCD-426"and the server resolves it automatically across all your workspaces - Number — pass
workspaceId+number: 426for a direct lookup in a specific workspace
The response includes two description fields: descriptionText (Markdown string, ready to display) and description (raw Plate.js node array). Use descriptionText for reading and displaying content.
| Parameter | Type | Description |
|---|---|---|
| taskIdoptional | string | Internal task ID or prefixed reference like SCD-426. Omit when using number. |
| workspaceIdoptional | string | Workspace ID. Speeds up number lookup; if omitted, all workspaces are searched. |
| numberoptional | number | Public task number (digits only — e.g. 426 from SCD-426). When provided, taskId is ignored. |
list_comments read
Returns a task's comments, oldest first. Like get_task's description, each comment has contentText (Markdown string, ready to display) and content (raw Plate.js node array). Use contentText for reading.
| Parameter | Type | Description |
|---|---|---|
| taskId* | string | Internal task ID (the id from list_tasks, not the public SCD-XXX number) |
[{ "id": "comment_xyz", "authorId": "user_pasha", "contentText": "Fixed in projectsSaga.ts:287", "content": [ /* Plate nodes */ ], "createdAt": "2026-06-25T12:43:31.401Z" }]
list_members read
Returns all members of a workspace. Use userId as assigneeId when creating or updating tasks.
[{ "userId": "user_abc", "name": "Jane Smith", "email": "[email protected]", "role": "member" }]
list_statuses read
Returns workflow statuses for a workspace. Use the returned id as statusId when creating or updating tasks.
[{ "id": "status_abc", "name": "In Progress", "color": "#4fa3e0", "systemType": null, "order": 1 }]
list_activity read
Task change history over a time range — status changes, assignments, moves, etc. Use it for time-based questions like which tasks were completed last week, or what a person did. Each row gives the task, the status transition, who made the change, and the task's owner and assignee.
| Parameter | Type | Description |
|---|---|---|
| workspaceId* | string | Workspace ID from list_workspaces |
| from | string | Start of range, ISO 8601 (e.g. 2026-06-01) |
| to | string | End of range, ISO 8601 |
| actorId | string | Only changes made by this userId (from list_members) |
| type | string | task_status_changed, or completed for transitions into a Done status |
| projectId | string | Limit to one project |
| limit | number | Max rows (default 100, max 500) |
[{ "at": "2026-06-05T14:12:00.000Z", "type": "task_status_changed", "task": "SCD-42", "taskName": "Review API docs", "change": "In Progress → Done", "completed": true, "actor": "Pasha", "owner": "Karl", "assignee": "Pasha" }]
create_task write
Creates a new task in a project section. Returns the new task ID and its auto-assigned number.
| Parameter | Type | Description |
|---|---|---|
| projectId* | string | Project ID |
| listId* | string | Section ID from list_sections |
| name* | string | Task name |
| statusIdoptional | string | Initial status ID |
| assigneeIdoptional | string | Assignee user ID |
{ "id": "task_456", "number": 43 }
Free plan: max 300 tasks per workspace. Pro: unlimited.
update_task write
Updates one or more fields on a task. Only the fields you provide are changed.
| Parameter | Type | Description |
|---|---|---|
| taskId* | string | Task ID |
| nameoptional | string | New task name |
| statusIdoptional | string | New status ID. Also updates isCompleted. |
| assigneeIdoptional | string | null | New assignee. Pass null to unassign. |
| listIdoptional | string | Move task to a different section. Must belong to the same project. |
| descriptionoptional | string | New description. Markdown supported. |
{ "id": "task_123" }
complete_task write
Marks a task as completed or re-opens it. Automatically sets the status to the system "done" or "todo" status.
| Parameter | Type | Description |
|---|---|---|
| taskId* | string | Task ID |
| isCompletedoptional | boolean | true to complete, false to reopen (default: true) |
{ "id": "task_123", "isCompleted": true }
delete_task write
Permanently deletes a task. Comments and attachments are removed automatically.
| Parameter | Type | Description |
|---|---|---|
| taskId* | string | Task ID |
{ "id": "task_abc", "deleted": true }
create_project write
Creates a new project with a default "To Do" section. If a project with the same name already exists in the workspace, returns the existing project instead of creating a duplicate — check created in the response to distinguish the two cases. defaultListId is null if the existing project has no sections.
| Parameter | Type | Description |
|---|---|---|
| workspaceId* | string | Workspace ID |
| name* | string | Project name |
| descriptionoptional | string | Project description (plain text) |
{ "id": "proj_new", "defaultListId": "list_new", "created": true }
Free plan: max 3 projects per workspace. Pro: unlimited.
update_project write
Renames a project or updates its description.
| Parameter | Type | Description |
|---|---|---|
| projectId* | string | Project ID |
| nameoptional | string | New project name |
| descriptionoptional | string | null | New description, or null to clear |
{ "id": "proj_abc" }
create_section write
Creates a new section in a project. If a section with the same name already exists in the project, returns the existing section instead of creating a duplicate — check created in the response to distinguish the two cases.
| Parameter | Type | Description |
|---|---|---|
| projectId* | string | Project ID |
| name* | string | Section name |
{ "id": "section_abc", "created": true }
update_section write
Renames a section.
| Parameter | Type | Description |
|---|---|---|
| sectionId* | string | Section ID |
| name* | string | New section name |
{ "id": "section_abc" }
create_comment write
Adds a comment to a task. The comment is posted as the authenticated user.
| Parameter | Type | Description |
|---|---|---|
| taskId* | string | Task ID |
| text* | string | Comment text. Markdown supported. |
{ "id": "comment_abc" }
delete_comment write
Deletes a comment from a task.
| Parameter | Type | Description |
|---|---|---|
| commentId* | string | Comment ID |
{ "id": "comment_abc", "deleted": true }
Batch Tools
Batch tools let you create, update, or delete multiple items in a single call — reducing the number of confirmation prompts in AI clients that ask per-tool-call.
create_tasks write
Creates multiple tasks in a project atomically. If any validation fails, nothing is created. Maximum 50 tasks per call.
| Parameter | Type | Description |
|---|---|---|
| projectId* | string | Project ID |
| listId | string | Default section ID (used when a task omits its own listId) |
| tasks* | array (1–50) | Tasks to create. Each item: name (required), listId, assigneeId, statusId, description (markdown), dueDate |
{ "items": [{ "id": "task_abc", "number": 42, "name": "Task A", "listId": "list_xyz", "projectId": "proj_1", "workspaceId": "ws_1" }] }
update_tasks write
Updates multiple tasks atomically. Maximum 50 tasks per call.
| Parameter | Type | Description |
|---|---|---|
| tasks* | array (1–50) | Tasks to update. Each item: taskId (required), then any of: name, listId, assigneeId, statusId, description (markdown), dueDate |
{ "items": [{ "id": "task_abc" }] }
complete_tasks write
Marks multiple tasks as completed (or reopens them). Already-completed tasks are left as-is. Maximum 100 tasks per call.
| Parameter | Type | Description |
|---|---|---|
| taskIds* | array (1–100) | Internal task IDs to complete |
| isCompleted | boolean | true to complete, false to reopen (default: true) |
{ "items": [{ "id": "task_abc", "isCompleted": true }] }
delete_tasks write
Permanently deletes multiple tasks. All tasks are validated before any are deleted. Maximum 50 tasks per call.
| Parameter | Type | Description |
|---|---|---|
| taskIds* | array (1–50) | Internal task IDs to delete |
{ "items": [{ "id": "task_abc", "deleted": true }] }
create_sections write
Creates multiple sections in a project. Sections with duplicate names are returned as-is (created: false). Maximum 30 sections per call.
| Parameter | Type | Description |
|---|---|---|
| projectId* | string | Project ID |
| sections* | array (1–30) | Sections to create. Each item: name (required) |
{ "items": [{ "id": "list_abc", "name": "Backlog", "created": true }] }
update_sections write
Renames multiple sections atomically. Maximum 30 sections per call.
| Parameter | Type | Description |
|---|---|---|
| sections* | array (1–30) | Sections to update. Each item: sectionId (required), name (required) |
{ "items": [{ "id": "list_abc" }] }
create_comments write
Adds multiple comments to tasks. Maximum 50 comments per call.
| Parameter | Type | Description |
|---|---|---|
| comments* | array (1–50) | Comments to create. Each item: taskId (required), text (required, markdown) |
{ "items": [{ "id": "comment_abc", "taskId": "task_xyz" }] }
delete_comments write
Permanently deletes multiple comments. All comments are validated before any are deleted. Maximum 50 comments per call.
| Parameter | Type | Description |
|---|---|---|
| commentIds* | array (1–50) | Comment IDs to delete |
{ "items": [{ "id": "comment_abc", "deleted": true }] }
Text Formatting
The description field in update_task and the text field in create_comment accept markdown. It is converted to rich text and rendered in the Plate editor.
| Syntax | Result |
|---|---|
| # Heading | Heading 1 |
| ## Heading | Heading 2 |
| ### Heading | Heading 3 |
| - item or * item | Bullet list item |
| 1. item | Numbered list item |
| > text | Blockquote |
| **text** | Bold |
| *text* | Italic |
| ***text*** | Bold + italic |
| ~~text~~ | Strikethrough |
| `text` | Inline code |
Blank lines separate blocks. Consecutive plain lines without a blank line between them are merged into a single paragraph.
Example description
"## Steps to reproduce\n\n- Open settings\n- Click Profile\n\nExpected: profile page opens\nActual: 404 error"
Renders as:
Heading 2: "Steps to reproduce"
Bullet: "Open settings"
Bullet: "Click Profile"
Paragraph with bold "Expected:" and "Actual:" inline
Errors
All tools throw a descriptive error string on failure. Common causes:
| Error message | Cause |
|---|---|
| Access denied or workspace not found | The authenticated user is not a member of the requested workspace |
| Task not found | Invalid task ID, or task belongs to a different workspace |
| Project not found | Invalid project ID |
| Section not found | Invalid section ID, or section belongs to a different project |
| Free plan limit reached: 300 tasks maximum | Workspace is on the free plan and has reached the task limit |
| Free plan limit reached: 3 projects maximum | Workspace is on the free plan and has reached the project limit |
Questions? Write to us at [email protected]