課題:MCP経由での反復作業が招く「ディレクトリの乱立」

本プロジェクトで採用している「記事ごとに連番ディレクトリ(34-slug/など)を自動生成して管理する」という独自の運用ルールと、MCP(Model Context Protocol)によるエージェントの操作は、そのままでは非常に相性が悪いことが判明しました。

問題は、MCPツールの呼び出しが基本的にステートレス状態を持たない)であることに起因します。

何が起きたか

本プロジェクトでは、AIエージェントが記事を執筆・入稿するための専用ツールとして、自作のMCPツール draft_post を使用しています。このツール本来の役割は、「外部の原稿(Seedファイル)を受け取り、プロジェクト内の適切なディレクトリに連番を振って配置する」という入稿の自動化でした。

しかし、以下のような作業フローにおいて、設計上の致命的な欠陥が露呈しました。

  1. 初回入稿: エージェントが /path/to/seed.md を作成し、draft_post でプロジェクト(例:2026-01)へ送信。 → サーバーは 34-slug/article.md を新規作成する。
  2. 修正指示: 人間が「タイトルを少し変えて」と指示。
  3. 修正・再送: エージェントは手元の /path/to/seed.md を編集し、再度修正版を draft_post で送信する。

このとき、ツール側はリクエストが来るたびに「これは新しい入稿だ」と愚直に判断し、新しい連番を一つずつ増やして配置してしまいます。その結果、修正を重ねるほどリポジトリ内には実体のない「枝番」のようなディレクトリが乱立し、管理が即座に破綻してしまったのです。

  • /34-mcp-article/article.md(初稿)
  • /35-mcp-article/article.md(1回目の修正)
  • /36-mcp-article/article.md(2回目の修正)

これはAIの習性の問題ではなく、「連番というステートフルな管理体系」に対して、「一回限りの命令として設計されたツール」をぶつけたことによる設計の不整合です。

解決策:外部ファイルを「永続的な種(Seed)」として定義する

この不整合を解消するため、我々は外部にある原稿ファイルを、単なる一時的なデータではなく「プロジェクト内記事のアイデンティティを決定する種Seed)」として再定義しました。

具体的には、送信元ファイル(外部ファイル)の絶対パスから一意な source_id を生成し、記事のFrontmatterに永続化させる仕組みを導入しました。

「パスをハッシュ化する」ことの意味

なぜ内容のハッシュではなく「パスのハッシュ」なのか。ここが設計の肝です。

  • 執筆中の「場所」は変わらない: AIエージェントは、人間からの修正指示を受けるたびに、手元の原稿ファイル(例:seed.md)に対して編集操作を行い、その最新状態をツールに渡します。
  • 場所をIdentityにする: 内容がどれだけ書き換わっても、「その場所にあるファイル」である限り、ハッシュ(source_id)は不変です。
  • 不変の紐付け: プロジェクト側に一度この ID を書き込んでしまえば、外の世界(編集中の原稿)と中の世界(リポジトリの記事)の間に、堅牢な架け橋が架かります。

Upsertによる自動同期のフロー

サーバー側は、ツールが呼ばれるたびに以下の「紐付け確認」を自動で行います。

  1. パスの特定: ツールに渡された原稿パス(FILE:path/to/seed.md)から絶対パスを取得。
  2. Identity計算: その絶対パスをハッシュ化して source_id を算出。
  3. リポジトリスキャン: projects/ 下の既存記事から、同じIDを持つ Frontmatter を探す。
  4. 自動的な振る舞いの切り替え:
    • IDが見つかった: 「これは以前この seed.md から作られた記事の更新だ」と判断し、既存ディレクトリを上書き。
    • IDが見つからない: 「これは新しい種(Seed)による新規記事だ」と判断し、新しい連番を発行。

設計の教訓:ステートレスな命令を、場所の不変性でステートフルに繋ぐ

エージェントが「今これが新規か更新か」という状態を意識しなくても、サーバー側が「呼び出し元の場所」を見ることで、暗黙的に状態を復元(Upsert化)できます。 この「場所の不変性(Path as Identity)」を活用した設計によって、リポジトリの美しさを保ちつつ、エージェントには自由な執筆・修正環境を提供することが可能になりました。

まとめ

MCPを介したローカルリポジトリ操作において、ツールの冪等性は単なる「便利機能」ではなく、プロジェクトの整合性を保つための「必須要件」です。 source_id という単純な Identity 管理を挟むだけで、ステートフルなディレクトリ管理とステートレスなMCPツール呼び出しは、見事に調和させることができます。