内容
# clickup-mcp
[](https://github.com/darthapple/clickup-mcp/actions/workflows/ci.yml)
[](https://github.com/darthapple/clickup-mcp/releases/latest)
[](go.mod)
[](LICENSE)
一个本地的MCP服务器(标准输入输出传输),暴露了ClickUp REST API v2(以及v3聊天和文档API)作为MCP工具,构建于[`mark3labs/mcp-go`](https://github.com/mark3labs/mcp-go)之上。
## 调用者需知的行为注意事项
每个工具的完整行为都在其自身的`description`字段(以及每个参数的`description`字段)中记录——这是MCP客户端/代理实际看到的真实来源。下面列出的项目是跨工具的常见模式,值得了解,因为它们每个都影响多个工具,并且很容易在隔离的情况下阅读一个工具的模式时忽略:
- **日期/时间是纯UTC字符串**,不是毫秒级时间戳:`"YYYY-MM-DD HH:MM:SS"`表示精确的时刻,或`"YYYY-MM-DD"`表示仅需日期(`due_date`/`start_date`)。持续时间字段(`duration`,`duration_ms`)是毫秒级时间戳,因为它们是时间长度,而不是时间点。
- **自定义任务ID(`"CT-123"`样式)仅适用于`clickup_get_task`**。其他任务相关的工具(更新、删除、评论、检查清单、自定义字段、依赖关系、链接、列表成员)仅接受ClickUp的内部任务ID,如果使用自定义ID则返回404错误——请先使用`clickup_get_task`解析。
- **`clickup_update_doc_page`默认`content_edit_mode`为`"replace"`**,省略时静默覆盖整个页面内容,而不是追加。请在添加现有内容时显式传递`content_edit_mode`。
- **多个工具在省略筛选器时静默缩小范围**,而不是报错:`clickup_list_time_entries`默认过去30天和调用令牌的用户;要查看完整或聚合视图,请使用`clickup_get_list_time_report`/`clickup_get_user_time_report`而不是手动组装。
- **一些列表样式的工具在服务器端仅限一页**,没有信号表明存在更多数据:评论列表工具(`clickup_list_task_comments`等)和`clickup_search_docs`(50文档限制)。`clickup_list_tasks`/`clickup_search_tasks`/`clickup_get_view_tasks`支持分页,但每次调用仅限一页——调用者必须手动增加`page`参数。
- **访客管理和工作区用户管理员工具仅适用于企业计划**,在ClickUp API层面(邀请/更新/删除工作区用户,所有访客邀请/权限工具)——非企业工作区会收到预期的4xx错误,与ClickUp网页UI允许的操作无关。
- **模板ID(`template_id`,用于`clickup_create_*_from_template`工具)无法通过此服务器发现**——没有模板列表工具;请在ClickUp网页应用中找到ID。
## 环境变量
必需:
- `CLICKUP_API_TOKEN` — ClickUp个人API令牌(以`pk_`开头)。
- `CLICKUP_TEAM_ID` — 您的ClickUp工作区ID,用于需要工作区ID的工具的默认设置。
可选:
- `CLICKUP_API_BASE_URL`(默认为`https://api.clickup.com/api/v2`)
- `CLICKUP_API_BASE_URL_V3`(默认为`https://api.clickup.com/api/v3`)
- `CLICKUP_HTTP_TIMEOUT`(默认为`30s`)
- `CLICKUP_MAX_RETRIES`(默认为`4`,适用于429/5xx响应)
- `CLICKUP_E2E_SPACE_ID` — 仅需运行真正的端到端测试(见下文)。必须指向专用于测试固件的ClickUp空间:测试套件在每次运行中创建和删除真实的列表/任务/评论/检查清单。
## 构建
```sh
# 本地二进制文件,仅用于本地开发/测试:
go build -o bin/clickup-mcp ./cmd/clickup-mcp
```
`bin/` 目录被git忽略。
## 测试
共有四个层级,从最快/最便宜到最真实。`justfile` 包装了所有这些层级——运行 `just`(无参数)列出所有配方。
| 层级 | 命令 | 是否调用真实的ClickUp? | 证明内容 |
| --- | --- | --- | --- |
| 单元测试 | `just test-clickup`,`just test-tools` | 否 | 每个REST客户端方法/MCP工具处理程序在隔离情况下是否正确运行,对抗一个伪造的`httptest`服务器,其固件是我们自己编写的。 |
| 集成测试 | `just test-integration` | 否 | 完整的`RegisterAll -> server.MCPServer -> JSON-RPC -> handler`管道是否正确连接——仍然对抗一个伪造的服务器,因此无法捕获对ClickUp实际行为的错误假设。 |
| **端到端测试** | `just test-e2e` | **是** | 真实的测试:创建/获取/更新/删除生命周期在可丢弃的沙盒列表(由测试套件本身创建和销毁)中运行,对ClickUp的实际响应进行断言——不是我们编造的固件。这是回答我们如何知道ClickUp假设正确的层级。 |
| 烟雾测试 | `just smoke` | 是 | 快速的只读预检(“我们能否认证并列出事物”),可以在**任何**真实工作区中安全运行,无需设置。比端到端测试更浅。 |
普通的 `go test ./...`(或 `go vet ./...`,`gofmt -l .`)仅运行单元测试和集成测试——无需秘密,无需网络,CI(`.github/workflows/ci.yml`)在每次推送/拉取请求时运行。
**端到端测试**(`cmd/clickup-mcp/e2e_test.go`,构建标签`e2e`)和**烟雾测试**(`cmd/clickup-mcp/smoke_test.go`,构建标签`smoke`)都通过编译后的二进制文件运行,并调用真实的ClickUp API,因此它们被排除在CI(无ClickUp秘密存储)之外,只能在本地运行:
```sh
just test-e2e # 需要 CLICKUP_API_TOKEN, CLICKUP_TEAM_ID, CLICKUP_E2E_SPACE_ID
just smoke # 需要 CLICKUP_API_TOKEN, CLICKUP_TEAM_ID
```
端到端测试修改真实数据(仅在其自己的可丢弃的沙盒列表中)——永远不要将 `CLICKUP_E2E_SPACE_ID` 指向您用于实际工作的工作空间。烟雾测试从不创建/更新/删除任何内容,因此它对您的主工作空间是安全的。
## 版本发布
`main`分支上的每次推送,如果CI通过,则检查自上一次发布标签以来是否有[Conventional Commits](https://www.conventionalcommits.org/)(`feat:`/`fix:`/重大变更(`!:`或`BREAKING CHANGE:`页脚)提交主题,如果找到任何,则:
1. 计算下一个semver标签(重大变更→主版本号,`feat:`→次版本号,`fix:`→补丁版本号)并推送它。
2. 创建一个GitHub发布,附带自动生成的注释。
3. 为`linux/amd64`、`linux/arm64`、`darwin/amd64`、`darwin/arm64`和`windows/amd64`交叉编译二进制文件,并将每个文件作为原始(未压缩)资产上传——不需要Go工具链即可使用。
没有匹配的提交→没有发布;工作流直接退出。
每个二进制文件都以两个名称上传:
- `clickup-mcp-vX.Y.Z-<os>-<arch>` — 固定为该确切版本。
- `clickup-mcp-<os>-<arch>` — 在每次发布时重新上传(覆盖),因此始终反映GitHub当前标记为**最新**版本的内容。
要始终获取适用于某个平台的最新构建,无需知道当前版本:
```sh
curl -L -o clickup-mcp \
https://github.com/darthapple/clickup-mcp/releases/latest/download/clickup-mcp-linux-amd64
chmod +x clickup-mcp
```
要固定到确切的版本,请使用该版本标签下的版本资产名称:
```sh
curl -L -o clickup-mcp \
https://github.com/darthapple/clickup-mcp/releases/download/v1.2.3/clickup-mcp-v1.2.3-linux-amd64
chmod +x clickup-mcp
```
(Windows资产有`.exe`后缀,例如`clickup-mcp-windows-amd64.exe`。)
`clickup-mcp --version`打印正在运行的二进制文件的版本——在构建时通过`-ldflags "-X main.version=vX.Y.Z"`设置;本地`go build`无此标志,报告为`dev`。
## 连接到MCP客户端
以下每个MCP客户端都需要两样东西:`clickup-mcp`二进制文件的路径(从[发布](#发布)中下载,或自己使用`go build`编译),以及`CLICKUP_API_TOKEN`/`CLICKUP_TEAM_ID`作为环境变量传递——MCP客户端以子进程启动并注入环境变量,因此它们不需要预先在您的shell中设置。
### Claude Code
```sh
claude mcp add clickup --scope user \
--env CLICKUP_API_TOKEN=pk_xxx \
--env CLICKUP_TEAM_ID=xxxxxxxx \
-- /path/to/clickup-mcp
```
`--scope user`使其在每个项目中都可用;使用 `--scope project`将其写入`.mcp.json`并通过git与团队共享。可以使用`claude mcp list` / `claude mcp get clickup` / `claude mcp remove clickup`进行管理。
### Claude Desktop
直接编辑配置文件——macOS上的`~/Library/Application Support/Claude/claude_desktop_config.json`,Windows上的`%APPDATA%\Claude\claude_desktop_config.json`:
```json
{
"mcpServers": {
"clickup": {
"command": "/path/to/clickup-mcp",
"env": {
"CLICKUP_API_TOKEN": "pk_xxx",
"CLICKUP_TEAM_ID": "xxxxxxxx"
}
}
}
}
```
编辑后重启Claude Desktop。
### Cursor / Windsurf / 任何使用`mcp.json`样式配置的客户端
大多数其他MCP客户端(Cursor的`.cursor/mcp.json`,Windsurf的`~/.codeium/windsurf/mcp_config.json`等)接受相同的格式:
```json
{
"mcpServers": {
"clickup": {
"command": "/path/to/clickup-mcp",
"args": [],
"env": {
"CLICKUP_API_TOKEN": "pk_xxx",
"CLICKUP_TEAM_ID": "xxxxxxxx"
}
}
}
}
```
查看特定客户端的文档以获取确切的配置文件位置和键名(如果此处未列出)。
### 始终运行最新的版本
MCP客户端需要一个字面文件系统路径,而不是URL,因此“始终最新”意味着将二进制文件重新获取到固定路径,而不是更改配置:
```sh
curl -sL -o ~/.local/bin/clickup-mcp \
https://github.com/darthapple/clickup-mcp/releases/latest/download/clickup-mcp-<os>-<arch>
chmod +x ~/.local/bin/clickup-mcp
```
(`<os>`/`<arch>`根据[发布](#发布)部分上述内容,例如`darwin-arm64`,`linux-amd64`。)将每个客户端指向`~/.local/bin/clickup-mcp`;重新运行该`curl`行以更新时,只需更改配置即可。