← Back to Blog
AI Architecture

MCP-as-API-Wrapper: Inverting the MCP Pattern

What if your MCP server had just 3 tools — and the entire API evolved behind it?

Scott Alter • March 14, 2026 • 8 min read

We've been building and operating MCP (Model Context Protocol) servers at Guru Cloud & AI for months. As our tooling grew to dozens of specialized tools, a pattern emerged that felt increasingly wrong: every time the underlying API changed, every MCP client had to reconnect.

So we asked a simple question: What if we inverted the pattern?

The Problem with Traditional MCP

In the standard MCP pattern, each tool is a capability. Want to list users? That's a tool. Want to create a user? Another tool. Search? Another tool. Every new feature means a new tool definition, and API changes mean MCP server updates that force all connected clients to reconnect.

Traditional MCP API-Wrapper MCP
Tools One per capability (10-50+) Exactly 3 (never changes)
API changes Require server update + reconnect Transparent, zero reconnects
Auth Tied to MCP session Independent API-level auth
Scalability Tool list grows with API Stable regardless of API size

The Inverted Pattern: 3 Tools, Full API

The MCP-as-API-Wrapper pattern reduces the MCP server to a thin discovery and authentication layer with exactly three tools:

getAPIEndpoints
Returns the current API surface — base URL, available paths, supported methods, and version. Call this to understand what the API can do.
getAuthToken
Authenticates a client and returns a scoped Bearer token with permissions, TTL, and rate limits. The token is used for direct API calls, independent of the MCP session.
getDocumentation
Returns a URL to download the full API documentation (OpenAPI, Markdown, or HTML). Always reflects the latest deployed version.

These three tools never change. The entire API surface — hundreds of endpoints if needed — evolves independently behind them.

Architecture

Client Agent ───MCP Protocol──▶ Thin MCP Server (3 tools) │ │ │ Direct API Calls │ Discovery + Auth │ (Bearer Token) │ ▼ ▼ API Server ◀──── deploys ──── Backend Agent (Full API) (API Manager) │ Message Queue (Agent-to-Agent)

The flow is straightforward:

1
Client connects to MCP server (once, stays connected indefinitely)
2
Calls getAuthToken — receives a scoped Bearer token
3
Calls getDocumentation — fetches full API docs
4
Bypasses MCP entirely — makes direct HTTP calls to the API with the Bearer token

The key insight: MCP is only used for bootstrapping. Once the client has a token and docs, it talks directly to the API. This means the MCP layer is incredibly stable — it doesn't need to change when the API adds or modifies endpoints.

Decoupled Authentication

One of the most powerful aspects of this pattern is that authentication lives at the API layer, not the MCP layer. The MCP session handles basic connectivity. But the real security — 2FA, OAuth, RBAC, certificate pinning, rate limiting — all happens through the API's auth service.

Why does this matter?

// Token issued by getAuthToken
{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "Bearer",
  "scopes": ["read", "write"],
  "expires_at": "2026-03-15T00:00:00Z",
  "api_base_url": "https://api.example.com/v2",
  "rate_limit": {
    "requests_per_minute": 100,
    "requests_per_hour": 1000
  }
}

Dynamic API Evolution

This is where it gets really interesting. The API lives in a git repository managed by a backend agent. Client agents can request API changes through a message queue, and the backend agent implements them autonomously.

1
Client agent needs a capability the API doesn't have
2
Sends request via message queue: "Can you add a /users/{id}/activity endpoint?"
3
Backend agent picks up the request, evaluates feasibility
4
Implements the change, runs tests, deploys
5
Replies: "Done. Deployed as v1.1.0."
6
Client calls getDocumentation() — gets updated docs with new endpoint
7
Client immediately uses the new endpoint — zero reconnects

This creates a living API. Two agents negotiate capabilities at runtime. The client expresses what it needs; the server evolves to meet it. The MCP layer doesn't change throughout this entire process.

Code: It's Real

This isn't just a concept — it's a working, tested implementation. The MCP server is roughly 120 lines of Python:

from mcp.server import Server
from mcp.types import TextContent, Tool

server = Server("api-wrapper")

@server.list_tools()
async def list_tools() -> list[Tool]:
    return [
        Tool(name="getAPIEndpoints", ...),
        Tool(name="getAuthToken", ...),
        Tool(name="getDocumentation", ...),
    ]

@server.call_tool()
async def call_tool(name, arguments):
    if name == "getAPIEndpoints":
        return registry.get_all()       # reads from endpoint registry
    elif name == "getAuthToken":
        return token_service.issue(...)  # delegates to auth service
    elif name == "getDocumentation":
        return docs_url(...)             # returns URL to latest docs

The full project includes:

View on GitHub →

When to Use This Pattern

The MCP-as-API-Wrapper pattern is ideal when:

The traditional MCP pattern still works well for small, stable toolsets where each tool maps to a specific, well-defined action. But as your system grows, the inverted pattern offers a path to scalability without the reconnection overhead.

What's Next

We're actively developing the backend agent component — the piece that monitors the message queue, implements API changes, and deploys them. This is the most architecturally interesting part: an AI agent that manages a codebase and responds to other agents' needs in real time.

We're also exploring how this pattern could integrate with existing API gateways and service meshes, bringing the "discover, authenticate, call directly" flow to production microservice architectures.

The code is open source. We'd love to hear how you think about MCP server design and agent-to-agent integration. Check out the repo, run the example, and let us know what you think.