We Shipped an Agent-Native API Without OpenAPI

If you have been putting off writing an OpenAPI document for your agent-facing API and feeling vaguely negligent about it: you may not need one. We shipped without it on purpose, and so far the absence has cost us nothing I can point at.
This is not an argument against OpenAPI. It is an argument that "machine-readable API description" and "OpenAPI document" stopped being the same thing when the machine doing the reading became an agent. The MCP specification(opens in new tab) defines that surface, and we have argued before for shipping one integration surface properly.
What an agent actually needs
An OpenAPI document describes every route, every parameter, every response shape. It is complete by design, and completeness is its value. A code generator needs all of it to emit a client.
An agent is not a code generator. An agent needs to answer one question: given what the user asked for, which call should I make and with what? The other forty routes are noise it has to spend context filtering out. That filtering is not free, and it is where multi-step agents lose reliability.
MCP's tools/list answers exactly that question. It returns the tools an agent should
consider, each with a description written for a reader who is deciding whether to call it,
and a JSON Schema for the arguments. Not the route table. The decision surface.
Ours returns seven: quote, make, get run, list voices, list actors, upload image, get account. That is the whole machine-readable surface, and it is small enough to print here, which is the point.
The difference shows up most clearly in what each format encourages you to write. An OpenAPI
summary field tends to end up as "Creates a run": accurate, useless for choosing. A tool
description has nowhere to hide: if you cannot say when an agent should reach for this and
when it should not, you have discovered something about your own API.
The property that matters: it cannot drift
This is what made it a real decision rather than a rationalisation.
A spec is a description of your API maintained next to your API. The two agree as long as somebody keeps them in agreement. The failure mode is familiar: the endpoint gained a parameter, the document did not, and a client generated from the document is now wrong in a way nobody will notice until it breaks in production. Keeping a description true is not something a format can enforce. It is the same failure as an agent that says done when it is not.
Generators help and do not solve it — they move the drift from the document to the annotations that produce the document.
tools/list is served by the same server that executes the tools. It is not a description of
the surface; it is the surface, enumerating itself. A tool that does not exist cannot be
listed, and a tool that changed its arguments reports the changed arguments, because the
schema it returns is the schema it validates against.
That is not better documentation. It is a different category of thing: the class of bug where docs and reality disagree is unavailable, rather than defended against.
What you give up
Three things, and they are not nothing.
The client-generation ecosystem. No openapi-generator producing typed clients in nine
languages. If you have human developers who want a Python SDK, you write it or you skip it.
We publish a TypeScript SDK, and it costs less to maintain than it looks: its input and
response types are inferred from the same zod schemas that validate REST and produce
tools/list, so an API change updates the client types without anyone retyping them.
Browsable reference docs. Nobody opens a Swagger UI against tools/list. Human-facing
documentation becomes something you write deliberately instead of something you get as a
byproduct, and writing it deliberately is more work.
Ecosystem assumptions. Some tools (API gateways, contract testing, certain monitoring products) expect an OpenAPI document and have no fallback. If one of those is load-bearing for you, this trade is worse than it was for us.
We are a video generation API whose primary consumer is an agent. The last item cost us nothing and the first two cost us some writing. For an API whose primary consumer is a frontend team in another building, the arithmetic inverts.
When to reach for it
The honest boundary: tools/list is the right primary surface when agents are the main
consumer and the call surface is small.
Small matters. MCP tools are enumerated in full, so a hundred-tool server hands an agent a hundred descriptions to reason through, which is the context problem OpenAPI has, arriving by a different road. Our seven exist because the product is seven verbs. If yours is a CRUD API over forty resources, tool enumeration is not automatically the answer, and the real work is deciding which forty operations are worth exposing as tools at all.
There is also a middle path we did not take but would consider: serve both, generated from one source. It gets you the ecosystem back at the cost of reintroducing exactly the drift problem this avoids. We have written before about picking one integration surface and selling it properly rather than shipping three half-maintained ones.
FAQ
Is not having OpenAPI a problem for enterprise buyers?
It comes up, and the question underneath it is usually "can we integrate this into our existing tooling", not "do you have this specific file". Answering the real question has worked better than producing a document to satisfy a checklist. If a buyer genuinely needs an OpenAPI document for a gateway, that is a concrete requirement and we would rather hear it stated than infer it.
How do human developers learn the API without reference docs?
A hand-written agent guide ships inside the MCP server package, and the typed SDK covers the rest. What we do not have is a public API reference, and that is the real cost of the choice: the material a generator would have produced is material someone has to write, and that writing has not happened yet.
Does MCP lock you into one ecosystem?
Less than it looks. tools/list returns names, descriptions, and JSON Schema — the same
information an OpenAPI operation carries, in a different envelope. Producing an OpenAPI
document from it later is mechanical. Starting with a spec and deriving good tool
descriptions is the direction that does not work, because the descriptions an agent needs
were never in the spec to begin with.
Your agent does not need your route list. It needs the ones it should call.
Clipwright's machine-readable entry point is the MCP server's tools/list — the same surface the agent calls, so it cannot describe something that is not there.
About the Author
Dimantika
Founder of Dimantika. Co-founded and exited a SaaS at $1.2M ARR. Now building AI tools for founders who want autonomous growth without blind trust in agents.
View all postsRelated posts
More articles you might like.

The Cheapest Way to Run an AI Product Is to Not Pay for It
Three products now let the user's own Claude plan pay for inference. Anthropic's terms permit one shape of that and ban another, and you cannot tell which.

Negotiate the Format Before You Pay the Vendor
A 3% aspect mismatch is a rounding error. A 40% one is a different video. The threshold between them decides whether you refuse before the bill or apologise after.

Never Answer an Agent With a Silent Substitution
An unmet parameter should come back named. We learned why the hard way: two warnings went missing for weeks and every test stayed green.