MCP — agent access
Point an LLM agent at The Grid over the Model Context Protocol.
It's the same public, read-only data as /api/v1, exposed as
agent tools: ask about hazards, evacuations, roads, and weather for the central Sierra
in natural language, and the model calls the right tool. No key, no auth,
read-only — like the rest of the API.
The endpoint
One URL — https://data.sierragridteam.org/mcp — speaking MCP over Streamable HTTP.
Clients POST JSON-RPC 2.0; there's no server-initiated stream, so a
GET returns 405. It's a thin
adapter over the /api/v1 API: geometry is stripped for token efficiency,
and the fail-loud honesty contract is preserved on every result.
Connect a client
Add it as a remote MCP server. Clients that speak Streamable HTTP directly take the URL:
{
"mcpServers": {
"sierra-grid": {
"url": "https://data.sierragridteam.org/mcp"
}
}
}
For a client that only supports stdio servers, bridge it with
mcp-remote:
npx mcp-remote https://data.sierragridteam.org/mcp
Add it to Claude or ChatGPT
Because it's keyless and read-only, there's nothing to authorize — you just point the client at the URL and go.
Claude
Claude.ai / Claude Desktop. On a paid plan, open
Settings → Connectors → Add custom connector, give it a name
(Sierra Grid), and paste the endpoint URL:
https://data.sierragridteam.org/mcp
It connects with no OAuth step — the eight tools appear in the composer's tool menu, and you can ask questions like the ones below in plain language.
Claude Code. Add it as a remote HTTP server from the CLI:
claude mcp add --transport http sierra-grid https://data.sierragridteam.org/mcp
OpenAI / ChatGPT
ChatGPT. On Pro, Business, or Enterprise, enable
Settings → Connectors (developer mode), add a custom MCP
connector, and paste the same https://data.sierragridteam.org/mcp URL — no
authentication.
OpenAI API. The Responses API takes a remote MCP server as a hosted
mcp tool — the model calls the Grid's tools directly, server-side:
# OpenAI Responses API — the endpoint as a hosted MCP tool
client.responses.create(
model="gpt-5",
tools=[{
"type": "mcp",
"server_label": "sierra_grid",
"server_url": "https://data.sierragridteam.org/mcp",
"require_approval": "never",
}],
input="Is it safe near Arnold, CA right now?",
) Tools
Every tool accepts a flexible location — a place slug
(ebbetts-pass), a street address, or lat,lng.
| Tool | Arguments | What it returns |
|---|---|---|
| grid_situation | location | Area mode (QUIET/WATCH/ACTIVE) + rollup for a place, address, or lat,lng. Start here. |
| grid_events | location?, layer?, severity_min?, status?, since?, limit? | List active events (wildfire, evacuation, weather alert, earthquake, road incident, and mesh-node presence via layer=mesh). |
| grid_event | id | Full detail on one event: summary, description, provenance, canonical link. |
| grid_conditions | location? | Road + weather conditions (travel times, chain control, fire weather). |
| grid_resolve | address | lat,lng | Resolve a location to the places that contain it, most-specific first. |
| grid_places | kind?, q? | The place directory — discover valid area / county / town / corridor slugs. |
| grid_sources | — | Feed health (OK / STALE / UNAVAILABLE) for every upstream source. |
| grid_history | location?, layer?, from?, to? | Revision timeline — how an event evolved over a time range. |
Example questions
You don't call tools by hand — the agent does. These are the kinds of questions that map onto a single call:
| Ask | Tool call |
|---|---|
| "Is it safe near Arnold right now?" | grid_situation { "location": "Arnold, CA" } |
| "Any active wildfires in Calaveras County?" | grid_events { "location": "Calaveras County", "layer": "wildfire" } |
| "What are road and weather conditions on Ebbetts Pass?" | grid_conditions { "location": "ebbetts-pass" } |
| "I'm at 38.03, -120.40 — what hazards affect me?" | grid_situation { "location": "38.03,-120.40" } |
| "Which data feeds are currently down?" | grid_sources { } |
| "When did the SIERRA mesh node last check in?" | grid_events { "layer": "mesh" } → match the node by name; use its observedAt (last heard) |
Try it with curl
Discover the tools:
curl -sX POST https://data.sierragridteam.org/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' Ask what's happening near a town:
curl -sX POST https://data.sierragridteam.org/mcp \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0", "id": 3, "method": "tools/call",
"params": {
"name": "grid_situation",
"arguments": { "location": "Arnold, CA" }
}
}' A trimmed response — note the preserved honesty fields:
{
"resolved_place": "arnold",
"mode": "WATCH",
"summary": {
"highest_severity": "SEVERE",
"active_evacuations": null, // null = UNKNOWN (Cal OES errored), not 0
"evacuation_status": "UNAVAILABLE"
},
"domains": [ { "domain": "fire", "status": "OK", "active_count": 1 }, ... ],
"disclaimer": "Reference only — verify with official sources ..."
} Handshake (what an MCP client sends first):
curl -sX POST https://data.sierragridteam.org/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize"}' Reading the data honestly
This is reference-only, life-safety data. Every
result carries a disclaimer, and an agent relaying it must
respect the fail-loud contract:
- Every source reports OK / STALE / UNAVAILABLE. UNAVAILABLE means the status is unknown, not clear — never present absence of data as an all-clear.
- Evacuations:
active_evacuationsis an explicitnull(source errored → unknown),0(Cal OES healthy, no active zones — caveated, not a guarantee), orN(active). null and 0 are different — never collapse them. - Evacuation orders and directive text are shown verbatim; link the authoritative source, don't paraphrase.
The full model — severity scale, place ids, the evacuation contract — is in the
/api/v1 reference. The MCP server also exposes it as an in-band resource
(grid://reference).