Python SDK for the dida365 (TickTick) MCP server.
Project description
dida365
滴答清单 / dida365(TickTick)官方 MCP 服务 的 Python SDK。把 32 个 MCP 工具包装成同名方法,同时提供同步与异步接口、完整类型标注、自动重试与凭据隔离。
A Python SDK for the official dida365 / TickTick MCP server. Wraps all 32 MCP tools as Python methods with sync + async clients, full type stubs, automatic retries, and safe credential handling.
中文文档
安装
pip install dida365-sdk # 仅同步客户端
pip install "dida365-sdk[async]" # 同时安装 httpx,启用 AsyncClient
安装名是
dida365-sdk,导入名仍是import dida365。
获取 Token
打开 滴答清单网页版,进入 头像 → 设置 → 账户与安全 → API 口令,新建并复制 token。
设置环境变量(推荐):
export DIDA365_TOKEN=dp_xxxxxxxxxxxxxxxxxxxxxxxxxx
或者在项目目录创建 .env 文件:
DIDA365_TOKEN=dp_xxxxxxxxxxxxxxxxxxxxxxxxxx
快速开始
import dida365
with dida365.Client() as client:
# 1. 列出所有清单
projects = client.list_projects()
# 2. 创建任务
task = client.create_task(task={
"projectId": projects[0]["id"],
"title": "明天提交周报",
"priority": 5, # 0=无 1=低 3=中 5=高
"startDate": "2026-05-09T09:00:00+08:00",
"isAllDay": False,
"timeZone": "Asia/Shanghai",
"tags": ["work"],
})
# 3. 查询今日待办
today = client.list_undone_tasks_by_time_query(query_command="today")
# 4. 完成任务
client.complete_task(project_id=task["projectId"], task_id=task["id"])
异步用法
import asyncio
import dida365
async def main() -> None:
async with dida365.AsyncClient() as client:
projects, today = await asyncio.gather(
client.list_projects(),
client.list_undone_tasks_by_time_query(query_command="today"),
)
print(f"{len(projects)} projects, {len(today)} tasks today")
asyncio.run(main())
错误处理
import dida365
try:
client = dida365.Client(token="bad-token")
except dida365.AuthenticationError as e:
print(f"token 失效: {e.code}") # 401 / 403
except dida365.MCPProtocolError as e:
print(f"网络/协议错误: {e}")
except dida365.ToolError as e:
print(f"工具调用失败: {e.tool} -> {e}")
全部 32 个工具
| 类别 | 工具 |
|---|---|
| 清单 | list_projects get_project_by_id get_project_with_undone_tasks create_project update_project |
| 任务 | create_task update_task get_task_in_project get_task_by_id complete_task complete_tasks_in_project move_task batch_add_tasks batch_update_tasks |
| 查询 | search search_task fetch filter_tasks list_undone_tasks_by_date list_undone_tasks_by_time_query list_completed_tasks_by_date |
| 习惯 | list_habits list_habit_sections get_habit create_habit update_habit upsert_habit_checkins get_habit_checkins |
| 专注 | get_focus get_focuses_by_time delete_focus |
| 偏好 | get_user_preference |
每个工具的参数与返回类型已经在 dida365/client.pyi 中声明,IDE / mypy / pyright 都能直接获取补全。
高级配置
client = dida365.Client(
token="dp_xxx", # 显式 token(默认从 env 读取)
url="https://mcp.dida365.com", # MCP 服务地址
timeout=(5.0, 30.0), # (connect, read)
max_retries=3, # 5xx / 429 / 网络错误的重试次数
)
Client 与 AsyncClient 都自动遵循 Retry-After 头部、自动透传 Mcp-Session-Id 与 MCP-Protocol-Version 头部。
安全约定
repr(client)不会泄露 token;只显示Client(url=...)。- 进程环境变量只接受
DIDA365_TOKEN,避免与其他工具的TOKEN冲突。 .env中可使用DIDA365_TOKEN或TOKEN(仅在cwd/.env中生效)。
开发
本仓库使用 uv 管理 Python 环境与依赖。
git clone https://github.com/shawn-bluce/dida365-sdk.git
cd dida365-sdk
uv sync --all-extras # 创建 .venv 并安装 dev + async 依赖
# 单元测试(不联网)
uv run pytest
# 实测脚本(会创建并关闭一个沙箱清单)
DIDA365_TOKEN=dp_xxx uv run python tests/integration/test_smoke_live.py
# 重新生成类型存根
uv run python scripts/generate_stubs.py --refresh
# 打包与发布
uv build # 生成 dist/*.whl 与 dist/*.tar.gz
uv publish # 上传到 PyPI(需配置 token)
English Documentation
Install
pip install dida365-sdk # sync client only
pip install "dida365-sdk[async]" # also installs httpx for AsyncClient
The distribution name is
dida365-sdk; the import name remainsimport dida365.
Get a token
In the dida365 web app, open Profile → Settings → Account & Security → API Token, create and copy a new token. Then either:
export DIDA365_TOKEN=dp_xxxxxxxxxxxxxxxxxxxxxxxxxx
…or drop a .env file at the project root with DIDA365_TOKEN=....
Quickstart
import dida365
with dida365.Client() as client:
projects = client.list_projects()
task = client.create_task(task={
"projectId": projects[0]["id"],
"title": "Submit weekly report",
"priority": 5,
"startDate": "2026-05-09T09:00:00+08:00",
"isAllDay": False,
"timeZone": "Asia/Shanghai",
"tags": ["work"],
})
today = client.list_undone_tasks_by_time_query(query_command="today")
client.complete_task(project_id=task["projectId"], task_id=task["id"])
Async usage
import asyncio
import dida365
async def main() -> None:
async with dida365.AsyncClient() as client:
projects, today = await asyncio.gather(
client.list_projects(),
client.list_undone_tasks_by_time_query(query_command="today"),
)
print(f"{len(projects)} projects, {len(today)} tasks today")
asyncio.run(main())
Error handling
import dida365
try:
client = dida365.Client(token="bad-token")
except dida365.AuthenticationError as e:
... # HTTP 401 / 403
except dida365.MCPProtocolError as e:
... # network / HTTP / JSON-RPC error
except dida365.ToolError as e:
... # tool reported isError=true
Tool catalogue
All 32 server-advertised tools are dispatched dynamically by name and statically typed via client.pyi / async_client.pyi. Categories: projects (5), tasks (9), querying (7), habits (7), focus (3), preferences (1).
Advanced configuration
client = dida365.Client(
token="dp_xxx", # explicit token (defaults to env)
url="https://mcp.dida365.com", # MCP endpoint
timeout=(5.0, 30.0), # (connect, read)
max_retries=3, # 5xx / 429 / network retries
)
Both Client and AsyncClient honor Retry-After, round-trip Mcp-Session-Id, and send MCP-Protocol-Version on every non-initialize request.
Security defaults
repr(client)masks the bearer token.- Only
DIDA365_TOKENis read from process env (avoids collisions withTOKENset by other tools). .envin the current working directory acceptsDIDA365_TOKENorTOKEN.
Development
This repo uses uv to manage the Python environment and dependencies.
git clone https://github.com/shawn-bluce/dida365-sdk.git
cd dida365-sdk
uv sync --all-extras # creates .venv and installs dev + async extras
# Unit tests (offline)
uv run pytest
# Live integration smoke test (creates a sandbox project, closes it after)
DIDA365_TOKEN=dp_xxx uv run python tests/integration/test_smoke_live.py
# Regenerate type stubs from the live MCP catalogue
uv run python scripts/generate_stubs.py --refresh
# Build & publish
uv build # produces dist/*.whl and dist/*.tar.gz
uv publish # uploads to PyPI (requires token)
License
MIT © 2026 Hao Zhang
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dida365_sdk-0.1.0.tar.gz.
File metadata
- Download URL: dida365_sdk-0.1.0.tar.gz
- Upload date:
- Size: 37.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a554b62d71777408a99ce16f6fbad67808766a6a42150487bd86ff74ad0a409
|
|
| MD5 |
61e3ad183e0ad9eeaf69e8304438b435
|
|
| BLAKE2b-256 |
63855b5aa8f55e3691bb350c76d0f3a088e5f3640c1c7cbc7208da16af822a73
|
Provenance
The following attestation bundles were made for dida365_sdk-0.1.0.tar.gz:
Publisher:
workflow.yml on shawn-bluce/dida365-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dida365_sdk-0.1.0.tar.gz -
Subject digest:
9a554b62d71777408a99ce16f6fbad67808766a6a42150487bd86ff74ad0a409 - Sigstore transparency entry: 1471922761
- Sigstore integration time:
-
Permalink:
shawn-bluce/dida365-sdk@4808cd2cbff53d41e7d93336faa8bd43e8358f2b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/shawn-bluce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@4808cd2cbff53d41e7d93336faa8bd43e8358f2b -
Trigger Event:
push
-
Statement type:
File details
Details for the file dida365_sdk-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dida365_sdk-0.1.0-py3-none-any.whl
- Upload date:
- Size: 24.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc3dce1451735220eb10da9650e1fc2d13b0f079e0fba216af107a7c8e512263
|
|
| MD5 |
6863cb2b149aa5267540c3011639d219
|
|
| BLAKE2b-256 |
dcf7b7832f6449ca3ae9f631618685f1436e3916737e55b8f49371d7689d187b
|
Provenance
The following attestation bundles were made for dida365_sdk-0.1.0-py3-none-any.whl:
Publisher:
workflow.yml on shawn-bluce/dida365-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dida365_sdk-0.1.0-py3-none-any.whl -
Subject digest:
dc3dce1451735220eb10da9650e1fc2d13b0f079e0fba216af107a7c8e512263 - Sigstore transparency entry: 1471922989
- Sigstore integration time:
-
Permalink:
shawn-bluce/dida365-sdk@4808cd2cbff53d41e7d93336faa8bd43e8358f2b -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/shawn-bluce
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@4808cd2cbff53d41e7d93336faa8bd43e8358f2b -
Trigger Event:
push
-
Statement type: