Skip to content

WebSocket Server

At the heart of the Gateway is a WebSocket server built on the ws library. It uses a protocol with three frame types: request, response, and event.

Protocol Frames

Source: src/gateway/protocol/index.ts

The Gateway defines three frame types. All frames are validated against JSON Schema using AJV:

typescript
// RequestFrame - Client → Server
interface RequestFrame {
  id: string;           // Request correlation ID
  method: string;       // e.g. "chat.send", "config.patch"
  params?: unknown;     // Method-specific parameters
}

// ResponseFrame - Server → Client
interface ResponseFrame {
  id: string;           // Matches request ID
  ok: boolean;          // Success flag
  result?: unknown;     // Response payload
  error?: string;       // Error message
  meta?: unknown;       // Additional metadata
}

// EventFrame - Server → Client (push)
interface EventFrame {
  event: string;        // Event name
  data?: unknown;       // Event payload
}

The protocol supports versioning (PROTOCOL_VERSION) to ensure compatibility between client and server.

Server Implementation

Source: src/gateway/server.impl.ts

GatewayServer is the core runtime type that manages all connections and state:

typescript
// src/gateway/server.impl.ts (simplified)
interface GatewayServer {
  config: GatewayConfig;
  channels: ChannelRegistry;
  agents: AgentRegistry;
  plugins: PluginRegistry;
  runtimeState: RuntimeState;
  // Health snapshots, presence versions, agent run sequences...
}

Client SDK

Source: src/gateway/client.ts

The GatewayClient class encapsulates the WebSocket connection from client to Gateway:

typescript
// src/gateway/client.ts (simplified)
interface GatewayClientOptions {
  url: string;                    // ws://127.0.0.1:18789
  credentials: {
    token?: string;
    password?: string;
  };
  instance: string;              // Client instance identifier
  mode: "operator" | "node";    // Connection role
  scopes: string[];             // Permission scopes
  capabilities: string[];       // Feature capabilities
}

class GatewayClient {
  constructor(options: GatewayClientOptions);
  // Protocol version negotiation
  // Token/password auth
  // TLS fingerprint validation
  // Auto-reconnection handling
}

Key client features:

  • Protocol version negotiation
  • Token / Password / Tailscale authentication
  • TLS fingerprint validation
  • Automatic reconnection

Method Dispatch

Source: src/gateway/server-methods.ts

handleGatewayRequest() is the single entry point for all requests. It routes each request to the appropriate handler module:

typescript
// src/gateway/server-methods.ts (simplified)
async function handleGatewayRequest(
  method: string,
  params: unknown,
  options: GatewayRequestOptions
): Promise<void> {
  // 1. Authorize the method call
  const authResult = authorizeGatewayMethod(method, options);
  if (!authResult.ok) {
    return respond(false, null, authResult.error);
  }

  // 2. Look up handler in registry
  const handler = coreGatewayHandlers[method];
  if (!handler) {
    return respond(false, null, `Unknown method: ${method}`);
  }

  // 3. Execute handler
  await handler(params, options);
}

Authorization Flow

Authorization dimensions:

DimensionDescriptionExample
Roleoperator (admin) vs node (device)Operators can modify config
Scopeadmin, read, write, approvals, pairingwrite scope required to send messages
Method-levelEach method declares required scopeconfig.patch requires admin

Handler Modules

Source: src/gateway/server-methods/ (43 modules)

Each handler module exports a GatewayRequestHandlers-typed method map:

server-methods/
├── agent.ts         # Agent management
├── agents.ts        # Multi-Agent operations
├── browser.ts       # Browser control
├── channels.ts      # Channel state and lifecycle
├── chat.ts          # Chat interactions
├── config.ts        # Configuration read/write
├── connect.ts       # Connection management
├── cron.ts          # Cron jobs
├── device.ts        # Device management
├── exec-approvals.ts # Execution approvals
├── health.ts        # Health checks
├── logs.ts          # Log queries
├── models.ts        # Model management
├── nodes.ts         # Node management
├── send.ts          # Message sending
├── sessions.ts      # Session operations
├── skills.ts        # Skill management
├── system.ts        # System information
├── talk.ts          # Voice conversation
├── tts.ts           # Text-to-speech
├── update.ts        # Version updates
├── usage.ts         # Usage statistics
├── voicewake.ts     # Voice wake
├── web.ts           # Web UI
└── wizard.ts        # Setup wizard

Send Handler

Source: src/gateway/server-methods/send.ts

The send handler supports idempotency deduplication:

typescript
// src/gateway/server-methods/send.ts (simplified)
const sendHandlers = {
  async send(params, options) {
    // 1. Validate params (to, message, channel, idempotencyKey)
    // 2. Check idempotency deduplication
    if (idempotencyKey && seen.has(idempotencyKey)) {
      return respond(true, seen.get(idempotencyKey));
    }
    // 3. Resolve channel and outbound adapter
    // 4. Deliver message via outbound pipeline
    // 5. Cache result for idempotency
  }
};

Authentication Implementation

Source: src/gateway/auth.ts

Key security measures:

  • Token comparison uses timing-safe comparison to prevent timing side-channel attacks
  • Local connection detection (loopback + localhost validation)
  • Tailscale integration verifies device identity via whois query
typescript
// src/gateway/auth.ts (simplified)
interface ResolvedGatewayAuth {
  mode: "token" | "password";
  // ...
}

async function authorizeGatewayConnect(
  credentials: unknown,
  auth: ResolvedGatewayAuth
): Promise<AuthResult> {
  // Timing-safe token comparison
  // Tailscale user verification via whois
  // Fallback to token/password modes
}

Summary

  • The Gateway uses the ws library with RequestFrame / ResponseFrame / EventFrame as its three frame types
  • handleGatewayRequest() is the unified request entry point, performing role -> scope -> method-level authorization
  • 43 handler modules cover all functionality: chat, send, config, sessions, channels, and more
  • Authentication supports Token, Password, and Tailscale modes with timing-safe comparison
  • The client SDK (GatewayClient) wraps connection management, protocol negotiation, and auto-reconnection

Next: Session Management

OpenClaw Source Code Tutorial