Skip to main content

MCP server for AI Agents to manage Dida365 (TickTick) tasks and projects

Project description

dida365-agent-mcp

MCP server for AI agents to manage Dida365 / TickTick tasks and projects

中文文档

Python 3.12+ FastMCP 3.x Transport License


A Python MCP server built on FastMCP that connects AI agents (Claude Code, Cursor, Windsurf, etc.) to the Dida365 / TickTick Open API. Manage tasks and projects through natural language.

Supports both Dida365 (China) and TickTick (International) — switch with a single env var.

Features

  • 40 tools — 19 V1 (official Open API) + 21 V2 (private API: tags, search, habits, folders, parent tasks)
  • Dual transportstdio for local clients; streamable-http for remote agents
  • Dual platform — Dida365 and TickTick via DIDA365_REGION config
  • One-click OAuth — script auto-opens browser, receives callback, saves token
  • Docker readydocker compose up to deploy
  • Agent-friendly — structured JSON responses, clear tool annotations, actionable error messages

Deployment

Four options, ordered from simplest to most complex.


Option A — uvx (no install)

No git clone, no venv. Requires only uv.

1. Get API credentials

Create an app at the developer portal and copy the Client ID and Secret:

Set Redirect URI to http://localhost:8000/oauth/callback.

2. Create .env and authorize

# Create config file
cat > .env << 'EOF'
DIDA365_REGION=china
DIDA365_CLIENT_ID=your_client_id
DIDA365_CLIENT_SECRET=your_client_secret
EOF

# Run OAuth — opens browser, saves token (~180 days)
uvx --from dida365-agent-mcp dida365-oauth

3. Connect your AI client

Claude Code

Edit ~/.claude/mcp.json:

{
  "mcpServers": {
    "dida365": {
      "command": "uvx",
      "args": ["dida365-agent-mcp"]
    }
  }
}
Cursor

Go to Settings > MCP > Add new global MCP server:

{
  "mcpServers": {
    "dida365": {
      "command": "uvx",
      "args": ["dida365-agent-mcp"]
    }
  }
}

Option B — pip install

pip install dida365-agent-mcp

Then follow the same steps as Option A, replacing uvx --from dida365-agent-mcp dida365-oauth with dida365-oauth and uvx dida365-agent-mcp with dida365-mcp.


Option C — git clone (source / development)

git clone https://github.com/linhai0872/dida365-agent-mcp.git
cd dida365-agent-mcp
uv sync
cp .env.example .env   # fill in CLIENT_ID and CLIENT_SECRET
uv run python scripts/oauth_flow.py

MCP client config:

{
  "mcpServers": {
    "dida365": {
      "command": "uv",
      "args": ["--directory", "/path/to/dida365-agent-mcp", "run", "dida365-mcp"]
    }
  }
}

Option D — Remote (Docker + HTTP)

For always-on or team deployments.

1. Get the access token first (run OAuth from Option A, B, or C)

2. Deploy

git clone https://github.com/linhai0872/dida365-agent-mcp.git
cd dida365-agent-mcp
cp .env.example .env
# Set DIDA365_REGION and DIDA365_ACCESS_TOKEN in .env
docker compose up -d

Connect to http://your-host:8000/mcp.

The container cannot open a browser, so set DIDA365_ACCESS_TOKEN directly instead of running the OAuth script inside Docker.


(Optional) Enable V2 tools — tags, search, habits, folders, parent tasks

Add one of the following to your .env (or MCP client env block):

# Method 1: Session token (manual, most secure, 30-day expiry)
# Browser DevTools → Application → Cookies → copy 't' value
DIDA365_V2_SESSION_TOKEN=your_token

# Method 2: Auto-login (convenient, does not support 2FA)
DIDA365_USERNAME=your_email
DIDA365_PASSWORD=your_password

Without V2 config, you still get 19 V1 tools. With V2, you get all 40.


Try It

Talk to your AI agent naturally:

  • "List all my projects"
  • "Create a high-priority task 'Review PR' in Work, due tomorrow"
  • "What tasks did I complete this week?"
  • "Move 'Design review' to the Archive project"
  • "Search tasks containing 'meeting'" (V2)
  • "List all my tags" (V2)
  • "Did I check in my reading habit today?" (V2)

Tools

Task Operations

Tool Description
dida365_create_task Create a task with title, project, dates, priority, tags, reminders, recurrence
dida365_update_task Update any task fields (partial update)
dida365_complete_task Mark a task as completed
dida365_delete_task Permanently delete a task
dida365_get_task Get full details of a single task
dida365_move_task Move a task between projects

Query Operations

Tool Description
dida365_get_project_tasks Get all uncompleted tasks in a project
dida365_filter_tasks Filter by project, date range, priority, tags, status
dida365_get_completed_tasks Get completed tasks within a time range

Project Operations

Tool Description
dida365_list_projects List all projects (call this first to get IDs)
dida365_get_project Get project details
dida365_create_project Create a project (list / kanban / timeline view)
dida365_update_project Update project properties
dida365_delete_project Permanently delete a project and all its tasks

Batch Operations

Tool Description
dida365_get_task_by_id Get a task by ID only (no project_id needed)
dida365_list_undone_tasks List undone tasks by date range or project
dida365_batch_create_tasks Batch create multiple tasks
dida365_batch_update_tasks Batch update multiple tasks
dida365_batch_complete_tasks Batch complete multiple tasks

V2 Tools (optional — requires V2 auth)

Tool Description
dida365_search_tasks Server-side full-text search with keyword, project, tag, status, date filters
dida365_list_tags List all tags
dida365_create_tags Batch create tags
dida365_update_tags Batch update tags
dida365_delete_tags Batch delete tags
dida365_delete_tag Delete a single tag by name
dida365_set_task_parent Set parent-child task relationship
dida365_unset_task_parent Remove parent, make task top-level
dida365_pin_task Pin or unpin a task
dida365_list_habits List all habits
dida365_create_habit Batch create habits
dida365_update_habit Batch update habits
dida365_delete_habit Batch delete habits
dida365_checkin_habit Check in a habit for a date
dida365_undo_checkin Undo a habit checkin
dida365_list_habit_checkins List checkin records for a habit
dida365_list_habit_sections List habit sections/groups
dida365_list_folders List project folders
dida365_create_folder Create a project folder
dida365_update_folder Update a project folder
dida365_delete_folder Delete a project folder

Configuration

Variable Description Default
DIDA365_REGION china (dida365.com) or international (ticktick.com) china
DIDA365_CLIENT_ID OAuth Client ID
DIDA365_CLIENT_SECRET OAuth Client Secret
DIDA365_ACCESS_TOKEN Access token (set directly to skip OAuth)
DIDA365_REDIRECT_URI OAuth callback URL http://localhost:8000/oauth/callback
DIDA365_V2_SESSION_TOKEN V2 session token (browser cookie t, 30-day expiry)
DIDA365_USERNAME V2 auto-login email/phone (alternative to session token)
DIDA365_PASSWORD V2 auto-login password (does not support 2FA)
TRANSPORT stdio, streamable-http, or sse (legacy) stdio
HOST Bind address (http / sse only) 0.0.0.0
PORT Port (http / sse only) 8000

Token Lifecycle

Item Detail
Validity ~180 days
Auto-refresh Not supported (API limitation)
Expiry detection Built-in, warns 24h before expiry
Renewal Re-run dida365-oauth (or uvx --from dida365-agent-mcp dida365-oauth)
Storage ~/.dida365-agent-mcp/token.json (auto-loaded)

Development

uv sync                                    # Install dependencies
uv run pytest tests/ -v                    # Run tests
uv run ruff check src/ tests/ scripts/     # Lint
uv run ruff format src/ tests/ scripts/    # Format
uv run pyright src/                        # Type check
uv run dida365-mcp                         # Run (stdio)
TRANSPORT=streamable-http uv run dida365-mcp   # Run (Streamable HTTP)

Project Structure

dida365-agent-mcp/
├── src/dida365_agent_mcp/
│   ├── server.py        # FastMCP server + 19 V1 tool definitions + MCP resource
│   ├── server_v2.py     # 21 V2 tool definitions (tags, search, habits, folders)
│   ├── client.py        # V1 async API client (httpx + OAuth)
│   ├── client_v2.py     # V2 async API client (httpx + session cookie)
│   ├── auth.py          # OAuth2 flow + token management
│   ├── models.py        # Pydantic data models (V1 + V2)
│   └── config.py        # Region-aware configuration
├── scripts/
│   └── oauth_flow.py    # One-click OAuth script
├── tests/               # 62 unit tests (respx)
├── Dockerfile           # Multi-stage build
└── docker-compose.yml

License

MIT

Acknowledgments

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_agent_mcp-2.0.1.tar.gz (16.8 kB view details)

Uploaded Source

Built Distribution

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

dida365_agent_mcp-2.0.1-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file dida365_agent_mcp-2.0.1.tar.gz.

File metadata

  • Download URL: dida365_agent_mcp-2.0.1.tar.gz
  • Upload date:
  • Size: 16.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dida365_agent_mcp-2.0.1.tar.gz
Algorithm Hash digest
SHA256 821380fd433c99f66efd046b86946c2173dc665b937b070819a3802e0516f6a1
MD5 ed970d5f09e7e5b2281359d790e04ac4
BLAKE2b-256 21274c2e076e9b6e72bb75192f26b3f35652855919b06812843b60d44f8ce061

See more details on using hashes here.

File details

Details for the file dida365_agent_mcp-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: dida365_agent_mcp-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.27 {"installer":{"name":"uv","version":"0.9.27","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for dida365_agent_mcp-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f8d94594a407480c6927dc85d5b9ae250274e7d87560557100d08cb2f699fe67
MD5 6da2f5a0fd4309a34fd3ac59bdc98345
BLAKE2b-256 5d87e730f82209c78b3a4b98f03c0dbb7925bf8579e385680d88931fc66a0788

See more details on using hashes here.

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