ボトルネックはコピペではなく往復だった — claude.aiからClaude Codeへブリーフを直接渡す仕組み(cc-bridge)を作るまで【1/4】

この記事はシリーズの1本目です。自宅のMac Studioで動かしている「claude.ai(PM役)とClaude Code(実装役)の受け渡しを自動化する仕組み(cc-bridge)」について、発案から1か月分の顛末を4本に分けて書きます。1本目は作る前の話、つまり何が問題で、何を作ることにしたか、です。

1. 間に挟まっていたのは私だった

このブログで何度か書いているとおり、私の開発はこういう分担でやっています。

  • claude.ai(チャット): 方針を相談し、作業指示(ブリーフ)を書いてもらい、結果を読んで次を決める。PM役
  • Claude Code(Mac Studio上): ブリーフを受け取って実装する。実装役
  • 私: 決める人。GUI操作と承認を担当

この分担自体はうまく回っていました。問題はその間でした。チャットが書いたブリーフを私がコピーしてターミナルのClaude Codeに貼る。終わったらClaude Codeの出力をコピーしてチャットに貼り戻す。1日に何往復もあり、スマホからだとさらに面倒で、「ここが一番のボトルネック」とはっきり自覚していました。

9月下旬のある夜、チャットにそのまま聞きました。「Claude Code と claude.ai のやり取りを自動化する方法はありませんか。そこがボトルネックです。付随する課題の抽出と解決法も提案して」。

2. 「コピペを無くしても効果は半分」と言われた

返ってきた最初の一文が、このシリーズ全体の軸になりました。

本当のボトルネックは「コピペの手間」より「往復回数」と「両者のコンテキスト断絶」です。コピペだけを自動化しても、往復が多い構造のままなら効果は半分程度にとどまります。

言われてみればそのとおりで、私が疲れていたのはコピペの操作そのものより、「止まるたびに私が両者を取り持たないと先に進まない」構造でした。中継の自動化と、往復そのものを減らす設計を同時にやる、というのが出発点になりました。

提案は3案ありました。

  • A. MCPブリッジ(本命): Mac Studioに自前のリモートMCPサーバーを立て、claude.aiのカスタムコネクタとして接続する。チャットから dispatch(repo, brief) でヘッドレスのClaude Codeを起動し、status / report で結果を読み、reply で同じセッションに追加指示を送る。既に自前MCP(docs-search)を1本つないでいたので、経路には実績がある
  • B. PM役もClaude Code側に寄せる: PMセッションが実装セッションを指揮する。中継は構造的に消えるが、claude.aiの記憶・横断的な文脈・壁打ちの質を失う
  • C. ファイル受け渡しだけ先にやる: リポジトリ内に .pm/briefs/NNN.md と .pm/reports/NNN.md を置き、やり取りを全部ファイル経由にする。今日からできて、Aの土台にもなる

Bを選ばなかった理由は明確で、私はclaude.ai側の記憶と文脈を手放したくなかった。チャット側は複数のプロジェクトをまたいで私の方針を知っていて、その文脈でブリーフを書けるのが価値です。それを捨ててまで中継を消す意味はない。

順番についても注文がありました。「Cを飛ばしてAから作ると、読みにくい長文報告が自動で飛んでくるだけになる」。つまり先にファイルの規約と報告の書式を固め、その上にブリッジを載せる。これは後になるほど効いたと思います。

3. 付随する課題は7つあった

同じ回答で、自動化すると表に出てくる課題も列挙されました。自分用に残しておきます。

  1. 往復が多い: ブリーフに受け入れ基準(完了条件・テスト方法)を必ず入れる。「判断が必要なこと以外は止まらず進め、判断事項はまとめて報告」をClaude Code側の規約(CLAUDE.md)に書く。これが一番効く
  2. 報告が長くて読みにくい: 報告の書式を固定する(状態 / 変更ファイル / テスト結果 / 未解決点 / 要判断事項)。チャット側が機械的に読めるようにする
  3. ジョブは長く、チャットのターンは短い: 非同期にして、完了したらDiscordに通知する。通知を見て「結果見て」と言えば済む
  4. 意思決定が会話に埋もれる: 決定事項はリポジトリの DECISIONS.md に追記させ、会話ではなくリポジトリを正本にする
  5. 外部公開MCPのセキュリティ: 認証必須、実行できるツールを限定、作業はgit worktreeに閉じ込め、push・mergeは人間承認のみ
  6. 暴走とコスト: ターン数上限と1ジョブあたりの上限を設ける
  7. 人間のゲートが曖昧: 承認は「ブリーフ送信時」ではなく「マージ時」の1点に絞る。毎回承認していたら自動化した意味がない

7番は、後で何度も立ち返ることになる原則です。

4. 「ログを記録代わりにしている」ことへの懸念

ここで話が少し横に逸れます。私はclaude.aiの会話ログとClaude Codeのログを全部NASに溜めて、検索できるようにしています(過去記事)。それを「記録代わり」にしているつもりだったので、この設計に懸念はあるかと聞きました。

答えは「懸念はある。ログは証拠としては優秀だが、記録としては欠陥が多い」。挙がった理由のうち、刺さったものを3つ。

  • 確定事項と途中経過が区別できない。ログには没案も、AIの提案も、私の決定も同じ重みで混ざっている。検索で出てきた一文が「採用された方針」なのか「検討して捨てた案」なのか、前後を読み直さないと分からない。後で別のAIが読むと、提案を決定と取り違える
  • 直近の決定ほど検索できない逆転。claude.aiの会話は月次(当時)のエクスポートでしか検索に乗らないので、最大1か月の空白ができる。一番知りたい「先週何を決めたか」が一番引けない
  • 機密の集積。仕事の話、家のネットワーク構成、個人的な事情が一か所に丸ごと溜まる。ブログに抜き出すときの事故源にもなる

対策は二層構造でした。生ログは一次資料として今までどおり保存する。別に、プロジェクトごとの STATUS.md(いまの状態)と DECISIONS.md(日付・決定・理由・却下案)を正本として小さく持ち、作業終了時にClaude Codeに更新させる。DECISIONS.mdに「却下案」の欄を必ず入れるのは、後で「なぜこれにしなかったか」を探すときに一番効くからです。

この二層構造は、2の「C案(ファイル受け渡し)」と同じ規約の中に収まります。結果として、受け渡しの規約と記録の正本が1本のブリーフで一緒に決まりました。

5. 先の話を2つ片付けた

作る前に、将来の話を2つ確認しました。

Hermes(Discordのbot)と統合したらどうなるか。入口がチャットからDiscordに移り、/job と打てば依頼から完了報告まで1つのスレッドに並ぶ。cc-bridgeはMCPサーバーなので、claude.aiから呼ぶのもHermesから呼ぶのも同じ口で、新しい配管は要らない。だから後回しでいい。ただし注意が1つあって、Hermes側のモデルは私との会話の記憶を持っていないので、「方針を考えて」まで任せると過去の決定を知らないまま指示を出す事故が起きる。これもDECISIONS.mdを正本にする理由になります。

私の結論は「文脈を理解して欲しいので、しばらくはclaude.aiに任せたい」。Hermes統合はcc-bridgeが安定してから判断、で止めました。

MulmoTerminal(複数のClaude Codeを並べて眺める端末)は使わなくなるのか。答えは「役割が変わるだけ」。cc-bridgeは「ブリーフを投げて放置し、報告を読む」非同期の運用で、MulmoTerminalは「動いているセッションを横に並べて眺め、必要なら割り込む」対話の運用。ヘッドレスのジョブが失敗して手で追いたいとき、探索的で先にブリーフに落とせないとき、許可確認が頻発して無人で回しにくいときは残る。「普段はcc-bridge、詰まったらMulmoTerminal」という位置づけで落ち着きました。

6. MVPのブリーフ

「実際に使ってみてイメージを付けたい」と言って、最小構成のブリーフを出してもらいました。要点だけ書き写します。

# cc-bridge MVP: claude.ai から Claude Code をヘッドレス起動する MCP ブリッジ

## 目的
claude.ai(PM役)が出すブリーフを、コピペなしで Claude Code に渡し、結果を読み戻せるようにする。
まずは1リポジトリ相手に「dispatch → 実行 → 報告 → claude.aiで読む」が1周回ることを確認するのがゴール。

## 前提・調査してから着手すること
- 既存の docs-search MCP サーバーの実装・公開方法・認証方式を確認し、同じ構成で作る
- `claude --help` でヘッドレス実行(-p)、セッション再開、ツール許可、ターン数上限の現行オプションを確認してから使う
- Discord 通知は既存の仕組みを流用できるか確認する

## 作るもの
1. MCP サーバー(Python)。ツールは dispatch / status / report / reply の4つ
   - dispatch はブリーフを `.pm/briefs/NNN.md` に保存して Claude Code をバックグラウンド起動し、すぐ job_id を返す(完了を待たない)
   - ジョブ管理は `jobs/<job_id>.json` のファイルベース。DB は使わない
2. 対象リポジトリ側の規約(まずは cc-bridge 自身で試す)
   - `.pm/briefs/` `.pm/reports/` `STATUS.md` `DECISIONS.md`
   - CLAUDE.md に「作業終了時に報告を書く」「STATUS/DECISIONS を更新」「判断が必要なこと以外では止まらない」を追記
   - 報告書式: 状態 / 変更ファイル / テスト結果 / 未解決点 / 要判断事項
3. 完了・失敗・判断待ちで Discord に通知

## 安全側の制約
- 実行は git worktree 上。メインブランチへのマージ・push は行わない
- 許可ツールを限定し、ターン数上限を付けて起動する
- 対象リポジトリは設定ファイルで許可リスト化し、それ以外は拒否
- 外部公開は既存コネクタと同じ経路・認証。認証なしで公開しない

## 受け入れ条件
- dispatch → status が done → report で書式どおりの報告が読める
- reply で同じセッションに追加指示が渡る
- 失敗時に status が failed になり Discord に通知が来る
- claude.ai のカスタムコネクタとして登録でき、4ツールが呼べる

できあがる構成を図にするとこうです(後にREADMEに載せたもの)。

claude.ai ──(MCP / OAuth)──> cc-bridge ──> git worktree 上で claude -p(バックグラウンド)
    ▲                           │                     │
    └── status / report ────────┘      .pm/reports/NNN.md・Discord 通知

ブリーフの中で「まずはcc-bridge自身を最初の対象リポジトリにする」と書いてあるのがポイントで、他のプロジェクトを巻き込まずに1周試せます。これは今も続いていて、cc-bridgeの改修はすべてcc-bridge自身のジョブとして流しています。

この夜のうちに mkdir ~/cc-bridge && git init && claude でブリーフを貼り、サーバーができ、カスタムコネクタの登録まで済みました。登録の画面で「今すぐサインイン」と「自動的に登録」の両方に「検出済み」が付いていれば、OAuthとクライアント自動登録を正しく応答している証拠だそうです。ツールごとの権限は、読むだけの status / report を常に許可、Claude Codeを動かす dispatch / reply は承認が必要、で始めました。

初めてチャットからジョブを投げ、Discordに完了通知が来て、チャットが report で報告を読み戻したところまでが、この日の到達点です。その先で何が起きたかは次回に書きます。

7. 運用ルールとして残すこと

この記事の時点で決まった、今も変えていない原則です。

  • 自動化するのは「中継」だけでなく「往復」。止まる回数を減らす設計を先に考える
  • PM役はclaude.aiに残す。記憶と横断的な文脈を持っている側にブリーフを書かせる
  • 受け渡しはファイル経由(.pm/briefs と .pm/reports)。チャットの本文に貼らない
  • 記録の正本はリポジトリの STATUS.md / DECISIONS.md。会話ログは一次資料であって記録ではない。DECISIONSには却下案を必ず書く
  • ブリーフには受け入れ基準を入れる。Claude Codeには「判断が必要なこと以外で止まらない」を規約として渡す
  • 人間のゲートはマージの1点。ブリーフを投げるたびに承認はしない
  • 実行はworktreeの中。許可ツールは限定、対象リポジトリは許可リスト
  • 新しい仕組みはまず自分自身(cc-bridge)を対象に試し、回ってから横に広げる
  • Hermes統合は「安定してから」。MulmoTerminalは「詰まったとき用」として残す

次回は、この仕組みを実際に回し始めた最初の数日、「ボトルネックがターミナルのコピペに移った」ところからです。