The grid needs an interface agents can reason with.
Nine typed tools, one authenticated resource per market, and a dataset contract that travels with every number. What it takes to make the grid legible to an agent.

A useful power-market agent cannot begin with a blank text box and end with a fluent paragraph. The grid is too physical, too temporal, and too particular about where every number came from. Before it can answer anything, it has to find the right record, read that record's contract, query the right interval in the right timezone, put the result somewhere on a map, and hand back the evidence beside the answer.
Model Context Protocol is useful to us because it gives that work a boundary we can publish. Ask the Grid runs one MCP resource per live market — ERCOT, CAISO, NYISO, and PJM — with the market in the resource URL, so an agent's grid scope is owned by code rather than by a tool argument the model chooses. Behind each resource are nine typed tools and the same discovery-to-query workflow the product's own agent runs.

One question. A visible chain of work.
The next agent receives the evidence, not just the prose.
Conceptual product sequence. The tools and records vary with the market question.
01
The hard part is not moving a number.
APIs already move values between systems. The harder problem is that a power price is not one thing. ERCOT publishes settlement point prices every five minutes out of security-constrained economic dispatch, and ERCOT LMP carries no marginal-loss component, so a point's congestion is what remains once the same interval's system lambda is subtracted. PJM publishes a five-minute LMP that is explicitly unverified, then the settled hourly record roughly eighteen hours later, with system energy, congestion, and loss broken out separately. Two feeds, both fairly described as the real-time price, that cannot be substituted for one another.
So every dataset in the catalog carries a contract rather than a description. The contract names the grain, the evidence class — observed, forecast, cleared day-ahead, or reference — which column is event time and which is publication time, whether a timestamp is an instant or an interval start, how revisions collapse before aggregation, which filters are required, and what an empty result is allowed to mean. describe_data returns all of it along with up to three recent rows, so a filter is written against real identifier and enum values instead of plausible ones.
The protocol matters only if the market context survives the handoff.
02
Discovery belongs inside the reasoning loop.
search_data is not a search box bolted onto a warehouse. It takes the whole job in one query, including the operative intent, and returns a small query-ready package: the exact dotted table to select from, the columns that matter for this question, the grain, the cautions, and a query recipe. Datasets come back labeled primary, explanatory, alternative, or supporting, so a substitute is never mistaken for a second piece of evidence.
The recipe is the part that changes behavior, because it is copyable SQL rather than advice. For an ERCOT calendar day it returns a local-calendar filter against America/Chicago, so local midnight never silently becomes UTC midnight. For a dataset published in vintages it returns the causal predicate — publication time at or before target time — together with the ranking that reduces each target to one publication.
Inside the product that recipe is enforced rather than suggested. A historical forecast comparison that filters causally but leaves several vintages standing comes back as requiring vintage reduction before it reaches the database, and one that ranks vintages without the causal filter is rejected too. Over MCP, query_data holds the boundary that can be enforced from outside the reasoning: one read-only SELECT, only tables the catalog registered for the connected market, and at most 200 rows back. Either way, discovery stops being documentation someone might read and becomes part of the analytical system.
03
A question should be able to move the product.
Take a desk asking what changed in ERCOT congestion over the last hour. Prices alone cannot answer it: a spread between two settlement points establishes that they separated, not why. The sequence that does answer it aligns real-time settlement point prices with the five-minute system lambda to isolate the congestion component, then reads the SCED shadow price record, where each row is a binding constraint and contingency pair with the marginal system cost of that constraint in that interval.
It also has to stop where the evidence stops. A shadow-price row establishes that the named facility bound and what it cost the dispatch. It does not establish which hub or node it moved; that attribution needs shift factors, and the dataset's cautions say so rather than leaving the model to fill the gap from plausibility.
The result is a product state, not only prose. The map can select the node by id and coordinate, the scrubber can jump to the exact instant, a chart can draw the interval, and the next question inherits the market, the selection, and the clock. MCP is how that same sequence runs inside another approved client instead of only inside our own interface.
04
Public evidence and private state need a visible seam.
Access control is not a wrapper around the analytical experience; it is part of the model the agent reasons against. The surface speaks protocol revision 2025-11-25 over remote Streamable HTTP, and a client authorizes through OAuth 2.1 with PKCE against five scopes: catalog read, grid read, SQL read, asset read, and asset write. Tokens are short-lived and bound to a single market resource, so an ERCOT connection cannot quietly answer a CAISO question, and a client can be revoked from the account at any time.
Eight of the nine tools read. The only write queues an Enterprise hydration request for an asset that already exists, under its own scope, and it cannot publish research without review. Underneath all of them, queries run as a select-only database account with server-side execution and memory caps it cannot raise, with external table functions blocked outright, so an instruction that arrives inside a document has nothing useful to reach for.
The same discipline is what makes private context safe to add later. When telemetry, positions, or topology join the public market surface, which tools read public records, which crossed a private boundary, what was calculated, and what may leave the workspace all stay legible in the trace.
05
What becomes possible.
The rule builder above is a fair picture of what an agent-usable primitive looks like. An alert rule is a typed object rather than a sentence. It has a scope, which is one asset, a dropped pin with a radius between 1 and 250 km, or the whole grid. It has a trigger, which is either a published grid event or a threshold on a measured signal. Its metric comes from a registered list that includes real-time price, the congestion component, the day-ahead to real-time spread, system load, reserve headroom, reported outages, and load forecast divergence. Its condition is tested as a level, a percent move over a lookback, or a break against a moving average, above a severity floor of info, watch, warning, or emergency.
Because it is typed, it can be validated, replayed against history, explained, and called. The same is true of a catalog query, a geographic lookup, or an event query. That is the whole bet behind the MCP surface. Not that every workflow should run without a person in it, but that a model does better work against primitives that carry contracts than against a text box and a paragraph of instructions.