컨텐츠로 건너뛰기
Developer Preview — APIs and language features may change before 1.0

Surfaces: WebSocket

이 콘텐츠는 아직 해당 언어로 제공되지 않습니다.

The websocket surface establishes a persistent, bidirectional connection between a client and a machine. Use it for real-time dashboards, live notifications, streaming results, collaborative editing, or any scenario where the client and machine need to exchange messages continuously.

Declaring a WebSocket surface

machine live_metrics
accepts
metric_name as text
responds with
value as number
timestamp as text
ensures
permissions
allowed to
reason
implements
ask latest, using: "anthropic:claude-haiku-4-5"
with task "Retrieve the latest value for metric: ${input.metric_name}"
returns
value as number
timestamp as text
assuming
value: 42.5
timestamp: "2026-05-07T12:00:00Z"
expresses
websocket
path: "/ws/metrics"

Configuration options

ConfigRequiredDefaultDescription
pathYes-URL path for the WebSocket endpoint

Connecting

From JavaScript

const ws = new WebSocket("ws://localhost:9000/ws/metrics");
ws.onopen = () => {
// Send a message to invoke the machine
ws.send(JSON.stringify({
metric_name: "cpu_usage"
}));
};
ws.onmessage = (event) => {
const result = JSON.parse(event.data);
console.log(result.value, result.timestamp);
};

From the command line

Terminal window
# Using websocat
websocat ws://localhost:9000/ws/metrics
# Type JSON messages, receive results

Cloud or tunnel

// Cloud cell
const ws = new WebSocket("wss://myorg.mashin.live/ws/metrics");
// Via tunnel (local cell exposed through mashin.live)
const ws = new WebSocket("wss://mashin.live/tunnel/live_metrics/ws/metrics");

Message flow

WebSocket connections support two patterns:

Request-response

The client sends a message (mapped to accepts), the machine runs, and the result (from responds with) is sent back:

Client Machine
│ │
│──── {"metric_name": "cpu"} ──►│
│ │── governance check
│ │── execute steps
│◄── {"value": 42.5, ...} ─────│
│ │

Server-push (streaming)

For machines that produce results over time (monitoring, live feeds), the WebSocket stays open and the machine can push updates:

Client Machine
│ │
│──── {"subscribe": "cpu"} ────►│
│ │
│◄── {"value": 41.2, ...} ─────│ (push)
│◄── {"value": 43.8, ...} ─────│ (push)
│◄── {"value": 40.1, ...} ─────│ (push)
│ │

Combining with other surfaces

WebSocket works well alongside API and page surfaces:

machine dashboard
expresses
api
path: "/api/metrics"
method: "GET"
websocket
path: "/ws/metrics"
page
path: "/dashboard"
title: "System Dashboard"

The page surface serves the dashboard UI. The WebSocket provides live updates. The API provides a REST fallback for clients that do not support WebSocket.

Authentication

WebSocket connections inherit the cell’s authentication. For cloud deployments, the initial WebSocket handshake includes authentication credentials (API key or bearer token) as query parameters or headers during the HTTP upgrade.

Governance

Every message received over WebSocket is governed:

  1. The message payload is validated against accepts
  2. Governance permissions are checked
  3. The machine executes
  4. A SurfaceAccess event is recorded with :websocket surface
  5. The result is sent back

Messages that fail governance are responded to with an error message, not silently dropped. The WebSocket connection stays open.

Connection lifecycle

EventBehavior
ConnectAuthentication verified, connection established
MessageValidated, governed, executed, result returned
DisconnectConnection closed, resources cleaned up
ErrorError message sent, connection stays open
TimeoutIdle connections closed after configurable timeout

When to use WebSocket vs. other surfaces

ScenarioBest surface
One-off request/responseAPI
Live dashboard updatesWebSocket
External event receiverWebhook
AI tool callingMCP
Agent-to-agent communicationA2A
Browser-based appPage + WebSocket

Next steps