Reference

MCP Protocol

The JSON-RPC 2.0 surface the server speaks, with worked request/response examples.


The server implements the Model Context Protocol over JSON-RPC 2.0. Whether you connect over HTTP, WebSocket, or STDIO, the wire format is the same: a JSON object with jsonrpc, id, method, and (usually) params.

Methods

The server supports the core MCP methods plus a handful of extensions:

MethodDirectionNotes
initializeclient → serverHandshake. Returns protocolVersion, serverInfo, and capabilities.
tools/listclient → serverReturns the manifest: name, description, inputSchema, annotations for each tool.
tools/callclient → serverInvokes a tool. params.name is the tool name, params.arguments is the input.
resources/listclient → serverReturns the cached HA state (subset of list_devices).
resources/readclient → serverReads one resource by URI.
prompts/listclient → serverReturns the prompt templates (morning routine, energy saving, …).
prompts/getclient → serverRenders a prompt by name.
notifications/*server → clientStreaming events (state changed, automation triggered, …).
notifications/cancelledclient → serverCancels an in-flight request.

initialize example

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "clientInfo": { "name": "claude-desktop", "version": "0.7.0" },
    "capabilities": {}
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "serverInfo": { "name": "homeassistant-mcp", "version": "0.1.0" },
    "capabilities": { "tools": {}, "resources": {}, "prompts": {} }
  }
}

tools/list example

Request:

{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }

Response (truncated):

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "list_devices",
        "description": "List Home Assistant devices, optionally filtered by domain or area.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "domain": { "type": "string" },
            "area": { "type": "string" }
          }
        },
        "annotations": { "readOnlyHint": true, "openWorldHint": true }
      },
      {
        "name": "control_light",
        "description": "Turn a light on or off, set brightness, color, or color temperature.",
        "inputSchema": { "type": "object", "required": ["entity_id", "action"], "properties": { ... } },
        "annotations": { "destructiveHint": true, "openWorldHint": true }
      }
    ]
  }
}

tools/call example

Request:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "control_light",
    "arguments": {
      "entity_id": "light.living_room",
      "action": "turn_on",
      "brightness": 128
    }
  }
}

Success response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\"entity_id\":\"light.living_room\",\"state\":\"on\",\"brightness\":128}"
      }
    ]
  }
}

The content array is part of the MCP spec — every tool returns a list of content blocks, most commonly a single text block with a JSON string.

Error response

{
  "jsonrpc": "2.0",
  "id": 3,
  "error": {
    "code": -32602,
    "message": "Validation failed",
    "data": {
      "issues": [
        { "path": ["brightness"], "message": "Expected number, got string" }
      ]
    }
  }
}

The code is one of the standard JSON-RPC codes or one of the custom MCPErrorCode values defined in src/mcp/MCPServer.ts. See API Errors for the full table.

Streaming (HTTP+WS only)

Subscribe to events with tools/call subscribe_events:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "subscribe_events",
    "arguments": {
      "event_type": "state_changed",
      "entity_id": "light.living_room"
    }
  }
}

The server returns the initial result immediately and then pushes a notification for every matching event:

{
  "jsonrpc": "2.0",
  "method": "notifications/state_changed",
  "params": {
    "entity_id": "light.living_room",
    "old_state": { "state": "on", "attributes": { "brightness": 128 } },
    "new_state": { "state": "off", "attributes": {} }
  }
}

To stop, send notifications/cancelled with the subscription id (returned in the initial result’s meta.subscriptionId).

Next