ticktick-mcp
ticktick-mcp
用于 TickTick 任务管理的 MCP 服务器。通过 TickTick v2 API 创建、更新、完成、移动和筛选任务,具备字段保留更新、星期几日期验证、写后读验证和幂等完成跟踪功能。
专为 Claude Code 及其他 MCP 客户端设计。
非官方项目。与 TickTick Ltd. 无关联。基于 ticktick-py(MIT)构建。
功能特性
完整任务生命周期 —— 创建、更新、完成、移动、设为子任务和删除
字段保留更新 ——
ticktick_update_task会重新获取任务,并且只叠加你设置的字段,因此 API 永远不会清除你省略的字段星期几验证 —— 任何设置日期的调用都必须确认星期几,在差一天的日期错误到达服务器之前就将其捕获
写后读验证 —— 创建/更新会重新读取任务,当服务器回显不一致时显示
_verification_warnings紧凑列表 —— 列表工具默认返回精简视图,让大型项目保持在 MCP 结果大小上限以内(见下文)
新鲜读取 —— 读取工具按需重新同步服务器状态,因此其他设备上 TickTick 应用所做的编辑无需重启即可显示出来
完成跟踪 —— 将已完成任务标记为已处理,以便智能体对每个任务恰好审查一次
Related MCP server: ticktick-mcp-server
环境要求
Python 3.13+
uv(推荐——见下方安装说明)
一个 TickTick 账户
一个已注册的 TickTick 应用,用于获取 OAuth 凭据(免费——developer.ticktick.com)
安装
git clone https://github.com/partymola/ticktick-mcp
cd ticktick-mcp
uv sync这会创建一个 .venv,并根据 uv.lock 安装,得到位于 .venv/bin/ticktick-mcp 的控制台脚本,在 Windows 上则是 .venv\Scripts\ticktick-mcp。下面每条命令都以 POSIX 方式引用它。
pip install . 也可以。此服务器所需的 ticktick-py 分支以直接 git 引用形式固定在 dependencies 中,pip 和 uv 都会遵循;推荐使用 uv sync,因为它安装的是 uv.lock 中的精确版本,而不是重新解析依赖。
凭据
TickTick 登录需要两样东西:一个 OAuth 应用(客户端 ID + 密钥)和你自己的账户登录信息。
在 developer.ticktick.com 注册一个应用。将 重定向 URI 设置为
http://localhost:8080/redirect。记下 客户端 ID 和 客户端密钥。将模板复制到服务器读取的目录中,然后填写:
mkdir -p ~/.config/ticktick-mcp && cp .env.example ~/.config/ticktick-mcp/.envTICKTICK_CLIENT_ID=your_client_id TICKTICK_CLIENT_SECRET=your_client_secret TICKTICK_REDIRECT_URI=http://localhost:8080/redirect TICKTICK_USERNAME=your_ticktick_email TICKTICK_PASSWORD=your_ticktick_password此文件以明文形式保存你的账户密码,而服务器不会创建它,所以请自行收紧权限。在 POSIX 上:
chmod 700 ~/.config/ticktick-mcp chmod 600 ~/.config/ticktick-mcp/.env这些是 POSIX 模式位,在 Windows 上它们不起作用:那里的访问权限遵循文件从其父目录继承的 ACL。此处没有记录这两条命令的 Windows 等效命令。
旁边的两个令牌文件在创建时仅所有者可读,服务器创建的配置目录也是如此——但如果是服务器发现时已存在的配置目录,则保持原样。这些同样是 POSIX 模式,在 Windows 上也会设置,但在那里它们并不会限制谁能读取什么。
在注册服务器之前,先在终端中授权一次:
.venv/bin/ticktick-mcp auth它会打开浏览器,要求你粘贴回落地页的 URL,然后退出。令牌会作为 .token-oauth 缓存在你的 .env 旁边,之后每次启动都会复用。TickTick 不签发刷新令牌,因此令牌过期时需要重来一次——再次运行同一条命令即可。
不要让这一步发生在 MCP 服务器内部。该提示会从标准输入读取,而对 stdio 服务器来说,标准输入就是 JSON-RPC 通道,因此未授权状态下的第一次工具调用会在主机上打开浏览器并阻塞。在容器中它根本无法完成——请先在主机上运行 auth,再把配置目录挂载进去。
用户名/密码部分无需单独步骤:服务器会在第一次工具调用时惰性登录,并将该会话令牌缓存为 .token-v2,因此不会在每次启动时重新提交你的凭据。
服务器按以下顺序查找 .env:先是 --dotenv-dir <path> 参数,然后是 TICKTICK_MCP_DOTENV_DIR 环境变量,最后是 ~/.config/ticktick-mcp/。如果没有找到 .env,它会直接回退到 TICKTICK_* 环境变量,这对容器/CI 使用很方便。
隐私与非官方 API
你的 TickTick 凭据只存在于本地 .env(或环境中),并且只发送给 TickTick 自己的服务器——绝不会发送给开发者或任何第三方。服务器只读写你自己的账户。
此服务器使用 TickTick 的非官方 v2 API(通过 ticktick-py),而不是官方 Open API。这是一个刻意的选择:官方 API 没有列出已完成任务的端点、没有标签,也没有跨项目任务列表——而这些都是此服务器所依赖的。完整理由、风险权衡以及会促使我们重新考虑的条件,请参见 docs/why-not-the-official-api.md。
注册到 Claude Code
claude mcp add -s user ticktick -- /path/to/ticktick-mcp/.venv/bin/ticktick-mcp --dotenv-dir /path/to/config如果你的 .env 位于 ~/.config/ticktick-mcp/,或者你通过环境提供 TICKTICK_* 变量,那么 --dotenv-dir 是可选的。
然后可以这样问 Claude:
“我这周的 TickTick 列表上有什么?”
“添加一个任务:周五早上 9 点给牙医打电话。”
“把杂货采购任务标记为完成。”
“把预算任务移到 Finance 项目。”
Docker
镜像发布到 ghcr.io/partymola/ticktick-mcp。标签带有 v 前缀(:vX.Y.Z),:latest 跟随最新发布版本。
先在装有浏览器的机器上授权,然后再挂载该目录。 这是唯一途径,即使使用 docker run -it 也是如此:底层库会自己打开浏览器,而且绝不打印 URL,因此从没有浏览器的容器中无法复制出任何内容。然后它会在标准输入上等待该 URL,而对 stdio 服务器来说,标准输入就是 JSON-RPC 通道——所以,针对没有缓存令牌的目录启动的容器也不会干净利落地失败,它会继续消耗你客户端的请求,等待永远不会到来的输入。
授权需要源码安装(安装)以及凭据中提到的凭据——没有可用来运行它的已发布包。不要 pip install ticktick-mcp: PyPI 上的这个名字属于一个无关项目,其描述几乎相同。
.venv/bin/ticktick-mcp auth # once, on the host, in a terminal
claude mcp add -s user ticktick -- \
docker run --rm -i --user $(id -u):$(id -g) \
-v ~/.config/ticktick-mcp:/data \
ghcr.io/partymola/ticktick-mcp:latest-i 是必需的——服务器通过 stdin 和 stdout 进行 JSON-RPC 通信。
--user 之所以存在,是因为容器默认以 root 身份运行,它写入挂载目录的任何内容都会变成 root 所有——之后主机端的 ticktick-mcp 就无法再更新其会话令牌缓存,并在每次启动时回退到受限速的登录。你之后还会在主机上运行它:OAuth 令牌无法刷新,因此到期时需要再次运行 auth。
挂载一个已经授权的目录,绝不要挂载空卷。 /data 保存 .env、缓存的 OAuth 令牌、v2 会话令牌和完成跟踪数据库。全新卷中这些一个都没有,而密码登录回退会被限速,导致 15-30 分钟的锁定。
如果你完全不想在磁盘上保留 .env,也可以改为通过环境变量传递凭据。挂载仍然是必需的——它保存的是令牌缓存,而不仅仅是 .env:
docker run --rm -i --user $(id -u):$(id -g) \
-v ~/.config/ticktick-mcp:/data \
-e TICKTICK_CLIENT_ID -e TICKTICK_CLIENT_SECRET \
-e TICKTICK_USERNAME -e TICKTICK_PASSWORD \
ghcr.io/partymola/ticktick-mcp:latest逐个列出变量名而不带值,会从你的 shell 中原样传递,因此命令或 shell 历史中不会出现任何机密。这些覆盖已挂载的 .env:文件加载时不使用 override,因此环境中已有的任何内容都会优先。授权仍然需要这些变量在主机上导出,因为 auth 同样没有 .env 可读。
CLI
ticktick-mcp Start the MCP server (stdio transport)
ticktick-mcp --dotenv-dir PATH Directory holding the .env file
ticktick-mcp --version Print the installed package versionauth 是仅有的另一个子命令,它的存在是为了让浏览器步骤在终端中发生,而不是在服务器内部。所有任务操作都通过下面的 MCP 工具进行。
MCP 工具
工具 | 描述 |
| 创建任务,保留日期/提醒/优先级/时区字段;如果没有设置截止日期,则发出警告(因为没有截止日期就不会触发提醒) |
| 通过只把你设置的字段叠加到当前服务器对象上来更新任务(省略的字段永远不会被清除) |
| 将任务标记为完成并重新验证;区分循环任务向前滚动与正常完成 |
| 按 ID 删除一个或多个任务 |
| 将任务移动到另一个项目 |
| 将一个任务嵌套为同一项目中另一个任务的子任务 |
| 列出项目中的所有未完成任务(紧凑或完整) |
| 按项目、优先级、标签、状态以及截止/完成日期窗口的任意组合查找任务 |
| 按完整 ID 查找任何任务、项目或标签 |
| 从本地状态导出所有项目或所有标签 |
| 强制立即从服务器刷新本地状态 |
| 列出项目中最近完成但尚未标记为已处理的任务 |
| 记录已完成任务已被审查,将其排除在未来的检查之外 |
| 将 ISO 8601 日期时间 + IANA 时区转换为 TickTick 的传输格式 |
项目:名称或 ID
每个接受项目 ID 的工具也接受项目的名称——ticktick_create_task、ticktick_get_tasks_from_project、ticktick_update_task、ticktick_move_task、ticktick_delete_tasks、ticktick_filter_tasks,以及两个完成跟踪工具:
ticktick_create_task(title="Renew insurance", project_id="Home Admin")名称匹配不区分大小写,并忽略周围空白,"Inbox" 会解析到你的收件箱。ID 继续按原样工作并且始终优先,所以任何现在能用的用法都不会改变。
唯一新增的错误是歧义:如果两个项目同名,调用会失败,并同时报出两个 ID,而不是二选一——因为猜测会把任务放到你根本不会想到去找的地方。服务器无法解析的其他任何内容都会原封不动地传给 API,和之前完全一样。
这两个完成追踪工具是例外:它们会拒绝一个无法确认的项目引用,而不是继续传递下去,因为该引用正是它们本地数据库的写入键。一个无法解析的引用会写入一行之后按 ID 查找也无法找到的记录。如果项目列表无法刷新以进行核查,它们会如实说明(outcome: "project_list_unverifiable"),而不是声称该项目不存在。
列出任务:紧凑输出为默认
返回列表的工具 ticktick_get_tasks_from_project 和 ticktick_filter_tasks 默认使用 detail="compact"。紧凑输出保留与浏览相关的字段(id、projectId、title、dueDate、startDate、priority、status、isAllDay、timeZone、tags),外加一个 contentPreview(content 的前约 200 个字符),并丢弃占用较大的 content/desc/checklist items 数据块以及庞大的同步元数据。这让大型项目保持在 com生成 MKP result 大小上限以下,客户端无需将结果溢出到磁盘。关键字搜索仍然基于 title 和 contentPreview 进行。
需要完整对象?传入
detail="full"。需要某个任务的完整内容?使用
ticktick_get_by_id。编辑任务: 先用
ticktick_get_by_id获取完整对象,再通过ticktick_update_task将所有字段传回。TickTick API 会清除任何更新中省略的字段,因此紧凑输出绝不能用于更新操作。
如果紧凑结果仍然超过大小预算,则返回最早到期的任务,并由最后的 _truncation_note 元素报告省略了多少——没有任何内容会被静默丢弃。其余任务可用范围更窄的 ticktick_filter_tasks 查询、detail="full" 或 ticktick_get_by_id 获取。
数据新鲜度:读取保持最新
TickTick 账户在服务器运行时,可能会被其他设备上的应用所编辑。为了避免读取到过期数据,读取工具会按需重新同步状态,每时间窗口至多执行一次(默认 15 秒,可通过 TICKTICK_MCP_SYNC_TL_SECONDS 覆盖)。在其他设备上产生的更改会在该窗口内可见;调用 ticktick_sync 可以强制立即刷新并获取当前的任务/项目计数。如果如果同步失败,则返回最后已知状态而不是报错——但 ticktick_get_all 除外,它会在每次调用都刷新并在失败时报告失败,因为全量导出转储并不适合静默提供过期数据。
配置
变量 | 默认值 | 描述 |
|
| 存放 |
|
| 按需读取重新同步之间的最小秒数 |
|
| 首次连接失败后重试客户端登录之前的冷却时间 |
|
| 限频(HTTP 429)后重试登录之前的冷却时间;比初始化冷却更长,因为 429 清除缓慢,而且每次重试都会延长清除时间 |
| 未设置 | 智能体绝不能修改的任务 ID,以空格或逗号分隔。每个修改工具都会在发送任何内容之前报拒;读取不受影响。未设置表示没有保护 |
保护任务不被修改
某些任务无论如何被要求执行,都绝不应被智能体修改。在 TICKTICK_MCP_PROTECTED_TASK_IDS 中列出它们的 ID:
TICKTICK_MCP_PROTECTED_TASK_IDS="60ca9dbc8f08516d9dd56324,60ca9dbc8f08516d9dd56325"ticktick_update_task、ticktick_complete_task、ticktick_delete_tasks、ticktick_move_task 和 ticktick_make_subtask 随后会拒绝任何指定受保护任务的调用,并返回 outcome: "protected_task"。不会发送任何读取或写入该任务的请求。包含受保护 ID 的批量删除会被整体拒绝,而不会被部分执行,因为部分删除无法撤销。
由于 TickTick 会通过子任务传播 delete 和 move,因此当受保护的任务是所指定任务的父任务或子任务时,delete、move 和 make_subtask 也会拒绝。检查会先刷新本地状态,因此在配置了保护的期间,每次删除、移动或重设父任务都会增加一次请求——如果刷新失败,则返回 outcome: "protection_unveritable",因为在无法更新的快照上无法排除受保护的子任务。未设置该变量时,它不会做任何额外工作。ID 匹配会忽略两端空白、引号和大小写。读取受保护的任务始终有效。
凭据(TICKTICK_CLIENT_ID、TICKTICK_CLIENT_SECRET、TICKTICK_REDIRECT_URI、TICKTICK_USERNAME、TICKTICK_PASSWORD)从 .env 文件中读取;如果没有,则直接读取环境变量。
数据安全
pre-commit 钩子(scripts/check-no-data.sh)会阻止意外提交数据库、凭据和大文件:*.db 及备份变体、config/ 下除 .gitkeep 和 *.example* 之外的所有内容,以及超过 100KB 的文件(uv.lock 除外)。克隆后安装它:
ln -sf ../../scripts/check-no-data.sh .git/hooks/pre-commit参与贡献
开发环境设置、测试工作流和 pre-commit 钩子请见 CONTRIBUTING.md。变更记录在 CHANGELOG.md 中。
许可证
Maintenance
Related MCP Servers
- AlicenseCqualityCmaintenanceAgent-friendly CLI and MCP server for TickTick and Dida365 task management APIs, enabling project and task management with stable JSON output and OAuth authentication.171MIT
- AlicenseNot gradedqualityDmaintenanceMCP server for TickTick API enabling task management, project organization, habit tracking, and more.4272MIT
- FlicenseNot gradedqualityDmaintenanceRemote MCP server for managing TickTick tasks and projects, offering 22 tools for CRUD, search, and GTD workflows via any MCP client.1
- AlicenseNot gradedqualityCmaintenanceA security-hardened MCP server for TickTick that enables managing your tasks directly through any MCP-compatible client.1MIT
Related MCP Connectors
ClickUp MCP — wraps the ClickUp REST API v2 (BYO API key)
MCP server wrapping the Tesla Fleet API and TeslaMate API
MCP server for Withings health data — sleep, activity, heart, and body metrics.
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/partymola/ticktick-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server