MCP server

Connect any MCP client to Cymo. Agents read rooms, run scenarios and manage webhooks with one tool per API operation.

Remote MCP server

Cymo hosts the MCP server at:

Streamable HTTP
https://mcp.cymatics.tech/mcp

Connect any MCP client that supports remote servers over Streamable HTTP. There's nothing to install or run. The server holds no data: each tool calls the API with your key, so the key's scopes, rate limits and metering apply, and a test key keeps every call on the simulator.

Authentication

Send a Cymo API key from the dashboard as a bearer token: Authorization: Bearer cym_test_…. A request without one gets 401 missing_api_key. Use a cym_test_ key while you build and a cym_live_ key for your paired Cymos.

Set up your client

Replace cym_test_… with your key.

terminal
claude mcp add --transport http cymo https://mcp.cymatics.tech/mcp \
  --header "Authorization: Bearer cym_test_…"

Claude's custom connectors (Settings > Connectors) sign in with OAuth and can't send an API key, so in Claude Desktop use the local server. Any other client that can send a header on a remote server works with the same URL and header.

Read-only mode

Add ?read_only=1 to the URL to list only tools that read, for an agent that should look but never change anything. The key's scopes still apply on top.

URL
https://mcp.cymatics.tech/mcp?read_only=1

Local MCP server

The hosted server runs the same code as @cymos/mcp. Run it yourself over stdio with your key in CYMO_API_KEY; add --read-only after the package name to list only read tools.

claude_desktop_config.json
{
  "mcpServers": {
    "cymo": {
      "command": "npx",
      "args": [
        "-y",
        "@cymos/mcp"
      ],
      "env": {
        "CYMO_API_KEY": "cym_test_…"
      }
    }
  }
}

With cymatics mock start, the whole loop runs on your machine:

terminal
$ cymatics mock start --port 8787

# then run the MCP server against it
$ CYMO_API_URL=http://127.0.0.1:8787 CYMO_API_KEY=cym_test_local \
    npx -y @cymos/mcp

Local HTTP server

The package also serves Streamable HTTP at http://127.0.0.1:8788/mcp, with each client sending its own key as a bearer token, as with the hosted server.

terminal
$ npm install @cymos/mcp
$ PORT=8788 node node_modules/@cymos/mcp/dist/http.js
~/.cursor/mcp.json
{
  "mcpServers": {
    "cymo": {
      "url": "http://127.0.0.1:8788/mcp",
      "headers": {
        "Authorization": "Bearer cym_test_…"
      }
    }
  }
}
CYMO_API_KEYstdio, requiredThe key every tool call is made with.
CYMO_API_URLdefault https://api.cymatics.techThe API the tools call, such as a local simulator.
CYMO_MCP_READ_ONLY1 or trueList only tools that read, for every client. The --read-only flag does the same over stdio.
PORT, HOSTHTTP, default 8788, 127.0.0.1Where the HTTP server listens.

MCP tools

The server has one tool per API operation, named after it and generated from the same contract, with the operation's input schema and read, write and destructive hints. Each API reference page names its tool. Tools for operations with a request body take it as input. Read-only mode hides the tools marked write.

Streaming windows

Stream tools return a bounded window instead of an open stream. They watch for duration_ms (default 10 s, up to 60 s) or until max_samples messages (default 20, up to 200), then return them with truncated set when more may have followed. Raw radar bytes have no tool; use the raw-data export tools instead.

MCP tool
stream_room({ room_id: "room_bedroom", duration_ms: 30000, max_samples: 50 })

{
  "data": {
    "object": "stream_window",
    "operation_id": "stream-room",
    "sample_count": 50,
    "truncated": true,
    "ended_by": "max_samples",
    "messages": [{ "id": "…", "kind": "snapshot", "data": { … } }, …]
  },
  "meta": { "livemode": false, … }
}

Example prompts

  • Run the bed_exit scenario and tell me when the person left bed.create_scenario_run, list_events
  • Is anyone in room_bedroom right now? What are their heart rate and breathing?get_room, get_vitals
  • Watch room_bedroom for 30 seconds and summarise what changed.stream_room
  • How did the person in room_bedroom sleep last night?get_sleep_summary
  • Send bed.exited and fall.detected events to my staging webhook.create_webhook, test_webhook
  • Which of my requests failed today, and why?list_request_logs