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#

RPCDoes
PowerBlastRadiusrecursive power rollup → affected/protected + diagram
TraceCablePathrecursive cable-path trace → hops/segments + diagram
GetRackfull rack elevation + occupants + capacity
ThermalHeadroomheat-vs-cooling rollup, hotspot detection
FabricTopologyleaf-spine links + utilization + congestion
FloorPlantop-down floor layout, per-rack health (ok/watch/fault)
SearchDevicescursor-paginated device search with filtering + counts
GetDevice / GetPortinspector hydrate (used by click-to-drill)
Renderre-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)#

RPCDoes
UpsertDevice / DeleteDevicecreate/update or remove a device by code
UpsertRack / DeleteRackcreate/update or remove a rack by code
UpsertCrac / DeleteCraccreate/update or remove a CRAC/CRAH unit

Bulk mutations#

RPCDoes
BulkUpsertDevices / BulkDeleteDevicesmany devices in one transaction
BulkUpsertRacks / BulkDeleteRacksmany racks in one transaction
BulkUpsertCracs / BulkDeleteCracsmany 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)#

RPCDoes
UpsertCable / DeleteCablea physical cable, keyed by its two device-port endpoints
UpsertFabricLink / DeleteFabricLinka 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:

RoutePurpose
GET /metricsPrometheus metrics (unauthenticated) — see Observability
GET /audit/historychange history read-back — see Audit & CDC
POST /audit/webhookCockroachDB CHANGEFEED webhook sink — see Audit & CDC