ticktick-mcp について
ticktick-mcpは、Claude CodeなどのMCPクライアントからTickTickのタスクを管理するサーバーです。タスクの一連の操作に加え、指定外フィールドの保持、書き込み後の再確認、完了タスクの追跡に対応します。
主な機能
- 01タスクの作成、更新、完了、移動
- 02更新で指定外フィールドを保持
- 03日付設定時の曜日検証
- 04書き込み後の再取得と確認
- 05未確認の完了タスクを追跡
活用シーン
- 01プロジェクトや期限でタスクを絞り込み
- 02他のフィールドを残してタスクを更新
- 03サーバー外で完了したタスクを確認
MCP 対応
MCPサーバーはタスクの作成、検索、更新、削除、絞り込み、完了追跡のツールをクライアントに提供し、必要に応じてTickTickの状態を同期します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e TICKTICK_CLIENT_ID -e TICKTICK_CLIENT_SECRET -e TICKTICK_USERNAME -e TICKTICK_PASSWORD ghcr.io/partymola/ticktick-mcp:v0.5.0TICKTICK_CLIENT_IDTickTick OAuth client ID. Needed only if you are not mounting a .env file.TICKTICK_CLIENT_SECRETシークレットTickTick OAuth client secret. Needed only if you are not mounting a .env file.TICKTICK_USERNAMETickTick account username. Needed only if you are not mounting a .env file.TICKTICK_PASSWORDシークレットTickTick account password. Needed only if you are not mounting a .env file.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/partymola/ticktick-mcp:v0.5.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
ticktick-mcp
TickTick のタスク管理用 MCP サーバーです。TickTick v2 API を介してタスクの作成、更新、完了、移動、絞り込みを行えます。フィールドを保持した更新、曜日の日付検証、書き込み後の検証、冪等な完了追跡に対応しています。
Claude Code やその他の MCP クライアント向けに設計されています。
非公式です。TickTick Ltd. とは提携していません。ticktick-py(MIT)を基盤に構築されています。
機能
- タスクのライフサイクル全般 - 作成、更新、完了、移動、サブタスク化、削除
- フィールドを保持した更新 -
ticktick_update_taskはタスクを再取得し、設定したフィールドのみを重ねて適用するため、省略したフィールドが API によって消去されることはありません - 曜日の検証 - 日付を設定する呼び出しでは曜日の確認が必要です。これにより、サーバーに届く前に日付のずれを検出できます
- 書き込み後の検証 - 作成/更新後にタスクを再読み込みし、サーバーからの応答が一致しない場合は
_verification_warningsを表示します - コンパクトな一覧表示 - 一覧ツールはデフォルトで情報を絞ったビューを返すため、大規模なプロジェクトでも MCP の結果サイズ上限を超えません(下記参照)
- 最新情報の読み込み - 読み取りツールは必要に応じてサーバーの状態を再同期するため、他のデバイスの TickTick アプリで行った編集も再起動せずに反映されます
- 完了の追跡 - 完了したタスクを処理済みとして記録し、エージェントが各タスクを一度だけ確認できるようにします。このサーバー経由で完了したタスクも自動的に記録されます
要件
- Python 3.13+(CI で Linux、macOS、Windows 上の 3.13 および 3.14 をテスト済み)
- uv(推奨。インストールに関する注意は下記を参照)
- TickTick アカウント
- OAuth 認証情報用に登録した TickTick アプリ(無料 - developer.ticktick.com)
インストール
git clone https://github.com/partymola/ticktick-mcp
cd ticktick-mcp
uv sync
これにより .venv が作成され、uv.lock を使ってインストールされます。コンソールスクリプトは .venv/bin/ticktick-mcp、Windows では .venv\Scripts\ticktick-mcp に配置されます。以下のコマンドではすべて POSIX 形式で記載しています。
pip install . も使用できます。このサーバーが必要とする ticktick-py のフォークは、dependencies 内で直接の git 参照として固定されており、pip と uv の両方で利用できます。uv sync を推奨します。依存関係を再解決するのではなく、uv.lock に記載された正確なバージョンをインストールするためです。
認証情報
TickTick へのサインインには、OAuth アプリ(クライアント ID とシークレット)と、ご自身のアカウントへのログイン情報が必要です。
-
developer.ticktick.com でアプリを登録します。Redirect URI を
http://localhost:8080/redirectに設定します。Client ID と Client Secret を控えておきます。 -
テンプレートをサーバーが読み込むディレクトリにコピーし、内容を記入します。
mkdir -p ~/.config/ticktick-mcp && cp .env.example ~/.config/ticktick-mcp/.envTICKTICK_CLIENT_ID=your_client_id TICKTICK_CLIENT_SECRET=your_client_secret TICKTICK_REDIRECT_URI=http://localhost:8080/redirect TICKTICK_USERNAME=your_ticktick_email TICKTICK_PASSWORD=your_ticktick_password -
このファイルにはアカウントのパスワードが平文で保存されます。また、サーバーはファイルを作成しないため、アクセス権を自分で厳しく設定してください。POSIX の場合:
chmod 700 ~/.config/ticktick-mcp chmod 600 ~/.config/ticktick-mcp/.envこれらは POSIX のアクセス権ビットです。Windows では機能せず、アクセス権は親ディレクトリから継承される ACL に従います。ここでは、2 つのコマンドに相当する Windows の方法は説明していません。
その隣にある 2 つのトークンファイルは所有者のみがアクセスできる設定で作成され、サーバーが作成する設定ディレクトリも同様です。ただし、すでに存在するディレクトリが見つかった場合は、そのまま変更されません。これらも POSIX のアクセス権であり、Windows でも設定されますが、誰が読み取れるかを制限する効果はありません。
サーバーを登録する前に、ターミナルで一度認証してください:
.venv/bin/ticktick-mcp auth
ブラウザーが開き、遷移先の URL を貼り付けるよう求められたあと、終了します。トークンは .env と同じ場所に .token-oauth としてキャッシュされ、以降の起動では毎回再利用されます。TickTick はリフレッシュトークンを発行しないため、トークンの有効期限が切れたら同じコマンドを再実行してください。
この手順を MCP サーバー内で実行しないでください。プロンプトは標準入力から読み取りますが、stdio サーバーでは標準入力が JSON-RPC チャネルであるため、未認証状態で最初のツール呼び出しを行うと、ホスト上でブラウザーが開き、処理がブロックされます。コンテナー内では完了できません。ホスト上で auth を実行し、設定ディレクトリをマウントしてください。
ユーザー名とパスワードについては、別の手順は必要ありません。サーバーは最初のツール呼び出し時にログインし、そのセッショントークンを .token-v2 としてキャッシュするため、起動のたびに認証情報を再送信することはありません。
サーバーは次の順序で .env を探します。--dotenv-dir <path> 引数、TICKTICK_MCP_DOTENV_DIR 環境変数、~/.config/ticktick-mcp/ の順です。.env が見つからない場合は、代わりに TICKTICK_* 環境変数を直接使用します。これはコンテナーや CI での使用に便利です。
プライバシーと非公式 API
TickTick の認証情報はローカルの .env(または環境変数)にのみ保存され、TickTick のサーバーにのみ送信されます。開発者や第三者に送信されることはありません。サーバーはご自身のアカウントのみを読み書きします。
このサーバーは公式 Open API ではなく、ticktick-py 経由で TickTick の非公式 v2 API を使用します。これは意図的な選択です。公式 API には、完了済みタスクの一覧取得エンドポイント、タグ、プロジェクトをまたいだタスク一覧取得がなく、いずれもこのサーバーが必要とする機能です。選択の根拠、リスクとのトレードオフ、方針を再検討するきっかけについて詳しくは、docs/why-not-the-official-api.md をご覧ください。
Claude Code への登録
claude mcp add -s user ticktick -- /path/to/ticktick-mcp/.venv/bin/ticktick-mcp --dotenv-dir /path/to/config
.env が ~/.config/ticktick-mcp/ にある場合、または TICKTICK_* 変数を環境経由で指定する場合は、--dotenv-dir は省略できます。
その後、Claude に次のようなことを尋ねてください。
- 「今週の TickTick リストには何がある?」
- 「金曜日の午前 9 時に歯医者へ電話するタスクを追加して。」
- 「食料品のタスクを完了にして。」
- 「予算のタスクを Finance プロジェクトに移動して。」
Docker
イメージは ghcr.io/partymola/ticktick-mcp に公開されています。タグには v プレフィックスが付き(:vX.Y.Z)、:latest は最新リリースを指します。
まずブラウザーのあるマシンで認証し、そのディレクトリをマウントしてください。 これが唯一の方法であり、docker run -it を使う場合も同様です。基盤となるライブラリはブラウザーを自ら開き、URL を出力することはありません。そのため、ブラウザーのないコンテナから URL をコピーすることはできません。その後、標準入力から URL が入力されるのを待ちます。stdio サーバーの場合、これは JSON-RPC チャネルです。そのため、トークンがキャッシュされていないディレクトリを指定してコンテナを起動しても、正常に失敗するわけではありません。到着しない入力を待ちながら、クライアントのリクエストを消費してしまいます。
認証には、ソースからのインストール(インストール)と認証情報に記載された情報が必要です。実行に使える公開パッケージはありません。pip install ticktick-mcp は実行しないでください。 PyPI 上のその名前のパッケージは、説明がほぼ同一の無関係なプロジェクトのものです。
.venv/bin/ticktick-mcp auth # once, on the host, in a terminal
claude mcp add -s user ticktick -- \
docker run --rm -i --user $(id -u):$(id -g) \
-v ~/.config/ticktick-mcp:/data \
ghcr.io/partymola/ticktick-mcp:latest
サーバーは stdin と stdout で JSON-RPC を通信するため、-i が必要です。
コンテナはデフォルトで root として実行され、マウントしたディレクトリに書き込まれるファイルも root 所有になります。そうなると、ホスト側の ticktick-mcp はセッショントークンのキャッシュを更新できなくなり、起動のたびに、スロットリングされたサインオンにフォールバックします。そのため、--user を指定しています。ホストでも再び実行することになります。OAuth トークンには更新機能がないため、有効期限が切れると auth が再度必要です。
すでに認証済みのディレクトリをマウントしてください。空のボリュームは使用しないでください。 /data には .env、キャッシュされた OAuth トークン、v2 セッショントークン、完了状況の追跡データベースが保存されます。新しいボリュームにはこれらがなく、パスワードによるサインオンのフォールバックはスロットリングされ、15~30 分間ロックアウトされます。
.env をディスクに保存したくない場合は、代わりに環境変数として認証情報を渡してください。マウントは引き続き必要です。ここには .env だけでなく、トークンキャッシュも保存されます。
docker run --rm -i --user $(id -u):$(id -g) \
-v ~/.config/ticktick-mcp:/data \
-e TICKTICK_CLIENT_ID -e TICKTICK_CLIENT_SECRET \
-e TICKTICK_USERNAME -e TICKTICK_PASSWORD \
ghcr.io/partymola/ticktick-mcp:latest
各変数名だけを値なしで指定すると、シェルからその値が引き継がれるため、コマンドやシェル履歴にシークレットが残りません。これらの変数は、マウントした .env の値を上書きします。ファイルは override なしで読み込まれるため、すでに環境に設定されている値が優先されます。auth も読み込む .env がないため、認証時にもホスト上でこれらの変数をエクスポートしておく必要があります。
CLI
ticktick-mcp Start the MCP server (stdio transport)
ticktick-mcp --dotenv-dir PATH Directory holding the .env file
ticktick-mcp --version Print the installed package version
もう一方の唯一のサブコマンドは auth です。これは、ブラウザーを使う手順をサーバー内ではなくターミナル上で実行するためのものです。タスクに関するすべての操作は、以下の MCP ツールを通じて行います。
MCP ツール
| ツール | 説明 |
|---|---|
ticktick_create_task | 日付/リマインダー/優先度/タイムゾーンの各フィールドを保持してタスクを作成します。作成結果について確認が必要な事項があれば、_verification_warnings を付加します |
ticktick_update_task | 設定したフィールドのみを現在のサーバーオブジェクトに重ねてタスクを更新します(省略したフィールドが消去されることはありません) |
ticktick_complete_task | タスクを完了にして再確認します。繰り返しタスクが次の期日に進んだ場合と通常の完了を区別し、完了を処理済みとして記録します |
ticktick_delete_tasks | ID を指定して 1 つ以上のタスクを削除します |
ticktick_move_task | タスクを別のプロジェクトに移動します |
ticktick_make_subtask | 同じプロジェクト内のタスクを、別のタスクのサブタスクにします |
ticktick_get_tasks_from_project | プロジェクト内の未完了タスクをすべて一覧表示します(簡易表示または全項目表示) |
ticktick_filter_tasks | プロジェクト、優先度、タグ、ステータス、期限/完了日の範囲を組み合わせてタスクを検索します |
ticktick_get_by_id | 完全な ID を指定して、タスク、プロジェクト、またはタグを検索します |
ticktick_get_all | ローカルの状態からすべてのプロジェクトまたはすべてのタグを取得します |
ticktick_sync | サーバーからローカルの状態をただちに更新します |
ticktick_get_unprocessed_completions | プロジェクト内で最近完了したタスクのうち、処理済みとしてまだ記録されていないものを一覧表示します。実際には、このサーバー以外で完了したタスクが対象です |
ticktick_mark_completion_processed | 完了したタスクを確認済みとして記録し、以降の確認対象から除外します |
ticktick_convert_datetime_to_ticktick_format | ISO 8601 の日時と IANA タイムゾーンを TickTick のワイヤ形式に変換します |
プロジェクト:名前または ID
プロジェクト ID を受け取るすべてのツールでは、プロジェクトの名前も使用できます。対象は ticktick_create_task、ticktick_get_tasks_from_project、ticktick_update_task、ticktick_move_task、ticktick_delete_tasks、ticktick_filter_tasks、および 2 つの完了追跡ツールです。
ticktick_create_task(title="Renew insurance", project_id="Home Admin")
名前は大文字と小文字を区別せず、前後の空白を無視して照合されます。また、"Inbox" は受信トレイとして解決されます。ID はそのまま使用でき、常に名前より優先されます。
同じ名前のプロジェクトが 2 つある場合、どちらかを選ばず、両方の ID を示して呼び出しは失敗します。推測によって、意図した場所とは別の場所にタスクが登録されるのを防ぐためです。
3 つのツールは、参照先を特定できないまま渡すのではなく、使用前にその参照先を確認します。2 つの完了追跡ツールが確認するのは、その値がローカルデータベースへの書き込みキーであり、解決できない値で書き込むと、後から ID で検索しても見つからない行が作成されるためです。ticktick_filter_tasks が確認するのは、ローカルでフィルタリングするためです。未知のプロジェクトをそのまま渡すと、空のリストが返り、「そのようなプロジェクトはない」ではなく「一致するタスクがない」と受け取られるおそれがあります。3 つのツールはいずれも、2 種類の失敗を区別します。確認のためにプロジェクト一覧を更新できなかった場合は、プロジェクトが存在しないと断定せず、その旨を伝えます(outcome: "project_list_unverifiable")。
それ以外のツールでは、認識されない値は変更せずに渡されます。その場合、ticktick_get_tasks_from_project と ticktick_move_task は、リクエストを送信する前にクライアントライブラリ独自のローカル検索で失敗します。ticktick_create_task、ticktick_update_task、ticktick_delete_tasks は、その値を使用する場合に TickTick へ送信します。
タスクの一覧表示:デフォルトではコンパクト
リストを返すツールである ticktick_get_tasks_from_project と ticktick_filter_tasks は、デフォルトで detail="compact" を使用します。コンパクト出力には、一覧表示に必要なフィールド(id、projectId、title、dueDate、startDate、priority、status、isAllDay、timeZone、tags)と contentPreview(content の先頭約200文字)が含まれます。一方、サイズの大きい content/desc/チェックリストの items のデータや、かさばる同期メタデータは除外されます。これにより、大規模なプロジェクトでも MCP の結果サイズ上限を超えず、クライアントが結果をディスクに書き出す必要がなくなります。キーワード検索は引き続き title と contentPreview を対象に行われます。
- オブジェクト全体が必要ですか?
detail="full"を指定してください。 - 1つのタスクの完全な内容が必要ですか?
ticktick_get_by_idを使用してください。 - タスクの編集: まず
ticktick_get_by_idでオブジェクト全体を取得し、その後ticktick_update_taskにすべてのフィールドを渡してください。TickTick API は更新時に省略されたフィールドを消去するため、コンパクト出力を更新に使用してはいけません。
コンパクトな結果でもサイズ上限を超える場合は、期限が最も近いタスクが返され、最後の要素 _truncation_note に省略された件数が記載されます。何も通知されずに削除されることはありません。残りのタスクには、より絞り込んだ ticktick_filter_tasks クエリ、detail="full"、または ticktick_get_by_id を使ってアクセスしてください。
最新性:読み取り結果は常に最新
サーバーの実行中に、ほかのデバイスのアプリから TickTick アカウントを編集できます。読み取り結果が古くならないよう、読み取りツールは必要に応じてサーバーの状態を再同期します。ただし、再同期はウィンドウごとに最大1回に制限されます(デフォルトは15秒で、TICKTICK_MCP_SYNC_TTL_SECONDS で変更できます)。別の場所で行われた変更は、そのウィンドウ内に反映されます。すぐに更新して最新のタスク数とプロジェクト数を取得するには、ticktick_sync を呼び出してください。同期に失敗した場合は、エラーを返すのではなく最後に確認された状態を返します。ただし ticktick_get_all は例外で、毎回更新を行い、失敗した場合はその失敗を報告します。全データの取得時に、古い結果をひそかに返すのは適切ではないためです。
完了状況の追跡:キューの目的
ticktick_get_unprocessed_completions は、プロジェクト内で完了済みのタスクのうち、まだエージェントが対応を記録していないものを一覧表示し、ticktick_mark_completion_processed はその対応を記録します。このキューの目的は、あなたが完了させたのではないタスクの完了を扱うことです。つまり、TickTick アプリでチェックを付けたタスクについて、何が起きたかを説明するメモを読むためのものです。
そのため、ticktick_complete_task は自らが完了させたタスクを記録し、記録が成功したかどうかを completion_recorded として報告します。どちらの場合もタスクは完了しています。記録は API 呼び出しの後に書き込まれ、ローカルへの書き込みが失敗した場合はエラーにするのではなくログに記録されるためです。このサーバー経由でタスクを完了した後に ticktick_mark_completion_processed を呼び出す必要はありません。ここですでに記録されているタスクに対して呼び出しても、何も起こりません。
設計上、対応していないケースが1つあります。繰り返しタスクを完了すると、完了したインスタンスは新しい ID で登録されますが、完了処理の呼び出しではその ID を取得できません。そのため、誰が完了させたかにかかわらず、そのインスタンスはキューに入ります。繰り返しタスクの完了については、どのような形でも記録されず、結果に completion_recorded は false ではなく、そもそも含まれません。補うために系列の ID に対して ticktick_mark_completion_processed を呼び出さないでください。キューに表示されている ID とは異なるため、その行は何も消去しません。
ticktick_update_task でタスクを再開すると、以前の完了記録が消去されます。そのため、次の完了は通常どおり表示されます。status: 0 を設定すると、記録は削除されます。そうしないと、このサーバー経由で完了したタスクは、後からアプリでメモ付きで完了にした場合も含め、その後ずっとキューに表示されなくなります。一方、アプリでタスクを再開した場合は記録が保持されるため、その後アプリで完了してもキューには表示されません。
記録は、.env とトークンキャッシュの隣にある completion_tracking.db に保存されます。
設定
| 変数 | デフォルト | 説明 |
|---|---|---|
TICKTICK_MCP_DOTENV_DIR | ~/.config/ticktick-mcp/ | .env、キャッシュされたトークン、完了追跡データベースを格納するディレクトリです(--dotenv-dir 引数が優先されます)。コンテナーイメージでは /data に設定されています |
TICKTICK_MCP_SYNC_TTL_SECONDS | 15 | オンデマンドの読み取り再同期の最小間隔(秒)です |
TICKTICK_MCP_INIT_RETRY_SECONDS | 60 | 最初の接続に失敗した後、クライアントのログインを再試行するまでの待機時間です |
TICKTICK_MCP_RATELIMIT_RETRY_SECONDS | 300 | レート制限(HTTP 429)の後、ログインを再試行するまでの待機時間です。429 の解消には時間がかかり、再試行のたびに制限が長引くため、初回接続時の待機時間より長く設定されています |
TICKTICK_MCP_PROTECTED_TASK_IDS | 未設定 | エージェントによる変更を禁止するタスク ID です。スペースまたはカンマで区切ります。すべての変更ツールは何も送信する前に拒否します。読み取りには影響しません。未設定の場合、保護は行われません。 |
タスクを変更から保護する
エージェントにどのような操作を指示しても、変更してはならないタスクがあります。その ID を TICKTICK_MCP_PROTECTED_TASK_IDS に指定してください。
TICKTICK_MCP_PROTECTED_TASK_IDS="60ca9dbc8f08516d9dd56324,60ca9dbc8f08516d9dd56325"
ticktick_update_task、ticktick_complete_task、ticktick_delete_tasks、ticktick_move_task、ticktick_make_subtask は、保護対象のタスクを指定する呼び出しを拒否し、outcome: "protected_task" を返します。タスクの読み取りや書き込みを行うリクエストは送信されません。保護対象の ID を含む一括削除は、部分的な削除を元に戻せないため、一部だけ適用するのではなく全体が拒否されます。
TickTick では削除と移動がサブタスクにも伝播するため、保護対象のタスクが指定したタスクの親タスクまたはサブタスクである場合も、delete、move、make_subtask は拒否されます。この確認では最初にローカル状態を更新するため、保護が設定されている場合、削除、移動、親タスクの変更ごとにリクエストが 1 回追加されます。更新に失敗すると、更新できなかったスナップショット上で保護対象のサブタスクが存在しないと判断できないため、outcome: "protection_unverifiable" が返されます。この変数が未設定の場合、追加の処理は一切行われません。ID は前後の空白、引用符、大文字と小文字を無視して照合されます。保護対象のタスクは常に読み取れます。
認証情報(TICKTICK_CLIENT_ID、TICKTICK_CLIENT_SECRET、TICKTICK_REDIRECT_URI、TICKTICK_USERNAME、TICKTICK_PASSWORD)は、.env ファイルから読み込まれます。ファイルにない場合は、環境変数から直接読み込まれます。
データの安全性
pre-commit フック(scripts/check-no-data.sh)は、*.db ファイルとそのバックアップファイル、.gitkeep を除く config/ 以下のすべてのファイル、*.example および *.example.*、さらに 100KB を超えるファイル(uv.lock を除く)が誤ってコミットされるのを防ぎます。ファイルの内容は読み取りません。クローン後にインストールしてください。
ln -sf ../../scripts/check-no-data.sh .git/hooks/pre-commit
コントリビューション
開発環境のセットアップ、テストのワークフロー、pre-commit フックについては、CONTRIBUTING.md を参照してください。変更履歴は CHANGELOG.md で確認できます。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。