ACP: Agent Client Protocol
ACP は stdio 上で動作する JSON-RPC 2.0 プロトコルで、エディターや IDE が実行中の ZeroClaw エージェントをセッションホストとして制御できるようにします。改行区切りの JSON で、軽量かつストリーミング可能で、サブプロセスへの接続も簡単です。
これを「エージェント版LSP」と考えてください。エディターがzeroclaw acpを起動し、stdin経由でプロンプトを送信し、stdoutでセッションの更新を受信します。
使用用途
- 「このファイルについてエージェントに質問する」コマンドを提供するエディター拡張機能
- エージェントセッションのサイドペインを開くターミナルマルチプレクサの統合
- エージェントをプログラムで操作するCIランナーで、完全なゲートウェイセットアップは不要
- HTTPを使用せず、ポートをバインドせずにエージェントセッションを必要とするもの
プロトコル形状: v1
すべてのメッセージは JSON-RPC 2.0(改行区切り)です。ZeroClaw は プロトコルバージョン 1 を実装しています。
initialize
ハンドシェイク。サーバーの機能一覧を返します。
→ {"jsonrpc":"2.0","id":1,「method」:初期化}
← {"jsonrpc":"2.0","id":1,"result":{
protocolVersion: 1,
agentCapabilities: {
loadSession: true,
promptCapabilities: {image: false, 音声: false, embeddedContext: true},
mcpCapabilities: {http: false, sse: false},
sessionCapabilities: {resume: {}, 閉じる: {}}
},
agentInfo: {
"name": zeroclaw-acp,
title: ZeroClaw ACP,
version: 0.7.x
},
authMethods: [],
_meta: {
zeroclaw: {
`defaultModel`: anthropic/claude-sonnet-4.6,
"maxSessions": 10,
`sessionTimeoutSecs`: 3600
}
}
}}
loadSession: true および sessionCapabilities: {"resume": {}, "close": {}} は、セッションの永続化が有効であることを示します。起動時に SQLite ストアを開けなかった場合、これら3つはすべて存在しないか false となり、session/load、session/resume、session/close は SESSION_NOT_FOUND エラーを返します。
_meta.zeroclaw には、ベースの ACP 仕様には含まれない ZeroClaw 固有の拡張フィールドが含まれます。ベース仕様のみを実装するクライアントは、このオブジェクトを無視できます。
promptCapabilities.embeddedContext: true は、クライアントが session/prompt で base64 の blob を含む埋め込み resource ブロックを送信できることを意味します(下記参照)。image と audio は現時点では false のままです。ネイティブの ACP Image/Audio ContentBlocks はまだアドバタイズされていません。
サーバーは常に protocolVersion: 1 を返します。クライアント側で protocolVersion: 0 を送信しても、1 が返されます。v0 クライアントでは新しいメッセージ形式に対して解析エラーが発生します。詳しくは以下のバージョン互換性を参照してください。
session/new
分離されたエージェントセッションを開く。
agentAlias は、使用する [agents.<alias>] エントリの設定名を指定します。複数のエージェントが設定されている場合は必須です。エージェントが1つだけの場合は自動的に選択され、このフィールドは省略できます。エイリアスは、キャメルケースの agentAlias、スネークケースの agent_alias、または短縮形の agent を受け付けます。
gateway WebSocket エンドポイントを介して接続する場合、接続 URL には ?agent=<alias> クエリパラメーターを指定することもできます。この値は接続スコープのデフォルト値であり、設定変更ではありません。session/new のエイリアス解決は、次の優先順位に従います:
session/newパラメーター内でのagentAlias/agent_alias/agentの明示的な指定- WebSocket URL の
?agent=<alias>ゲートウェイ [acp].default_agent- 存在するエントリがちょうど1つの場合、設定された唯一の
[agents.<alias>]エントリ - エイリアスを解決できない場合のエラー
解決されたエイリアスは、どのステップで選択されたかに関係なく、有効でディスパッチ可能なエージェントを指している必要があります。不明なエイリアスおよび設定済みだが無効化されているエージェントは、session/new で -32602 INVALID_PARAMS により失敗します。空白または空白文字のみの ?agent= は指定なしとして扱われ、次のステップにフォールスルーします。
スタンドアロンの zeroclaw acp(stdio サブプロセス)は ?agent= を読み取りません。その場合は明示的な agentAlias または [acp].default_agent を使用してください。
オプションの cwd パラメーター(エイリアス: workspaceDir、workspace_dir)はセッションごとのファイルアクセス境界を固定し、すべてのファイルツールが適用する SecurityPolicy 内の workspace_dir になります。これはエージェント自身の永続状態の場所を変更するものではありません。エージェントごとのプレーンテキスト状態(MEMORY.md、IDENTITY.md、SOUL.md)は解決済みの エージェントワークスペース(agent_workspace_dir(<alias>)、つまり [agents.<alias>] ワークスペース)に格納され、そこは追加で許可されるルートのままです。共有 SQLite ストアと cron 状態は config.data_dir 配下に格納されます。これらのいずれも、単一のデーモンレベルの workspace_dir ではありません。
→ {"jsonrpc":"2.0","id":2,「method」:"セッション/新規","params":{
agentAlias: myagent,
"現在の作業ディレクトリ": "/path/to/project"
}}
← {"jsonrpc":"2.0","id":2,"result":{
"sessionId": "s-ab12cd",
workspaceDir: "/path/to/project"
}}
cwd は受け付け時に正規化されるため、../ によるトラバーサルで意図したルートの外に出ることはできません。明示的に指定した cwd は、エージェントのワークスペース内のより狭いサブディレクトリであっても、セッション境界として正確に適用されます。
cwd が省略されている場合、サーバーは解決済みエージェントのワークスペースディレクトリ([agents.<alias>] のワークスペース)を使用し、デーモンの起動ディレクトリは使用しません。唯一の特殊ケースは、インストールルート自体に正規化される cwd です。Thunderbolt などのクライアントはプレースホルダーとして . を送信し、これはデーモンの作業ディレクトリに解決されます。この単独のプレースホルダーは「意味のある cwd なし」として扱われ、エージェントごとのワークスペースにフォールバックします。そのため、アップロードとツールサンドボックスがデーモンルート内に置かれることはありません。その他の明示的なパスは、インストールルート配下のものも含め、指定されたとおりに固定され、決して範囲を広げられません。
session/prompt
プロンプトを送信します。レスポンスは session/update 通知のシーケンスとしてストリーミングされ、session/prompt の結果で終了します。
promptパラメータは、プレーン文字列またはコンテンツパーツの配列のいずれかを受け付けます:
"prompt": "直近のコミットの変更を要約してください。"- Array: 各要素はテキストパート
{"text": "..."}または ACP リソースブロックです:- テキスト リソース:
{"type": "resource", "resource": {"uri": "file:///path/to/file.rs", "text": "<file contents>"}}。インライン テキスト付きのエディター@-記法の添付ファイル。 - Blob リソース:
{"type": "resource", "resource": {"uri": "file:///path/to/report.pdf", "mimeType": "application/pdf", "blob": "<base64>"}}。バイナリの埋め込み(PDF、DOCX、画像など)。ZeroClaw は blob をデコードし、{session.workspaceDir}/uploads/(SHA 名)に書き込み、エージェントプロンプトにマーカー([Document: …]、image/*の場合は[IMAGE: …])を表示します。デコード後の最大サイズは 10 MB で、無効な base64 やサイズ超過の blob はINVALID_PARAMSを返します。
- テキスト リソース:
各パートは、出現順に二重改行で結合されます。Blob の取り込みはストアに依存しません(RPC file/attach は呼び出しません)。MCP ツールの結果に resource+blob コンテンツが含まれる場合にも、同じマテリアライズ用ヘルパーが使用されます(MCP embedded resource blobs を参照)。
→ {"jsonrpc":"2.0","id":3,「method」:"セッション/プロンプト","params":{
"sessionId": "s-ab12cd",
"prompt": 「最後のコミットの変更点を要約してください。」
}}
← {"jsonrpc":"2.0",「method」:"session/update","params":{
"sessionId": "s-ab12cd",
update: {sessionUpdate: agent_message_chunk, "内容": {"type":"text","text":「最後のコミット...」}}
}}
← {"jsonrpc":"2.0",「method」:"session/update","params":{
"sessionId": "s-ab12cd",
update: {sessionUpdate: "ツール呼び出し", "toolCallId": tc-1, title: シェル,
種類: 実行, 「status」: pending, rawInput: {...}}
}}
← {"jsonrpc":"2.0",「method」:"session/update","params":{
"sessionId": "s-ab12cd",
update: {sessionUpdate: tool_call_update, "toolCallId": tc-1,
「status」: 完了, rawOutput: "..."}
}}
← {"jsonrpc":"2.0","id":3,"result":{
"sessionId": "s-ab12cd",
"stopReason": "end_turn",
"内容": 最後のコミットでは、以下が導入されています...
}}
stopReason は通常の完了時には "end_turn" となり、ターンが session/cancel によって中断された場合には "cancelled" となります。ACP の完了シグナルは stopReason です。ZeroClaw は既存のクライアント向けに、現在の最終的な content 文字列も含みます。
エラー:
| コード | 意味 |
|---|---|
-32000 SESSION_NOT_FOUND | 指定された sessionId のアクティブなセッションがありません |
-32002 SESSION_BUSY | このセッションでは既にプロンプトの処理が進行中です。完了を待つか、先にキャンセルしてください |
-32602 INVALID_PARAMS | sessionId / prompt が見つからないか、形式が正しくありません |
-32603 INTERNAL_ERROR | エージェントタスクがパニックしたか、ターンが失敗しました |
session/update 通知(エージェント → クライアント)
ZeroClaw はプロンプトターン中に 4 種類の session/update 通知を送信します。判別子は update 内の sessionUpdate フィールドです:
sessionUpdate 値 | 出力時 | キーフィールド |
|---|---|---|
agent_message_chunk | 各ストリーミングテキストトークン | content.type = "text", content.text |
agent_thought_chunk | 内部推論トークン(有効な場合) | content.type = "text", content.text |
tool_call | ツール呼び出しを開始しました | toolCallId、title、kind、status: "pending"、rawInput |
tool_call_update | ツール呼び出しが完了しました | toolCallId、status: "completed"、rawOutput、content[] |
tool_call と tool_call_update の toolCallId は安定しており、相互に対応しています。呼び出しを完了する更新は、その呼び出しを開始したものと同じ toolCallId を持ちます。
tool_call_update の name フィールドは ZeroClaw の拡張です(ベースの ACP 仕様では必須ではありません)。クライアントは表示用に使用できますが、無視しても問題ありません。
クライアントへのファイル配信 (deliver_file)
エージェントがワークスペースのファイルをダウンロードまたはプレビュー用に返す必要がある場合、deliver_file ツール(path、オプションの mimeType、オプションの title)を呼び出します。完了時に、ZeroClaw は通常の tool_call_update を発行しますが、その rawOutput / body は小さいまま保たれます(短い人間向けの要約であり、base64 ダンプは含まず、マシン用のトレーラーも含みません。すべての配信フィールドは型付きツールアーティファクト上に構造的に伝わります)。標準の tool_call_update.title は人間が読めるチャットラベルを持ちます。呼び出し元の title(任意の文章、例: "Quarterly report")、またはデフォルトではファイル名です。content 配列にはさらに標準の ACP 埋め込みリソースが含まれます:
{
"type": "内容",
"内容": {
"type": "リソース",
"リソース": {
"uri": "attachment://deliver/9f2c1a7b0e4d5f6a3b8c2d1e0f4a5b6c7d8e9f0a1b2c3d4e5f60718293a4b5c6d.pdf",
"mimeType": "application/pdf",
"blob": "<base64>"
}
}
}
uri は、不透明なコンテンツアドレス方式の識別子です。attachment://deliver/<sha256>.<ext> は、ファイルのバイト列の完全な 16 進数 SHA-256 ダイジェストです。URI セーフで、完全な 256 ビットのダイジェスト強度において衝突耐性があり、呼び出し元が指定したファイル名から導出されることは決してありません。同じ完全なダイジェストがディスク上の uploads/ のストレージ名となるため、異なるコンテンツが 1 つのファイルや 1 つの uri にエイリアスされることはありません。同じ uri は、ツール結果(JSON フィールド uri)と型付きツールアーティファクトの両方に構造的に保持されます。モデル向けテキストにはマシントレーラーはありません。blob を埋め込む前に、ACP レイヤーはファイルを再読み込みしてこのハッシュを再計算し、一致しなくなっている場合は添付を拒否します。ツールの検証と配信の間での差し替えは検出され、信頼されることはありません。Thunderbolt などのクライアントは送信用 blob を実体化し、その uri をキーとする引用 ref-map を構築します。エージェントは、返された uri を <widget:document-result fileId="…"> / [N] の引用にコピーし、プレフィックスを独自に作成してはなりません。チャット表示名 は標準の tool_call_update.title(呼び出し元の title、それがなければファイル名)です。ACP の resource オブジェクトには filename フィールドが ありません。title は表示専用であり、ディスク上の名前になることは決してありません。
ファイルはセッションのワークスペース(file_read と同じ jail)内に置く必要があります。サイズが大きすぎるファイル(10 MB 超)はツールによって拒否されます。
session/request_permission(エージェント → クライアント、送信リクエスト)
ツールがユーザーの承認を必要とする場合(autonomy 設定の always_ask や、ask_user/escalate_to_human ツール経由)、ZeroClaw はエージェントからクライアントへ JSON-RPC リクエスト を発行します。クライアントはツール呼び出しが続行される前に結果を返信する必要があります。
← {"jsonrpc":"2.0","id":zc-out-0,「method」:"session/request_permission","params":{
"sessionId": "s-ab12cd",
options: [
{optionId: allow-once, "name": 「一度だけ許可」, 種類: allow_once},
{optionId: allow-always,"name": "常に許可",種類: allow_always},
{optionId: reject-once, "name": 拒否, 種類: reject_once}
],
toolCall: {
"toolCallId": "approval-...",
title: 「シェルを承認しますか?」,
種類: 実行,
「status」: pending,
rawInput: {tool: シェル, 概要: git status --short},
"内容": [{"type": "内容", "内容": {"type": "text", "text": git status --short}}]
}
}}
→ {"jsonrpc":"2.0","id":zc-out-0,"result":{
アウトカム: {アウトカム: 選択済み, optionId: allow-once}
}}
サーバーが発行する ID ("zc-out-N") は、常に zc-out- を接頭辞とする文字列です。相関は方向ごとに行われます。各ピアは自身の保留中リクエストマップに対してのみ応答を照合するため、同じテキストの ID が両方向で独立して処理中になる可能性があります。
レスポンスの形式:
{"outcome": {"outcome": "selected", "optionId": "<id>"}}、ユーザーがオプションを選択しました{"outcome": {"outcome": "cancelled"}}、ユーザーがプロンプトを閉じました
クライアントが応答しない場合(クラッシュ、ネットワーク切断、ユーザーによるIDEの終了など)、リクエストは sessionTimeoutSecs 後にタイムアウトし、ツール呼び出しは拒否されます。
ask_user は同じ session/request_permission メカニズムを使用し、質問の choices を権限オプションにマッピングします。自由記述形式(選択肢なし)の ask_user は、ACP elicitation RFD が導入されるまでサポートされません。ACP セッションで choices なしに ask_user を呼び出すと、明確なエラーで即座に失敗します。
session/cancel (ZeroClaw 拡張)
実行中の session/prompt ターンを中止します。このメソッドは ZeroClaw の拡張であり、基本の ACP 仕様には含まれません。今後 ACP が競合する session/cancel を標準化した場合、ZeroClaw はこの拡張を _meta/session/cancel に移行します。
キャンセルと停止の違い: session/cancel は実行中のプロンプトターンを中断し、中断時点までにストリーミングされたテキストを蓄積したうえで stopReason: "cancelled" を返します。session/stop は現在のターンが完了した後にセッションを正常に終了します。ターンを中断するのではなく、ターンが終了するまで待機します。
正規のパラメーターは sessionId です。session_id は互換性のためのエイリアスとして受け付けられます。
→ {"jsonrpc":"2.0",「method」:session/cancel,"params":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0",「method」:"session/update","params":{
"sessionId": "s-ab12cd",
update: {sessionUpdate: agent_message_chunk, "内容": {"type":"text","text":"部分的..."}}
}}
← {"jsonrpc":"2.0","id":3,"result":{
"sessionId": "s-ab12cd",
"stopReason": cancelled,
"内容": partial...\n\n[クライアントによりターンがキャンセルされました]
}}
セッションでアクティブなターンが存在しない場合、キャンセルは何も行わず、エラーなしで暗黙的に成功します。これはACP通知のセマンティクスに従っています。通知はエラーを発生させてはなりません。
session/stop (ZeroClaw 拡張機能)
セッションを正常に終了します。ベースの ACP 仕様には含まれていません。ZeroClaw 固有の機能です。将来の ACP 仕様のリビジョンで異なるセマンティクスを持つ session/stop が追加された場合、これは _meta/session/stop にリネームされます。
→ {"jsonrpc":"2.0","id":4,「method」:"セッションの停止","params":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0","id":4,"result":{"sessionId": "s-ab12cd", 停止:true}}
session/update(クライアント → サーバー)(ZeroClaw 拡張)
ZeroClaw は、カスタムイベントの注入のために、クライアントからの受信 session/update(およびレガシーの session/event エイリアス)通知も受け付けます。これはベースの ACP 仕様には含まれない、ZeroClaw 固有の機能です。今後 ACP 仕様で異なるセマンティクスを持つ受信 session/update が定義された場合、これは _meta/session/update に名称変更されます。
セッションの永続化
ZeroClaw は ACP セッションを自動的に SQLite に永続化します。設定は不要で、zeroclaw acp の起動時、またはゲートウェイの WebSocket ACP 接続が受け入れられたときに、ストアが <workspace_dir>/sessions/acp-sessions.db で開かれます。ファイルを作成できない場合(読み取り専用ファイルシステム、不正な権限)、サーバーはメモリ内のみのセッションにフォールバックし、initialize レスポンスで loadSession が false を報告します。
永続化される内容:
- セッションメタデータ:
sessionId、workspaceDir、created_at、last_activity - 1回の完了した
session/promptターンごとに書き込まれるすべてのConversationMessage(ターンごとに1つのアトミックなトランザクション)を含む完全な会話履歴
セッションはプロセスの再起動後も保持されます。ある zeroclaw acp の呼び出しで作成されたセッションは、同じ workspace_dir(つまり同じ acp-sessions.db ファイル)が使用されている限り、後続の呼び出しで読み込みまたは再開できます。
セッションは自動的に削除されません。session/close を使用してセッションを削除せずに非アクティブ化し、その後 session/load または session/resume を使用して復元します。
session/load (ZeroClaw 拡張)
完全な履歴リプレイを伴って、以前に永続化されたセッションを復元します。サーバーは保存された会話履歴をエージェントにシードし、その履歴を session/update 通知のシーケンスとしてクライアントにストリーミングで返してから処理を返します。クライアントは、セッションが終了しなかった場合に受け取っていたであろう更新ストリームと同じものを受信します。
→ {"jsonrpc":"2.0","id":5,「method」:session/load,"params":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0",「method」:"session/update","params":{
"sessionId": "s-ab12cd",
update: {sessionUpdate: agent_message_chunk, "内容": {"type":"text","text":「最後のコミット...」}}
}}
← ... (remaining stored messages replayed as session/update notifications)
← {"jsonrpc":"2.0","id":5,"result":{}}
session/loadが返された後、セッションはアクティブになり、session/prompt呼び出しを受け入れる準備が整います。
永続化されたセッションを復元する際、サーバーは対象エージェントがまだディスパッチ可能な場合にのみ、保存されたオーナーエイリアスを再利用します。それ以外の場合は、オペレーター制御の [acp].default_agent → sole-agent チェーンにフォールバックし、無効化されたエイリアスをスキップします。ゲートウェイの ?agent= は session/new のデフォルトとしてのみ機能し、復元時の再バインドは行いません。
session_id は sessionId の snake_case エイリアスとして受け付けられます。
エラー:
| コード | 意味 |
|---|---|
-32000 SESSION_NOT_FOUND | ストア内に指定された sessionId のレコードが存在しません |
-32001 SESSION_LIMIT_REACHED | max_sessions 個のアクティブなセッションがすでに実行中です |
-32602 INVALID_PARAMS | セッションはすでにアクティブです。先に session/close を呼び出してください |
-32603 INTERNAL_ERROR | SQLite の読み取りに失敗しました |
session/resume (ZeroClaw 拡張機能)
履歴の再生なしで、以前に永続化されたセッションを復元します。エージェントには保存された会話履歴がシードされるため、次のターンに向けた完全なコンテキストを保持しますが、session/update 通知は発行されません。クライアントが以前の接続から既に履歴を持っており、エージェントの状態のみを復元する必要がある場合に使用します。
→ {"jsonrpc":"2.0","id":5,「method」:"session/resume","params":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0","id":5,"result":{}}
session/resume が返った後、セッションはアクティブになり、session/prompt の呼び出しを受け付ける準備が整います。エラーは session/load と同様です。復元エイリアスの選択は、session/load と同じディスパッチ可能なオーナーのフォールバックルールに従います。
ロードと再開の違い: 予期しない切断後に再接続し、クライアントが保存された履歴から UI を再構築する必要がある場合は session/load を使用します。クライアントがすでに履歴を持っている場合(例: ローカルに保存している場合)で、サーバー側のエージェント状態の復元のみが必要な場合は session/resume を使用します。
session/close (ZeroClaw 拡張)
アクティブなセッションを無効化します。実行中のターンをキャンセルし、メモリ内のアクティブセットからセッションを削除し、ACP バックチャネルの登録を解除します。SQLite ストア内のセッションレコードは削除されません。セッションは後で session/load または session/resume で復元できます。
→ {"jsonrpc":"2.0","id":6,「method」:session/close,"params":{"sessionId":"s-ab12cd"}}
← {"jsonrpc":"2.0","id":6,"result":{}}
session_id は sessionId の snake_case エイリアスとして受け付けられます。
セッションが現在アクティブでない場合(ストアにはまだ存在している可能性があります)、SESSION_NOT_FOUND(-32000)を返します。
Close と stop の違い: session/close はセッションを非アクティブ化しつつ、後で再読み込みできるよう永続レコードを保持します。session/stop もセッションをメモリから削除しますが、ストアに対しては同じ効果があります。どちらも SQLite レコードを削除しません。
設定
default_agent
session/new で agentAlias が省略され、複数のエージェントが設定されている場合に使用するエージェントエイリアス。エージェントがちょうど1つだけ存在する場合は、このフィールドに関係なく自動的に選択されます。
任意のサーフェスに設定する場合:
ゲートウェイダッシュボード
/config/acp を開いて acp.default_agent フィールドを設定します。
zerocode
Config ペインで、acp.default_agent フィールドを設定します。
zeroclaw config
zeroclaw config set acp.default_agent <value>
環境変数
オーバーライドをエクスポートします(POSIXシェル用。~/.bashrc、~/.zshrc、.env、またはDockerfileに記述します)。<alias>を実際のエイリアスに置き換えてください。
export ZEROCLAW_acp__default_agent=
max_sessions
同時に実行できる ACP セッションの最大数。デフォルト: 10。
任意のサーフェスに設定する場合:
ゲートウェイダッシュボード
/config/acp を開いて acp.max_sessions フィールドを設定します。
zerocode
Configペインで、acp.max_sessionsフィールドを設定します。
zeroclaw config
zeroclaw config set acp.max_sessions <value>
環境変数
オーバーライドをエクスポートします(POSIXシェル用。~/.bashrc、~/.zshrc、.env、またはDockerfileに記述します)。<alias>を実際のエイリアスに置き換えてください。
export ZEROCLAW_acp__max_sessions=
session_timeout_secs
アイドルセッションのタイムアウト(秒単位)。この時間アクティビティがなかったセッションは破棄の対象になります。デフォルト: 3600(1時間)。
任意のサーフェスに設定する場合:
ゲートウェイダッシュボード
/config/acp を開いて acp.session_timeout_secs フィールドを設定します。
zerocode
Config ペインで、acp.session_timeout_secs フィールドを設定します。
zeroclaw config
zeroclaw config set acp.session_timeout_secs <value>
環境変数
オーバーライドをエクスポートします(POSIXシェル用。~/.bashrc、~/.zshrc、.env、またはDockerfileに記述します)。<alias>を実際のエイリアスに置き換えてください。
export ZEROCLAW_acp__session_timeout_secs=
session/new で agentAlias が省略され、複数のエージェントが設定されている場合に default_agent が参照されます。これが指定されておらず、[agents.<alias>] エントリがちょうど 1 つだけ存在する場合は、そのエージェントが自動的に選択されます。
サブプロセスとして zeroclaw acp を実行すると、コマンドは無条件にサーバーを起動します。デーモンとして実行すると、ゲートウェイは追加設定なしで WebSocket 経由の ACP を /acp で公開します。ゲートウェイクライアントはその URL に ?agent=<alias> を追加することで、仕様準拠のエンドポイントごとに 1 つのエージェントを使用するクライアントから、設定済みの各エージェントにアクセスできます。認証(Authorization、Sec-WebSocket-Protocol、または ?token=)は接続がアップグレードされる前に適用され、クエリパラメーターによって、すでに設定されているエージェントの選択以外のアクセス権が付与されることはありません。
実行中
サブプロセスとして(一般的なIDE統合):
sh
zeroclaw acp
このバイナリは標準入力を読み取り、標準出力に書き出し、EOF で終了します。
デーモンゲートウェイ経由(リモートまたは同一ホスト):
デーモンを通常通り起動してください。ゲートウェイは常に /acp でWebSocket経由でACPを公開しており、追加の設定フラグは不要です。クライアントは直接接続できます。マルチエージェント環境では、ws://127.0.0.1:8080/acp?agent=myagent のようなURLを使用することで session/new で agentAlias を省略できます。または zeroclaw-acp-bridge を経由して接続することもできます。これはstdio ACPプロトコルをゲートウェイのWebSocketにブリッジします。
sh
zeroclaw-acp-bridge
ブリッジは、デーモンと同じ設定からゲートウェイのアドレスと認証トークンを読み取ります。デーモンをデフォルト以外の設定ディレクトリ(例: --config-dir /tmp/zeroclaw)で実行する場合は、ブリッジを同じディレクトリに向けてください:
sh
zeroclaw-acp-bridge --config-dir /tmp/zeroclaw
# または同等の表記:
zeroclaw-acp-bridge --config-dir=/tmp/zeroclaw
キャッシュされたトークンファイルに依存したくない場合は、ZEROCLAW_ACP_BRIDGE_TOKEN を介して直接ベアラートークンを指定することもできます。
バージョン互換性
ACP v0 クライアント(フラットな {streaming, maxSessions, ...} initialize レスポンスと kind: "text"|"tool_call" の session/update 形式を使用)は、v1 サーバーへの接続時にデシリアライズエラーが発生します。判別子(discriminant)とエンベロープ形式が破壊的な方法で変更されました。アップグレード手順:
session/update通知を判別するには、kindではなくsessionUpdateを使用してください。session/promptの結果を{finished, usage}ではなく{sessionId, stopReason, content}として解析します。session/request_permissionレスポンス処理を実装する: 承認メカニズムがサーバー通知からクライアントが応答する RPC へ移行しました。session/newからsystemPromptパラメーターを削除してください。読み込まれていません。
セキュリティ
ACPは実行中の設定の自律性レベルを継承します。[autonomy] level = "supervised" の場合、中リスクのツール呼び出しはACPバックチャネルを介して承認をトリガーします。これはクライアントが確認する必要がある session/request_permission のアウトバウンドリクエストです。full モードでは、ツール呼び出しは承認なしで実行され、workspace_only は暗黙的に無効化されます(エージェントはセッションのcwd外のパスにアクセスできます)。forbidden_paths は引き続き適用されます。
session/new の cwd は、そのセッションで使用されるすべてのファイルツールおよびシェルツールの SecurityPolicy ワークスペース境界になります。エージェントのシステムプロンプトには、同じ実効セッションワークスペースが反映されます。プロンプトの「作業ディレクトリ」は SecurityPolicy.workspace_dir(セッションの cwd、または cwd が省略された場合はエージェントワークスペース)から生成される一方、エージェントのアイデンティティとパーソナリティ(IDENTITY.md、SOUL.md)は別のエージェントワークスペースから読み込まれます。そのため、モデルはファイルツールおよびシェルツールが実際にルートとするディレクトリを認識します。
2 つのルートによるファイル権限。 セッションの cwd を設定すると、ファイルおよびシェルツール のパス(読み取り/書き込み/一覧表示、シェル起動時の CWD、埋め込みリソースの uploads/)がそのディレクトリに限定されます。セッションが排他的な隔離環境になるわけではありません。解決された エージェントワークスペースは引き続き許可されたルート であるため、セッションの cwd に関係なく、エージェント自身のリソース(スキル、アイデンティティ、[agents.<alias>] 配下のエージェントごとの状態)には引き続きアクセスできます。つまり、workspaceDir は セッションのファイル操作 のルートを制御しますが、エージェントワークスペースは引き続きエージェント自身の設定スコープのリソースを支えます。cwd を省略した場合(またはインストールルートのプレースホルダーである場合)、セッションがエージェントワークスペース自体をルートとするため、2 つは一致します。
メモリ
ACP セッションはエージェントの永続的メモリシステムと連携しません。これは意図的な設計上の選択です。ACP は IDE 主導のコーディングタスク向けであり、長期的な関係構築を目的としたものではありません。
ACPセッションが継承する内容(エージェント設定から):パーソナリティ、スキル、リスクプロファイル、ランタイムプロファイル、モデルプロバイダー、およびすべての非メモリツール。
ACP セッションに含まれないもの:
- メモリツール(
memory_recall、memory_store、memory_forget、memory_export、memory_purge)は利用できません - 自動メモリ呼び出し(各ターンで長期メモリから構築されるコンテキストプリアンブル)が無効になっています
- エージェントのメモリストアへの会話の自動保存が無効になっています
セッションコンテキストは、acp-sessions.dbに永続化された会話履歴から取得されます。セッションは永続的で、再開可能かつ削除可能であり、セッション履歴はエージェントの長期記憶ではなく、作業用コンテキストとして機能します。
この分離により、一時的なコーディング支援の会話がエージェントの長期記憶を汚染することがなくなり、またチャットチャンネルからの無関係な知識がACPセッションに混入することもなくなります。
コードリファレンス
- ACP サーバー:
crates/zeroclaw-channels/src/orchestrator/acp_server.rs - ACPバックチャネル:
crates/zeroclaw-channels/src/acp_channel.rs - セッションストア (SQLite):
crates/zeroclaw-infra/src/acp_session_store.rs - Gateway ACP-over-WebSocket エンドポイント:
crates/zeroclaw-gateway/src/acp.rs - セッションごとのパス強制:
crates/zeroclaw-config/src/policy.rs(SecurityPolicy::from_config)、crates/zeroclaw-runtime/src/agent/agent.rs(from_config_with_session_cwd_and_mcp) - OSレベルのサンドボックス検出/バックエンド:
crates/zeroclaw-runtime/src/security/detect.rs、landlock.rs、bubblewrap.rs、seatbelt.rs
関連項目も参照してください
- チャンネル → 概要
- ツール → MCP: エージェントにツールを提供するクライアント。ACP はその逆
- セキュリティ → 自律性
- セキュリティ → 概要