RPC ソケットトランスポート
デーモンは、ローカルIPCストリーム(Unixではドメインソケット、Windowsでは名前付きパイプ)上でJSON-RPC 2.0インターフェースを公開します。これは、zerocodeのようなローカルクライアントの主要なトランスポートです。HTTP/WSゲートウェイは、Webhook、Webダッシュボード、およびリモートRESTコンシューマー向けに引き続き利用できます。
エンドポイントの解決
各データディレクトリには独自のエンドポイントが割り当てられるため、同一マシン上で複数のデーモンインスタンスが衝突することはありません。データディレクトリは設定ディレクトリ(--config-dir / ZEROCLAW_CONFIG_DIR、または ZEROCLAW_DATA_DIR)から導出されます。
| OS | デフォルトエンドポイント |
|---|---|
| Linux | <data_dir>/daemon.sock(Unix ドメインソケット) |
| macOS | <data_dir>/daemon.sock(Unix ドメインソケット) |
| Windows | \\.\pipe\zeroclaw-<hash>(<hash> は data_dir から導出されます) |
どちらのプラットフォームでも ZEROCLAW_SOCKET 環境変数で上書きできます:
sh
export ZEROCLAW_SOCKET=/tmp/my-zeroclaw.sock
zeroclaw daemon
PowerShell
$env:ZEROCLAW_SOCKET = '\\.\pipe\my-zeroclaw'
zeroclaw daemon
ワイヤープロトコル
NDJSON(改行区切りJSON)。各行は完全なJSON-RPC 2.0メッセージです。HTTPフレーミングや長さプレフィックスはありません。フレーミングはすべてのプラットフォームで同一です。名前付きパイプはUnixソケットと同じバイトストリームを伝送します。
{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":1},"id":1}\n
{"jsonrpc":"2.0","result":{"protocolVersion":1,"serverVersion":"0.8.5"},"id":1}\n
ハンドシェイク
最初のRPC呼び出しは必ず initialize でなければなりません。デーモンは initialize が成功するまで、他のすべてのメソッドを拒否します。プロトコルバージョンの不一致は、コード -32011 の構造化エラーを生成します。
{
"jsonrpc": "2.0",
「method」: 初期化,
"params": {
protocolVersion: 1
},
"id": 1
}
エンドポイントはペアリングトークンを必要としません。アクセス制御はオペレーティングシステムによって処理されます:
- Unix: ソケットは
0o600、親ディレクトリは0o700。 - Windows: 名前付きパイプの ACL は、作成したユーザーと
SYSTEMがデフォルトになります。
メソッド
| 方法 | 方向 | 説明 |
|---|---|---|
initialize | client -> daemon | 認証してプロトコルバージョンをネゴシエートする |
session/new | client -> daemon | エージェントセッションを作成します(agentAlias が必要です。cwd、sessionId は省略可能です。省略可能な keep_siblings を指定すると、兄弟セッションのライフサイクルを自ら管理するマルチセッション クライアントで、アイドル状態の同一モードの兄弟セッションの排除を抑制します) |
session/close | client -> daemon | セッションを閉じてクリーンアップする |
session/prompt | client -> daemon | ターンを実行(session/update 通知経由でストリーミング) |
session/cancel | client -> daemon | 進行中のターンをキャンセルする |
status | client -> daemon | サーバーバージョン、プロトコルバージョン、アクティブセッション一覧 |
session/update | デーモン → クライアント | ターン中のストリーミング通知(テキストチャンク、ツール呼び出し、承認) |
elicitation/create | デーモン → クライアント | ask-user と poll フローの対話型入力を要求する |
双方向リクエスト
どちらの側からでも、確立済みのソケット上でリクエストを送信できます。受信側は同じ id を使用し、result または error のいずれか一方だけで応答する必要があります。各ピアは送信リクエストに対して独自の zc-out-<number> シーケンスを使用します。このプレフィックスはグローバルに一意な名前空間ではありません。相関は方向ごとに行われます。各ピアは自身の保留中リクエストのマップに対してのみ応答を照合するため、同じ文字列の ID が反対方向で独立して処理中になる可能性があります。
{"jsonrpc":"2.0",「method」:"elicitation/create","params":{"message":"続行しますか?"},"id":zc-out-0}
{"jsonrpc":"2.0","result":{"action":"accept","内容":{回答:"はい"}},"id":zc-out-0}
明示的な "result": null は成功応答であり、保留中の呼び出し元も解決されます。error オブジェクトの場合は、失敗として解決されます。ピアが応答しない場合、開始した ask-user または poll 操作では、従来のタイムアウト動作が維持されます。
すべてのフレームは、"jsonrpc": "2.0" を含む JSON オブジェクトでなければなりません。リクエストには文字列の method が必要です。params が存在する場合は、オブジェクトまたは配列でなければなりません。レスポンスには文字列、数値、または null の id と、レスポンスメンバーが正確に 1 つ必要です。無効な JSON では -32700(解析エラー)が生成されます。不正なリクエスト形式のエンベロープでは -32600(無効なリクエスト)が生成され、復元できる場合は有効なリクエスト ID が使用されます。不正なレスポンス形式のエンベロープは、フレームの内容をログに記録せずに破棄され、返信も行われません。これは、その ID をエコーすると、反対方向にある無関係なリクエストを完了させてしまう可能性があるためです。方向を判別できないエンベロープでは id: null を使用します。未知の有効なレスポンス ID も同様にログに記録して無視し、応答は返しません。これによりレスポンスループを防ぎます。
ストリーミングをオンにする
session/prompt はターンが完了すると最終結果を返します。実行中、デーモンは増分イベントを含む session/update 通知を送信します。
{"jsonrpc":"2.0",「method」:"session/update","params":{"sessionId":"...","type":agent_message_chunk,"text":こんにちは}}
{"jsonrpc":"2.0",「method」:"session/update","params":{"sessionId":"...","type":"ツール呼び出し","toolCallId":tc_1,"name":bash,rawInput:{...}}}
{"jsonrpc":"2.0",「method」:"session/update","params":{"sessionId":"...","type":"ツール結果","toolCallId":tc_1,"name":bash,rawOutput:"..."}}
イベントタイプ: agent_message_chunk、agent_thought_chunk、tool_call、tool_result、approval_request。
一時モード
zeroclaw daemon --ephemeral は接続中のクライアントを追跡し、最後のクライアントが切断されると自身を終了します(1秒の猶予期間の後)。猶予期間中に再接続するとシャットダウンはキャンセルされます。デーモンは少なくとも1つのクライアントが接続するまで終了しません。
--ephemeral を指定せずに起動したデーモンは、クライアント数を無視し、明示的に停止されるまで実行され続けます。
セキュリティ
- Unixソケットディレクトリ:
0o700(所有者のみ) - Unixソケットファイル:
0o600(所有者のみ) - Windows 名前付きパイプ: デフォルトの ACL は作成ユーザーと
SYSTEMにアクセス権を付与します SO_PEERCREDは Linux において、監査ログ用に接続元プロセスの PID と UID を提供します。Windows ではピアラベルとしてpipe:localがログに記録されます
クイックテスト
デーモンを1つのターミナルで起動します:
sh
zeroclaw daemon
2 つ目のターミナルで Unix を使用している場合は、socat で接続します:
sh
socat READLINE UNIX-CONNECT:~/.zeroclaw/data/daemon.sock
行を1行ずつ貼り付けてください:
{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":1},"id":1}
{"jsonrpc":"2.0","method":"status","params":{},"id":2}
Windowsでは、任意の名前付きパイプクライアント(PowerShellの[System.IO.Pipes.NamedPipeClientStream]、WSL経由のnc、または単にzerocodeを実行)を使用してください。
内部構造
ディスパッチ層は crates/zeroclaw-runtime/src/rpc/ にあります:
| ファイル | 役割 |
|---|---|
transport.rs | RpcTransport トレイト |
turn.rs | execute_turn() 共有ターン実行プログラム |
session.rs | RpcSession, SessionStore |
dispatch.rs | RpcDispatcher メソッドルーティング |
local.rs | LocalTransport + リスナー(Unix ソケット / Windows 名前付きパイプ) |
wss.rs | WSS (WebSocket Secure) トランスポート + TLS アクセプター |
attachments.rs | ファイルアップロード処理、重複排除、マーカー生成 |
RpcTransportトレイトは、追加のトランスポート(vsock、カスタムIPC)をディスパッチやセッションのロジックに手を加えることなく組み込めるように設計されています。local.rsモジュールは、tokio::io::splitを使用して、UnixとWindowsのプリミティブを単一のLocalTransport構造体の背後にラップするため、読み取り/書き込みループは両プラットフォーム間で共有されます。