UdiWatch

API key on watch tools

POST /mcp

JSON-RPC MCP endpoint for device search and watches. One HTTP request, one JSON response. Not a stdio process.

Endpoint: POST https://udiwatch.com/mcp. JSON-RPC 2.0. Protocol version 2024-11-05. Server name udiwatch, version 1.0.0.

This is one HTTP request and one JSON response. It is not a stdio process, and it does not open an SSE stream or issue an MCP session id. Put the API key on the HTTP request. It is not a tool argument.

{
  "mcpServers": {
    "udiwatch": {
      "type": "http",
      "url": "https://udiwatch.com/mcp",
      "headers": {"X-API-Key": "uw_…"}
    }
  }
}

Handshake

curl -sS -X POST "$BASE/mcp" \
  -H 'Content-Type: application/json' \
  -H "X-API-Key: $UW_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"example","version":"0"}}}'

Then notifications/initialized and tools/list. ping returns an empty result. An unknown method is -32601. A body that is not an object is -32600. HTTP status is still 200. A batch is an array of at most 20 messages.

Calling a tool

curl -sS -X POST "$BASE/mcp" \
  -H 'Content-Type: application/json' \
  -H "X-API-Key: $UW_KEY" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_device","arguments":{"udi":"16977660098955"}}}'

The tool payload is a JSON string inside result.content[0].text. Parse it. result.isError is true when that payload has an error field. HTTP 200 does not mean the tool succeeded. HTTP 401 is reserved for the REST routes. HTTP 429 is returned before any tool runs. Limit: 60 calls per IP per minute.

Tools

ToolAuthArgumentsText payload
search_devicesNoq required, limit optionalSame as GET /v1/search
lookup_udiNoudi requiredSame as GET /v1/devices/{udi}
get_deviceNoudi requiredSame record as lookup_udi
get_actorNosrn requiredSame as GET /v1/actors/{srn}
list_watchesKey or sessionnone{"watches":[…]}
add_watchActive accountsubject required{"watch":{…},"error":null}
sync_watchesActive accountnoneSame as POST /v1/sync
list_changesActive accountnone{"events":[…]}, newest 50

Unknown tool name: text {"error":"Unknown tool."} and isError: true. Each tool has its own page.

POST /v1/webhook/testTOOL search_devices