WebSocket Protocol
Channel 3 — the live session plane — runs over a WebSocket between core-mcp and the user’s client. It carries agent push notifications, outbound stream deliveries, and canonical inbound user actions.
The WebSocket is used by the React SDK (
@ggui-ai/react) in the browser. Agents use the MCP HTTP API on channel 2. You typically don’t interact with the WebSocket directly unless building a custom frontend.
Client → Server Messages
Section titled “Client → Server Messages”subscribe
Section titled “subscribe”Bind the connection to a session. Must be sent before any other messages.
{ "type": "subscribe", "payload": { "sessionId": "ses_abc123", "appId": "app_myapp" }}Optional resume: pass fromSeq: N to replay outbound stream envelopes with seq > N before the live tail. Honored by OSS @ggui-ai/mcp-server (via SessionStreamBuffer); ignored by hosted cloud today.
action
Section titled “action”Send a canonical ActionEnvelope (Section 4.2 of the protocol spec). The envelope is flat — no nested blocks.
{ "type": "action", "payload": { "sessionId": "ses_abc123", "type": "data:submit", "payload": { "action": "submit", "data": { "rating": 5 } }, "stackIndex": 0, "clientSeq": 1 }}Server → Client Messages
Section titled “Server → Client Messages”Acknowledges a subscribe or event. Carries the current inbound sequence, optional outbound streamSeq cursor (used to seed resume), and optional replayTruncated flag when a requested fromSeq could not be honored fully.
{ "type": "ack", "payload": { "sequence": 42, "streamSeq": 12, "stack": [] }}Notifies the client that a new UI card was pushed by the agent.
{ "type": "push", "payload": { "stackItem": { "id": "si_xyz", "componentCode": "...", "prompt": "Show a settings panel" } }}Carries an outbound StreamEnvelope (Section 4.3 of the protocol spec). channel identifies which streamSpec[name] the payload belongs to.
{ "type": "data", "payload": { "sessionId": "ses_abc123", "channel": "message", "mode": "append", "payload": { "text": "Found 3 flights.", "sender": "agent" }, "seq": 7 }}progress
Section titled “progress”Generation progress update during UI creation.
| Step | Description |
|---|---|
queued | Request is queued for processing |
primitives | Loading available UI primitives |
writing | LLM is generating component code |
compiling | Compiling and validating the component |
Error response from the server.
Connection Lifecycle
Section titled “Connection Lifecycle”1. Connect to WebSocket URL2. Send "subscribe" with sessionId + appId (optional fromSeq for resume)3. Receive "ack" confirming subscription (carries streamSeq + initial stack)4. Receive "push" / "data" / "progress" / "url" messages as they occur5. Send "action" messages for user interactions6. Connection closes when session ends or client disconnectsReconnection
Section titled “Reconnection”The React SDK handles automatic reconnection with exponential backoff (1s, 2s, 4s, … up to 30s, max 10 attempts). Clients SHOULD track the last observed StreamEnvelope.seq and pass it back as SubscribePayload.fromSeq on reconnect to resume the outbound stream (where the target implementation supports it).
Connection Status
Section titled “Connection Status”| Status | Description |
|---|---|
connecting | Initial connection in progress |
connected | Connected and subscribed |
disconnected | Not connected |
reconnecting | Attempting to reconnect after a drop |