MCP Server for Data: The Grounding Layer Every Agent Needs
Why production agents in 2026 need a typed MCP grounding layer — not another search API. Seven design choices that separate toys from production tools.
The quiet consensus of 2026
If you’ve shipped an agent to production this year, you’ve probably noticed the same thing we have: the model isn’t the bottleneck any more. The data is. Model Context Protocol solved the wiring problem — agents can now call tools without bespoke function-calling schemas per vendor — but it did nothing for what those tools return. That’s where most production agents still fall over.
MCP is a transport. Grounding is a discipline. This post is about the second one, and why the teams getting it right are treating their grounding layer as infrastructure, not a side project.
What MCP actually solves (and what it doesn’t)
MCP, at its core, is an RPC protocol with a handshake. It lets a host (Claude Desktop, Cursor, your own agent runtime) discover tools, resources and prompts from a server, and call them with a typed schema. It standardises the plumbing — auth, streaming, cancellation, tool listing — so you stop writing one-off adapters for every LLM provider.
What it does not do: tell you what a good tool looks like. The protocol is perfectly happy for you to expose search(query: string) -> string and return a markdown blob. Most early MCP servers do exactly that, and it’s why agents built on them behave like a slightly drunk intern with a browser.
The interesting design question is what belongs behind an MCP tool. Our answer, after building FreshGeo against UK data sources, is that search-shaped APIs aren’t enough. Agents need grounding tools — typed, cached, attributable, and narrow.
Why generic search APIs fail agents
The pitch for a general-purpose search API is seductive: one endpoint, any query, LLM-ready markdown. In practice it produces three failure modes we see weekly in customer postmortems:
- Token bloat. A search result for “current UK corporation tax rate” returns 8,000 tokens of scraped HMRC page. The answer is two numbers.
- Silent drift. The same query returns different top results on Tuesday than Monday, because a news site republished an explainer. Your eval suite now fails for no reason.
- No provenance. The model sees a paragraph. It doesn’t see whether that paragraph came from Companies House or a Reddit thread. Neither do you, when the customer complains.
The fix isn’t a better ranker. It’s narrower tools with stronger contracts.
What a typed grounding tool looks like
Here’s the shape we’ve converged on. A grounding tool is domain-specific, returns structured data, cites every field, and is idempotent within a cache window.
// FreshGeo pricing tool, as exposed over MCP
type PricingQuery = {
product: string; // 'gas' | 'electricity' | 'broadband' | ...
region: string; // ISO 3166-2:GB code
as_of?: string; // ISO date, defaults to 'now'
};
type PricingResponse = {
cache_id: string; // deterministic hash of inputs + data window
as_of: string;
currency: 'GBP';
values: Array<{
tariff: string;
unit_price: number;
standing_charge: number;
source: { publisher: string; url: string; fetched_at: string };
confidence: number; // 0..1
}>;
evidence_url: string; // signed URL to raw source snapshot
};
Three things to notice. The inputs are enumerated, not free text. Every value carries its source. The response has a cache_id — we’ll come back to that. This is the opposite of a search API: you cannot ask it a question it doesn’t already know the shape of, and that’s the point.
Seven design choices for production-ready grounding
These are the decisions we’d defend in front of any platform team. None of them are novel on their own — but we rarely see all seven in one place.
1. Determinism by default
Same inputs, same data window, byte-identical response. If an upstream source updates, the cache window rolls and the cache_id changes. Agents that rely on stochastic tools cannot be evaluated.
2. cache_id on every response
A stable hash of (tool, inputs, data_window). Agents can log it, replay it, dedupe on it. Our customers use it for eval harnesses, prod retries and regulator-facing audit.
3. Per-agent API keys, not per-tenant
If five agents in your org share a key, you cannot rate-limit or deprecate one without affecting all. Issue keys per agent, with scopes.
4. Scoped tool visibility
An agent that does lead enrichment has no business calling the news/risk tool. MCP allows server-side scope enforcement at tools/list. Use it. Narrower surface area means shorter system prompts and fewer hallucinated tool calls.
5. Audit log as a first-class resource
Every tool call, with inputs, cache_id, caller, latency, and upstream source fingerprint. When something goes wrong in production, this is the difference between a ten-minute postmortem and a four-hour one.
6. An entity graph under the tools
All seven FreshGeo tools resolve to the same internal entity IDs — a company, a postcode, a tariff. This means an agent can pivot from a pricing lookup to a competitor lookup to a news query without restating the subject.
7. Evidence, not just citations
A URL is not evidence if the page changes. Every response includes a signed snapshot URL pointing at the raw content as we saw it. Regulated customers require this; everyone else discovers they need it the first time a source silently edits a number.
Plugging FreshGeo into Claude
Minimal example. Assumes you have a FreshGeo key and the Anthropic SDK installed.
from anthropic import Anthropic
client = Anthropic()
resp = client.messages.create(
model="claude-opus-4-7",
max_tokens=2048,
mcp_servers=[{
"url": "https://mcp.freshgeo.com",
"name": "freshgeo",
}],
messages=[{"role": "user", "content": "..."}],
)
The only FreshGeo-specific line is the endpoint. Everything else is vanilla MCP — which is the whole point of the protocol. Swap us out for another grounding provider and your agent code doesn’t change.
Where this is going
The agents shipping to production in late 2026 look very different from the ones that shipped in 2024. They use fewer tools, not more. The tools they use are narrow, typed and cached. The grounding layer is treated as a distinct concern from the model, with its own SLOs and its own on-call rotation.
If you’re building one of those agents and your tool list still includes a general-purpose web search, that’s the first thing to replace. Start with the data your agent actually needs — pricing, intent, competitor signal, whatever it is — and find or build a typed tool for it. See our product list for the seven we cover, or pricing if you’re sizing up.
MCP got us a common socket. What you plug into it is still the decision that matters.