<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>OpenAPI on RockB</title><link>https://baeseokjae.github.io/tags/openapi/</link><description>Recent content in OpenAPI on RockB</description><image><title>RockB</title><url>https://baeseokjae.github.io/images/og-default.png</url><link>https://baeseokjae.github.io/images/og-default.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 01 Oct 2026 08:18:32 +0000</lastBuildDate><atom:link href="https://baeseokjae.github.io/tags/openapi/index.xml" rel="self" type="application/rss+xml"/><item><title>MCP Proxy: Add MCP Support to Any REST API Without Code Changes</title><link>https://baeseokjae.github.io/posts/mcp-proxy-rest-api-to-mcp/</link><pubDate>Thu, 01 Oct 2026 08:18:32 +0000</pubDate><guid>https://baeseokjae.github.io/posts/mcp-proxy-rest-api-to-mcp/</guid><description>An MCP proxy turns an existing REST API into MCP tools from its OpenAPI spec — no backend rewrite. Here are the three zero-code paths and how to pick one.</description><content:encoded><![CDATA[<p>An mcp rest api bridge works by reading your API&rsquo;s OpenAPI spec at runtime and translating each operation into an MCP tool. You keep the REST API exactly as it is, add a proxy or gateway in front of it, and point your agent at the MCP endpoint. Nothing in the backend is rewritten or redeployed.</p>
<p>That is the short answer, and it is genuinely accurate — with one important caveat that the marketing pages bury. &ldquo;No code changes&rdquo; describes the API, not the project. You still own a configuration surface, an authentication decision, and a curation judgment call. The teams that get burned are the ones who treat auto-conversion as the finished deliverable instead of step one.</p>
<p>This guide fixes the direction confusion first, then walks the three real zero-code paths (managed gateway, runtime spec proxy, generated project), explains how to lock the bridge down, and states plainly why mass-converting a 200-endpoint spec will make your agent slower and more expensive.</p>
<h2 id="rest-to-mcp-or-mcp-to-rest-getting-the-direction-right-first">REST to MCP or MCP to REST? Getting the direction right first</h2>
<p>Almost every listicle about &ldquo;converting APIs to MCP&rdquo; mixes two opposite jobs. Getting the direction wrong means you install the wrong tool and then wonder why your agent cannot see your API.</p>
<ul>
<li><strong>REST → MCP (the bridge):</strong> you have a REST API and you want an AI agent to call it as MCP tools. The MCP server is the <em>new</em> surface; the REST API is the backend. Tools like FastMCP&rsquo;s <code>from_openapi()</code>, Kong&rsquo;s AI MCP Proxy plugin, Azure API Management&rsquo;s &ldquo;Expose an API as an MCP server&rdquo;, and AWS API Gateway&rsquo;s MCP proxy support all do this.</li>
<li><strong>MCP → REST (the reverse proxy):</strong> you have an MCP server and you want ordinary HTTP/OpenAPI clients to call it. <a href="https://github.com/open-webui/mcpo"><code>mcpo</code></a> (4,387 stars, MIT) is the canonical tool here. It is regularly miscited in REST-to-MCP roundups because it sells the same benefits — auto-generated docs, standard auth, no stdio plumbing.</li>
</ul>
<p>If your goal is &ldquo;make my REST API callable by Claude, Cursor, or a Bedrock agent,&rdquo; you want the first direction. That is the rest of this article.</p>
<h3 id="why-does-this-matter-more-than-it-did-a-year-ago">Why does this matter more than it did a year ago?</h3>
<p>Because the MCP surface itself has become large enough that almost every internal API now has an agent consumer waiting for it. The official MCP Registry held <a href="https://dev.to/amareswer/the-mcp-registry-by-the-numbers-38nc">30,375 unique servers</a> (99,114 server-plus-version records) as of 2026-09-10 — roughly three times its May 2026 size. August 2026 alone saw 6,265 servers first published, more than the registry&rsquo;s entire first five months combined. Monthly MCP SDK downloads passed <a href="https://cybertizeweb.com/blog/ai/mcp-adoption-report-2026/">97 million</a> (Python plus TypeScript) by March 2026, up from roughly 100,000 in November 2024.</p>
<p>The tooling grew to match. On the enterprise side, 41% of surveyed software organizations were in limited (29%) or broad (12%) production with MCP servers, and API/MCP gateways plus full self-hosting each account for roughly 30% of deployment models — with nearly 60% of developers preferring a hybrid of the two. That split is exactly the decision this article is about.</p>
<h2 id="what-no-code-changes-really-means-and-the-one-thing-you-still-must-change">What &ldquo;no code changes&rdquo; really means (and the one thing you still must change)</h2>
<p>Every tool in this space advertises zero code changes. That claim is narrower than it sounds, and understanding the boundary saves you a failed sprint.</p>
<table>
  <thead>
      <tr>
          <th>Claimed</th>
          <th>What is actually true</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>No changes to your API</td>
          <td>True. The bridge reads OpenAPI and calls your existing HTTP routes. Your controllers, DTOs and deployment are untouched.</td>
      </tr>
      <tr>
          <td>No new infrastructure</td>
          <td>False in most cases. A runtime proxy is still a process you must run, monitor and authenticate. A managed gateway is infrastructure someone else runs — which is not the same as none.</td>
      </tr>
      <tr>
          <td>No configuration</td>
          <td>False. You must supply the spec, the auth credentials, the transport, and the inclusion/exclusion rules.</td>
      </tr>
      <tr>
          <td>Nothing to maintain</td>
          <td>Depends entirely on path. A generated TypeScript project is code you now own; a gateway plugin is a config block you version along with the rest of the gateway.</td>
      </tr>
  </tbody>
</table>
<p>The one thing you always change is the <strong>tool surface your agent sees</strong>. That is the real deliverable. The OpenAPI spec describes what humans need across 40+ operations with polymorphic bodies and pagination cursors; the agent needs eight outcome-shaped tools with honest descriptions. A bridge does not make that decision for you, and if you skip it, you have not shipped a feature — you have shipped a context tax.</p>
<h2 id="three-ways-to-bridge-a-rest-api-into-mcp">Three ways to bridge a REST API into MCP</h2>
<p>Before the paths, the decision table. Every serious option in 2026 falls into one of three categories, and the differences that matter are who runs it, how much control you get, and what you now own.</p>
<table>
  <thead>
      <tr>
          <th>Approach</th>
          <th>Example tools</th>
          <th>New services to run</th>
          <th>Control</th>
          <th>What you own long-term</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Managed gateway</td>
          <td>Kong AI MCP Proxy, Azure APIM, AWS API Gateway</td>
          <td>Zero (you configure an existing gateway)</td>
          <td>Low to medium</td>
          <td>Configuration, plus per-tier licensing</td>
      </tr>
      <tr>
          <td>Runtime spec proxy</td>
          <td>FastMCP <code>from_openapi()</code>, <code>mcp-openapi-proxy</code></td>
          <td>One process</td>
          <td>High (FastMCP), low (mcp-openapi-proxy)</td>
          <td>Uptime, auth, curation code</td>
      </tr>
      <tr>
          <td>Generated project</td>
          <td><code>openapi-mcp-generator</code></td>
          <td>One deployable you own</td>
          <td>Medium</td>
          <td>A codebase: regeneration, dependencies, upgrades</td>
      </tr>
      <tr>
          <td>OSS gateway / registry</td>
          <td>IBM ContextForge</td>
          <td>One stack (Docker/Helm)</td>
          <td>High</td>
          <td>Everything, including federation and policy</td>
      </tr>
  </tbody>
</table>
<p>Two adjacent tools appear in nearly every list and deserve a one-line verdict up front. <code>mcpo</code> is the reverse direction (MCP → REST) and is not a bridge. IBM ContextForge (<a href="https://github.com/IBM/mcp-context-forge">4,555 stars, 892 forks, Apache-2.0</a>, pushed 2026-10-01) is the most active open-source option, but it is a gateway and registry rather than a minimal converter — you adopt it when you are federating many MCP, REST and gRPC backends behind one endpoint, not when you want one API exposed.</p>
<h2 id="path-a-managed-gateway--zero-new-services-to-run">Path A: Managed gateway — zero new services to run</h2>
<p>If you already run Kong, Azure API Management or AWS API Gateway, the fastest correct answer is usually the bridge you already pay for.</p>
<p><strong>Kong AI MCP Proxy</strong> is a protocol bridge plugin with a <code>mode</code> parameter that switches between proxying MCP servers, converting a REST API into MCP tools, and aggregating tool sets into one MCP server. The flow is: MCP request → matched to an OpenAPI operation → converted into an upstream HTTP call → response wrapped back into MCP format. The endpoint is provisioned dynamically on the gateway; you do not host or scale a separate server. Crucially, the MCP traffic inherits the gateway features you already trust — OIDC or key auth, rate limiting, ACLs, logging and tracing, request transforms.</p>
<p>Two constraints to check before you commit: it requires Kong Gateway Enterprise 3.12+ (AI Gateway tier), and it must not be combined with other AI plugins on the same Service or Route.</p>
<p><strong>Azure API Management</strong> takes the portal route: APIs → MCP Servers → &ldquo;+ Create MCP server&rdquo; → &ldquo;Expose an API as an MCP server&rdquo;. You pick a managed API and version, then choose all operations or a specific subset to expose as tools; that selection is editable later in the Tools blade. Policies then supply JWT auth, rate limits and IP filtering on the MCP surface with no change to the backend. Known limitations, widely reported: it exposes tools only — no MCP resources or prompts — and it requires a paid tier, not Consumption.</p>
<p><strong>AWS API Gateway</strong> added MCP proxy support in December 2025, turning existing REST APIs into MCP-compatible endpoints with no application modification. Protocol translation, dual authentication (agent identity plus outbound credentials) and semantic API discovery are handled by Bedrock AgentCore Gateway. Availability is restricted to the <a href="https://aws-news.com/article/2025-12-02-amazon-api-gateway-adds-mcp-proxy-support">nine AWS regions where Bedrock AgentCore operates</a>.</p>
<p>The gateway path is also, quietly, the security path. Only 8.5% of MCP servers implement the OAuth 2.1 with PKCE that has been mandatory for remote servers since the November 2025 spec revision, 53% expose credentials via hard-coded values in config files, and just 18% implement any access scoping for tool permissions. Centralizing credential policy, rate limiting and audit at a gateway is how you avoid being one of those statistics — which is a large part of why roughly 30% of deployments are gateway-based.</p>
<h2 id="path-b-runtime-proxy-with-fastmcp-from_openapi--about-15-lines">Path B: Runtime proxy with FastMCP from_openapi() — about 15 lines</h2>
<p><a href="https://gofastmcp.com/integrations/openapi">FastMCP</a> (27,946 stars, 2,412 forks, Apache-2.0) is the main Python MCP framework, and <code>FastMCP.from_openapi()</code> builds an MCP server directly from an OpenAPI spec — a dict, a URL, or a live FastAPI app. Each route becomes a tool by default, at runtime, with no generated project to maintain.</p>
<p>The shape of it:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> httpx
</span></span><span style="display:flex;"><span><span style="color:#f92672">from</span> fastmcp <span style="color:#f92672">import</span> FastMCP
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>spec <span style="color:#f92672">=</span> httpx<span style="color:#f92672">.</span>get(<span style="color:#e6db74">&#34;https://api.example.com/openapi.json&#34;</span>)<span style="color:#f92672">.</span>json()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>client <span style="color:#f92672">=</span> httpx<span style="color:#f92672">.</span>AsyncClient(
</span></span><span style="display:flex;"><span>    base_url<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://api.example.com&#34;</span>,
</span></span><span style="display:flex;"><span>    headers<span style="color:#f92672">=</span>{<span style="color:#e6db74">&#34;Authorization&#34;</span>: <span style="color:#e6db74">&#34;Bearer YOUR_TOKEN&#34;</span>},
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>mcp <span style="color:#f92672">=</span> FastMCP<span style="color:#f92672">.</span>from_openapi(
</span></span><span style="display:flex;"><span>    openapi_spec<span style="color:#f92672">=</span>spec,
</span></span><span style="display:flex;"><span>    client<span style="color:#f92672">=</span>client,
</span></span><span style="display:flex;"><span>    name<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;Example API&#34;</span>,
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
</span></span><span style="display:flex;"><span>    mcp<span style="color:#f92672">.</span>run()  <span style="color:#75715e"># stdio by default; mcp.run(transport=&#34;http&#34;) for Streamable HTTP</span>
</span></span></code></pre></div><p>Authentication lives on the <code>httpx</code> client, so the underlying API is untouched. The control surface is <code>RouteMap</code>, which maps methods, URL patterns and tags to <code>TOOL</code>, <code>RESOURCE</code>, <code>RESOURCE_TEMPLATE</code> or <code>EXCLUDE</code>. A first-pass guard looks like this:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">from</span> fastmcp.server.openapi <span style="color:#f92672">import</span> RouteMap, MCPType
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>mcp <span style="color:#f92672">=</span> FastMCP<span style="color:#f92672">.</span>from_openapi(
</span></span><span style="display:flex;"><span>    openapi_spec<span style="color:#f92672">=</span>spec,
</span></span><span style="display:flex;"><span>    client<span style="color:#f92672">=</span>client,
</span></span><span style="display:flex;"><span>    route_maps<span style="color:#f92672">=</span>[
</span></span><span style="display:flex;"><span>        RouteMap(methods<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;*&#34;</span>, pattern<span style="color:#f92672">=</span><span style="color:#e6db74">r</span><span style="color:#e6db74">&#34;^/admin/.*&#34;</span>, mcp_type<span style="color:#f92672">=</span>MCPType<span style="color:#f92672">.</span>EXCLUDE),
</span></span><span style="display:flex;"><span>        RouteMap(methods<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;*&#34;</span>, tags<span style="color:#f92672">=</span>{<span style="color:#e6db74">&#34;internal&#34;</span>}, mcp_type<span style="color:#f92672">=</span>MCPType<span style="color:#f92672">.</span>EXCLUDE),
</span></span><span style="display:flex;"><span>        RouteMap(methods<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;GET&#34;</span>], pattern<span style="color:#f92672">=</span><span style="color:#e6db74">r</span><span style="color:#e6db74">&#34;^/users/\{[^/]+\}$&#34;</span>, mcp_type<span style="color:#f92672">=</span>MCPType<span style="color:#f92672">.</span>RESOURCE_TEMPLATE),
</span></span><span style="display:flex;"><span>        RouteMap(methods<span style="color:#f92672">=</span>[<span style="color:#e6db74">&#34;GET&#34;</span>], pattern<span style="color:#f92672">=</span><span style="color:#e6db74">r</span><span style="color:#e6db74">&#34;^/.*&#34;</span>, mcp_type<span style="color:#f92672">=</span>MCPType<span style="color:#f92672">.</span>RESOURCE),
</span></span><span style="display:flex;"><span>    ],
</span></span><span style="display:flex;"><span>)
</span></span></code></pre></div><p>A clean mapping to start from, which several guides converge on: <code>GET</code> without parameters → resource, <code>GET</code> with path parameters → resource template, <code>POST</code>/<code>PUT</code>/<code>DELETE</code> → tool, query parameters flattened into the tool input schema, and auth handled in server configuration rather than per call.</p>
<p>FastMCP&rsquo;s own documentation is blunt that an auto-converted server performs worse than a curated one and recommends it for bootstrapping and prototyping rather than mirroring the whole API to clients. Take that seriously — it is the framework telling you the truth about itself.</p>
<p><strong><code>mcp-openapi-proxy</code></strong> is the lowest-effort variant: <code>uvx mcp-openapi-proxy</code> reads <code>OPENAPI_SPEC_URL</code> at startup and dynamically exposes endpoints as tools. It supports a FastMCP &ldquo;simple mode&rdquo; (<code>OPENAPI_SIMPLE_MODE=true</code>) that exposes a fixed, hand-chosen tool set instead of every endpoint, plus JMESPath-based payload auth for APIs like Slack that want the token in the request body, and custom header names beyond <code>Bearer</code>. Its changelog is a useful catalogue of the failure modes auto-conversion produces: tool names truncated at <code>TOOL_NAME_MAX_LENGTH</code> collided and silently dropped tools, and array parameters emitted without an <code>items</code> schema were rejected by the OpenAI API.</p>
<h2 id="path-c-generate-a-standalone-server-with-openapi-mcp-generator">Path C: Generate a standalone server with openapi-mcp-generator</h2>
<p>If your team is TypeScript-first and you want a typed, versioned artifact rather than a runtime process, generate a project instead of proxying. <code>openapi-mcp-generator</code> produces an MCP server from a spec, with an <code>x-mcp.exclude</code> extension and programmatic <code>filterFn</code> / <code>excludeOperationIds</code> hooks so internal endpoints never reach the agent.</p>
<p>The trade is straightforward. You gain a reviewable codebase, typed handlers and the ability to hand-edit tool descriptions — which is exactly where curation actually happens. You take on regeneration, dependency churn and a deployable to keep alive. For a single internal API consumed by one team, a runtime proxy is usually less work. For a public API vendor shipping MCP support to many customers, the generated artifact is the right shape because it can be versioned alongside your SDKs and pinned by consumers.</p>
<h2 id="lock-it-down-auth-transport-and-tool-scoping">Lock it down: auth, transport, and tool scoping</h2>
<p><strong>Transport.</strong> The current spec revision (2026-07-28) defines two standard transports: stdio and Streamable HTTP, where each message is an HTTP POST to a single MCP endpoint and replies come back as JSON or a request-scoped SSE stream. Older remote SSE implementations are superseded and carry a deprecation window — if you have a remote SSE setup, plan the migration now rather than during an incident.</p>
<p><strong>Auth.</strong> OAuth 2.1 with PKCE is mandatory for remote servers, and almost nobody implements it. If your bridge terminates auth at a gateway, you fix that in one place for every tool instead of per server. If you self-host a runtime proxy, the credentials live in the proxy&rsquo;s environment: use a scoped service account or short-lived token, never a long-lived admin key, and never a hard-coded value in a config file that gets committed.</p>
<p><strong>Scoping.</strong> Decide which operations are callable by which agent. The mapping table above shows the mechanics; the judgment is that read operations and write operations do not deserve the same exposure. A bridge that gives an autonomous agent <code>DELETE /everything</code> because it happened to be in the spec is not a convenience — it is an incident waiting for a trigger.</p>
<h2 id="verify-with-mcp-inspector-before-your-agent-ever-sees-the-tools">Verify with MCP Inspector before your agent ever sees the tools</h2>
<p>Do not debug the bridge through your agent&rsquo;s production traces. Generate, then inspect.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># FastMCP ships a dev server + Inspector for exactly this</span>
</span></span><span style="display:flex;"><span>fastmcp dev server.py
</span></span></code></pre></div><p>MCP Inspector shows you the actual tool list and the actual JSON schemas — the two things most likely to be wrong. Check four things explicitly:</p>
<ol>
<li><strong>Every operation you intended is present.</strong> Silent drops from name truncation are real, and they are invisible until an agent says it cannot do something.</li>
<li><strong>Tool names are unique and readable.</strong> Collisions after a 56-character cap produce one surviving tool with a confusing name.</li>
<li><strong>Parameter schemas are valid.</strong> Array and object parameters without an <code>items</code> schema will be rejected by OpenAI-compatible tool-calling APIs at call time, not registration time.</li>
<li><strong>No internal endpoints leaked.</strong> Search the tool list for <code>admin</code>, <code>internal</code>, <code>debug</code>, <code>_test</code>, and anything with <code>DELETE</code> in it.</li>
</ol>
<p>This is the cheapest five minutes in the whole project. The alternative is discovering that the agent has been calling a staging endpoint for a week.</p>
<h2 id="curate-before-you-ship-why-200-auto-generated-tools-make-agents-dumber">Curate before you ship: why 200 auto-generated tools make agents dumber</h2>
<p>The FastMCP creator — the author of the most widely used OpenAPI-to-MCP converter — published <a href="https://www.jlowin.dev/blog/stop-converting-rest-apis-to-mcp">Stop Converting Your REST APIs to MCP</a> with the line that should be pinned above every bridge project: an API built for a human will poison your AI agent.</p>
<p>Two failure modes, both structural rather than cosmetic.</p>
<p><strong>Literal context cost.</strong> Every tool&rsquo;s name, description and parameter schema is re-processed on every reasoning step. A 200-tool server does not cost 200 tools&rsquo; worth of tokens once; it costs a slice of every step the agent takes. Context pollution turns agents into obsessive API librarians, and it gets worse with every tool you add.</p>
<p><strong>Atomicity as an anti-pattern.</strong> When each tool maps to one REST operation, the agent needs a full reasoning round trip per step. Composing &ldquo;find the customer, check their open orders, refund the eligible one&rdquo; becomes three or more model passes, each carrying the accumulated context forward.</p>
<p>The prescription is the same one the community has converged on independently: <strong>bootstrap from OpenAPI, find the real agent workflows, then collapse to 5–15 outcome-oriented tools.</strong> Trim response payloads so the agent gets the fields it reasons over rather than the full DTO. Write tool descriptions as instructions — what the tool does, when to reach for it, and what it returns — not as one-line summaries. Use <code>Tool.from_tool()</code> (or equivalent composition) to rename and merge operations into outcomes: one <code>refund_order</code> tool that internally makes the calls a human would.</p>
<p>Naming matters more than it looks. Follow <code>get_</code> / <code>list_</code> / <code>search_</code> / <code>create_</code> / <code>update_</code> / <code>delete_</code> plus <code>{action}_{resource}</code>. Avoid REST-path mirroring: <code>users_post</code> and <code>doStuff</code> tell a model nothing about when to use them.</p>
<p>There is a measured precedent for why this pays. In the code-mode research, a workflow that required 40 sequential tool calls and 262,159 characters of intermediate payload dropped to a single script and 903 characters — the model stopped being an API librarian and started being a reasoner. You get a fraction of that benefit from curation alone, without writing a single line of agent code.</p>
<h2 id="production-checklist-rate-limits-audit-logging-exclusions-version-pinning">Production checklist: rate limits, audit logging, exclusions, version pinning</h2>
<p>Before you call the bridge done, walk this list.</p>
<ul>
<li><strong>Exclude internal and admin routes explicitly.</strong> Tag-based exclusion where the spec supports it, path-pattern exclusion otherwise. Never rely on &ldquo;nothing sensitive is in the spec&rdquo; — specs drift.</li>
<li><strong>Rate-limit the MCP surface separately.</strong> An agent retry loop is a different traffic shape from a human UI, and it will find your ceiling.</li>
<li><strong>Log every tool invocation with the agent identity.</strong> Gateway logging earns its keep here: you get tool-level audit for free, and you will need it the first time an agent does something surprising.</li>
<li><strong>Pin the spec version and the proxy version.</strong> Auto-conversion against a live spec means a backend deploy can silently change your tool surface. Snapshot the spec, diff it in CI, and promote changes deliberately.</li>
<li><strong>Choose the transport deliberately.</strong> stdio for local single-user setups; Streamable HTTP for remote and shared. Have a written position on the legacy SSE deprecation.</li>
<li><strong>Re-run the Inspector check after every spec change.</strong> It is the only cheap test that catches silent drops.</li>
<li><strong>Decide who owns curation.</strong> If the answer is &ldquo;nobody,&rdquo; the tool count only grows, and the agent only gets slower.</li>
</ul>
<h2 id="faq">FAQ</h2>
<h3 id="what-is-an-mcp-proxy-in-one-sentence">What is an MCP proxy in one sentence?</h3>
<p>An MCP proxy reads your REST API&rsquo;s OpenAPI specification, translates each operation into an MCP tool, and forwards the resulting calls back to your existing HTTP endpoints — so an agent can use your API as MCP without any change to the API itself.</p>
<h3 id="do-i-need-to-modify-my-rest-api-to-add-mcp-support">Do I need to modify my REST API to add MCP support?</h3>
<p>No. That is the point of every tool covered here. Kong&rsquo;s plugin, Azure APIM, AWS API Gateway&rsquo;s MCP proxy, FastMCP&rsquo;s <code>from_openapi()</code> and <code>openapi-mcp-generator</code> all consume your existing spec and call your existing routes. Authentication is configured on the bridge&rsquo;s side, in headers or a gateway policy.</p>
<h3 id="which-is-better-for-a-rest-api-to-mcp-bridge--a-managed-gateway-or-a-self-hosted-proxy">Which is better for a REST API to MCP bridge — a managed gateway or a self-hosted proxy?</h3>
<p>Use a managed gateway (Kong, Azure APIM, AWS API Gateway) when you already run one and want auth, rate limiting and audit inherited for free — roughly 30% of MCP deployments are gateway-based, and the security statistics argue for it. Use a self-hosted runtime proxy like FastMCP when you need fine-grained curation, route-level transforms, or freedom from enterprise tier licensing. A large share of teams end up hybrid: gateway for policy, a curated proxy for the tool surface.</p>
<h3 id="is-mcpo-a-rest-to-mcp-bridge">Is mcpo a REST-to-MCP bridge?</h3>
<p>No — it is the opposite direction. <code>mcpo</code> exposes an MCP server as an OpenAPI/REST HTTP server so that OpenAPI-only clients can call it. If your goal is to give an agent access to a REST API, <code>mcpo</code> is not the tool, despite appearing in many &ldquo;REST to MCP&rdquo; roundups.</p>
<h3 id="why-does-my-auto-generated-mcp-server-make-the-agent-slower">Why does my auto-generated MCP server make the agent slower?</h3>
<p>Because every tool&rsquo;s name, description and parameter schema is re-processed on every reasoning step, and because one tool per REST operation forces a full model round trip per step. The converter&rsquo;s own author recommends against mass conversion: auto-convert to discover the surface, then collapse it to 5–15 outcome-oriented tools with descriptive names and trimmed response payloads before you let an agent near it.</p>
]]></content:encoded></item></channel></rss>