Giving Agents the API Spec Only (OpenAPI)
When an agent drives an HTTP client, the most common failure is inventing paths, methods, or fields that are not in the contract. A short chat note (“the API is roughly like this”) is weaker than handing it one OpenAPI (Swagger) document and requiring it to use only declared paths and components.
This post covers only where to put the spec · how to give response examples · how to reduce hallucinations. mcp-tool-schema is MCP tool JSON Schema wording; mcp-resource-vs-tool is resource vs tool selection. Here the axis is feeding OpenAPI alone into agent context. No pricing, plans, tokens, or affiliate links.
Grounded in OpenAPI Specification v3.1.0 (Paths, Media Type, Response, Example Object) and the usual workflow of attaching a read-only contract file to the agent.
Where should the spec file live?
One-line answer: Keep a single source of truth (OpenAPI YAML/JSON) in the repo and point the agent at that path or URI. Do not paste the full document into every prompt.
Practical layout:
| Location | Role | How the agent gets it |
|---|---|---|
openapi.yaml / openapi.json (root, docs/, or specs/) | Contract source of truth | Fix the relative path in Rule / AGENTS.md |
| CI-generated snapshot | Schema extracted from code | Reference only the committed artifact path |
| MCP resource URI | Host-pulled read-only context | Supply the spec via resources/read |
| Internal HTML docs site | Human narrative | Prefer the raw OpenAPI as agent input |
Suggested prompt line:
API contract: only <repo>/docs/openapi.yaml
Allowed: paths + components declared there.
Forbidden: invent endpoints, fields, status codes, or auth schemes.
Avoid:
- Pasting a memo of paths without schemas → field names and types hallucinate immediately.
- Giving only README curl samples and hiding OpenAPI → when samples drift, the agent treats the sample as truth.
- Loading
openapi-v1.yamlandopenapi-v2.yamltogether → name one allowed version in the Rule.
If the document is huge, do not inject the whole file every turn. Have the agent read a path-prefix slice or a generated partial with resolved $refs—and still keep the canonical file path in the brief.
How should response examples be supplied?
One-line answer: Put examples on the OpenAPI Media Type Object as example or examples, alongside schema. Do not drop bare JSON into chat as the contract.
In OpenAPI 3.1, request and response body examples live on the Media Type Object. example and examples are mutually exclusive; Media Type values override any example on the schema. A Response Object’s content map is media-type key → Media Type Object.
Minimal shape (conceptual):
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Item"
examples:
sample:
summary: typical item
value:
id: "item_1"
name: "widget"
"404":
description: Not found
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
example:
code: "not_found"
message: "Item not found"
Rules when briefing the agent:
- Include success and failure —
200alone invites invented error bodies. Declare4xx/5xxschemas and examples. - Field names match the schema — keys that appear only in examples look like undocumented fields.
- Use the
examplesmap for variants — name cases likeempty_listorwith_cursor. - External samples — Example Object may use
externalValue, but if the agent cannot fetch the network, prefer inlinevalue. - Same for request bodies — Media Type
example/exampleson the request body cuts payload hallucination.
Short chat helper:
Prefer response examples from the OpenAPI Media Type Object.
Do not treat README curl snippets as the contract if they diverge.
How do you reduce hallucinations?
One-line answer: Lock a forbid rule—“if it is not in the spec, do not call or write it”—and require a pre-call check of path · method · required against the document.
Checklist:
[ ] Single OpenAPI path in Rule / brief (one file, one version)
[ ] Agent may only use operationId or method+path listed under paths
[ ] required parameters / requestBody fields must come from the spec
[ ] Status codes and error bodies must match declared responses
[ ] If unsure: stop and ask / open a ticket — do not invent
[ ] After edit: regenerate or validate OpenAPI (spectral, openapi-cli, etc.)
Typical failure modes:
| Symptom | Cause | Mitigation |
|---|---|---|
Invented path like /v2/widgets | Natural-language-only brief | Allow only paths keys |
Mixed camelCase / snake_case | Example vs schema drift | Align examples with schema |
| Random headers or query params | Missing Parameter Objects | Declare parameters and required |
| Assumes only 200 bodies | No error responses | Define 4xx / default |
| Old endpoints reappear | Mixed old versions in context | One version, one file |
If you have tooling, parse the spec into an allow-list before HTTP calls—stronger than chat reminders. Even without tools, put “every called path exists under openapi paths” in the Done definition so human review is cheap.
Adjacent posts: whether to attach the spec as an MCP resource belongs in mcp-resource-vs-tool; tool-argument wording belongs in mcp-tool-schema.
One-line wrap-up: One OpenAPI path → Media Type examples for success/failure → forbid calls outside paths. Do not send an agent out on prose-only API descriptions.
FAQ
Does OpenAPI 2.0 (Swagger) work the same way?
The principle—hand a contract file and forbid anything outside paths—is the same. This post uses 3.x Media Type Object placement for examples. If your team is on 2.0, follow that document’s examples / definitions rules.
Can we use an agent before a spec exists?
Commit a minimal OpenAPI (paths, methods, schemas, a couple of examples) first, then attach the agent. Generating code with no contract usually costs more when you reconcile later.
What if README and OpenAPI disagree?
Agent rules should prefer OpenAPI. Keep README as human narrative; fix the spec or the README—do not tell the agent to “merge them somehow.”
The full spec is too large for context?
Narrow the task scope with a path prefix, tags, or operationId list, and read only those Path Items plus related $refs. Keep the forbid rule: do not invent paths outside the list.
Sources
- OpenAPI Specification v3.1.0 — Paths, Media Type (
example/examples), Response, Example Object - OpenAPI Initiative · OAS — specification hub
- Adjacent: mcp-resource-vs-tool (spec as resource), mcp-tool-schema (tool schema wording)