loading…
Search for a command to run...
loading…
Enables AI integration with TickTick to manage tasks, projects, and tags through the Model Context Protocol. It allows users to import from Markdown, export pro
Enables AI integration with TickTick to manage tasks, projects, and tags through the Model Context Protocol. It allows users to import from Markdown, export project data to multiple formats, and perform task operations using natural language.
A Python tool for importing and exporting TickTick notes and tasks to Markdown and JSON formats.
Three ways to use:
# Using pip
pip install -r requirements.txt
# Or using uv (recommended)
uv pip install -r requirements.txt
Create a .env file in the project root:
cp .env.example .env
Edit .env and add your TickTick OAuth credentials:
TICKTICK_CLIENT_ID=your_client_id_here
TICKTICK_CLIENT_SECRET=your_client_secret_here
TICKTICK_REDIRECT_URI=http://localhost:8000/auth/ticktick/callback
TICKTICK_ACCESS_TOKEN=your_access_token_here
Run the token helper to authenticate:
python -m src.utils.get_token
Follow the prompts to:
.envpython ticktick_cli.py
The interactive menu provides all functionality:
Choose your output format (Markdown or JSON) when exporting.
The CLI provides a unified interface for all operations:
Run the CLI and select option 1:
python ticktick_cli.py
# Then select: 1. Import tasks from Markdown
You'll be prompted to:
Tasks should be formatted as bullet lists with checkboxes:
- [ ] Review pull request
Tags: code-review, urgent
Project: Work Tasks
Check for performance issues and security
- [ ] Buy groceries
Tags: shopping, personal
Milk, bread, eggs
- [x] Completed task
Tags: done
Metadata Fields:
Tags: work, urgent)Project: Work Tasks)Task States:
- [ ] - Unchecked task (will be imported)- [x] - Completed task (skipped during import)Run the CLI and select option 2 or 3:
python ticktick_cli.py
# Then select:
# 2. Export notes by tag
# 3. Export entire project
Export options:
If you need to use the functionality in your own Python scripts:
from src.exporters.notes_exporter import NotesManager, MarkdownExporter, JSONExporter
from src.importers.task_importer import TaskImporter
# Initialize
manager = NotesManager()
# Export by tag (Markdown)
manager.export_by_tag(
tag_name="journal",
output_file="journal.md",
project_name="On My Mind"
)
# Export by tag (JSON)
manager.export_by_tag(
tag_name="work",
output_file="work_notes.json",
project_name="Work Tasks",
exporter=JSONExporter()
)
# Export entire project
manager.export_project(
project_name="Personal",
output_file="personal_notes.md"
)
# List all projects
manager.list_projects()
# List tags in a project
manager.list_tags(project_name="On My Mind")
Use the TickTick API wrapper directly:
from src.api.ticktick_api import TickTickAPI, TickTickOAuth
import os
# Initialize API
api = TickTickAPI(os.getenv('TICKTICK_ACCESS_TOKEN'))
# Get user info
user = api.get_user_info()
# Get all projects
projects = api.get_projects()
# Get project data with tasks
project_data = api.get_projects_data(project_id)
# Create a task
task = api.create_task(
title="New Task",
content="Task description",
project_id="project_id_here",
tags=["work", "urgent"]
)
The MCP (Model Context Protocol) server allows Claude AI to directly interact with your TickTick account for importing and exporting tasks.
MCP is a protocol that lets AI assistants like Claude access external tools and data sources. With the TickTick MCP server, you can ask Claude to:
Install MCP dependency:
pip install mcp>=1.0.0
The .mcp.json file is already configured in the project root - no setup needed!
Set your access token:
export TICKTICK_ACCESS_TOKEN=your_token_here
Use with Claude Code:
The server exposes these tools to Claude:
list-projectsList all your TickTick projects/lists.
Example: "Show me all my TickTick projects"
list-tagsList all tags in a specific project.
Parameters:
- project_name: Name of the project
Example: "What tags are in my Work Tasks project?"
export-by-tagExport tasks filtered by a specific tag.
Parameters:
- tag_name: Tag to filter by
- project_name: Project to export from
- format: 'markdown' or 'json' (default: markdown)
Example: "Export all tasks tagged 'urgent' from Work Tasks"
export-projectExport all tasks from an entire project.
Parameters:
- project_name: Project to export
- format: 'markdown' or 'json' (default: markdown)
Example: "Export my Personal project as markdown"
import-from-markdownImport tasks from markdown content into TickTick.
Parameters:
- markdown_content: Markdown formatted task list
- project_name: Target project (defaults to Inbox)
- dry_run: Preview without creating (default: true)
Example: "Import these tasks to my Work project:
- [ ] Review documentation
Tags: work, urgent
- [ ] Schedule meeting
Tags: work"
create-taskCreate a single task in TickTick.
Parameters:
- title: Task title
- project_name: Project to add to (optional)
- content: Task description (optional)
- tags: List of tags (optional)
Example: "Create a task 'Buy groceries' with tags shopping and personal"
Export tasks:
You: "Export all my work tasks tagged 'urgent' as markdown"
Claude: *uses export-by-tag tool*
Claude: "Here are your urgent work tasks: [markdown content]"
Import tasks:
You: "Here's a list of tasks, import them to my Home project:
- [ ] Fix leaky faucet
Tags: home, maintenance
- [ ] Plant garden
Tags: home, weekend"
Claude: *uses import-from-markdown tool with dry_run=false*
Claude: "I've imported 2 tasks to your Home project"
List and organize:
You: "What projects do I have in TickTick?"
Claude: *uses list-projects tool*
Claude: "You have 5 projects: Work Tasks, Personal, Home Tasks, Shopping, Ideas"
The .mcp.json file in the project root is pre-configured:
{
"mcpServers": {
"ticktick": {
"command": "python3",
"args": ["ticktick_mcp_server.py"]
}
}
}
Make sure TICKTICK_ACCESS_TOKEN is set in your environment or .env file.
For Claude Desktop (if you use it), add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"ticktick": {
"command": "python3",
"args": ["/absolute/path/to/pyTickTick/ticktick_mcp_server.py"],
"env": {
"TICKTICK_ACCESS_TOKEN": "your_token_here"
}
}
}
}
The MCP server reuses all existing code:
src/api/ticktick_api.py)src/importers/)src/exporters/)No duplication - the MCP server is a thin wrapper that exposes existing functionality to Claude via the Model Context Protocol.
"Server not detected":
.mcp.json exists in project rootTICKTICK_ACCESS_TOKEN is set in environment"Authentication failed":
python -m src.utils.get_token to get a fresh token.env file with new tokenexport TICKTICK_ACCESS_TOKEN=token"Import not working":
dry_run=False in the import commanddry_run=True for safety (preview mode)Exports tasks as a formatted Markdown document:
# Journal Notes
Exported on January 03, 2026 at 07:31 PM
Total notes: 7
---
## 2025-12-31 My Note Title
**Date:** December 31, 2025
Note content here...
---
Features:
YYYY-MM-DD)Exports tasks as structured JSON:
{
"metadata": {
"exported_at": "2026-01-03T19:31:00.123456",
"total_tasks": 7,
"tag_name": "journal",
"project_name": "On My Mind"
},
"tasks": [
{
"id": "...",
"title": "2025-12-31 My Note",
"content": "Note content...",
"tags": ["journal"],
...
}
]
}
The exporter intelligently handles dates:
From Title - Extracts dates from titles like 2025-12-31 Task Name
YYYY-MM-DD at the start of the titleFrom API - Falls back to modifiedTime or createdTime if available
No Date - Shows "No date" if neither source is available
Quickly get a new OAuth access token:
python -m src.utils.get_token
Inspect task structure and find tags:
python -m src.utils.debug_tags
Shows:
pyTickTick/
├── 🚀 ticktick_cli.py # Main CLI - Interactive terminal interface
├── 🤖 ticktick_mcp_server.py # MCP Server - AI integration with Claude
│
├── src/ # Source code (organized by function)
│ ├── api/
│ │ └── ticktick_api.py # TickTick API wrapper (OAuth + API client)
│ │
│ ├── exporters/
│ │ └── notes_exporter.py # Export tasks to Markdown/JSON
│ │
│ ├── importers/
│ │ ├── task_importer.py # Import tasks from Markdown
│ │ └── markdown_parser.py# Parse markdown task format
│ │
│ └── utils/
│ ├── get_token.py # OAuth token helper
│ └── debug_tags.py # Task structure debugger
│
├── tests/ # Comprehensive test suite
│ ├── conftest.py # Pytest fixtures and configuration
│ ├── test_markdown_parser.py
│ ├── test_task_importer.py
│ ├── test_notes_exporter.py
│ └── test_ticktick_api.py
│
├── 📝 Config:
│ ├── .env.example # Template for credentials (copy to .env)
│ ├── .mcp.json # MCP server configuration for Claude
│ ├── requirements.txt # Python dependencies
│ ├── pyproject.toml # Project metadata
│ └── pytest.ini # Pytest configuration
│
├── LICENSE # MIT License
└── README.md # This file
Three Ways to Use:
python ticktick_cli.py for interactive interfacesrc/ modules in your own codeGetting Started:
python -m src.utils.get_token once to authenticatepython ticktick_cli.py for all import/export operationspython -m src.utils.debug_tags to inspect task structureshttp://localhost:8000/auth/ticktick/callbackAdd your credentials to .env:
TICKTICK_CLIENT_ID=your_client_id_from_developer_portal
TICKTICK_CLIENT_SECRET=your_client_secret_from_developer_portal
TICKTICK_REDIRECT_URI=http://localhost:8000/auth/ticktick/callback
Run python -m src.utils.get_token and follow the prompts.
Run python -m src.utils.get_token to authenticate and get a new token.
tasks:read tasks:writepython -m src.utils.get_tokencreatedTime/modifiedTime for notesYYYY-MM-DD Task NameMake sure all dependencies are installed:
pip install -r requirements.txt
The project includes a comprehensive test suite using pytest.
# Install test dependencies
pip install -r requirements.txt
# Run all tests
pytest
# Run with coverage report
pytest --cov=src --cov-report=html
# Run specific test file
pytest tests/test_markdown_parser.py
# Run tests with specific marker
pytest -m unit # Run only unit tests
pytest -m integration # Run only integration tests
pytest -m api # Run only API tests
# Run with verbose output
pytest -v
The test suite covers:
# tests/test_example.py
import pytest
@pytest.mark.unit
def test_example(sample_markdown_content):
"""Test description"""
# Your test code here
assert True
Available fixtures:
sample_markdown_content - Sample markdown for testingmock_ticktick_api - Mocked API instancemock_env_token - Mocked environment tokensample_tasks - Sample task dataExtend the BaseExporter class:
from src.exporters.notes_exporter import BaseExporter
class CSVExporter(BaseExporter):
def export(self, tasks, output_file, metadata):
# Your CSV export logic here
pass
Then use it:
manager.export_by_tag(
tag_name="notes",
output_file="notes.csv",
exporter=CSVExporter()
)
See requirements.txt for complete list.
MIT License - see LICENSE for details.
Contributions are welcome! Please feel free to submit issues and pull requests.
Future ideas under consideration:
For issues or questions:
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"ticktick-md-mcp": {
"command": "npx",
"args": []
}
}
}