// ============================================================================
// Azure APIM MCP Demo - Main Infrastructure (App Service Version)
// ============================================================================
// This Bicep template deploys:
// - Azure App Service (Express.js API backend)
// - Azure API Management (MCP Server gateway)
// - Application Insights for monitoring
// ============================================================================
@description('Azure region for all resources')
param location string = resourceGroup().location
@description('Name prefix for all resources')
param namePrefix string = 'apimmcp'
@description('Environment (dev, staging, prod)')
@allowed(['dev', 'staging', 'prod'])
param environment string = 'dev'
@description('Email address for APIM publisher')
param apimPublisherEmail string
// Resource names
var appServicePlanName = '${namePrefix}-plan-${environment}'
var webAppName = '${namePrefix}-api-${environment}'
var apimName = '${namePrefix}-apim-${environment}'
var appInsightsName = '${namePrefix}-insights-${environment}'
var logAnalyticsName = '${namePrefix}-logs-${environment}'
// Tags
var tags = {
environment: environment
project: 'apim-mcp-demo'
deployedBy: 'bicep'
}
// ============================================================================
// Log Analytics Workspace
// ============================================================================
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
name: logAnalyticsName
location: location
tags: tags
properties: {
sku: {
name: 'PerGB2018'
}
retentionInDays: 30
}
}
// ============================================================================
// Application Insights
// ============================================================================
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
name: appInsightsName
location: location
tags: tags
kind: 'web'
properties: {
Application_Type: 'web'
WorkspaceResourceId: logAnalytics.id
}
}
// ============================================================================
// App Service Plan
// ============================================================================
resource appServicePlan 'Microsoft.Web/serverfarms@2023-01-01' = {
name: appServicePlanName
location: location
tags: tags
sku: {
name: 'B1'
tier: 'Basic'
capacity: 1
}
kind: 'linux'
properties: {
reserved: true
}
}
// ============================================================================
// Web App (API Backend)
// ============================================================================
resource webApp 'Microsoft.Web/sites@2023-01-01' = {
name: webAppName
location: location
tags: tags
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
siteConfig: {
linuxFxVersion: 'NODE|20-lts'
alwaysOn: true
appSettings: [
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: appInsights.properties.ConnectionString
}
{
name: 'NODE_ENV'
value: 'production'
}
]
}
}
}
// ============================================================================
// API Management
// ============================================================================
resource apim 'Microsoft.ApiManagement/service@2023-03-01-preview' = {
name: apimName
location: location
tags: tags
sku: {
name: 'Developer'
capacity: 1
}
properties: {
publisherEmail: apimPublisherEmail
publisherName: 'APIM MCP Demo'
}
}
// APIM Named Values
resource backendUrlNamedValue 'Microsoft.ApiManagement/service/namedValues@2023-03-01-preview' = {
parent: apim
name: 'BackendApiUrl'
properties: {
displayName: 'BackendApiUrl'
value: 'https://${webApp.properties.defaultHostName}'
secret: false
}
}
// APIM API - MCP Server
resource mcpApi 'Microsoft.ApiManagement/service/apis@2023-03-01-preview' = {
parent: apim
name: 'mcp-server'
properties: {
displayName: 'MCP Server'
description: 'Model Context Protocol Server API'
subscriptionRequired: true
path: 'mcp'
protocols: ['https']
serviceUrl: 'https://${webApp.properties.defaultHostName}/api/mcp'
}
}
// MCP Operation
resource mcpOperation 'Microsoft.ApiManagement/service/apis/operations@2023-03-01-preview' = {
parent: mcpApi
name: 'mcp-endpoint'
properties: {
displayName: 'MCP Endpoint'
method: 'POST'
urlTemplate: '/'
description: 'Main MCP JSON-RPC endpoint'
}
}
// MCP API Policy - using default backend forwarding
resource mcpApiPolicy 'Microsoft.ApiManagement/service/apis/policies@2023-03-01-preview' = {
parent: mcpApi
name: 'policy'
properties: {
format: 'rawxml'
value: '<policies><inbound><base /></inbound><backend><base /></backend><outbound><base /></outbound><on-error><base /></on-error></policies>'
}
}
// APIM Product
resource mcpProduct 'Microsoft.ApiManagement/service/products@2023-03-01-preview' = {
parent: apim
name: 'mcp-product'
properties: {
displayName: 'MCP Server Access'
description: 'Access to MCP Server API'
subscriptionRequired: true
approvalRequired: false
state: 'published'
}
}
// Link API to Product
resource productApi 'Microsoft.ApiManagement/service/products/apis@2023-03-01-preview' = {
parent: mcpProduct
name: 'mcp-server'
dependsOn: [mcpApi]
}
// Subscription for Product
resource mcpSubscription 'Microsoft.ApiManagement/service/subscriptions@2023-03-01-preview' = {
parent: apim
name: 'mcp-subscription'
properties: {
displayName: 'MCP Subscription'
scope: '/products/${mcpProduct.id}'
state: 'active'
}
dependsOn: [mcpProduct]
}
// ============================================================================
// Outputs
// ============================================================================
output webAppUrl string = 'https://${webApp.properties.defaultHostName}'
output apimGatewayUrl string = apim.properties.gatewayUrl
output mcpEndpoint string = '${apim.properties.gatewayUrl}/mcp'
output apimPortalUrl string = apim.properties.developerPortalUrl
output webAppName string = webApp.name
output apimName string = apim.name