Ticktick Mcp について
ticktick-sdk は、TickTick および滴滴清単(Dida365)向けの非同期 Python SDK で、AI アシスタントからタスク、プロジェクト、タグ、習慣を管理できる MCP サーバーを含みます。Python で TickTick を操作したい開発者や、アシスタント経由で操作したい利用者を対象としています。
主な機能
- 01httpx を基盤とする非同期 Python SDK
- 02タスクとプロジェクトを扱う 43 個の MCP ツール
- 03タスクの一括作成、更新、完了、削除
- 04カンバンの列、タグ、フォルダーの管理
- 05チェックインとストリークによる習慣の追跡
- 06Pydantic v2 による型検証
活用シーン
- 01AI アシスタントで今日期限のタスクを確認
- 02アシスタントから習慣のチェックインと連続記録を確認
- 03Python アプリケーションから TickTick のタスクを一括管理
MCP 対応
本プロジェクトは MCP サーバーであり、タスク、プロジェクト、カンバン列、タグ、習慣、ユーザー統計、フォーカスデータに関するツールを MCP クライアントに提供します。モジュールまたはツール名で絞り込めます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
ticktick-sdk:TickTick MCP サーバー&フル機能 Python SDK
MCP(Model Context Protocol)サーバーをサポートする、TickTick 用の包括的な非同期 Python SDK です。
Dida365(滴答清单)も完全にサポートしています。
Python から TickTick をプログラムで操作することも、AI アシスタントにタスクを管理させることもできます。
目次
- 機能
- このライブラリを選ぶ理由
- インストール
- MCP サーバーのセットアップと使い方
- Python ライブラリのセットアップと使い方
- アーキテクチャ
- API リファレンス
- TickTick API の注意点
- 環境変数
- テストの実行
- トラブルシューティング
- コントリビューション
機能
MCP サーバー
- 43 個のツール:TickTick の機能を効率よく網羅
- 一括操作:すべての変更操作でリスト(1~100 項目)を受け付け、一括処理が可能
- AI 対応:Claude、GPT、その他の MCP 対応アシスタントで動作
- 2 種類の出力:人間向けの Markdown と、機械向けの JSON
Python ライブラリ
- 完全な非同期処理をサポート:高パフォーマンスな非同期操作を実現する
httpxを基盤として構築 - 一括操作:1 回の呼び出しで最大 100 件のタスクを作成、更新、削除、完了
- 完全なタスク管理:タスクの作成、読み取り、更新、削除、完了、移動、ピン留め
- カンバンボード:列の完全な管理(作成、更新、削除、列間でのタスク移動)
- プロジェクトの整理:プロジェクト、フォルダー、カンバンボード
- タグシステム:色付きの階層型タグ
- 習慣の追跡:一括チェックイン、連続記録、目標を含む、習慣の完全な CRUD
- 集中/ポモドーロ:集中セッションのデータと統計にアクセス
- ユーザー分析:生産性スコア、レベル、完了率
開発者向け機能
- 型安全:包括的な型ヒントを備えた、Pydantic v2 による完全な検証
- 十分なテスト:モックと実 API の両方の操作を網羅する 300 件以上のテスト
- ドキュメント完備:詳細な docstring と使用例
このライブラリを選ぶ理由
2 種類の API の問題
TickTick には異なる 2 種類の APIがあります。
| API | 種類 | 用途 |
|---|---|---|
| V1(OAuth2) | 公式、ドキュメントあり | すべてのタスクを含むプロジェクト、基本操作 |
| V2(セッション) | 非公式、リバースエンジニアリング済み | タグ、フォルダー、習慣、集中、サブタスクなど |
公式の V1 API には制限があります。TickTick の高度な機能の多く(タグ、習慣、集中の追跡など)は、ドキュメント化されていない V2 Web API からのみ利用できます。このライブラリは両方を組み合わせ、各操作を適切な API に自動的に振り分けます。
他のライブラリとの比較
利用可能な TickTick Python ライブラリの実際のソースコードを分析した結果:
| 機能 | ticktick-sdk | pyticktick | ticktick-py | tickthon | ticktick-python |
|---|---|---|---|---|---|
| I/O モデル | 非同期 | 非同期 | 同期 | 同期 | 同期 |
| 型システム | Pydantic V2 | Pydantic V2 | Dicts | attrs | addict |
| MCP サーバー | あり | なし | なし | なし | なし |
| 習慣 | 完全な CRUD | なし | 基本 | 基本 | なし |
| フォーカス/ポモドーロ | あり | あり | あり | あり | なし |
| V1+V2 統合 | スマートルーティング | 個別 | 両方 | V2 のみ | V2 のみ |
| サブタスク | 高度 | 一括 | あり | 基本 | 基本 |
| タグ | 完全対応(統合/名前変更) | あり | あり | あり | なし |
主な差別化要素:
- MCP サーバー:Model Context Protocol を介した AI アシスタントとの統合を提供するのは ticktick-sdk のみです
- 統合 API ルーティング:機能要件に基づいて、操作を V1 または V2 に自動でルーティングします
- 習慣の完全な CRUD:チェックイン、連続記録、アーカイブ/アーカイブ解除を含む、習慣の完全な管理が可能です
- 非同期優先:高パフォーマンスな非同期操作を実現するため、
httpxを基盤にしています
インストール
pip install ticktick-sdk
要件:
- Python 3.11+
- TickTick アカウント(無料または Pro)
MCP サーバーのセットアップと使い方
Model Context Protocol を介して、Claude などの AI アシスタントで TickTick を使用できます。
ステップ 1:アプリを登録する
- TickTick Developer Portal にアクセスします
- **「Create App」**をクリックします
- 以下を入力します:
- App Name:「My TickTick MCP」など
- Redirect URI:
http://127.0.0.1:8080/callback
- Client ID と Client Secret を保存します
ステップ 2:OAuth2 アクセストークンを取得する
認証情報を指定して、認証コマンドを実行します:
TICKTICK_CLIENT_ID=your_client_id \
TICKTICK_CLIENT_SECRET=your_client_secret \
ticktick-sdk auth
次の操作が行われます:
- TickTick の認証ページをブラウザーで開きます
- アプリを認証します:「Authorize」をクリックしてアクセスを許可します
- ターミナルに戻ります:認証後、次のような出力が表示されます:
============================================================
SUCCESS! Here is your access token:
============================================================
a]234abc-5678-90de-f012-34567890abcd
============================================================
NEXT STEPS:
For Claude Code users:
Run (replace YOUR_* placeholders):
claude mcp add ticktick \
-e TICKTICK_CLIENT_ID=YOUR_CLIENT_ID \
...
- このトークンをコピーします:次のステップで必要になります
注:ブラウザーに「invalid credentials」というエラーページが表示されることがあります。その場合はページを更新すると、動作するはずです。
SSH/ヘッドレス環境のユーザー向け:ブラウザーを使わないテキストベースのフローを利用するには、
--manualフラグを追加します。
ステップ 3:AI アシスタントを設定する
Claude Code(推奨)
claude mcp add ticktick \
-e TICKTICK_CLIENT_ID=your_client_id \
-e TICKTICK_CLIENT_SECRET=your_client_secret \
-e TICKTICK_ACCESS_TOKEN=your_access_token \
-e TICKTICK_USERNAME=your_email \
-e TICKTICK_PASSWORD=your_password \
-- ticktick-sdk
注:
TICKTICK_ACCESS_TOKENには、ステップ 2 でコピーしたトークンを貼り付けます。
動作を確認します:
claude mcp list # See all configured servers
/mcp # Within Claude Code, check server status
Claude Desktop
Claude Desktop の設定に追加します:
macOS:~/Library/Application Support/Claude/claude_desktop_config.json
Windows:%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"ticktick": {
"command": "ticktick-sdk",
"env": {
"TICKTICK_CLIENT_ID": "your_client_id",
"TICKTICK_CLIENT_SECRET": "your_client_secret",
"TICKTICK_ACCESS_TOKEN": "your_access_token",
"TICKTICK_USERNAME": "your_email",
"TICKTICK_PASSWORD": "your_password"
}
}
}
}
その他の MCP 対応ツール
このサーバーは、Model Context Protocol に対応するあらゆるツールで動作します。これには、最新の AI アシスタントや IDE のほとんどが含まれます。設定方法は同様です。コマンド(ticktick-sdk)と、上記の環境変数を指定するだけです。
CLI リファレンス
ticktick-sdk コマンドには、いくつかのサブコマンドがあります:
| コマンド | 説明 |
|---|---|
ticktick-sdk | MCP サーバーを起動します(デフォルト) |
ticktick-sdk server | MCP サーバーを起動します(明示的に指定) |
ticktick-sdk server --host HOST | 特定の API ホスト(ticktick.com または dida365.com)を使用します |
ticktick-sdk server --enabledModules MODULES | 特定のツールモジュールのみを有効にします(カンマ区切り) |
ticktick-sdk server --enabledTools TOOLS | 特定のツールのみを有効にします(カンマ区切り) |
ticktick-sdk auth | OAuth2 アクセストークンを取得します(ブラウザーを開きます) |
ticktick-sdk auth --manual | OAuth2 アクセストークンを取得します(SSH に対応) |
ticktick-sdk --version | バージョン情報を表示します |
ticktick-sdk --help | ヘルプメッセージを表示します |
ツールのフィルタリング(AI アシスタントのコンテキストウィンドウの使用量を削減します):
# Enable only task and project tools
ticktick-sdk server --enabledModules tasks,projects
# Enable specific tools only
ticktick-sdk server --enabledTools ticktick_create_tasks,ticktick_list_tasks
# Available modules: tasks, projects, folders, columns, tags, habits, user, focus
会話例
設定が完了したら、Claude に次のようなことを尋ねられます。
- 「今日が期限のタスクは何ですか?」
- 「明日の午後2時に John に電話するタスクを作成して」
- 「優先度の高いタスクを表示して」
- 「食料品の買い物タスクを完了済みにして」
- 「運動の習慣の現在の連続記録は何日ですか?」
- 「今日の瞑想の習慣を記録して」
- 「毎日コップ8杯の水を飲む新しい習慣を作成して」
利用可能な MCP ツール(合計43個)
すべての変更系ツールは、一括操作用のリスト(1~100件)を受け付けます。
タスクツール(一括操作対応)
| ツール | 説明 |
|---|---|
ticktick_create_tasks | タイトル、日付、タグなどを指定して、1~50件のタスクを作成します |
ticktick_get_task | IDでタスクの詳細を取得します |
ticktick_list_tasks | タスクを一覧表示します(ステータスフィルターでアクティブ/完了済み/放棄済み/削除済みを指定できます) |
ticktick_update_tasks | 1~100件のタスクを更新します(列の割り当てを含みます) |
ticktick_complete_tasks | 1~100件のタスクを完了します |
ticktick_delete_tasks | 1~100件のタスクを削除します(ゴミ箱に移動します) |
ticktick_move_tasks | 1~50件のタスクをプロジェクト間で移動します |
ticktick_set_task_parents | 1~50件のタスクに親子関係を設定します |
ticktick_unparent_tasks | 1~50件のタスクから親子関係を解除します |
ticktick_search_tasks | テキストでタスクを検索します |
ticktick_pin_tasks | 1~100件のタスクをピン留め、またはピン留め解除します |
プロジェクトツール
| ツール | 説明 |
|---|---|
ticktick_list_projects | すべてのプロジェクトを一覧表示します |
ticktick_get_project | タスクを含むプロジェクトの詳細を取得します |
ticktick_create_project | 新しいプロジェクトを作成します |
ticktick_update_project | プロジェクトのプロパティを更新します |
ticktick_delete_project | プロジェクトを削除します |
フォルダーツール
| ツール | 説明 |
|---|---|
ticktick_list_folders | すべてのフォルダーを一覧表示します |
ticktick_create_folder | フォルダーを作成します |
ticktick_rename_folder | フォルダーの名前を変更します |
ticktick_delete_folder | フォルダーを削除します |
カンバン列ツール
| ツール | 説明 |
|---|---|
ticktick_list_columns | カンバンプロジェクトの列を一覧表示します |
ticktick_create_column | カンバン列を作成します |
ticktick_update_column | 列の名前または順序を更新します |
ticktick_delete_column | カンバン列を削除します |
タグツール
| ツール | 説明 |
|---|---|
ticktick_list_tags | すべてのタグを一覧表示します |
ticktick_create_tag | 色を指定してタグを作成します |
ticktick_update_tag | タグのプロパティを更新します(label による名前変更を含みます) |
ticktick_delete_tag | タグを削除します |
ticktick_merge_tags | 2つのタグを統合します |
習慣ツール(一括操作対応)
| ツール | 説明 |
|---|---|
ticktick_habits | すべての習慣を一覧表示します |
ticktick_habit | 習慣の詳細を取得します |
ticktick_habit_sections | セクション(朝/午後/夜)を一覧表示します |
ticktick_create_habit | 新しい習慣を作成します |
ticktick_update_habit | 習慣のプロパティを更新します(アーカイブ/アーカイブ解除を含みます) |
ticktick_delete_habit | 習慣を削除します |
ticktick_checkin_habits | 1~50件の習慣を記録します(過去の日付にも対応しています) |
ticktick_habit_checkins | 記録履歴を取得します |
ユーザーと分析ツール
| ツール | 説明 |
|---|---|
ticktick_get_profile | ユーザープロフィールを取得します |
ticktick_get_status | アカウントのステータスを取得します |
ticktick_get_statistics | 生産性の統計情報を取得します |
ticktick_get_preferences | ユーザー設定を取得します |
ticktick_focus_heatmap | 集中度ヒートマップのデータを取得します |
ticktick_focus_by_tag | タグ別の集中時間を取得します |
Python ライブラリのセットアップと使い方
Python アプリケーションで TickTick をプログラムから使用します。
セットアップ
ステップ1:アプリを登録する
MCP のセットアップと同様に、TickTick Developer Portal にアクセスしてアプリを作成します。
ステップ2:.env ファイルを作成する
プロジェクトディレクトリに .env ファイルを作成します。
# V1 API (OAuth2)
TICKTICK_CLIENT_ID=your_client_id_here
TICKTICK_CLIENT_SECRET=your_client_secret_here
TICKTICK_REDIRECT_URI=http://127.0.0.1:8080/callback
TICKTICK_ACCESS_TOKEN= # Will be filled in Step 3
# V2 API (Session)
[email protected]
TICKTICK_PASSWORD=your_ticktick_password
# Optional
TICKTICK_TIMEOUT=30
ステップ3:OAuth2 アクセストークンを取得する
# Source your .env file first, or export the variables
ticktick-sdk auth
アクセストークンを .env ファイルにコピーします。
ステップ4:セットアップを確認する
import asyncio
from ticktick_sdk import TickTickClient
async def test():
async with TickTickClient.from_settings() as client:
profile = await client.get_profile()
print(f'Connected as: {profile.display_name}')
asyncio.run(test())
クイックスタート
import asyncio
from ticktick_sdk import TickTickClient
async def main():
async with TickTickClient.from_settings() as client:
# Create a task
task = await client.create_task(
title="Learn ticktick-sdk",
tags=["python", "productivity"],
)
print(f"Created: {task.title} (ID: {task.id})")
# List all tasks
tasks = await client.get_all_tasks()
print(f"You have {len(tasks)} active tasks")
# Complete the task
await client.complete_task(task.id, task.project_id)
print("Task completed!")
asyncio.run(main())
タスク
タスクの作成
from datetime import datetime, timedelta
from ticktick_sdk import TickTickClient
async with TickTickClient.from_settings() as client:
# Simple task
task = await client.create_task(title="Buy groceries")
# Task with due date and priority
task = await client.create_task(
title="Submit report",
due_date=datetime.now() + timedelta(days=1),
priority="high", # none, low, medium, high
)
# Task with tags and content
task = await client.create_task(
title="Review PR #123",
content="Check for:\n- Code style\n- Tests\n- Documentation",
tags=["work", "code-review"],
)
# Recurring task (MUST include start_date!)
task = await client.create_task(
title="Daily standup",
start_date=datetime(2025, 1, 20, 9, 0),
recurrence="RRULE:FREQ=DAILY;BYDAY=MO,TU,WE,TH,FR",
)
# Task with reminder
task = await client.create_task(
title="Meeting with team",
due_date=datetime(2025, 1, 20, 14, 0),
reminders=["TRIGGER:-PT15M"], # 15 minutes before
)
# All-day task
task = await client.create_task(
title="Project deadline",
due_date=datetime(2025, 1, 31),
all_day=True,
)
タスクの管理
async with TickTickClient.from_settings() as client:
# Get a specific task
task = await client.get_task(task_id="...")
# Update a task
task.title = "Updated title"
task.priority = 5 # high priority
await client.update_task(task)
# Complete a task
await client.complete_task(task_id="...", project_id="...")
# Delete a task (moves to trash)
await client.delete_task(task_id="...", project_id="...")
# Move task to another project
await client.move_task(
task_id="...",
from_project_id="...",
to_project_id="...",
)
サブタスク
async with TickTickClient.from_settings() as client:
# Create parent task
parent = await client.create_task(title="Main task")
# Create child task
child = await client.create_task(title="Subtask")
# Make it a subtask (parent_id in create is ignored by API)
await client.make_subtask(
task_id=child.id,
parent_id=parent.id,
project_id=child.project_id,
)
# Remove parent relationship
await client.unparent_subtask(
task_id=child.id,
project_id=child.project_id,
)
タスクの検索
async with TickTickClient.from_settings() as client:
# All active tasks
all_tasks = await client.get_all_tasks()
# Tasks due today
today = await client.get_today_tasks()
# Overdue tasks
overdue = await client.get_overdue_tasks()
# Tasks by tag
work_tasks = await client.get_tasks_by_tag("work")
# Tasks by priority
urgent = await client.get_tasks_by_priority("high")
# Search tasks
results = await client.search_tasks("meeting")
# Recently completed
completed = await client.get_completed_tasks(days=7, limit=50)
# Abandoned tasks ("won't do")
abandoned = await client.get_abandoned_tasks(days=30)
# Deleted tasks (in trash)
deleted = await client.get_deleted_tasks(limit=50)
プロジェクトとフォルダー
プロジェクト
async with TickTickClient.from_settings() as client:
# List all projects
projects = await client.get_all_projects()
for project in projects:
print(f"{project.name} ({project.id})")
# Get project with all its tasks
project_data = await client.get_project_tasks(project_id="...")
print(f"Project: {project_data.project.name}")
print(f"Tasks: {len(project_data.tasks)}")
# Create a project
project = await client.create_project(
name="Q1 Goals",
color="#4A90D9",
view_mode="kanban", # list, kanban, timeline
)
# Update a project
await client.update_project(
project_id=project.id,
name="Q1 Goals 2025",
color="#FF5500",
)
# Delete a project
await client.delete_project(project_id="...")
フォルダー(プロジェクトグループ)
async with TickTickClient.from_settings() as client:
# List all folders
folders = await client.get_all_folders()
# Create a folder
folder = await client.create_folder(name="Work Projects")
# Create project in folder
project = await client.create_project(
name="Client A",
folder_id=folder.id,
)
# Rename a folder
await client.rename_folder(folder_id=folder.id, name="Work")
# Delete a folder
await client.delete_folder(folder_id="...")
タグ
TickTick のタグは階層(親子関係)とカスタムカラーに対応しています。
async with TickTickClient.from_settings() as client:
# List all tags
tags = await client.get_all_tags()
for tag in tags:
print(f"{tag.label} ({tag.name}) - {tag.color}")
# Create a tag
tag = await client.create_tag(
name="urgent",
color="#FF0000",
)
# Create nested tag
child_tag = await client.create_tag(
name="critical",
parent="urgent", # Parent tag name
)
# Rename a tag
await client.rename_tag(old_name="urgent", new_name="priority")
# Update tag color or parent
await client.update_tag(
name="priority",
color="#FF5500",
)
# Merge tags (move all tasks from source to target)
await client.merge_tags(source="old-tag", target="new-tag")
# Delete a tag
await client.delete_tag(name="obsolete")
習慣
TickTick の習慣は、毎日追跡したい繰り返しの活動です。
習慣の種類
| 種類 | 説明 | 例 |
|---|---|---|
Boolean | はい/いいえのシンプルな形式 | 「今日は運動しましたか?」 |
Real | 数値カウンター | 「何ページ読みましたか?」 |
習慣の作成と管理
async with TickTickClient.from_settings() as client:
# List all habits
habits = await client.get_all_habits()
# Boolean habit (yes/no)
exercise = await client.create_habit(
name="Exercise",
color="#4A90D9",
reminders=["07:00", "19:00"],
target_days=30,
encouragement="Stay strong!",
)
# Numeric habit
reading = await client.create_habit(
name="Read",
habit_type="Real",
goal=30, # 30 pages per day
step=5, # +5 button increment
unit="Pages",
)
# Check in a habit (today)
habit = await client.checkin_habit("habit_id")
print(f"Streak: {habit.current_streak} days!")
# Check in for a past date (backdate)
from datetime import date
habit = await client.checkin_habit("habit_id", checkin_date=date(2025, 12, 15))
# Archive/unarchive
await client.archive_habit("habit_id")
await client.unarchive_habit("habit_id")
習慣の繰り返しルール(RRULE 形式)
| スケジュール | RRULE |
|---|---|
| 毎日(毎日繰り返す) | RRULE:FREQ=WEEKLY;BYDAY=SU,MO,TU,WE,TH,FR,SA |
| 平日のみ | RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR |
| 週末のみ | RRULE:FREQ=WEEKLY;BYDAY=SA,SU |
| 週に X 回 | RRULE:FREQ=WEEKLY;TT_TIMES=5 |
| 特定の曜日 | RRULE:FREQ=WEEKLY;BYDAY=MO,WE,FR |
集中/ポモドーロ
from datetime import date, timedelta
async with TickTickClient.from_settings() as client:
# Focus heatmap (like GitHub contribution graph)
heatmap = await client.get_focus_heatmap(
start_date=date.today() - timedelta(days=90),
end_date=date.today(),
)
# Focus time by tag
by_tag = await client.get_focus_by_tag(days=30)
for tag, seconds in sorted(by_tag.items(), key=lambda x: -x[1]):
hours = seconds / 3600
print(f" {tag}: {hours:.1f} hours")
ユーザーと統計
async with TickTickClient.from_settings() as client:
# User profile
profile = await client.get_profile()
print(f"Username: {profile.username}")
# Account status
status = await client.get_status()
print(f"Pro User: {status.is_pro}")
print(f"Inbox ID: {status.inbox_id}")
# Productivity statistics
stats = await client.get_statistics()
print(f"Level: {stats.level}")
print(f"Score: {stats.score}")
print(f"Tasks completed today: {stats.today_completed}")
エラー処理
from ticktick_sdk import (
TickTickClient,
TickTickError,
TickTickNotFoundError,
TickTickAuthenticationError,
TickTickRateLimitError,
TickTickValidationError,
)
async with TickTickClient.from_settings() as client:
try:
task = await client.get_task("nonexistent-id")
except TickTickNotFoundError as e:
print(f"Task not found: {e}")
except TickTickAuthenticationError:
print("Authentication failed - check credentials")
except TickTickRateLimitError:
print("Rate limited - wait and retry")
except TickTickValidationError as e:
print(f"Invalid input: {e}")
except TickTickError as e:
print(f"TickTick error: {e}")
アーキテクチャ
┌─────────────────────────────────────────────────────────────┐
│ Your Application │
│ (or MCP Server for AI Assistants) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ TickTickClient │
│ High-level, user-friendly async API │
│ (tasks, projects, tags, habits, focus, user methods) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ UnifiedTickTickAPI │
│ Routes calls to V1 or V2, converts responses │
│ to unified Pydantic models │
└─────────────────────────┬───────────────────────────────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────┐
│ V1 API │ │ V2 API │
│ (OAuth2) │ │ (Session) │
│ │ │ │
│ • Official API │ │ • Unofficial API │
│ • Project with tasks │ │ • Tags, folders │
│ • Limited features │ │ • Habits, focus │
│ │ │ • Full subtasks │
└──────────────────────┘ └──────────────────────┘
主な設計上の決定事項
- V2 優先:ほとんどの操作では、より多くの機能を備えた V2 API を使用し、必要な場合にのみ V1 にフォールバックします
- モデルの統一:どの API からデータを取得する場合も、単一の Pydantic モデルセットを使用します
- 全体を非同期化:パフォーマンス向上のため、すべての I/O 操作を非同期で実行します
- 型安全性:完全な型ヒントと Pydantic による検証を備えています
API リファレンス
モデル
| モデル | 説明 |
|---|---|
Task | タイトル、日付、優先度、タグ、サブタスク、繰り返しなどを含むタスク |
Project | タスク用のプロジェクト/リストコンテナー |
ProjectGroup | プロジェクトを整理するためのフォルダー |
ProjectData | タスクを含むプロジェクト(get_project_tasks から取得) |
Column | ボード上のタスクを整理するためのカンバン列 |
Tag | 名前、ラベル、色、および任意の親を持つタグ |
Habit | 種類、目標、連続記録、チェックインを含む繰り返しの習慣 |
HabitSection | 時間帯ごとのグループ(朝/午後/夜) |
HabitCheckin | 個々の習慣のチェックイン記録 |
HabitPreferences | ユーザーの習慣設定 |
User | ユーザープロフィール情報 |
UserStatus | アカウントの状態(Pro、受信トレイ ID など) |
UserStatistics | 生産性統計(レベル、スコア、件数) |
ChecklistItem | タスク内のサブタスク/チェックリスト項目 |
列挙型
| 列挙型 | 値 |
|---|---|
TaskStatus | ABANDONED (-1), ACTIVE (0), COMPLETED (2) |
TaskPriority | NONE (0), LOW (1), MEDIUM (3), HIGH (5) |
TaskKind | TEXT, NOTE, CHECKLIST |
ProjectKind | TASK, NOTE |
ViewMode | LIST, KANBAN, TIMELINE |
例外
| 例外 | 説明 |
|---|---|
TickTickError | すべてのエラーの基底例外 |
TickTickAuthenticationError | 認証に失敗しました |
TickTickNotFoundError | リソースが見つかりません |
TickTickValidationError | 入力データが無効です |
TickTickRateLimitError | レート制限を超過しました |
TickTickConfigurationError | 設定が不足しています |
TickTickForbiddenError | アクセスが拒否されました |
TickTickServerError | サーバー側のエラー |
重要:TickTick API の注意点
TickTick API には、知っておくべきいくつかの独自の動作があります。
1. 繰り返しには start_date が必要です
start_date を指定せずに繰り返しタスクを作成すると、TickTick は繰り返しルールを通知なく無視します。
# WRONG - recurrence will be ignored!
task = await client.create_task(
title="Daily standup",
recurrence="RRULE:FREQ=DAILY",
)
# CORRECT
task = await client.create_task(
title="Daily standup",
start_date=datetime(2025, 1, 20, 9, 0),
recurrence="RRULE:FREQ=DAILY",
)
2. サブタスクには別の呼び出しが必要です
タスク作成時に parent_id を設定しても、API に無視されます。
# Create the child task first
child = await client.create_task(title="Subtask")
# Then make it a subtask
await client.make_subtask(
task_id=child.id,
parent_id="parent_task_id",
project_id=child.project_id,
)
3. 論理削除
タスクを削除すると、完全に削除されるのではなく、ゴミ箱に移動します(deleted=1)。
4. 日付のクリア
タスクの due_date をクリアするには、start_date もクリアする必要があります。
task.due_date = None
task.start_date = None
await client.update_task(task)
5. タグの順序は保持されません
API はタグの順序を保持しないため、タグは任意の順序で返される場合があります。
6. 受信箱は特別です
受信箱は削除できない特別なプロジェクトです。await client.get_status() でその ID を取得します。
環境変数
| 変数 | 必須 | 説明 |
|---|---|---|
TICKTICK_CLIENT_ID | はい | 開発者ポータルで取得した OAuth2 クライアント ID |
TICKTICK_CLIENT_SECRET | はい | OAuth2 クライアントシークレット |
TICKTICK_ACCESS_TOKEN | はい | OAuth2 アクセストークン(認証コマンドで取得) |
TICKTICK_USERNAME | はい | TickTick のメールアドレス |
TICKTICK_PASSWORD | はい | TickTick のパスワード |
TICKTICK_REDIRECT_URI | いいえ | OAuth2 リダイレクト URI(デフォルト:http://127.0.0.1:8080/callback) |
TICKTICK_HOST | いいえ | API ホスト:ticktick.com(デフォルト)または dida365.com(中国語版) |
TICKTICK_TIMEOUT | いいえ | リクエストのタイムアウト(秒)(デフォルト:30) |
TICKTICK_DEVICE_ID | いいえ | V2 API 用のデバイス ID(自動生成) |
テストの実行
# Install dev dependencies
pip install -e ".[dev]"
# All tests (mock mode - no API calls)
pytest
# With verbose output
pytest -v
# Live tests (requires credentials)
pytest --live
# With coverage
pytest --cov=ticktick_sdk --cov-report=term-missing
テストマーカー
| マーカー | 説明 |
|---|---|
unit | ユニットテスト(高速、独立) |
tasks | タスク関連のテスト |
projects | プロジェクト関連のテスト |
tags | タグ関連のテスト |
habits | 習慣関連のテスト |
focus | 集中/ポモドーロのテスト |
pinning | タスクのピン留めテスト |
columns | カンバン列のテスト |
mock_only | モックでのみ動作するテスト |
live_only | --live を指定した場合にのみ実行されるテスト |
トラブルシューティング
「トークン交換に失敗しました」
- クライアント ID とクライアントシークレットが正しいことを確認してください
- リダイレクト URI が完全に一致していること(末尾のスラッシュも含む)を確認してください
- 正しい TickTick 開発者ポータルを使用していることを確認してください
「認証に失敗しました」
- TickTick のユーザー名(メールアドレス)とパスワードを確認してください
- ticktick.com にログインして、認証情報を確認してください
「V2 の初期化に失敗しました」
- パスワードに特殊文字が含まれている可能性があります。変更してみてください
- 2FA/MFA が設定されていないか確認してください(現在はサポートされていません)
「レート制限を超えました」
- 再試行する前に 30~60 秒待ってください
- API 呼び出しの頻度を下げてください
コントリビューション
コントリビューションを歓迎します。次の手順に従ってください。
- リポジトリをフォークします
- 機能ブランチを作成します(
git checkout -b feature/amazing-feature) - 新しい機能のテストを作成します
- すべてのテストに合格することを確認します(
pytest) - 型チェックを実行します(
mypy src/) - プルリクエストを送信します
開発環境のセットアップ
git clone https://github.com/dev-mirzabicer/ticktick-sdk.git
cd ticktick-sdk
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
ライセンス
MIT License - 詳細は LICENSE を参照してください。
謝辞
- 優れたタスク管理アプリを提供する TickTick
- AI 統合標準を提供する Model Context Protocol
- MCP フレームワークを提供する FastMCP
- データ検証用の Pydantic
- 非同期 HTTP 用の httpx
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。