Skip to main content

Python SDK for the dida365 (TickTick) MCP server.

Project description

dida365

PyPI version Python versions License: MIT

滴答清单 / 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 / 网络错误的重试次数
)

ClientAsyncClient 都自动遵循 Retry-After 头部、自动透传 Mcp-Session-IdMCP-Protocol-Version 头部。

安全约定

  • repr(client) 不会泄露 token;只显示 Client(url=...)
  • 进程环境变量只接受 DIDA365_TOKEN,避免与其他工具的 TOKEN 冲突。
  • .env 中可使用 DIDA365_TOKENTOKEN(仅在 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 remains import 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_TOKEN is read from process env (avoids collisions with TOKEN set by other tools).
  • .env in the current working directory accepts DIDA365_TOKEN or TOKEN.

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dida365_sdk-0.1.0.tar.gz (37.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dida365_sdk-0.1.0-py3-none-any.whl (24.4 kB view details)

Uploaded Python 3

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

Hashes for dida365_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9a554b62d71777408a99ce16f6fbad67808766a6a42150487bd86ff74ad0a409
MD5 61e3ad183e0ad9eeaf69e8304438b435
BLAKE2b-256 63855b5aa8f55e3691bb350c76d0f3a088e5f3640c1c7cbc7208da16af822a73

See more details on using hashes here.

Provenance

The following attestation bundles were made for dida365_sdk-0.1.0.tar.gz:

Publisher: workflow.yml on shawn-bluce/dida365-sdk

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for dida365_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dc3dce1451735220eb10da9650e1fc2d13b0f079e0fba216af107a7c8e512263
MD5 6863cb2b149aa5267540c3011639d219
BLAKE2b-256 dcf7b7832f6449ca3ae9f631618685f1436e3916737e55b8f49371d7689d187b

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page