Skip to main content
The rpc.handshake method is the first call clients should make to negotiate protocol version and discover server capabilities.

Method

rpc.handshake

Request Format

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "rpc.handshake",
  "params": {
    "client_name": "demo",
    "client_version": "0.1.0",
    "protocol_version": "1.0.0",
    "strict": false
  }
}

Parameters

All parameters are optional:
FieldTypeDescription
client_namestringClient application name (informational)
client_versionstringClient application version (informational)
protocol_versionstringRequested protocol version (e.g., "1.0.0")
strictbooleanIf true, fail if protocol version doesn’t match exactly
If strict: false (default), the server accepts any protocol version and returns its own version. Clients should check the returned protocol_version to ensure compatibility.

Response Format

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocol_version": "1.0.0",
    "server_name": "loaf",
    "capabilities": {
      "events": true,
      "command_execute": true,
      "multi_session": true,
      "image_inputs": ["path", "data_url"]
    },
    "methods": [
      "auth.connect.antigravity",
      "auth.connect.openai",
      "auth.set.exa_key",
      "auth.set.openrouter_key",
      "auth.status",
      "command.execute",
      "debug.set",
      "history.clear_session",
      "history.get",
      "history.list",
      "limits.get",
      "model.list",
      "model.openrouter.providers",
      "model.select",
      "onboarding.complete",
      "onboarding.status",
      "rpc.handshake",
      "session.create",
      "session.get",
      "session.interrupt",
      "session.queue.clear",
      "session.queue.list",
      "session.send",
      "session.steer",
      "skills.list",
      "state.get",
      "system.ping",
      "system.shutdown",
      "tools.list"
    ]
  }
}

Response Fields

FieldTypeDescription
protocol_versionstringServer’s protocol version ("1.0.0")
server_namestringServer identifier ("loaf")
capabilitiesobjectFeature flags the server supports
methodsstring[]List of all available RPC methods (sorted alphabetically)

Capabilities

CapabilityTypeDescription
eventsbooleanServer emits event notifications
command_executebooleanSupports command.execute for tool execution
multi_sessionbooleanSupports multiple concurrent sessions
image_inputsstring[]Supported image input formats ("path", "data_url")

Version Negotiation

Flexible Mode (default)

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "rpc.handshake",
  "params": {
    "protocol_version": "1.0.0"
  }
}
Server responds with its version. Client checks compatibility:
const response = await sendRequest({
  method: "rpc.handshake",
  params: { protocol_version: "1.0.0" }
});

if (response.result.protocol_version !== "1.0.0") {
  console.warn("Protocol version mismatch!");
  // Handle gracefully - protocol 1.x is additive
}

Strict Mode

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "rpc.handshake",
  "params": {
    "protocol_version": "2.0.0",
    "strict": true
  }
}
If versions don’t match:
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "unsupported protocol_version: 2.0.0",
    "data": {
      "reason": "unsupported_protocol_version",
      "supported": "1.0.0"
    }
  }
}

Method Discovery

The methods array lists all callable methods. Clients can dynamically check for feature availability:
const { methods } = handshakeResponse.result;

if (methods.includes("auth.connect.openai")) {
  // OpenAI authentication is available
}

if (methods.includes("session.steer")) {
  // Session steering is supported
}

Typical Handshake Sequence

1. Client connects and sends handshake
{"jsonrpc":"2.0","id":1,"method":"rpc.handshake","params":{"client_name":"demo","protocol_version":"1.0.0"}}
2. Server responds with capabilities
{"jsonrpc":"2.0","id":1,"result":{"protocol_version":"1.0.0","server_name":"loaf","capabilities":{"events":true,"command_execute":true,"multi_session":true,"image_inputs":["path","data_url"]},"methods":["..."]}}  
3. Client validates version and capabilities
if (result.capabilities.events) {
  // Start listening for event notifications
  listenForEvents();
}
4. Client proceeds with session operations
{"jsonrpc":"2.0","id":2,"method":"session.create","params":{}}

Implementation Details

From src/rpc/router.ts:49-76:
this.handlers.set("rpc.handshake", async (params) => {
  const body = assertObjectParams(params ?? {}, "rpc.handshake");
  const protocolVersion = assertOptionalString(
    body.protocol_version,
    "protocol_version",
    "rpc.handshake"
  );
  const strict = assertOptionalBoolean(body.strict, "strict", "rpc.handshake") ?? false;

  if (strict && protocolVersion && protocolVersion !== PROTOCOL_VERSION) {
    throw buildRpcMethodError(
      JSON_RPC_ERROR.INVALID_PARAMS,
      `unsupported protocol_version: ${protocolVersion}`,
      {
        reason: "unsupported_protocol_version",
        supported: PROTOCOL_VERSION,
      }
    );
  }

  return {
    protocol_version: PROTOCOL_VERSION,
    server_name: "loaf",
    capabilities: {
      events: true,
      command_execute: true,
      multi_session: true,
      image_inputs: ["path", "data_url"],
    },
    methods: this.listMethods(),
  };
});
The protocol version constant is defined at src/rpc/router.ts:17:
const PROTOCOL_VERSION = "1.0.0";

Best Practices

  1. Always handshake first: Call rpc.handshake before any other methods
  2. Check capabilities: Use the capabilities object to detect features
  3. Method discovery: Use the methods array rather than hardcoding available methods
  4. Version checking: In production, validate protocol_version matches your expectations
  5. Graceful degradation: If a minor version differs, check for specific methods rather than failing

Error Handling

The handshake method can return these errors:
CodeReasonDescription
-32602invalid_paramsParameter validation failed
-32602unsupported_protocol_versionStrict mode version mismatch
In strict mode, an unsupported protocol version will fail the handshake. Use strict mode only when exact version matching is required.

Build docs developers (and LLMs) love