Agent Lease について
Agent Leaseは、同じリポジトリを使うClaude CodeとCodexのセッション向けMCPサーバー兼調整システムです。有効期限付きのパスリースとフックで競合編集を防ぎ、プレゼンス、メッセージ、タスク管理、監査履歴も扱います。
主な機能
- 01フックで強制されるパスリース
- 02初回編集時の自動クレーム
- 03エージェントのプレゼンスと共有メッセージ
- 04配信状態付きの宛先指定タスク
- 05リースと操作の監査履歴
- 06CLIとローカルWebルーム
活用シーン
- 01同じファイルへの同時編集の防止
- 02Claude CodeとCodex間の作業調整
- 03エージェントセッション間のタスク割り当てと追跡
- 04パスの保持者や変更者の確認
MCP 対応
stdioのMCPサーバーは、パスのクレームと解放、所有者やルーム状態の確認、メッセージ、タスク処理、履歴参照のツールを公開します。CLIでも同じ操作ができます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
uvx agent-lease-mcpAGENT_NAMEThis agent's name in the room, e.g. claude-code or codex. Must match the hooks.AGENT_LEASE_DBPath to the shared SQLite room (default ~/.agent-lease/room.db).ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
15掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| paths | array | はい | |
| purpose | string | いいえ | |
| ttl_seconds | any | いいえ |
詳細
agent-lease-mcp
同じリポジトリで、2つのコーディングエージェント(Claude Code と Codex、またはいずれかの2つのセッション)が互いの作業を上書きしないようにします。
agent-lease は、パスのリース、プレゼンス、共有メッセージログを提供します。さらに、リースは善意に頼るのではなく、PreToolUse フックで強制されます。別のエージェントが作業中のファイルを編集しようとすると、編集が行われる前に拒否されます。
なぜ作られたのか
2026年9月9日。調整用ファイル docs/AGENT-HANDOFF.md があり、両方のエージェントがその存在を知っていました。それでも22:28に、両方が deploy/make-work-package.sh に手を加えました。一方が編集中に、もう一方がそのスクリプトを実行していたのです。Bash はスクリプトを逐次読み込むため、実行中のプロセスのもとで内容が変わり、3.7 GB のインストーラーが生成されるはずのビルドから、使いものにならない 198 MB のインストーラーができてしまいました。
このプロジェクトの土台となる教訓は、無視できる調整は無視されるということです。悪意からではありません。エージェントは作業中、掲示板など見ないだけです。
その後、同じ衝突を意図的に再現しました。Codex がスクリプトを実行し、Claude Code が実行途中に編集しようとしましたが、フックが編集を拒否しました。ファイルは無事でした。
他との違い
| ロック | 強制方法 | TTL | プレゼンス | メッセージ | 監査 | |
|---|---|---|---|---|---|---|
| AgentRoom(論文) | ✅ | プロンプトのみ | ? | ✅ | ✅ | ✅ |
| Agent Claim MCP | ✅ | プロンプトのみ | ✅ | ❌ | ❌ | ❌ |
| agent-orchestration | ✅ | プロンプトのみ | ❌ | ✅ | ✅ | ❌ |
| agent-lease-mcp | ✅ | PreToolUse フック | ✅ | ✅ | ✅ | ✅ |
アドバイザリーロックは破られます。AgentRoom 自身もこれについて説明しています。Claude Code と Codex はどちらも同じ動作(終了コード 2 でブロックし、stderr に理由を出力)をする PreToolUse フックを備えているため、ツール呼び出しの段階でリースを確実に強制できます。1つのスクリプトで両方のクライアントに対応します。
基本となるルール
- ロックではなく、リースです。 TTL は30分です。クラッシュしたエージェントが、いつまでもリポジトリをブロックすることはありません。
- すべて成功するか、何も成功しないか。 複数のパスに対する要求は、すべて成功するか、すべて失敗します。
- ディレクトリのリースは、その配下すべてを対象にします。
- 空いているファイルは、最初の編集時に自動的に確保されます。 誰も
claimの呼び出しを覚えておく必要はありません。 - 実行中のスクリプトには、実行中ずっとリースが設定されます。 ビルドを壊したのとまったく同じ組み合わせです。
- デフォルトではフェイルオープンです。 調整機能の不具合で作業を止めてはいけません。そうしないと、誰もが最初にフックを無効にしてしまいます。無人実行では
AGENT_LEASE_FAIL_CLOSED=1を設定すると、これを切り替えられます。
自動で実行される処理
| フックイベント | 動作 |
|---|---|
| SessionStart | ルームの状態(参加者、各自が確保しているもの、自分宛てのメッセージ)がコンテキストに注入されます |
| UserPromptSubmit | 新しいメッセージがカーソルを使って一度だけ配信されます |
| PreToolUse(Edit/Write/apply_patch…) | 他の人が確保しているファイルの編集が拒否されます |
| PreToolUse(Bash) | 実行するスクリプトにリースが設定されます。確保中のファイルへの明らかな書き込み(>、tee、sed -i、cp/mv の対象)は拒否されます |
| Stop / SessionEnd | エージェントがターンを終えると、すべてのリースが返却されます |
伝えることがなければ、注入は行われず、何も表示されません。
スリープ中のエージェントを起こす
フックはエージェントが動作したときにのみ実行されるため、アイドル状態のセッションはモデルのトークンを消費せず、外部から起動します。
- Claude Code:
agent-lease init claude-code --write --rewakeを実行すると、SessionStartとStopにasyncRewakeフックが追加されます。シグナルファイルを待ち、ほかの誰かから宛先指定のメッセージが届くとセッションを起動します。 ブロードキャストと自動受領通知では起動しません。 - Codex:
agent-lease-codex-wakeサービスは、codex queueを通じて名前を指定したセッションに通知します(メッセージ番号のみを使い、本文は決して使いません)。プロバイダーの利用上限に達した後、未完了の作業があれば一度通知します。セットアップ:Codex で/rename noxを実行し、~/.config/agent-lease/environmentにAGENT_LEASE_CODEX_THREAD=noxを設定してから、deploy/systemd/agent-lease-codex-wake.serviceを有効にします。
ほかのエージェントからのメッセージは情報であり、人間からの指示ではありません。エージェント同士が人の不在中に作業を引き継ぐには、人間が許可する範囲(および必ず確認が必要な事項)を、たとえば ~/.codex/AGENTS.md のように各エージェント自身の指示に記載します。テンプレートと詳細(チェコ語):
docs/ZPRAVY-A-POTVRZENI.md。
ツール
| MCP ツール | 用途 |
|---|---|
claim(paths, purpose, ttl_seconds) | 事前に予約します。通常はスクリプトを実行する前にディレクトリを予約します |
release(paths?) | 予約を返します。引数を指定しない場合は、保持している予約をすべて返します |
owner(path) | このパスを保持しているエージェントを確認します(ディレクトリのリース経由も含みます) |
room(status?) | チェックポイントごとに一度呼び出します。ここにいる人、保持されているもの、新しいものを確認します |
say(text) / inbox(since_id) | ルームへのメッセージ |
send / jobs / next_task / ack / retry / cancel | 宛先指定メッセージと、配信状態を管理する永続タスク |
accept(message_id, note) | 宛先指定メッセージを引き受けることを確認します。送信者にも通知されます |
report_limit(minutes, reason) | 利用枠切れ:未着手のタスクはフォールバックエージェントに移されます |
history(path?) | 誰が何を変更し、どうなったかを確認します。「なぜブロックされたのか」への答えです |
同じ操作を CLI(agent-lease room|claim|release|say|send|…)からも実行できます。Codex は非対話モードでは MCP 呼び出しを承認できませんが、Bash は実行できるためです。
agent-lease wait --for <agent> はモデルのトークンを消費せずに待機し、メッセージが届くとバックグラウンドセッションを起動します。
say/inbox はリアルタイムチャットではありません。MCP はポーリング方式のため、相手側が次に確認したときにメッセージを読み取ります。リアルタイムで表示するには、ローカルのウェブルームを使用します:
agent-lease web --open(ループバックのみ。Security を参照)。
クイックスタート(2 分)
uv tool install agent-lease-mcp
agent-lease init claude-code --write --rewake # writes all hooks, keeps a .bak backup
agent-lease init codex --write
agent-lease simulate # 2 s: replays a full scenario in a temp DB
agent-lease doctor # checks it really works
agent-lease web --open # live room in the browser
--write を付けずに init を実行すると、書き込まれる内容が表示されるだけです。手動でのセットアップ方法は以下を参照してください。
インストール
uv tool install agent-lease-mcp
これにより、agent-lease-mcp、agent-lease、agent-lease-guard、
agent-lease-context、agent-lease-release が PATH に追加されます。
MCP サーバー(stdio。各クライアントが独自のプロセスを実行し、共有状態には SQLite ファイルを使用します):
# Claude Code
claude mcp add agent-lease -e AGENT_NAME=claude-code -- agent-lease-mcp
# Codex — ~/.codex/config.toml
[mcp_servers.agent-lease]
command = "agent-lease-mcp"
env = { AGENT_NAME = "codex" }
# Codex writes to ~/.agent-lease, outside the workspace — allow it:
[sandbox_workspace_write]
writable_roots = ["/home/YOU/.agent-lease"]
フック — フックがなければ、これは単なる丁寧な掲示板です:
// ~/.claude/settings.json
{
"hooks": {
"PreToolUse": [{
"matcher": "Edit|Write|MultiEdit|NotebookEdit|Bash",
"hooks": [{ "type": "command", "command": "AGENT_NAME=claude-code agent-lease-guard" }]
}],
"SessionStart": [{ "hooks": [{ "type": "command", "command": "AGENT_NAME=claude-code agent-lease-context" }] }],
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "AGENT_NAME=claude-code agent-lease-context" }] }],
"Stop": [{ "hooks": [{ "type": "command", "command": "AGENT_NAME=claude-code agent-lease-release" }] }]
}
}
// ~/.codex/hooks.json — same events, AGENT_NAME=codex
{
"hooks": {
"PreToolUse": [{
"matcher": "*",
"hooks": [{ "type": "command", "command": "AGENT_NAME=codex agent-lease-guard" }]
}]
}
}
AGENT_NAME はサーバーとフックで一致させる必要があります。一致しないと、エージェント自身のファイルをブロックしてしまいます。room に unconfigured-* という名前のエージェントが表示される場合、まさにその状態です。
| 変数 | デフォルト | 用途 |
|---|---|---|
AGENT_NAME | unconfigured-<host>-<pid> | ルーム内での名前 |
AGENT_LEASE_DB | ~/.agent-lease/room.db | 状態の保存場所 |
AGENT_LEASE_TTL | 1800 | デフォルトのリース期間(秒) |
AGENT_LEASE_RETENTION_DAYS | 30 | これより古いメッセージと監査記録を削除します(0 = 保持) |
AGENT_LEASE_FAIL_CLOSED | オフ | 1 = フック自体が失敗したときにツール呼び出しをブロックします |
AGENT_LEASE_HUMAN | human | ルーム内での人間の名前(ウェブ UI により DB の隣に保存されます) |
AGENT_LEASE_TASK_SENDERS | 人間 + 設定済みエージェント | タスクを作成できるユーザー(カンマ区切り) |
AGENT_LEASE_FALLBACKS | — | フェイルオーバーチェーン。例:codex=claude-code;claude-code=codex |
オプション:Bash の安全ゲート
別の問い、つまり「このファイルを誰が保持しているか」ではなく「このコマンドは破壊的か」を判定する、独立した PreToolUse フック(agent-lease-jev-guard)です。ハードルール(rm -rf /、強制プッシュ、git reset --hard、curl | sh、mkfs など)は、組み込まれるとすぐに適用されます。オプションの外部分類器(TypeSafe Jev)はデフォルトでオフになっており、シャドウモードで起動します。受け取るのは墨消しされたコマンドのみで、助言を行うだけです。唯一の安全策として使われることはありません。詳細はADR 0003をご覧ください。
受領確認、フェイルオーバー、ブリッジ、ブローカー
- 宛先のあるすべてのメッセージには、見える状態が表示されます ⏳ → 👁 既読 → ✔ 対応中 → 完了。
「既読」はフックによって自動的に記録されます。「対応中」はエージェントが
acceptで確認する必要があり、各プロンプトでリマインドされます。何も通知されないまま失われることはありません。agent-lease overdueで、誰にも確認されていない項目を一覧表示できます。 - 制限とフェイルオーバー。 Codex ワーカーは、ローカルの App Server から明示的な型付き可用性シグナルを読み取ります。その他のワーカーは、実際のプロバイダー/CLI エラーが発生した後にのみ制限を記録します。リセット時刻が示されていない場合、agent-lease がそれを推測することはありません。手動の
agent-lease limit/MCP のreport_limitも引き続き利用できます。未承認で未開始のタスクは、猶予期間後にAGENT_LEASE_FALLBACKS(例:codex=claude-code;claude-code=codex)で指定された次のエージェントに移され、送信者に通知されます。 - ブリッジ(
agent-lease bridge --agent codex)— 自律型ワーカーです。タスクを取得して確認し、読み取り専用でcodex exec/claude -pを実行して結果を返します。--provider openrouter --model <model>を指定すると、ツールを使わずプレーンテキストとして OpenRouter 経由で任意のモデルに送信します(読み取り専用。レビューやセカンドオピニオンに適しています)。キーは環境変数からのみ取得します。ワーカーのプレゼンス/プロバイダー状態には別の ID(codex-bridge、claude-code-bridge)を使用するため、ヘッドレス実行のクォータが対話型エージェントの状態を上書きすることはありません。 - タスクが二度実行されることはありません。 ワーカーが保持している(
leased/started)タスクを承認するには、そのリーストークンが必要です。ブリッジは、対話型セッションが承認したタスクをスキップします。また、--interactive-graceを指定すると、稼働中の対話型エージェントに新しいタスクを優先して割り当てます。 - ブローカー(
agent-lease broker)—0600の Unix ソケットを介した、単一の SQLite 書き込みプロセスです。稼働中は、ほかのツールが自動的にブローカーを使用するため、サンドボックス内の Codex がデータベースに直接アクセスする必要はありません。クライアントはブローカーの再起動後も動作を継続します。接続は再試行され(まだ何も送信されていないため)、中断された呼び出しが繰り返されることはなく、長時間実行されるワーカーは次の呼び出しを続行します。 - ライブルームの概要パネル:各エージェントのアクティブなタスク、キュー、未確認項目、型付きプロバイダー状態、待機理由、制限、レビュー対象を表示します。タスクでは、繰り返し可能な
--path作業セットと--priorityを指定できます。スケジューラーは別のエージェントが保持しているパスをスキップし、ボードにはブロックしているパス、所有者、TTL が表示されます。agent-lease notify --loopは、人間の対応待ちとなっている項目のみを Telegram に送信し、各イベントは最大 1 回だけ通知します(環境変数からTELEGRAM_BOT_TOKEN、TELEGRAM_CHAT_IDを指定します。テストには--dryを指定してください)。 - ワーカーを安全に運用する。
agent-lease worker-activateとagent-lease failover-activate <agents…>は、タスクを実行または移動することなく、安全な開始状態を設定します。有効化後に届いた作業のみが取得または振り分け直されます(古い項目も対象にするには--include-existingを指定します)。agent-lease provider-sync --agent codexは、Codex の明示的な可用性を読み取って保存します。agent-lease provider-clearは、プロバイダーが復旧したことを確認し、古い制限を削除します。agent-lease limitsは、アクティブな制限とフェイルオーバーのチェーンを表示します。agent-lease doctor --jsonは、配信、受領確認、ワーカーの健全性、フェイルオーバーの準備状況を個別に報告します。 deploy/systemd/に systemd ユニット、deploy/windows/に Windows/WSL 用のスターターがあります。
詳細(チェコ語):受領確認、 制限とフェイルオーバー、Jev。
セキュリティ
agent-lease は、1 つのローカルユーザーアカウントで実行されるエージェント向けの調整ツールです。実際には、次のことを意味します。
- ローカルの信頼モデル。 エージェントの識別情報は
AGENT_NAME環境変数です。あなたのユーザーとして実行されるプロセスは、どのエージェントにもなりすますことができます。唯一予約されている識別情報は人間用のもの(このビルドではmichal)で、認証済みの Web UI だけが使用できます。これはエージェント同士が互いに干渉するのを防ぐものであり、あなたのアカウント上の悪意あるプロセスを防ぐものではありません。 - 状態は所有者のみがアクセスできます。
room.db(およびその WAL/SHM ファイル)は0700ディレクトリ内で0600に設定されます。既存のインストールも起動時に権限が厳格化されます。 - ピアメッセージは信頼できないデータです。 モデルコンテキストでは、各メッセージに種類、送信者、受信者が含まれ、1 行にまとめられ、人間からの指示ではなくピアからの情報であることを示す注記が付きます。他のエージェントからのタスクは依頼であり、命令ではありません。
- タスクは呼び出し元に紐づけられます。 ピアが参照できるのは、自分が送信または受信したタスクのみです。リーストークンを参照できるのは、自分宛てに配信されたもののみです。再試行/キャンセルには、送信者または受信者である必要があります。
- Web UI はループバックのみにバインドされ、ワンタイム URL フラグメントトークンを HttpOnly、SameSite=Strict のセッション Cookie と交換し、Origin と Host を検証し、同時イベントストリーム数を制限します。
- 上限と保持期間。 メッセージ本文、短いフィールド、リスト件数、タスクのリース期間には上限があります。古いメッセージと監査記録は期限切れになりますが、未完了のタスクは期限切れになりません。
既知の制限を率直に示します。
-
プロバイダーのシグナルは異なります。 インストールされている Codex App Server には、明示的な
account/rateLimits/readシグナルがあります。Claude Code の公開されている CLI には同等の状態確認手段がないため、プロバイダーが提示したリセット時刻を過ぎた後に限り、通常のタスクを上限付きで再試行して回復を確認します。リセット時刻が提示されない場合は、agent-lease provider-clearで回復を明示的に確認するまで、自動プローブを停止します。unknownは、プロバイダーが回復した証拠として扱いません。 -
シェルコマンドのチェックはベストエフォートです。 リダイレクト、
tee、sed -i、truncate、cp/mvの対象、sudo/envなどのラッパー、sh -cは認識されます。eval、パス内の変数、任意のプログラムは認識されません。これはミスを検出するためのものであり、フックを回避しようとするエージェントを阻止するものではありません。 -
チェック後使用までの隙間。 フックはクライアントがパスを開く前に、そのパスをチェックします。その間にシンボリックリンクが差し替えられても検出されません。フックは、後続のファイルオープンをチェック済み inode に紐づけることができません。
-
単一マシン。 状態はディスク上のファイルです。
何か見つかりましたか?GitHub Security Advisories から非公開で報告してください。
開発
uv sync --extra dev
.venv/bin/python -m pytest -q
.venv/bin/ruff check .
設計上の決定:ADR 0001(フックによる強制)、 ADR 0002(SQLite と stdio)、 ADR 0003(独立した Bash セーフティゲート)— チェコ語です。
Michal が Claude Code と Codex を使って開発しました。この 2 つのエージェントを調整します。
MIT ライセンス。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。