No. 34 · AUG 2026 · 3 Min Read
The Model Has to Read the Manual
Abstract
Complex data APIs work better when query tools require a current guide receipt, then return errors that show the model exactly how to recover.
An on-demand data guide cannot help a model that skips it and starts guessing at the data.
In Writing a Good MCP Server, I stopped at get_help and get_docs: tools that let a model pull instructions when it needs them. That works when the model notices it is uncertain. A complex data API needs one more piece. The query tool should make the guide call a prerequisite.
The Guide Is Part of the Query
A data guide is a tool response built for the next call. It describes the record types, the relationships between them, the supported query shapes, a few good examples, and the footguns most likely to produce a plausible but wrong answer.
Call it get_docs, data_guide, schema_help, or anything else. The name does not matter. Its job is to put the smallest useful map of the data into context at the moment the model needs to navigate it.
I sometimes call this benevolent prompt injection: trusted context arriving through a tool result to help the model use the data correctly. It is an informal name for a useful effect. The model sees the guide beside the task it is trying to complete, rather than somewhere in a long-standing prompt it may not attend to.
A tool description can say, “Call data_guide before querying.” Models still skip that step. The query looks obvious. The model assumes it already knows what a field means. Or it reaches for a familiar SQL or filter shape that this API does not support.
The fix is to make sequencing part of the protocol.
Require a Guide Receipt
The guide response can include a short-lived or version-scoped guide_receipt. The query tool requires it:
data_guide("orders.relationships")
-> { guide: "...", guide_receipt: "gr_7K4..." }
query_data(
guide_receipt: "gr_7K4...",
query: { ... }
)
-> { rows: [...] }
The receipt can be a short-lived opaque nonce or an opaque value tied to the guide topic and version. Either way, the server binds it to the guide version it returned. If the receipt is missing, expired, or tied to an older version, query_data returns a structured error:
{
"code": "GUIDE_REQUIRED",
"guide_topic": "orders.relationships",
"message": "Call data_guide for this topic, then retry with its receipt."
}
That is enough. A query cannot run until the current guide response has been placed in the model’s context.
The boundary matters. A receipt proves only that the guide call completed and its current response entered the context carried into the query. It does not prove comprehension, correct reasoning, user authorization, or safe behavior. It should never grant access to data. Authorization still belongs at the data boundary, checked against the user’s identity and permissions on every call. Rules are not controls, and a guide receipt is not a security control either.
Errors After the First Query
Passing the receipt gate does not make the first query correct. The model can still choose the wrong record type, invent a field, or misunderstand a relationship. The API now knows which guide version the model saw, so its error can give a recovery path against that version.
{
"code": "INVALID_FIELD",
"field": "orders.customer_email",
"reason": "Email belongs to customer records, not orders.",
"guide_topic": "orders.relationships",
"retry_with_same_receipt": true,
"suggested_query": {
"from": "customers",
"where": { "email": "..." },
"include": ["orders"]
}
}
The error names the relationship assumption that failed, points to the guide topic, and says whether the receipt can be reused. If the guide changed, the server rejects the old receipt and the model fetches the topic again. If it is still current, the model corrects the query with the receipt it already has.