JSON Stream Protocol
When you run Wayland Core with --json-stream, it speaks a line-based JSON protocol over stdin and stdout instead of rendering a terminal UI. This is how a host process (an Electron app, a Node service) drives the engine: one process per conversation, kept alive across turns. stderr stays out of the protocol and carries diagnostic logs.
wayland-core --json-stream --provider anthropicTransport is JSON Lines: one UTF-8 JSON object per line, each with a type field.
The handshake
Section titled “The handshake”The engine emits a ready event once initialization finishes. The host must wait for it before sending anything. ready carries the protocol version, a session_id, and a capabilities object announcing which event variants this run will emit (tool approval, thinking, MCP, and more).
{ "type": "ready", "version": "0.2.0", "session_id": "a1b2c3", "capabilities": { "tool_approval": true, "mcp": true } }Events the engine emits
Section titled “Events the engine emits”The engine streams a turn as events: stream_start, text_delta, thinking, tool_request, tool_running, tool_result, tool_cancelled, and stream_end, among others. A tool_request pauses execution and waits for the host to approve or deny.
Commands the host sends
Section titled “Commands the host sends”The host writes commands to stdin. The core set:
| Command | Purpose |
|---|---|
message | Send a user message (with optional attached files) |
stop | Abort the current response stream |
tool_approve | Approve a pending tool call (scope once or always) |
tool_deny | Deny a pending tool call, with a reason |
set_mode | Switch approval mode: default, auto_edit, force (yolo is an accepted alias) |
set_config | Change model, thinking, effort, or compaction at runtime |
add_mcp_server | Inject an MCP server before the first message |
ping | Heartbeat; the engine replies with pong |
{ "type": "message", "msg_id": "m1", "content": "Read src/main.rs and explain it" }Approvals and dynamic MCP
Section titled “Approvals and dynamic MCP”A tool_request blocks until the host answers with tool_approve or tool_deny. Approving with scope: "always" adds the tool’s category to the session allow-list so later calls skip the gate.
add_mcp_server injects a server during the pre-message window: after ready and before the first message. The engine replies with mcp_ready listing the new tools. The first message closes the window, and later injection attempts are rejected.
Version skew
Section titled “Version skew”The host should tolerate event types it does not recognize. New variants stay off in config until a release enables them, and default-off capability flags are omitted from ready, so older hosts see the shape they expect. The full wire format lives in docs/json-stream-protocol.md in the engine repository.