Azure APIM MCP: The Good, The Bad, The Ugly
AI agents need APIs. But not just any APIs—they need discoverable, secure, governed APIs that won't accidentally delete your production database when an LLM hallucinates.
Enter the Model Context Protocol (MCP)—a standardized way to expose APIs as tools that AI agents can discover and invoke safely. And Azure API Management (APIM) now has preview support for it.
Sounds great, right?
Well... sort of. I spent the last few months test driving this for a banking platform, and let me tell you: the Azure Portal screenshots don't tell the whole story.
This is Part 1 of a 4-part series on building production-ready MCP servers on Azure APIM. I'll share what I learned the hard way, so you don't have to.
What is MCP? (And Why Should You Care?)
The Model Context Protocol is OpenAPI for AI agents. It gives agents:
- Tool Discovery: Agents ask "what can I do?" and get structured responses
- Safe Execution: Schemas prevent garbage-in-garbage-out
- Context Awareness: Agents know what tools exist and when to use them
Instead of throwing API endpoints at LLMs and hoping for the best, you give them curated tools with schemas, descriptions, and built-in safety.
Why APIM?
If you already have APIM, why build a separate MCP server? Your API gateway already does:
- Authentication & authorization
- Rate limiting & throttling
- Logging & monitoring
- Policy enforcement
- Multi-environment management
Why add another service to manage?
Architecture Overview
The Good: What Actually Works
APIM V2 Standard has preview MCP support. When it works, it's solid:
1. Native MCP Server Functionality
Expose APIs as MCP Tools with a few clicks (or REST API calls):
# Discover available tools
curl -X POST https://your-apim.azure-api.net/your-api-mcp/mcp \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: YOUR_KEY" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "getCustomer",
"description": "Retrieve customer information",
"inputSchema": {
"type": "object",
"properties": {
"id": {"type": "string"}
},
"required": ["id"]
}
}
]
}
}
2. JSON-RPC 2.0 Protocol
Standard /tools/list and /tools/call endpoints that work with any MCP client:
# Invoke a tool
curl -X POST https://your-apim.azure-api.net/your-api-mcp/mcp \
-H "Content-Type: application/json" \
-H "Ocp-Apim-Subscription-Key: YOUR_KEY" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "getCustomer",
"arguments": {"id": "123"}
},
"id": 2
}'
3. APIM Policy Framework
You get the full power of APIM policies:
- Rate limiting
- Request/response transformation
- Header manipulation
- Custom validation
- Backend routing
This is huge—you can apply enterprise-grade policies to your MCP endpoints.
4. Zero Additional Infrastructure
If you already have APIM (and most enterprises do), you're paying $0 extra for MCP capabilities. No new services to deploy, manage, or monitor.
The Bad: What's Frustrating
Now for the frustrating parts:
1. No Infrastructure as Code Support
This is the biggest problem. You cannot:
- Define MCP servers in ARM templates
- Manage them with Terraform
- Use Azure Service Operator (ASO)
- Deploy via standard GitOps pipelines
You're stuck with manual Azure Portal configuration or custom REST API automation.
In 2025. For an enterprise platform.
We've provided this feedback to Microsoft, and they've acknowledged it for their roadmap. No ETA yet, but it's on their radar. I'll keep publishing new parts of the series when there are changes.
2. Limited Documentation
Microsoft's docs are... sparse. Key questions like:
- How does
context.Productwork in MCP policies? (Spoiler: it doesn't) - What headers are preserved through MCP translation? (Some, not all)
- How do you handle user context propagation? (Figure it out yourself)
The docs show the happy path, but not the edge cases you'll hit in production.
3. Preview Tier Limitations
It's preview, which means:
- Features may change without notice
- Limited support channels
- No SLA guarantees
- Breaking changes possible
For a banking platform, that's... uncomfortable.
The Ugly: Critical Issues You Must Fix
These are the deal-breakers if you don't work around them:
1. The /tools/list Security Hole
The /tools/list endpoint bypasses APIM authentication.
That means anyone can enumerate your available tools without a subscription key.
# This works without any authentication :-/
curl -X POST https://your-apim.azure-api.net/your-api-mcp/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
You must manually add subscription key validation in your MCP server policy. (I'll show you how in Part 2)
2. context.Product is Always Null
APIM lets you organize APIs into Products (Basic, Premium, Enterprise tiers). This is fundamental to APIM's access control model.
It doesn't work for MCP servers. context.Product is always null.
You can't do product-based authorization. You're stuck with subscription-level whitelisting.
3. HTTP Status Code Masking
Backend returns HTTP 500? APIM gives you HTTP 200 with an error in the JSON body.
This breaks every standard HTTP error handling pattern:
# Direct API call
curl https://apim.azure-api.net/api/posts/999
# HTTP 500
# Same API via MCP
curl https://apim.azure-api.net/api-mcp/mcp \
-d '{"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "getPost", "arguments": {"id": "999"}}, "id": 1}'
# HTTP 200 with error in body... Say what now?
Your monitoring tools won't detect errors. Your client libraries won't trigger error handlers.
4. Response Body Access Hangs Requests
If you try to access context.Response.Body in your policies for audit logging, your requests will hang indefinitely.
<!-- This will kill your performance -->
<set-variable name="responseBody"
value="@(context.Response.Body.As<string>())" />
You must use workarounds (Content-Length headers, metadata only).
Should You Use Azure APIM for MCP?
Use it if:
- You already have APIM infrastructure
- You need enterprise-grade security and compliance
- You're willing to work around preview quirks
- You can accept manual configuration (for now)
- You have time to build custom automation
Don't use it if:
- You need full IaC support immediately
- You can't tolerate preview-tier instability
- You require perfect HTTP status code semantics
- You need product-based access control
- You can't invest time in workarounds
What's Next in This Series
In the remaining parts, I'll show you exactly how to work around these issues:
-
Part 2: Security - How to fix the
/tools/listhole, implement proper authentication, and handle user context propagation - Part 3: Logging & Monitoring - Audit logging without breaking performance, distributed tracing, and error handling
- Part 4: GitOps & Automation - Custom REST API automation, Python scripts for OpenAPI processing, and deployment pipelines
Bottom Line
APIM MCP works, but it's preview software with sharp edges.
With the right workarounds (which I'll share in this series), you can build production-ready MCP servers. You'll just be writing custom policies and automation scripts to paper over the gaps.
If you're already invested in Azure and APIM, it's worth it. You get enterprise-grade infrastructure without standing up new services.
Just don't expect it to work perfectly out of the box.
Next: Part 2 - Securing Azure APIM MCP Servers in Production (coming next week)
I'm a Product Architect at Backbase, where I design cloud-native banking and integration platforms. The patterns in this series come from real production implementations at enterprise scale. Views are my own.
Have you tried Azure APIM MCP? What's your experience been? Drop a comment on my Linkedin post or Dev.To blog—I'd love to hear your war stories.
Connect with me on LinkedIn for more Azure and platform engineering content.
Top comments (0)