@d4works/mcp-clickup
v0.5.1
Published
MCP server for ClickUp task management
Maintainers
Readme
@d4works/mcp-clickup
MCP (Model Context Protocol) server for ClickUp task management. Allows Claude to read task details from ClickUp and help with implementation.
Features
- Fetch task details (description, comments, attachments, custom fields, etc.)
- Support for multiple task ID formats (URL, custom ID, number)
- Instructions for Claude to analyze tasks before implementation
Configuration
1. Environment Variables
| Variable | Required | Description |
| --------------------- | -------- | ----------------------------------------------------------------------- |
| CLICKUP_API_TOKEN | Yes | Your ClickUp API token |
| CLICKUP_TEAM_ID | Yes | Your ClickUp team/workspace ID |
| CLICKUP_TASK_PREFIX | No | Task prefix for number-only input (e.g., "PROJ") |
| CLICKUP_SPACE_ID | No | Numeric space ID — skips the space lookup done by assign-release |
2. Get Your API Token
- Open ClickUp → Click your avatar → Settings
- Go to Apps section
- Generate or copy your API Token
3. Find Your Team ID
- Open ClickUp → Go to any workspace
- Look at the URL:
https://app.clickup.com/{TEAM_ID}/... - The number in the URL is your Team ID
4. Create MCP Configuration
Create .mcp.json in your project root.
First, store your API token in a local file that's gitignored:
echo "export CLICKUP_API_TOKEN=pk_your_token_here" >> .claude/.env.localThen configure .mcp.json to source this file before running the server:
{
"mcpServers": {
"clickup": {
"command": "bash",
"args": [
"-c",
"export $(cat .claude/.env.local | xargs) && npx -y @d4works/mcp-clickup"
],
"env": {
"CLICKUP_TEAM_ID": "your_team_id",
"CLICKUP_TASK_PREFIX": "PROJ"
}
}
}
}Note: If you have
CLICKUP_API_TOKENexported in your global~/.zshrcor~/.bashrc, you can simplify the command to justnpx -y @d4works/mcp-clickup.
Usage
Ask Claude to work on a task using any of these formats:
> Work on task ABC-123
> Work on task 123
> Work on task https://app.clickup.com/t/12345/ABC-123Claude will:
- Fetch task details from ClickUp
- Analyze the task (description, comments, attachments)
- Propose an implementation plan
- Wait for your approval before writing code
Available Tools
test-connection
Test connection to ClickUp API.
get-task
Get task details from ClickUp (description, status, comments, attachments, custom fields, checklists, etc.).
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or number
get-task-statuses
Get available statuses for a task. Use this before updating status to see valid options.
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or number
set-task-status
Set the status of a ClickUp task. Only used with explicit user confirmation.
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or numberstatus(string, required): New status name (must match one of the available statuses)
get-release-options
Get available Release dropdown options for a task. Use this to see valid values before setting Release.
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or numberfieldName(string, optional): Name of the dropdown field (default: "Release")
set-task-release
Set the Release dropdown value on a ClickUp task. Only used with explicit user confirmation.
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or numberrelease(string, required): Release value to set (must match one of the available options)fieldName(string, optional): Name of the dropdown field (default: "Release")
append-task-description
Append markdown content below the existing description of a ClickUp task. The existing description is always kept — there is no replace mode. Only used with explicit user confirmation.
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or numbercontent(string, required): Markdown content to append below the current description
add-task-comment
Add a comment to a ClickUp task. Only used with explicit user confirmation.
Parameters:
taskId(string, required): Task URL, custom ID (ABC-123), or numbercomment(string, required): The comment text to add to the tasknotifyAll(boolean, optional): Notify all task members about the comment (default: false)
assign-release
Tag one or more tasks with a release version and optionally move them to a status. Only used with explicit user confirmation.
The version is stored as a space tag, not as a dropdown custom field — the public ClickUp API cannot add options to a dropdown, but it can create tags. The tag is created on the space the first time a version is used, then attached to each task.
Parameters:
version(string, required): Release version used verbatim as the tag name — case and spaces matter (e.g."v1.17.4 (100)")taskIds(string[], required, min 1): Task URLs, custom IDs (ABC-123), or numbersstatus(string, optional): Status to set on every task (must match one of the available statuses)tagColor(object, optional):{ bg, fg }as 6-digit hex including#. Applied only when the tag is created for the first time (defaults:#4A78FF/#FFFFFF)
Behavior:
- Idempotent — re-running the same call neither duplicates the space tag nor the tag on a task
- Errors are collected per task, so one bad identifier does not abort the rest of the release; the call is only reported as failed when every task fails
- The space is resolved from the first task that can be read, unless
CLICKUP_SPACE_IDis set. All tasks in one call are expected to live in the same space — a task from another space is reported as failed, because its space does not have the tag
remove-release
The counterpart to assign-release: it detaches a release version tag from tasks instead of attaching it. Use it when a version was tagged by mistake — a failed build that never shipped, a typo in the version, or a re-tag that left both the old and the new version on the task. Only used with explicit user confirmation.
assign-release deliberately never replaces older version tags. Deleting them as a side effect of a write would mean a mis-derived commit range could destroy correct tags, so removal is this separate, explicit tool.
Parameters:
version(string, required): Release version matched verbatim against the tag name — case and spaces matter (e.g."v1.17.4 (101)")taskIds(string[], required, min 1): Task URLs, custom IDs (ABC-123), or numbersdeleteTagIfUnused(boolean, optional, defaultfalse): After removing the tag from the listed tasks, also delete it from the space — but only when no task uses it any more
Behavior:
- By default the tag is only detached from the listed tasks and stays available in the space
- Idempotent — re-running the same call changes nothing and reports every task as
removed: falsewith a reason - A tag that is not on a task is not an error: that task reports
removed: falsewithreason: "tag not present on task"and the rest of the batch continues - A tag that does not exist in the space is not an error either — nothing is changed and the result says so
- Errors are collected per task, so one bad identifier does not abort the rest; the call is only reported as failed when every task fails
Deleting the tag from the space is a separate, off-by-default step because it is irreversible and strips the tag from every task in the space at once. It only happens when all of the following hold, and the result explains which one blocked it otherwise:
- Every task in the call succeeded — an unreadable task might still carry the tag
- A search across the space (including closed and archived tasks) finds no other task using it, after subtracting the tasks this call just untagged
License
MIT
