mcpstepbystep

Compare & Decide

MCP vs OpenAPI: why not just give the model your API spec?

Auto-generating MCP tools from an OpenAPI spec vs hand-designing task-shaped tools: context cost, abstraction leaks, and when each approach actually works.

updated 2026-07-19

You have a REST API with a perfectly good OpenAPI spec. Every endpoint documented, every schema typed. The temptation is obvious: point a generator at the spec, get an MCP server with one tool per endpoint, done in an afternoon. Sometimes that’s exactly right. Often it’s how you end up with a server the model can’t use and a context window you can’t afford.

The core issue: OpenAPI and MCP answer different questions. OpenAPI describes what your API can do — exhaustively, for a programmer with docs open who will call it from code that’s written once and runs forever. MCP tools describe what a model should do — selectively, for a reasoning system that re-reads every tool description on every request and has to pick the right one from scratch each time.

What auto-generation gets you

One tool per endpoint: get_users, get_user_by_id, create_user, update_user, patch_user, delete_user, and on through the spec. Parameter schemas translated straight from the OpenAPI definitions, descriptions lifted from whatever summary fields your API team wrote three years ago.

That’s genuinely fine when three things are true:

  1. The spec is small — a couple of dozen endpoints, not hundreds.
  2. It’s internal — your own team consumes it, tolerates rough edges, and can regenerate when the API changes.
  3. The endpoints already map to tasks — some APIs are naturally task-shaped (send_notification, run_report), and for those, generation is honestly hard to beat on effort.

For internal prototyping — “let the agent poke our staging API this sprint” — generate away. FastMCP 2.x can even build the server from a spec directly, and you’ll have something working before lunch.

Where it falls apart

The context bill

Every tool definition — name, description, full parameter schema — is loaded into the model’s context at session start. A 100-endpoint spec becomes 100 tools whether or not the task at hand needs any of them. Real-world measurements make the point brutally: one 106-tool server weighed in at roughly 54K tokens at initialisation — a large fraction of a typical working context spent before the user has typed a word, and billed again on every single request.

And it’s not only cost. Tool selection degrades as the catalogue grows: faced with get_user, get_users, get_user_profile, query_users, and search_users, models pick wrong, retry, and burn turns. A hundred near-synonymous tools is a worse interface than five distinct ones — for a model even more than for a human.

Leaky abstractions

REST endpoints assume a caller who can orchestrate. “Create an invoice” in your API might really be: create draft → add line items → validate → finalise — four calls, in order, with IDs threaded between them. Auto-generated tools hand the model four fragments and hope it discovers the choreography. Sometimes it does. Under pressure, in a long session, it skips the validate step and you get support tickets.

Everything else leaks through too: pagination cursors, fields filter syntax, enum codes (status=3), auth-scoped variants of the same endpoint. Each leak is something the model must get right by inference that your backend previously got right by code. The failure isn’t an exception you can catch — it’s a plausible-looking wrong call.

Error shape

OpenAPI errors are written for developers reading logs (422: constraint violation on field customer_ref). A model needs errors that steer the next attempt (“customer_ref must be an existing customer ID — call find_customer first to look one up”). Generated servers pass raw API errors through; hand-built tools translate them into instructions.

The alternative: task-shaped tools

Instead of mirroring endpoints, design a handful of tools around the jobs users bring to the agent, and let each tool orchestrate as many API calls as the job needs:

Endpoint-shaped (generated)Task-shaped (hand-designed)
GranularityOne tool per endpointOne tool per user-visible job
Count for a 100-endpoint API~100 toolsTypically 5–15 tools
Context costTens of thousands of tokensSmall, predictable
Multi-step workflowsModel must orchestrateTool orchestrates internally
Error messagesRaw API errorsRewritten to guide the model’s next step
API changesRegenerate; churn hits the modelAbsorbed inside the tool; interface stays stable
EffortHoursDays — but it’s design, not plumbing

The invoice example becomes one tool — create_invoice(customer, line_items) — that runs the four-call dance internally and returns either the finalised invoice or a model-readable explanation of what to fix. The model sees one clean affordance instead of four sharp parts.

A useful smell test: if your tool descriptions read like your API reference, you’ve generated. If they read like instructions to a capable colleague, you’ve designed.

A pragmatic middle path

This isn’t all-or-nothing:

  • Generate, then prune. Start from the spec, keep the 10 endpoints agents actually need, delete the rest, and rewrite every surviving description for a model audience. Most of generation’s speed, a fraction of its context bill.
  • Wrap the messy 20% by hand. Generate the simple reads; hand-build tools for anything multi-step or dangerous (writes, deletes, money).
  • Split by audience. A wide generated server for internal experimentation; a narrow, designed server for anything users touch.

We walk through the hand-designed approach end to end — auth, pagination, error translation and all — in how to wrap a REST API in an MCP server.

Verdict

Give the model your OpenAPI spec only when the spec is small, internal, and already task-shaped — there, generation is a free win. For everything else, the spec is your source material, not your tool list: a 100-endpoint API auto-converted to 100 tools buys you a ~50K-token context bill, degraded tool selection, and leaked abstractions the model will fumble at the worst moment. Hand-design a small set of task-shaped tools that orchestrate the API internally. Endpoints are for programs; tools are for models — and the teams who respect that difference ship agents that work.

newsletter

One practical MCP guide in your inbox. No news, no hype.

Tutorials and decision frameworks as they ship. Unsubscribe anytime.