What this is for: how to connect, authenticate, and keep a WebSocket session open against the Comis daemon. Who it’s for: developers building real-time clients (dashboards, custom CLIs, browser apps).
Complete reference for the Comis WebSocket protocol. The gateway exposes a WebSocket endpoint at /ws for JSON-RPC 2.0 communication. This is the primary transport for the CLI and web dashboard.
Connection
Connect to the WebSocket endpoint with authentication to establish a JSON-RPC session.
Property Value Endpoint GET /ws (upgrades to WebSocket)Authentication Bearer token via Authorization header or ?token= query parameter Protocol JSON-RPC 2.0 over text WebSocket frames
Connection Examples
# Using wscat with Authorization header
wscat -c ws://localhost:4766/ws -H "Authorization: Bearer your-token"
If authentication fails, the server accepts the WebSocket upgrade but immediately closes the connection with close code 4001 (Unauthorized).
Protocol
All communication uses JSON-RPC 2.0 over text WebSocket frames. Binary frames are not supported and will receive a parse error response.
Request/Response Exchange
{
"jsonrpc" : "2.0" ,
"method" : "system.ping" ,
"id" : 1
}
Every request must include:
"jsonrpc": "2.0" — protocol version (required)
"method" — the method name in namespace.method format
"id" — a unique request identifier (integer or string)
"params" — method parameters (optional, defaults to {})
The server responds with the same id to correlate request and response. Notifications (requests without id) do not receive a response.
Batch Requests
Send an array of JSON-RPC requests to execute multiple methods in a single message. Responses are returned as an array in the same order.
[
{ "jsonrpc" : "2.0" , "method" : "system.ping" , "id" : 1 },
{ "jsonrpc" : "2.0" , "method" : "gateway.status" , "id" : 2 }
]
The maximum batch size is configurable via gateway.maxBatchSize. Exceeding the limit returns a -32600 error.
Heartbeat
The server sends periodic heartbeat notifications to all connected clients. Heartbeats are JSON-RPC notifications (no id field) and do not require a response.
{
"jsonrpc" : "2.0" ,
"method" : "heartbeat" ,
"params" : {
"ts" : 1773313498000
}
}
Property Value Interval Configurable via gateway.wsHeartbeatMs. Set to 0 to disable. Format JSON-RPC notification with method: "heartbeat" and params.ts (epoch milliseconds). Client behavior Clients should not respond to heartbeats. They are notifications, not requests.
Heartbeats serve as a keep-alive mechanism, preventing proxy timeouts and allowing clients to detect stale connections.
Rate Limiting
Each WebSocket connection has an independent sliding-window rate limiter that tracks message frequency.
Property Value Algorithm Sliding window counter Max messages Configurable via gateway.wsMessageRateLimit.maxMessages Window Configurable via gateway.wsMessageRateLimit.windowMs Error code -32000 (rate limit exceeded)
When the rate limit is exceeded, the server responds with an error and discards the message:
{
"jsonrpc" : "2.0" ,
"error" : {
"code" : -32000 ,
"message" : "Message rate limit exceeded"
},
"id" : null
}
The rate limit resets as messages age out of the sliding window. No backoff or retry-after header is provided — clients should reduce their message frequency.
Message Size Limit
Messages exceeding the configured maximum size are rejected before parsing.
Property Value Maximum size Configurable via gateway.wsMaxMessageBytes (character count before JSON.parse) Error code -32600 (invalid request)
{
"jsonrpc" : "2.0" ,
"error" : {
"code" : -32600 ,
"message" : "Message size 2048576 bytes exceeds maximum of 1048576"
},
"id" : null
}
Error Codes
JSON-RPC error codes returned by the WebSocket handler.
Code Meaning When -32700Parse error Invalid JSON or binary WebSocket frame -32600Invalid request Batch size exceeded or message too large -32603Internal error Insufficient scope for method or handler error -32000Rate limit exceeded Too many messages in the sliding window
All error responses follow the JSON-RPC 2.0 error format:
{
"jsonrpc" : "2.0" ,
"error" : {
"code" : -32603 ,
"message" : "Insufficient scope: requires 'admin'"
},
"id" : 1
}
Close Codes
WebSocket close codes used by the Comis gateway.
Code Meaning Description 1000Normal closure Clean disconnect initiated by client or server 1001Going away Server shutting down gracefully 4001Unauthorized Invalid or missing authentication token 1006Abnormal closure Network error or unexpected disconnect (no close frame received)
The server sends close code 1001 with reason "Server shutting down" during graceful shutdown, giving clients time to reconnect after restart.
Server Notifications
The server can push unsolicited notifications to connected clients. Notifications are JSON-RPC messages without an id field — clients must not send a response.
Targeted Notifications
The server can send notifications to a specific client (identified by clientId from the token configuration):
{
"jsonrpc" : "2.0" ,
"method" : "session.completed" ,
"params" : {
"sessionKey" : "sub-agent-task-1" ,
"result" : "Task completed successfully"
}
}
Broadcast Notifications
Some notifications (such as sub-agent completion announcements) are broadcast to all connected clients when the target client cannot be determined.
Clients should handle unknown notification methods gracefully by ignoring them. New notification types may be added in future versions.
JSON-RPC Methods All available JSON-RPC methods with parameters and examples
HTTP Gateway HTTP endpoint reference and authentication
Rate Limiting Rate limiting configuration and behavior
Config YAML Gateway configuration options