Blank white background with no objects or features visible.

Join the Resilient Agents online hackathon hosted by TrueFoundry. Win up to $10,000 in prizes. Register Now →

Converting an OpenAPI Spec to an MCP Server: Architecture and Edge Cases

von Boyu Wang

Aktualisiert: May 31, 2026

Anthropic introduced the Model Context Protocol in November 2024, and within a year nearly every API tooling vendor and several independent generators had shipped a way to mechanically convert an OpenAPI specification into a working MCP server. The basic mapping is mostly clean: path becomes tool name, parameters become input schema, success response becomes output schema. The interesting parts are where the mapping is lossy — pagination, multipart uploads, webhooks, streaming responses — and the operational pieces that determine whether the generated server is actually usable: auth injection, schema validation, description quality. This post walks the full algorithm and the specific patterns that don't translate.

Key Takeaways
  • OpenAPI-to-MCP conversion is a known multi-vendor pattern (TrueFoundry, Speakeasy, Stainless, FastMCP, and several open-source generators). The high-level mapping is broadly similar across all of them; the interesting differences sit in naming conventions, schema flattening, pagination defaults, and how each handles the lossy cases.
  • Tool naming uses operationId where present, otherwise method + path with non-alphanumerics replaced by underscores (GET /users/{user_id}/reposget_users_user_id_repos). Names should be snake_case and stable across regenerations — operationIds are almost always better than synthesized names.
  • Path parameters become required tool arguments; query parameters become optional with OpenAPI defaults preserved; application/json request bodies become structured object arguments. multipart/form-data and binary uploads are partial-support at best.
  • Only the success response schema (2xx) maps to the MCP outputSchema. Error responses are returned to the agent as tool errors, not as alternative output shapes — usually the right thing, occasionally not.
  • Pagination is the canonical lossy case. Three real options: expose paging arguments and let the agent paginate; fetch-all-pages inside the generated server; expose a separate next-page tool. Each has different cost, latency, and agent-complexity tradeoffs.
  • Auth injection happens at the gateway, not in generated code. The generated MCP server has no credentials of its own — it receives an HTTP client from the gateway runtime with the right token already attached for the calling user.
  • TrueFoundry's MCP Gateway includes an OpenAPI-to-MCP generator that runs as part of the gateway control plane. The auth, RBAC, schema validation, and audit logging are gateway primitives the generated server inherits by sitting behind the gateway — the same primitives that apply to any other MCP server registered with it.

Tuesday at Northwind. Priya, integrations lead on the logistics platform team, gets a ticket: "Make shipment-tracking-svc callable by the routing optimizer agent." The service has 47 REST endpoints, a maintained OpenAPI 3.1 spec, OAuth2 auth, cursor-based pagination, two webhook endpoints, and a streaming endpoint for live truck telemetry. The agent's MCP toolbox is currently 12 tools across three other services, each hand-coded over roughly a week. Forty-seven endpoints at that rate would be most of a quarter of engineering time.

The OpenAPI spec already describes the service in machine-readable form — paths, parameters, schemas, response shapes, even the OAuth2 scopes per operation. None of the hand-coding she's been doing is adding information the spec doesn't already contain. The work has mostly been translation from one schema language to another, with a small set of well-defined edge cases. That work belongs to a build step, not to a quarter of engineering.

This post is the conversion algorithm — what maps cleanly, what doesn't, and the operational pieces (auth, validation, description quality) that make the generated server actually usable.

1. The Conversion Algorithm: From OpenAPI Path to MCP Tool

The conversion walks the OpenAPI document and emits one MCP tool per (path, method) pair. For each pair, it computes four things: the tool name, the description, the input schema, and (where the target MCP revision supports it) the output schema.

Tool name. Prefer the operationId if the spec author provided one — operationIds are idiomatic identifiers, usually already chosen for readability. If absent, synthesize from method and path: lowercase the method, append the path with non-alphanumerics replaced by underscores, collapse duplicate underscores. GET /users/{user_id}/repos becomes get_users_user_id_repos. The synthesized form is syntactically valid but verbose; operationIds win where they exist.

Tool description. Prefer summary, then description, then a generated stub from method + path. Section 6 covers why this seemingly minor field matters more than people expect.

Input schema. A merge of path parameters, query parameters, and the request body schema into a single JSON Schema object, with the right required/optional markers. Details in section 2.

Output schema. The schema attached to the first 2xx response for application/json. Other content types and non-2xx responses are not represented. Details in section 3.

YAML — OpenAPI path item (excerpt from shipment-tracking-svc)

paths:
  /users/{user_id}/repos:
    get:
      operationId: listUserRepos
      summary: List a user's repositories
      description: Returns repositories accessible to the
        authenticated user, owned by user_id, paginated by cursor.
      parameters:
        - name: user_id
          in: path
          required: true
          schema: { type: string }
        - name: per_page
          in: query
          schema: { type: integer, default: 30, maximum: 100 }
        - name: cursor
          in: query
          schema: { type: string, nullable: true }
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RepoListPage'
        '401': { $ref: '#/components/responses/Unauthorized' }
        '404': { $ref: '#/components/responses/NotFound' }
      security:
        - oauth2: [repo:read]

JSON — generated MCP tool

{
  "name": "list_user_repos",
  "description": "List a user's repositories. Returns repositories accessible to the authenticated user, owned by user_id, paginated by cursor.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "user_id":  { "type": "string" },
      "per_page": { "type": "integer", "default": 30, "maximum": 100 },
      "cursor":   { "type": "string", "nullable": true }
    },
    "required": ["user_id"]
  },
  "outputSchema": { "$ref": "#/$defs/RepoListPage" }
}

Der schnellste Weg, deine KI zu entwickeln, zu steuern und zu skalieren

Melde dich an
Inhaltsverzeichniss

Steuern, implementieren und verfolgen Sie KI in Ihrer eigenen Infrastruktur

Buchen Sie eine 30-minütige Fahrt mit unserem KI-Experte

Eine Demo buchen

Der schnellste Weg, deine KI zu entwickeln, zu steuern und zu skalieren

Demo buchen

Entdecke mehr

Keine Artikel gefunden.
May 31, 2026
|
Lesedauer: 5 Minuten

Separating Agent Logic from Runtime: The Case for a Managed Agent Layer

Keine Artikel gefunden.
May 31, 2026
|
Lesedauer: 5 Minuten

Converting an OpenAPI Spec to an MCP Server: Architecture and Edge Cases

Keine Artikel gefunden.
May 30, 2026
|
Lesedauer: 5 Minuten

Innovation entfesseln: Höhepunkte des internen Hackathons von TrueFoundry

Kultur
May 30, 2026
|
Lesedauer: 5 Minuten

Konfiguration der Umgebung — warum, was und wie?

Technik und Produkt
Keine Artikel gefunden.

Aktuelle Blogs

Black left pointing arrow symbol on white background, directional indicator.
Black left pointing arrow symbol on white background, directional indicator.
Machen Sie eine kurze Produkttour
Produkttour starten
Produkttour