Skip to content

MCP ​

The controller's MCP endpoint and the nomos MCP Bridge

The controller includes a server for the Model Context Protocol (MCP). Through it, AI assistants such as Claude read and control the system: devices, scenes, rooms, automations and much more.

You switch the MCP skill on in the configuration interface, which is also where you create the tokens. How to set up common clients such as Claude Desktop, Cursor or Windsurf is described in MCP in the integrator handbook. This page describes the endpoint itself.

Endpoint ​

Addresshttp://<controller-ip>/mcp
TransportStreamable HTTP: POST for JSON-RPC, answers as text/event-stream, GET for the notification stream, DELETE ends the session
Authenticationheader Authorization: Bearer <token>
Sessionheader Mcp-Session-Id from the answer to initialize
Reachablelocal network only

The status codes help with troubleshooting:

CodeMeaning
404The MCP skill is switched off.
401The token is missing (Missing or invalid Authorization header) or unknown or disabled (Invalid token).
511The request came through remote access. MCP is only reachable in the local network.
400A request without a valid session that is not an initialize.

Permissions ​

A token is not tied to a nomos user. Whoever holds it works with administrator rights; room and scene permissions do not apply. Some areas are deliberately not offered by the server: users can only be read, and restoring a backup, factory reset, port forwarding and remote access remain reserved to the configuration interface.

Treat tokens like passwords: one token per client, and delete tokens you no longer need. Administrators manage them over the API with addMCPToken, getMCPTokens, setMCPToken and removeMCPToken.

What the server offers ​

  • Tools for components, scenes, rooms, zones, automations, skills and system functions. Read-only tools carry the hint readOnlyHint.
  • Resources such as nomos://components/all, nomos://scenes/all or nomos://rooms/all.
  • Prompts for frequent tasks, such as a status report or guided scene creation.
  • Instructions in the answer to initialize that explain the data model to the model.

The server itself returns the current list through tools/list, resources/list and prompts/list. When it changes, it notifies the connected clients.

Trying it with curl ​

This is the flow without an MCP client. Answers come as server-sent events, i.e. as lines event: message and data: {…}.

bash
TOKEN='<token>'
curl -si http://<controller-ip>/mcp \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
HTTP/1.1 200 OK
content-type: text/event-stream
mcp-session-id: 6f0c…

event: message
data: {"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{"listChanged":true},"resources":{"listChanged":true},"completions":{},"prompts":{"listChanged":true}},"serverInfo":{"name":"nomos-mcp",…

Continue with the session ID from the header: first the confirmation, then a tool call, and finally close the session.

bash
SESSION='<mcp-session-id>'
H=(-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json'
   -H 'Accept: application/json, text/event-stream'
   -H "Mcp-Session-Id: $SESSION" -H 'MCP-Protocol-Version: 2025-06-18')

curl -s http://<controller-ip>/mcp "${H[@]}" \
  -d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
curl -s http://<controller-ip>/mcp "${H[@]}" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"component_get_by_id","arguments":{"cid":"C5"}}}'
curl -s -X DELETE http://<controller-ip>/mcp "${H[@]}"
event: message
data: {"result":{"content":[{"type":"text","text":"{\n  \"name\": \"Switch\",\n  \"cid\": \"C5\",…

Setting up clients ​

Claude Code speaks Streamable HTTP itself and connects directly:

bash
claude mcp add --transport http nomos http://<controller-ip>/mcp \
  --header "Authorization: Bearer <token>"

nomos MCP Bridge: To work with several controllers, use the nomos MCP Bridge. It runs as a local stdio server (Node.js 18 or later), passes through the tools, resources and prompts of the selected controller and switches between controllers on request.

bash
claude mcp add nomos -- npx -y nomos-mcp-bridge

The bridge keeps the controllers in ~/.config/nomos-mcp/controllers.json, with address (http://<controller-ip>/mcp) and token. The tokens are stored there in plain text; protect the file accordingly. To add controllers, the bridge opens a setup page on http://localhost:18900 (or the next free port if that one is taken), reachable only from your own computer.

The configuration for Claude Desktop, Cursor, Windsurf and other clients is in the integrator handbook.

HTTP or HTTPS ​

The endpoint is also reachable at https://<controller-ip>/mcp. The controller's certificate, however, is self-signed and does not name the controller's address. Clients based on Node.js, the bridge among them, therefore reject it. The bridge's README suggests NODE_TLS_REJECT_UNAUTHORIZED=0 for this; with it, the whole process stops checking certificates altogether, for other servers as well. We do not recommend that.

In the local network, use http:// instead. The token then travels unencrypted; only use MCP in a network you trust. How to trust exactly this certificate in your own programs is described under HTTPS and certificate.