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:
These three tools never change. The entire API surface — hundreds of endpoints if needed — evolves independently behind them.
Architecture
The flow is straightforward:
getAuthToken — receives a scoped Bearer tokengetDocumentation — fetches full API docsThe 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?
- Security isolation — Even if the MCP layer is compromised, API auth is independent
- Enterprise auth — Support complex auth flows without changing the MCP protocol
- Token scoping — Each client gets only the permissions it needs
- Audit trails — API-level auth gives you full logging independent of MCP
// 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.
/users/{id}/activity endpoint?"getDocumentation() — gets updated docs with new endpointThis 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:
- JWT token service with scoped permissions and TTL
- Endpoint registry that auto-refreshes from OpenAPI specs
- Message queue for agent-to-agent communication
- Example FastAPI app showing a wrapped API
- 40 tests (unit + integration) all passing
- Runnable example that demonstrates the full 5-phase flow
When to Use This Pattern
The MCP-as-API-Wrapper pattern is ideal when:
- Your API is large or rapidly evolving — you don't want to update MCP tool definitions every time
- You need enterprise-grade security that goes beyond what MCP session auth provides
- You want agents to negotiate capabilities at runtime, not at deployment time
- You're building multi-agent systems where backend agents manage services autonomously
- You value protocol stability — the MCP spec can change without affecting your API capabilities
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.