Skip to main content

Real-time events

The TensorCost backend streams live events to the dashboard, partner integrations, and any authenticated client over Socket.IO. Events cover the full lifecycle of the platform — new metrics arriving, instances changing state, alerts firing, ML training, and the runaway-loop detector pausing an agent.
This describes the current design and the code path that implements it. If you connect and get a flat “not found” instead of a Socket.IO handshake response, that’s a live rollout gap on our side, not a mistake in your client — page support and we’ll confirm status for your tenant.

Where the WebSocket lives

Real-time events are Socket.IO traffic on the same host as the console app (there’s no separate ws. subdomain) — it’s routed to the backend through a dedicated /rt/* path so the upgrade request reaches the gateway instead of falling through to the static frontend.

Connecting

Authentication

  • Browser clients — the handshake carries your session’s httpOnly cookie automatically (withCredentials: true); there’s nothing to pass explicitly. This is what the console itself uses.
  • Non-browser clients (a script, a service) — pass a bearer token explicitly instead of relying on a cookie. Check with support for the current token-issuance path if you’re building outside the browser.
Clients are joined server-side to a room scoped to their own tenant, resolved from their session — never from anything the client sends. Cross-tenant events are unreachable by construction.

Event envelope

Every message arrives on the event channel with a uniform shape:

Event catalog

Using events in a React app

The shell pairs Socket.IO with TanStack Query (and legacy RTK Query during the migration). When the backend publishes an event, the client invalidates the right query key so any subscribed component refetches:
For more targeted UI (a progress banner, a toast), components can subscribe via a hook like useRunawayLoopEvents() that filters the stream and exposes only the relevant slice.

Reliability guarantees

  • In-process priority. Events dispatch to local subscribers synchronously in the publish path with no Redis dependency. A single-instance deployment works end-to-end with no broker.
  • Redis for durability (when configured). Events are also LPUSH’d onto per-type queues for cross-instance replay. A bounded LRU of recently-dispatched event IDs prevents double delivery.
  • Best-effort on Redis failure. If Redis is unreachable, events still reach all in-process subscribers (and thus the Socket.IO bridge). Only cross-instance replay is lost.
  • Per-type ordering. Events within a single type are ordered. Across types, no ordering guarantees.
  • Per-tenant rate limits. Socket.IO emit rate is capped per tenant to protect noisy-neighbor scenarios. Default 100 events/sec/tenant; raise on enterprise tier.

Webhooks

Every event in the catalog can also be delivered as a webhook (HMAC-signed X-TensorCost-Signature: t=<unix>,v1=<sig>). Configure under Integrations → Webhooks. Webhooks complement Socket.IO for systems that prefer pull-once-and-acknowledge delivery (PagerDuty, ServiceNow, internal eventing pipelines).

Debugging connection issues

Common causes of a failed handshake:
  • Wrong path. The upgrade must go to /rt on your console host, not a separate subdomain and not the Socket.IO default path (/socket.io/).
  • Expired session. If your cookie or token has expired, reconnect after re-authenticating. The console handles this automatically on route navigation.
  • A proxy stripping Connection: Upgrade / Upgrade: websocket headers. If you’re connecting through a corporate proxy, confirm it forwards WebSocket upgrade headers on /rt.

MCP

TensorCost exposes an MCP endpoint at /mcp on your console host, so Claude Desktop, internal LLM agents, and partner integrations can query the platform programmatically. See developer tools for setup and the CLI if you just want cost numbers from a terminal without wiring up MCP.
Rolling out to production tenants — if /mcp isn’t reachable on your console host yet, ask support whether it’s enabled for your tenant.

Tool surface

Scope-guarded by RBAC

Every tool call is scope-checked against the calling key. Read scopes are available on all plan tiers; write scopes require an explicit grant.

Authenticating

MCP clients authenticate with an API key, sent as the X-MCP-Key header — this is a different credential from your REST bearer token. Mint one under Settings → MCP.

Use cases

  • CFO / finance — point Claude Desktop at TensorCost MCP and ask “what drove last week’s Bedrock bill?” The model uses get_cost_summary + list_recommendations to compose the answer.
  • Platform engineer — wire your internal agent to MCP to check fleet health or workload cost during an incident.
  • Partner integration — build a Datadog / Grafana panel that consumes get_cost_summary and get_fleet_health for embedded TensorCost views.
The MCP endpoint is rate-limited per key. The same tenant-scoping guarantees that apply to REST apply here too.