API surface#
rackattack is one service core behind four interfaces. gRPC is the primary product contract. REST is generated from the same proto via grpc-gateway and served in-process. GraphQL (gqlgen, schema-first) is a third HTTP transport over the same core. MCP is a thin secondary adapter mapping the core to agent tools.
All four resolve through the single service core, so authorization, caching, and audit apply uniformly no matter which door a request comes in.
gRPC RPCs#
The proto lives at
proto/rackattack/v1/rackattack.proto.
The service exposes 24 RPCs in four groups.
Queries & screens#
| RPC | Does |
|---|---|
PowerBlastRadius | recursive power rollup → affected/protected + diagram |
TraceCablePath | recursive cable-path trace → hops/segments + diagram |
GetRack | full rack elevation + occupants + capacity |
ThermalHeadroom | heat-vs-cooling rollup, hotspot detection |
FabricTopology | leaf-spine links + utilization + congestion |
FloorPlan | top-down floor layout, per-rack health (ok/watch/fault) |
SearchDevices | cursor-paginated device search with filtering + counts |
GetDevice / GetPort | inspector hydrate (used by click-to-drill) |
Render | re-render any subgraph to SVG/PNG/HTML/DOT |
Each screen-generating RPC returns both structured data and a rendered
artifact (RenderResult), with RenderOptions controlling format
(SVG/PNG/HTML/DOT), theme, coloring, view, highlight, and whether to embed the
interactive dataset. SearchDevices takes a DeviceFilter, page_size, and
page_token, and returns next_page_token, total_count, and per-role counts.
Mutations (single)#
| RPC | Does |
|---|---|
UpsertDevice / DeleteDevice | create/update or remove a device by code |
UpsertRack / DeleteRack | create/update or remove a rack by code |
UpsertCrac / DeleteCrac | create/update or remove a CRAC/CRAH unit |
Bulk mutations#
| RPC | Does |
|---|---|
BulkUpsertDevices / BulkDeleteDevices | many devices in one transaction |
BulkUpsertRacks / BulkDeleteRacks | many racks in one transaction |
BulkUpsertCracs / BulkDeleteCracs | many CRAC units in one transaction |
Bulk calls return a BulkReply with per-item results, so a partial failure
reports exactly which items succeeded and which errored.
Edge mutations (cables & fabric)#
| RPC | Does |
|---|---|
UpsertCable / DeleteCable | a physical cable, keyed by its two device-port endpoints |
UpsertFabricLink / DeleteFabricLink | a logical leaf→spine uplink, keyed by its endpoints |
Edge entities are identified by their endpoints rather than a surrogate code, so the same pair of endpoints round-trips through upsert and delete.
REST (grpc-gateway)#
Every RPC is reachable over HTTP via grpc-gateway, served in-process by serve
on the HTTP port (:8081). For example, against a local serve:
curl -s localhost:8081/rackattack.v1.Rackattack/ThermalHeadroom \
-d '{"scope_ref":"floor:site-01/1"}'GraphQL#
A schema-first GraphQL endpoint (gqlgen) serves the same operations as a graph,
which is convenient for the read screens, the paginated/filtered device search,
and the upsert/delete + bulk mutations. The schema is at
internal/graph/schema.graphqls.
serve mounts two routes on the HTTP port:
POST /graphql— the GraphQL endpoint.GET /graphql/playground— an in-browser IDE for exploring the schema.
Queries: powerBlastRadius, traceCablePath, rack, thermalHeadroom,
fabricTopology, floorPlan, searchDevices (with DeviceFilter, pageSize,
pageToken → a DevicePage carrying nextPageToken, totalCount, and
roleCounts), device, port.
Mutations: upsertDevice / deleteDevice, upsertRack / deleteRack,
upsertCrac / deleteCrac, and the bulk variants (bulkUpsertDevices,
bulkDeleteDevices, …) returning a BulkResult with per-item outcomes.
query {
powerBlastRadius(sourceRef: "feed:B-3", includeProtected: true) {
impact { racksDark devicesOffline racksProtected }
affected { code }
protected { code }
}
}MCP#
The MCP adapter exposes the ten read operations as agent tools over JSON-RPC
on stdio: power_blast_radius, trace_cable_path, get_rack,
thermal_headroom, fabric_topology, floor_plan, search_devices,
get_device, get_port, and render. It’s the conversational front door for an
LLM agent and isn’t required for the gRPC story to stand on its own. The prompt →
tool-call mapping for each screen is documented in
TOOLS.md, and the
quickstart shows driving it with and without an agent.
See the dedicated MCP page for the full tool list and setup.
Authorization#
When auth is enabled, reads are open to any authenticated principal and mutations + bulk operations require a writer/admin role — enforced in the shared core so it applies across gRPC, REST, and GraphQL alike. See Security & auth.
Other HTTP endpoints#
serve also mounts, on the HTTP port:
| Route | Purpose |
|---|---|
GET /metrics | Prometheus metrics (unauthenticated) — see Observability |
GET /audit/history | change history read-back — see Audit & CDC |
POST /audit/webhook | CockroachDB CHANGEFEED webhook sink — see Audit & CDC |