Skip to content

WebSocket API

Airlock provides a WebSocket endpoint for real-time bidirectional communication with AI agents.

Connection

Endpoint

wss://ws.air-lock.ai?projectId={projectId}&token={token}

Parameters

ParameterRequiredDescription
projectIdYesYour server's project ID
tokenYesYour MCP access token

Example Connection

javascript
const ws = new WebSocket(
  'wss://ws.air-lock.ai?projectId=abc123&token=your-token'
);

ws.onopen = () => {
  console.log('Connected');
  // Send initialize message
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'initialize',
    params: {
      protocolVersion: '2024-11-05',
      capabilities: {},
      clientInfo: { name: 'my-client', version: '1.0.0' }
    }
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Received:', message);
};

Message Format

All messages use JSON-RPC 2.0:

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "methodName",
  "params": {}
}

Real-Time Notifications

The WebSocket connection receives push notifications for:

Approval Status Changes

When a pending request is approved, you receive the tool execution result:

json
{
  "jsonrpc": "2.0",
  "method": "notifications/tool-execution-result",
  "params": {
    "requestId": "abc123",
    "toolName": "list_users",
    "result": {
      "content": [
        {
          "type": "text",
          "text": "{\"users\": [...]}"
        }
      ]
    }
  }
}

When a request is rejected:

json
{
  "jsonrpc": "2.0",
  "method": "notifications/tool-execution-result",
  "params": {
    "requestId": "abc123",
    "toolName": "list_users",
    "error": "Request rejected by approver"
  }
}

TIP

The presence of result indicates approval; the presence of error indicates rejection.

Session Management

Connection Lifecycle

  1. Connect: Establish WebSocket with credentials
  2. Initialize: Send initialize message
  3. Interact: Call tools, receive notifications
  4. Disconnect: Connection closes (timeout or explicit)

Stateless Architecture

Airlock uses a stateless WebSocket architecture:

  • No server-side session state
  • Connection metadata stored in DynamoDB
  • MCP server reconstructed per message
  • Auto-cleanup on connection timeout

Connection Limits

  • Idle timeout: 10 minutes
  • Maximum message size: 128KB
  • Concurrent connections: Based on plan

Best Practices

Heartbeat

Send periodic messages to keep the connection alive:

javascript
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.send(JSON.stringify({
      jsonrpc: '2.0',
      method: 'ping'
    }));
  }
}, 30000); // Every 30 seconds

Reconnection

Implement automatic reconnection:

javascript
function connect() {
  const ws = new WebSocket(url);

  ws.onclose = () => {
    console.log('Disconnected, reconnecting...');
    setTimeout(connect, 1000);
  };

  ws.onerror = (error) => {
    console.error('WebSocket error:', error);
    ws.close();
  };

  return ws;
}

Error Handling

Handle both JSON-RPC errors and WebSocket errors:

javascript
ws.onmessage = (event) => {
  const message = JSON.parse(event.data);

  if (message.error) {
    console.error('RPC Error:', message.error);
    return;
  }

  // Handle result
  console.log('Result:', message.result);
};

Debugging

Connection Issues

  1. Verify projectId and token are correct
  2. Check network connectivity
  3. Ensure WebSocket is not blocked by firewall

Message Issues

  1. Validate JSON-RPC format
  2. Check method name spelling
  3. Verify parameter types match schema

Built with VitePress