Content
# TickTick MCP Service
> Bring TickTick task and goal data into MCP workflows with official OAuth and Open API support.
[Case study](https://aigalaxy.top/blog/ticktick-oauth-migration) · [AgentsGalaxy](https://aigalaxy.top/) · [GitHub](https://github.com/GalaxyXieyu/didatodolist-mcp)
`didatodolist-mcp` connects TickTick (Dida365) data to MCP-friendly workflows, with goal management, task analytics, and automation-friendly interfaces built on top of the official auth and API surface.
## Why it matters
- official OAuth 2.0 and Open API support makes the integration easier to trust
- MCP packaging makes task data more useful inside AI-native workflows
- the repo is suitable for productivity tooling, research flows, and personal operating systems
## Quick Start
1. Clone the repo and install Python dependencies.
2. Configure `.env` with your client credentials.
3. Run the OAuth helper once to get access and refresh tokens.
4. Start the MCP service and connect it to your editor or automation runtime.
## Tool List
## Main Features
- **Goal Management**: Create, query, update and delete personal goals
- **Task Analytics**: Generate task completion statistics reports
- **Keyword Extraction**: Extract keywords from task content (based on jieba segmentation)
- **Task and Goal Matching**: Intelligent matching of tasks with related goals
- **Goal Completion Progress Calculation**: Analyze and visualize goal completion progress
## Installation Requirements
- Python 3.8+
- TickTick account (support authentication via token, mobile phone number or email)
## Quick Start
1) Clone the project
```bash
git clone https://github.com/GalaxyXieyu/didatodolist-mcp.git
cd didatodolist-mcp
```
2) Install dependencies
```bash
pip install -r requirements.txt
```
3) Configure and authenticate (.env-only)
Recommended to use OAuth 2.0 (only .env):
Get Client ID / Secret:
- Open TickTick Open Platform documentation portal: https://developer.dida365.com/docs#/openapi
- Create an application on the open platform (fill in the name).
- In the application settings, fill in the OAuth Redirect URL: `http://localhost:38000/callback`
- Copy the application's `client_id` and `client_secret` for the following `.env` configuration.
Reference diagram:


- Configure `MCP_API_KEY=...`, `DIDA_CLIENT_ID`, `DIDA_CLIENT_SECRET` in `.env`; run `python scripts/oauth_authenticate.py --port 38000` to complete one-time authorization, the script will write `DIDA_ACCESS_TOKEN`, `DIDA_REFRESH_TOKEN` to `.env`.
Minimum available steps:
```bash
cp .env.example .env
# Edit .env, fill in MCP_API_KEY, DIDA_CLIENT_ID, DIDA_CLIENT_SECRET
python scripts/oauth_authenticate.py --port 38000 # Write DIDA_ACCESS_TOKEN/DIDA_REFRESH_TOKEN to .env after success
# Start service
export MCP_API_KEY=your-strong-key # or directly configure in .env
python main.py --sse --host 127.0.0.1 --port 3000
# Client request header needs to bring: x-api-key: your-strong-key
```
Optional `.env` example:
```
MCP_API_KEY=your-strong-key
# The following variables are managed by .env-only
# DIDA_CLIENT_ID=...
# DIDA_CLIENT_SECRET=...
# DIDA_ACCESS_TOKEN=...
# DIDA_REFRESH_TOKEN=...
```
More documentation:
- Unified OAuth guide (.env-only): `docs/openapi_oauth_guide.md`
- Document index: `docs/openapi_index.md`
- Project interface: `docs/openapi_project.md`
- Task interface: `docs/openapi_task.md`
- Data model definition: `docs/openapi_definitions.md`
- Local debugging (Inspector/mcp-cli): `docs/dev_debug_inspector.md`
- OpenClaw plugin: `docs/openclaw_plugin.md`
- OpenClaw native plugin (Open API): `docs/openclaw_openapi_plugin.md`
## OpenClaw Native Plugin (Recommended)
This plugin directly calls TickTick's official Open API, without relying on the MCP service.
### 1) Install plugin
```bash
openclaw plugins install -l ./openclaw-openapi-plugin
```
### 2) Write OpenClaw configuration and complete OAuth
Recommended to use script to automatically write (will write token to `~/.openclaw/openclaw.json`, and ensure allowlist):
```bash
python3 scripts/oauth_openclaw.py --open-browser
```
The script will read the following configuration (if missing, can be written manually):
```json
{
"plugins": {
"enabled": true,
"entries": {
"dida-openapi": {
"enabled": true,
"config": {
"clientId": "<YOUR_CLIENT_ID>",
"clientSecret": "<YOUR_CLIENT_SECRET>",
"redirectUri": "http://localhost:38000/callback",
"accessToken": "<ACCESS_TOKEN>",
"refreshToken": "<REFRESH_TOKEN>",
"timeoutMs": 15000,
"autoRefresh": true
}
}
}
},
"tools": {
"allow": ["dida-openapi"]
}
}
```
### 3) Restart Gateway to make configuration take effect
```bash
openclaw gateway restart
```
### 4) Verify if callable
```bash
openclaw plugins info dida-openapi
openclaw agent --agent main --message "Please call tool dida_get_projects and return result" --thinking minimal --timeout 30 --json
```
If UI prompts "accessToken not configured", it means Gateway did not read the latest configuration or token has expired: please run authorization script first, then restart Gateway.
### Docker/Compose Deployment (.env-only)
Recommended to complete one-time OAuth authorization on the local machine, write token to `.env` and then deploy container (no need to expose port 38000 on cloud).
1) Local pre-authorization (write `.env`)
```bash
cp .env.example .env
# Fill in MCP_API_KEY, DIDA_CLIENT_ID, DIDA_CLIENT_SECRET
python scripts/oauth_authenticate.py --port 38000 # Write DIDA_ACCESS_TOKEN / DIDA_REFRESH_TOKEN after success
```
2) Run using Docker Compose (only need port 3000)
```bash
# Copy authorized .env to data/.env (or directly place)
mkdir -p data && cp .env data/.env
docker compose up -d --build mcp
# SSE entrance: http://<host>:3000/sse (Headers: x-api-key: <your MCP_API_KEY>)
```
3) Connect using MCP Inspector or mcp-cli
- Inspector: `npx @modelcontextprotocol/inspector`, select SSE, URL `http://<host>:3000/sse`, Headers `x-api-key: <your MCP_API_KEY>`
- mcp-cli: `npx @wong2/mcp-cli`, select SSE, fill in the same URL and Headers
Description and best practices:
- callback(38000) only occurs during "authorization at the time", container operation does not depend on this port; cloud only needs to expose port 3000 or reverse proxy to `/sse`.
- Strong randomization of `MCP_API_KEY` and reverse proxy to pass `x-api-key`; production can limit source IP.
- When token expires, the server will try to use `DIDA_REFRESH_TOKEN` to automatically refresh and write back the new token to `.env`.
## Usage
### Start (stdio)
```bash
python main.py
```
### Start (SSE, recommended for debugging)
```bash
python main.py --sse --host 127.0.0.1 --port 3000
```
### Specify configuration file path
Unified to .env-only, no longer supports separate configuration file path parameters.
### Install to MCP client
```bash
python main.py --install
```
## Port and Authentication
- Callback port (one-time authorization): `38000`
- Align with environment variable `DIDA_REDIRECT_URI`, e.g. `http://localhost:38000/callback`
- Only temporarily listen when running `scripts/oauth_authenticate.py` for OAuth authorization
- MCP service port (SSE): `3000`
- Start with `python main.py --sse --host 127.0.0.1 --port 3000`
- Client connection to MCP needs to bring `x-api-key` in request header
Example:
```bash
export MCP_API_KEY="your-strong-key"
python main.py --sse --host 127.0.0.1 --port 3000
# Client request header: x-api-key: your-strong-key
```
## Port and Authentication (Summary)
- Callback port: 38000 (OAuth callback one-time use, align with `redirect_uri`)
- Service port: 3000 (SSE connection MCP service)
- Authentication: Client connection needs to bring `x-api-key`, server verifies `MCP_API_KEY`
## Authentication Mechanism (.env-only)
- Service → Official API: Read `DIDA_ACCESS_TOKEN`/`DIDA_REFRESH_TOKEN` from `.env` for OAuth call.
- Automatic refresh: When returning 401, use `DIDA_REFRESH_TOKEN` to automatically refresh and write back the new token to `.env`.
- No longer support mobile phone number/email password direct login; no use of any `oauth_config.json`/`config.json` file.
- Client → Service: Verify `MCP_API_KEY` through `x-api-key` request header.
## Functional Modules
### Goal Management
Goal management function allows users to create, track and manage different types of goals:
- **Stage goals**: Short-term goals with clear deadlines
- **Regular goals**: Long-term continuous goals
- **Habitual goals**: Regularly executed behavioral habits
### Statistics and Analysis
Statistics and analysis function provides multi-dimensional task completion analysis:
- **Time dimension**: Analyze task completion by day/week/month
- **Project dimension**: Classify tasks by project and count completion rate
- **Label dimension**: Analyze task distribution by label
### Keyword Extraction
Extract keywords from task content based on jieba segmentation library, support generating word cloud and heat analysis.
### Task-Goal Matching
Use content similarity and keyword matching algorithm to intelligently associate tasks with goals, helping users align daily tasks with long-term goals.
## Development Process
This project adopts a systematic development method, following the following development stages:
1. **Planning stage**: Defined project scope, functional requirements and technical specifications
2. **Architecture design**: Completed core data structure design
3. **Basic function development**: Implemented core API and data access layer
4. **Advanced function implementation**: Developed statistical analysis and goal matching algorithm
5. **Optimization and testing**: Improved performance and user experience
## Contribution
Welcome to submit issues and improvement suggestions! Please fork this repository and create a pull request.
## License
[MIT License](LICENSE)
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
Python tool for converting files and office documents to Markdown.
awesome-claude-skills
A curated list of awesome Claude Skills, resources, and tools for...
antigravity-awesome-skills
The Ultimate Collection of 130+ Agentic Skills for Claude...
openfang
Open-source Agent Operating System
context-mode
MCP is the protocol for tool access. We're the virtualization layer for context.