Skip to content

Runtime communication protocols

This page answers the cross-cutting protocol question for the extracted cli.js: how do runtime modules communicate, how do agents/subagents coordinate, and how does Claude Code talk to remote servers or hosts?

The short answer is that there is no single universal protocol. Inside the bundled runtime, most module boundaries are ordinary JavaScript calls, async queues, stores, and event emitters. Protocols appear at integration boundaries: MCP uses JSON-RPC-shaped messages, IDE/Chrome/Remote Control paths use JSON envelopes over WebSocket/SSE-like transports, task/subagent coordination uses built-in tools plus task-store events, and model/provider calls use HTTP(S) request/streaming responses.

Source anchors

Semantic aliasSource fileApproximate locationAnchorMeaning
BridgeToolCallFramecli.jsline ~64, byte 0x3629ftype:"tool_call"Chrome/IDE bridge sends JSON tool-call envelopes over a WebSocket-style bridge.
BridgePairingRequestcli.jsline ~64, byte 0x37641type:"pairing_request"Bridge pairing and device selection use explicit JSON envelope types.
BridgePermissionRequestcli.jsline ~64, byte 0x395a7permission_requestBridge receives permission prompts as typed JSON messages.
BridgePermissionResponsecli.jsline ~64, byte 0x39a71permission_responseBridge sends permission decisions back as typed JSON messages.
McpResourcesListMethodcli.jsline ~95, byte 0x8fe5cresources/listMCP resources are represented as JSON-RPC method schemas.
McpPromptsGetMethodcli.jsline ~95, byte 0x90205prompts/getMCP prompts use the same method-schema layer.
McpToolsListMethodcli.jsline ~95, byte 0x907a4tools/listMCP tools are listed through a JSON-RPC method.
TaskGetMethodcli.jsline ~99, byte 0x9a38emethod:"tasks/get"Task result/status protocol is method-based and JSON-RPC-shaped.
TaskCancelMethodcli.jsline ~99, byte 0x9a481method:"tasks/cancel"Task cancellation uses the same task method family.
ProviderRequestLogcli.jsline ~404, byte 0x2c1a5c[API REQUEST]Provider/API request logging surface for outbound HTTP calls.
ProviderEventStreamDetectioncli.jsline ~404, byte 0x2c1b55text/event-streamStreaming HTTP responses are detected as event streams.
ProviderRequestIdHeadercli.jsline ~404, byte 0x2c1dd8x-client-request-idProvider/API requests carry request IDs through HTTP headers.
RemoteSessionTransportcli.jsline ~791, byte 0x43cf82sendMessage, cancelRequest, disconnect, sendControlRequestRemote-session wrapper exposes a message/control transport API to the app.
TaskToolProtocolSurfacecli.jsline ~1091, byte 0x4804f6TaskCreate, TaskGet, TaskList, TaskUpdateAgent/task coordination is surfaced as tool/action constants.
AgentPeerMessageActioncli.jsline ~185, byte 0x11eb11SendMessagePeer/agent message sending is a first-class tool/action constant.
IdeBridgeTransportscli.jsline ~1660, byte variesws://, http://.../sseIDE integration accepts WebSocket or HTTP SSE endpoints.
ControlRequestFramecli.jsline ~2004, byte 0x519ca7control_requestHeadless/SDK/Remote Control ask path is a typed control frame.
SandboxPermissionFramecli.jsline ~2008, byte 0x51be67sandbox_permission_requestSandbox network/file approvals are typed remote/control envelopes.
TeamPermissionUpdateFramecli.jsline ~2008, byte 0x51c55ateam_permission_updateTeam/agent coordination emits typed update envelopes.
PlanApprovalRequestFramecli.jsline ~2008, byte 0x51c782plan_approval_requestPlan approval is another explicit control-envelope subtype.
WebSocketAuthFdcli.jsline ~2624, byte 0x6516a5CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTORRemote/bridge ingress can read WebSocket auth from an inherited file descriptor.
ExternalProtocolTransportLabelscli.jsline ~2744, byte 0x749135stdio, sse, httpTransport labels for external protocol adapters.
RemoteSessionConfigInjectioncli.jsline ~9573, byte 0xcd6d9bremoteSessionConfigRemote-session configuration is injected into the interactive app.
BridgeStateStreamFramecli.jsline ~19356, byte 0xdaf5aabridge_stateHeadless stream projects bridge state as a first-class frame.

Protocol matrix

BoundaryPrimary mechanismData shapeNotes
In-bundle modulesJavaScript calls, async functions, stores, event emitters, queuesRuntime objectsThe bundled cli.js is one process and one large module graph; logical modules are semantic boundaries, not wire protocols.
Built-in toolsTool definitions plus permission boundaryTool-use input/output objectsModel tool calls become validated tool inputs, then cross the permission/execution boundary.
MCP serversJSON-RPC 2.0-style requests, responses, notificationsmethod, params, id, jsonrpc, result/errorConfirmed by tools/list, tools/call, prompts/list, prompts/get, resources/list, task methods, and JSON-RPC error codes.
Agents/tasks/subagentsBuilt-in task/message tools, task store, hooks, typed notificationsTool inputs plus task records/eventsTaskCreate/TaskGet/TaskList/TaskUpdate and SendMessage are the model-facing protocol surface; hooks expose lifecycle events.
IDE bridgeWebSocket or HTTP SSE endpointJSON framesEndpoint detection accepts ws://... and http://.../sse; bridge frames use explicit type fields.
Chrome/browser bridgeWebSocket-style bridgeJSON frames (connect, tool_call, tool_result, permission_request, permission_response, pairing messages)The bridge has pairing, routing, tool call, result, permission, ping/pong, and device-selection messages.
SDK/headless outputStream-JSON/event projectionTyped framescontrol_request, permission_denied, session_state_changed, transcript_mirror, bridge_state, task_notification, and final result frames share a projection channel.
Remote Control / remote sessionsRemote message/control wrapper + bridge JSON envelopesMessage/control requests, permission responses, session configremoteSessionConfig, sendMessage, sendControlRequest, token/env anchors, and permission envelopes show bidirectional control.
Provider/model APIHTTP(S) plus streaming responsesHTTP headers, JSON bodies, SSE/event-stream chunkstext/event-stream, x-client-request-id, and API request logging confirm streaming HTTP boundaries; Bedrock can use Amazon event streams.

In-process module communication

Most named modules in the wiki — runtime lifecycle, context assembler, tool boundary, session store, agents, ops — are logical seams inside one bundled artifact. Their communication is direct and object-based:

flowchart TD
Commander[Commander/root action] --> Settings[settings and policy objects]
Commander --> Session[session envelope/store]
Commander --> Loop[interactive or headless loop]
Loop --> Context[context assembler]
Context --> Provider[provider request]
Loop --> Tools[tool execution boundary]
Tools --> Session
Loop --> Frames[UI / stream-json / remote frames]

This matters because a string such as TaskCreate or control_request is not evidence of a separate daemon by itself. It becomes a protocol only when it crosses an external boundary or is serialized into the headless/bridge stream.

MCP protocol boundary

MCP is the clearest protocol layer in the bundle. The source schemas include JSON-RPC error codes and method names such as:

  • tools/list, tools/call
  • prompts/list, prompts/get
  • resources/list, resources/read, resources/templates/list
  • tasks/get, tasks/list, tasks/result, tasks/cancel
  • cancellation notifications such as notifications/cancelled

The runtime therefore treats MCP as a method-oriented request/response/notification protocol. Transports can vary — the bundle contains references to stdio, sse, and http — but the semantic layer remains JSON-RPC-shaped.

Agent and subagent communication

Agents do not appear to use a separate free-form chat protocol between each other. The visible coordination surface is composed from:

  1. Tools/actions: SendMessage, TaskCreate, TaskGet, TaskList, TaskUpdate.
  2. Task store methods: tasks/get, tasks/result, tasks/list, tasks/cancel.
  3. Hooks and events: SubagentStart, SubagentStop, TaskCreated, TaskCompleted, TeammateIdle.
  4. Team/permission envelopes: team_permission_update, plan-approval frames, and mailbox/team-context system reminders.
sequenceDiagram
autonumber
participant Main as Main agent
participant Tools as Task/message tools
participant Store as Task store / queues
participant Sub as Subagent runtime
participant Hooks as Hook/event stream
Main->>Tools: TaskCreate / SendMessage
Tools->>Store: create task or enqueue message
Store->>Sub: assign work / provide context
Sub->>Hooks: SubagentStart
Sub->>Store: progress, task result, notifications
Store-->>Main: TaskGet / TaskList / task_notification
Sub->>Hooks: SubagentStop / TaskCompleted

The implication is that “agent-to-agent communication” is tool/state/event mediated. A subagent is not just a peer socket; it is a runtime context with transcript-backed state, task metadata, and hook-visible lifecycle.

Remote, bridge, and provider communication

Remote/server communication splits into several channels:

Provider/model APIs

The model request path is HTTP(S)-based and can stream responses. Anchors include [API REQUEST], x-client-request-id, text/event-stream, and vnd.amazon.eventstream. This supports the model/provider documentation: Anthropic-style streaming uses event-stream responses; Bedrock can expose Amazon event-stream content.

IDE and browser bridges

IDE and Chrome/browser bridges use persistent transport and JSON frames:

  • IDE endpoint discovery accepts ws:// and HTTP .../sse URLs.
  • Browser bridge frames include tool_call, tool_result, permission_request, permission_response, pairing_request, pairing_response, ping, and pong.
  • Permission decisions are sent back with request IDs, so approvals are correlated with pending tool calls.

Remote sessions and Remote Control

Remote sessions inject remoteSessionConfig into the interactive app. Remote Control/bridge paths expose functions with semantic names like sendMessage, cancelRequest, disconnect, and sendControlRequest, and they read auth/token material through anchors such as CLAUDE_CODE_WEBSOCKET_AUTH_FILE_DESCRIPTOR and CLAUDE_CODE_SESSION_ACCESS_TOKEN.

Remote Control is bidirectional: it can observe output frames, send permission responses, and issue control changes such as interrupt, model/thinking updates, mode changes, and plan approval responses.

Caveats

  • Bundled vendor libraries include gRPC/WebSocket/AWS Smithy/EventStream code. This page treats those as dependency support unless a string is connected to a Claude Code runtime path.
  • Approximate line numbers shift easily because cli.js is bundled and has very long lines. Use exact strings plus byte offsets for lookup.
  • Some schemas prove protocol shape; they do not prove which transport is selected for a particular user configuration.

Created and maintained by Yingting Huang.