Azure APIM + MCP Server Demo
This project demonstrates how to expose backend APIs through Azure API Management (APIM) as a Model Context Protocol (MCP) Server, enabling AI assistants and tools to interact with your APIs using the standardized MCP protocol.
🏗️ Architecture
┌──────────────────┐ ┌─────────────────────────┐ ┌─────────────────────────┐
│ MCP Client │────▶│ Azure API Management │────▶│ Azure App Service │
│ (AI Assistant) │ │ (Gateway) │ │ (Express.js API) │
└──────────────────┘ └─────────────────────────┘ └─────────────────────────┘
│ │ │
│ MCP Protocol │ Subscription Key │ REST API
│ (JSON-RPC 2.0) │ Rate Limiting │ Products/Orders
│ │ Monitoring │
└─────────────────────────┴──────────────────────────────┘
📦 Components
Backend API (backend-api/)
- Express.js application with TypeScript
- REST API endpoints for products and orders
- MCP JSON-RPC endpoint handler
- 5 MCP tools:
get_products- List all products in the catalogget_product_by_id- Get product details by IDsearch_products- Search products by query stringget_orders- List all orderscreate_order- Create a new order
Infrastructure (infrastructure/)
- Bicep templates for Azure deployment
- Azure App Service (Linux, Node.js 20 LTS, B1 Basic)
- Azure API Management (Developer SKU)
- Application Insights for monitoring
- Log Analytics workspace
🌐 Endpoints
| Endpoint | Description |
|---|---|
https://apimmcp-api-dev.azurewebsites.net/ | Backend root |
https://apimmcp-api-dev.azurewebsites.net/api/health | Health check |
https://apimmcp-api-dev.azurewebsites.net/api/products | Products REST API |
https://apimmcp-api-dev.azurewebsites.net/api/orders | Orders REST API |
https://apimmcp-api-dev.azurewebsites.net/api/mcp | MCP endpoint (direct) |
https://apimmcp-apim-dev.azure-api.net/mcp | MCP endpoint (via APIM) ⭐ |
📡 MCP Protocol
The server implements the Model Context Protocol (version 2024-11-05):
Initialize
{
"jsonrpc": "2.0",
"method": "initialize",
"id": 1,
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "client", "version": "1.0.0" }
}
}
List Tools
{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 2
}
Call Tool
{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 3,
"params": {
"name": "get_products"
}
}
Example: Search Products
{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 4,
"params": {
"name": "search_products",
"arguments": { "query": "smart" }
}
}
Example: Create Order
{
"jsonrpc": "2.0",
"method": "tools/call",
"id": 5,
"params": {
"name": "create_order",
"arguments": { "productId": "prod-001", "quantity": 2 }
}
}
🚀 Deployment
Prerequisites
- Azure CLI installed and logged in
- Azure subscription
- Node.js 18+ installed locally
1. Create Resource Group
az group create --name apim-mcp-demo-rg --location eastus
2. Deploy Infrastructure
az deployment group create `
--resource-group apim-mcp-demo-rg `
--template-file ./infrastructure/main-appservice.bicep `
--parameters location=eastus namePrefix=apimmcp environment=dev apimPublisherEmail="your-email@example.com"
⚠️ Note: APIM provisioning takes 15-30 minutes on first deployment.
3. Build Backend API
cd backend-api
npm install
npm run build
4. Deploy Backend API
Compress-Archive -Path "dist\*", "package.json", "web.config", "node_modules" -DestinationPath "deploy.zip" -Force
az webapp deploy --resource-group apim-mcp-demo-rg --name apimmcp-api-dev --src-path deploy.zip --type zip
5. Get APIM Subscription Key
az rest --method post `
--uri "https://management.azure.com/subscriptions/{subscription-id}/resourceGroups/apim-mcp-demo-rg/providers/Microsoft.ApiManagement/service/apimmcp-apim-dev/subscriptions/mcp-subscription/listSecrets?api-version=2022-08-01" `
--query "primaryKey" -o tsv
🧪 Testing
Run Test Script
.\test-mcp.ps1
Expected Output
========================================
MCP Server Test Suite
========================================
Endpoint: https://apimmcp-apim-dev.azure-api.net/mcp
1. Testing initialize...
Server: azure-product-catalog-server v1.0.0
Protocol: 2024-11-05
2. Testing tools/list...
Found 5 tools:
- get_products: Retrieve a list of all products in the catalog
- get_product_by_id: Get details of a specific product by its ID
...
3. Testing tools/call (get_products)...
Found 8 products:
- Widget Pro: $29.99
- Gadget Plus: $49.99
...
Manual Testing
$headers = @{
"Ocp-Apim-Subscription-Key" = "YOUR_SUBSCRIPTION_KEY"
"Content-Type" = "application/json"
}
$body = '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
Invoke-RestMethod -Uri "https://apimmcp-apim-dev.azure-api.net/mcp" -Method POST -Headers $headers -Body $body
🛠️ Development
Local Development
cd backend-api
npm install
npm run dev
The server will start on http://localhost:3000.
Project Structure
APIM-MCP/
├── backend-api/
│ ├── src/
│ │ ├── index.ts # Express server entry
│ │ ├── routes.ts # REST API routes
│ │ ├── mcp.ts # MCP endpoint handler
│ │ └── data.ts # Mock data store
│ ├── dist/ # Compiled JavaScript
│ ├── package.json
│ ├── tsconfig.json
│ └── web.config # IIS configuration for Azure
├── infrastructure/
│ └── main-appservice.bicep # Azure resources
├── test-mcp.ps1 # Test script
└── README.md
🔧 Configuration
APIM Settings
- Subscription Required: Yes
- Rate Limiting: Configurable via APIM policies
- Authentication: Subscription key header (
Ocp-Apim-Subscription-Key)
App Service Settings
- SKU: B1 Basic (Linux)
- Node Version: 20 LTS
- Startup Command:
node index.js
📊 Monitoring
- Application Insights integrated with both App Service and APIM
- Access logs in Log Analytics workspace
- Health endpoint available at
/api/health
🔗 Resources
- Model Context Protocol Specification
- Azure API Management Documentation
- Azure App Service Documentation
📄 License
MIT
