Skip to main content
Glama

todo-mcp

TODO.md をストアとするMCPサーバーです。TODO.md は手動で読み・編集・diff ができます。書き込みはバイト範囲のスプライスなので、ファイルは常にあなたのもののままです。手書きのテーブル、タブインデント、タスク外の散文が再シリアライズされることはありません。

MCPクライアントにはstdioで、それ以外にはStreamable HTTPで応答します。

クレジット

CalamityAdam/mcp-todo をベースにしています。createTodoMcpServer ファクトリの形やExpress の Streamable HTTP ラッパー、セッション処理というオリジナルのスキャフォールドを提供してくれました。

それ以外はほとんど残っていません。そのバージョンは ~/.mcp-todos.json のJSONブロブに番号付きレコードとしてtodosを保存し、{ id, title, done } に対する3つのツールを持っていました。このバージョンはストアをマークダウンドキュメントに置き換え、数値IDをスラグに変更し、ステータス、エリア、参照ブレッドクラム、日付入りログノート、全文検索、重複検出を備えた7つのツールへ拡張しました。2つのプロジェクトはもはや実装を共有していません。

アップストリームには LICENSE ファイルがありません。package.json はISCを宣言しており、このリポジトリはそれを引き継いでいます。

Related MCP server: MCP Project Manager

インストール

GitHubから直接実行できます。クローンは不要です。

npx github:adrianhardy/todo-mcp

変更をプッシュしたら、npx --ignore-existing github:adrianhardy/todo-mcp で変更を取り込めます。

通常の利用では、一度インストールすればあとは忘れて構いません。

npm i -g github:adrianhardy/todo-mcp
todo-mcp

どちらの方法でも、インストール時に prepare スクリプトがソースからビルドするため、dist/ がコミットされることはありません。Node 20 以降が必要です。

使い方

todo-mcp はデフォルトで HTTP サーバーを起動します。人がターミナルでサーバーを実行するときに便利だからです。MCPクライアントがサブプロセスとして起動する際に必要なstdioで通信したい場合は、MCP_STDIO=1 を設定してください。

MCPクライアントで利用する

{
  "mcpServers": {
    "todo": {
      "command": "npx",
      "args": ["-y", "github:adrianhardy/todo-mcp"],
      "env": { "MCP_STDIO": "1" }
    }
  }
}

グローバルにインストールした場合、同じ env ブロックで "command": "todo-mcp" になります。

どのファイルを使用するかは作業ディレクトリが決めます。 TODO_FILE はプロセスのcwdを基準に解決され、デフォルトは TODO.md です。プロジェクト内で起動したクライアントは、そのプロジェクトのTODOリストを編集します。サーバーをどこから起動しても共有のリストを使いたい場合は、TODO_FILE に絶対パスを設定してください。

HTTPで利用する

PORT=8080 TODO_MCP_TOKEN=$(openssl rand -hex 32) todo-mcp
  • POST /mcp - JSON-RPCリクエスト

  • GET /mcp - サーバー通知のSSEストリーム

  • DELETE /mcp - セッションを終了する

TODO_MCP_TOKEN を設定すると、この3つすべての操作に Authorization: Bearer <token> が必要になります。未設定にすると認証なしで通信でき、これはlocalhostでは問題ありませんが、それ以外の環境では許容できません。

設定

変数

デフォルト

意味

TODO_FILE

TODO.md

ストアのパス。cwdから解決される

MCP_STDIO

未設定

1 でHTTPではなくstdioを選択

PORT

3000

HTTPポート

TODO_MCP_TOKEN

未設定

bearerトークン。未設定は認証なし

.env ファイルがあれば読み込まれます。.env.example を参照してください。

ストレージ

TODO.md はJSONブロブではなくストアです。ファイル自体が記録であり、読み取り可能で、手動編集でき、gitでdiffを取ることができます。

タスクは ## セクションです。サーバーが所有するフィールドは見出し直下のコメントブロックにあり、その下は人間が所有する散文です。

## Feature Idea version two: the new widget which tracks things

<!-- todo
id: feature-idea-version-two
area: inventory
status: next
refs: [./src/do_stuff.ts, ClassName.Method, OtherClassName]
created: 2026-08-19
updated: 2026-08-22
-->

**Next step:** close the ledger. ClassName.Method uses 0.25 and it needs 17.2%.

**Already known:** ...

### Log

- 2026-08-22 Slab_Wall_1x3 not started; parade places 24 of those to every 6 of the 3x3.

IDは数字ではなくslugなので、並べ替えや削除があっても保たれます。ファイルの順序が優先順位なので、優先度フィールドはありません。

書き込みは バイト範囲スプライス です。mutationは自分が所有する範囲だけを書き換えます。手書きのテーブル、タブインデント、タスクセクション外の散文は決して再シリアライズされないため、並べ直されたり失われたりすることはありません。ハンドラーはロックにより直列化されています。というのも、read-modify-writeのサイクルが2回交錯すると、もはやファイルを表さないオフセットへスプライスしてしまうからです。

設計

  • リストは省略表現 — list_todos は1行のインデックスを返し、タスク本文は返しません。get_todo は1つのセクション全体を返します。q と ref が想定される遷移路で、全件の一覧取得は例外です。

  • 捕捉は1フィールドでok — 必須なのは title だけ。新しいタスクのステータスはデフォルトで captured になります。何かに気づいた瞬間にエリアと次のステップを要求するツールは使用されません。ファイルが役に立つのは、気づいたことをそのまま書き留められる場合だけです。トリアージは後で captured を open / next / parked / someday へ移動させます。

ステータス値

ステータス

意味

captured

未加工・未トリアージ。新規タスクの既定。フィルタなしリストでは非表示

open

理解済みの実際の作業

next

次に行う

parked

意図的に延期。理由は本文に書く

someday

いつかやりたい

done

完了。記録としてファイルに残る。フィルタなしリストでは非表示

ツール

  • list_todos - 省略インデックス。area・status・ref・q・limit でフィルタ

  • get_todo - 1タスクの完全なマークダウン、本文を含む

  • add_todo - タスクを拾う。必須は title のみ。重複の可能性を報告

  • update_todo - 任意のフィールドを変更。渡されたものだけ書き換える

  • append_note - 日付入りの箇条書きをタスクのログに追加

  • set_status - タスクをトリアージで進める

  • remove_todo - タスクとその散文を削除。できれば set_status done を使う

リソース

  • todos://list - 未完了タスクの1行インデックス

アーキテクチャ

  • src/todo.ts - マークダウンストア: パース、バイト範囲パッチ、クエリ、重複排除

  • src/server.ts - MCPツール群。pure factoryでimportしても副作用なし

  • src/http.ts - Streamable HTTPトランスポート、認証、セッションマップ

  • src/cli.ts - todo-mcp の実行ファイル。トランスポートを選んで起動する

Related MCP Connectors

Related MCP Servers