Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo, aprenderá a crear y administrar servidores MCP en Azure API Management mediante la API REST, plantillas de ARM, Bicep, el CLI de Azure y Terraform.
Important
Las características de administración del servidor MCP que se describen en este artículo requieren la versión 2025-09-01-preview o posterior de la API REST de API Management. Incluye esta versión en todas las solicitudes.
Para obtener información sobre las funcionalidades del servidor MCP, consulte Acerca de los servidores MCP en Azure API Management.
Prerrequisitos
Tu identidad debe tener permisos para leer el servicio de API Management y crear o actualizar API, herramientas de API, directivas de API y vinculaciones de API de producto. En el caso de Terraform, la identidad también necesita acceso de lectura al servicio de API Management existente que utiliza la fuente de datos
azurerm_api_management.Para la CLI de Azure:
Use el entorno de Bash en Azure Cloud Shell. Para obtener más información, consulte Introducción a Azure Cloud Shell.
Si prefieres ejecutar comandos de referencia CLI localmente, instala la CLI de Azure. Si estás utilizando Windows o macOS, considera ejecutar CLI de Azure en un contenedor Docker. Para obtener más información, consulte Cómo ejecutar el CLI de Azure en un contenedor de Docker.
Si estás utilizando una instalación local, inicia sesión en CLI de Azure utilizando el comando az login. Siga los pasos que se muestran en el terminal para completar el proceso de autenticación. Para ver otras opciones de inicio de sesión, consulte Autenticación en Azure mediante la CLI de Azure.
Cuando se le solicite, instale la extensión CLI de Azure en el primer uso. Para obtener más información sobre las extensiones, consulte Uso y administración de extensiones con la CLI de Azure.
Ejecute az version para ver la versión y las bibliotecas dependientes que están instaladas. Para actualizar a la versión más reciente, ejecute az upgrade.
Para Azure PowerShell:
- Si decide usar Azure PowerShell localmente:
- Instale la versión más reciente del módulo Az PowerShell.
- Conéctese a su cuenta de Azure mediante el cmdlet Connect-AzAccount.
- Si decide usar Azure Cloud Shell:
- Consulte Información general de Azure Cloud Shell para obtener más información.
- Si decide usar Azure PowerShell localmente:
Para Terraform: Instalación y configuración de Terraform
Modelo de recursos
Azure Resource Manager representa servidores MCP de la siguiente manera:
Servidor de paso: Apunta a un backend de MCP externo existente. El recurso del servidor MCP declara la URL del backend y el tipo de transporte (HTTP de transmisión o SSE).
Herramienta: Un subrecurso de la herramienta de API de un servidor MCP. Puede administrar recursos de herramientas de forma segura desde CI/CD. Puede agregar, cambiar el nombre o quitar herramientas sin volver a crear el servidor MCP.
Directivas: Al igual que con las API normales, adjunte la directiva de API o los subrecursos de directiva a un servidor MCP.
Productos: El enlace de productos es una relación secundaria independiente (
products/{productId}/apis/{mcpServerId}), lo que permite la implementación independiente y el enlace de varios productos.
Ejemplos de REST
Para mayor claridad, los ejemplos siguientes muestran cuerpos de respuesta abreviados. Para consultar los esquemas de respuesta completos, consulte la referencia de la API REST de API Management.
Al añadir el encabezado If-Match: * en los ejemplos de llamadas PUT y DELETE, las solicitudes se vuelven idempotentes. Este encabezado se aplica tanto si el recurso ya existe como si no, y esta es la práctica recomendada para las canalizaciones de CI/CD.
Antes de empezar
Establezca las siguientes variables antes de ejecutar cualquier ejemplo. Todos los ejemplos de esta sección hacen referencia a estas variables.
SUBSCRIPTION_ID="<your-subscription-id>"
RESOURCE_GROUP="<your-resource-group>"
APIM_NAME="<your-api-management-service-name>"
API_VERSION="2025-09-01-preview"
BASE_URL="https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ApiManagement/service/${APIM_NAME}"
TOKEN=$(az account get-access-token --resource https://management.azure.com --query accessToken -o tsv)
Enumerar servidores MCP
Devuelve todas las API de la instancia filtradas por el tipo mcp. Utiliza los parámetros de consulta $top y $skip para navegar por conjuntos de resultados de gran tamaño.
Referencia: Api - List By Service
curl -sG "${BASE_URL}/apis" \
--data-urlencode "api-version=${API_VERSION}" \
--data-urlencode "\$filter=type eq 'mcp'" \
-H "Authorization: Bearer ${TOKEN}"
Respuesta (200 OK)
{
"count": 1,
"value": [
{
"id": "/subscriptions/.../apis/my-mcp-server",
"name": "my-mcp-server",
"type": "Microsoft.ApiManagement/service/apis",
"properties": {
"type": "mcp",
"displayName": "My MCP Server",
"path": "my-mcp",
"protocols": [ "https" ]
}
}
]
}
Error común:401 Unauthorized. El token de portador ha expirado. Vuelva a ejecutar el comando de adquisición de tokens.
Obtención de un único servidor MCP
Referencia: Api - Get
MCP_SERVER_ID="my-mcp-server"
curl -s "${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}"
Respuesta (200 OK)
{
"id": "/subscriptions/.../apis/my-mcp-server",
"name": "my-mcp-server",
"type": "Microsoft.ApiManagement/service/apis",
"properties": {
"type": "mcp",
"displayName": "My MCP Server",
"path": "my-mcp",
"protocols": [ "https" ],
"serviceUrl": "https://api.contoso.com"
}
}
Error común:404 Not Found. Confirme que mcpServerId coincide con el name campo devuelto por la operación List.
Creación de un servidor MCP respaldado por la API REST
Crea el recurso del servidor MCP. Después de la creación, agregue herramientas a ella individualmente mediante la operación Agregar o actualizar una herramienta . Cada herramienta hace referencia a una operación específica en un recurso de API REST de respaldo.
Referencia: Api: Creación o actualización
MCP_SERVER_ID="my-mcp-server"
curl -s -X PUT \
"${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "If-Match: *" \
-d '{
"properties": {
"type": "mcp",
"path": "my-mcp",
"displayName": "My MCP Server",
"description": "MCP server backed by a REST API",
"protocols": ["https"]
}
}'
Respuesta (201 creado)
{
"id": "/subscriptions/.../apis/my-mcp-server",
"name": "my-mcp-server",
"type": "Microsoft.ApiManagement/service/apis",
"properties": {
"type": "mcp",
"displayName": "My MCP Server",
"path": "my-mcp",
"protocols": ["https"],
"provisioningState": "InProgress"
}
}
Note
Se espera provisioningState: InProgress para operaciones PUT asíncronas. Consulta la URL devuelta en el encabezado de respuesta Azure-AsyncOperation para confirmar la finalización.
Error común:400 Bad Request. Asegúrese de que type sea "mcp" y que path sea único dentro de la instancia del servicio.
Crea un servidor MCP de tipo passthrough
Un servidor de paso a través reenvía todas las solicitudes MCP directamente a un back-end de MCP externo. Establezca mcpProperties.transportType para que coincida con el transporte que implementa el back-end.
Antes de crear un servidor de acceso directo, confirme que el back-end es accesible desde la puerta de enlace de API Management e implementa el transporte MCP seleccionado en las rutas de acceso del punto de conexión que configure. Si el back-end requiere autenticación, configure las credenciales o encabezados necesarios mediante directivas de API Management o configuración de back-end.
Referencia: Api: Creación o actualización
Transporte HTTP que se puede transmitir
Utilice streamable para los backends que implementan la especificación actual de transporte HTTP en streaming de MCP. Se requiere una definición de punto de conexión único.
MCP_SERVER_ID="my-mcp-passthrough"
curl -s -X PUT \
"${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "If-Match: *" \
-d '{
"properties": {
"type": "mcp",
"path": "my-mcp-passthrough",
"displayName": "My Passthrough MCP Server",
"description": "Passthrough MCP server using streamable HTTP transport",
"protocols": ["https"],
"serviceUrl": "https://mcp-backend.contoso.com",
"mcpProperties": {
"transportType": "streamable",
"endpoints": [
{ "name": "message", "uriTemplate": "/mcp" }
]
}
}
}'
Respuesta (201 creado)
{
"id": "/subscriptions/.../apis/my-mcp-passthrough",
"name": "my-mcp-passthrough",
"type": "Microsoft.ApiManagement/service/apis",
"properties": {
"type": "mcp",
"displayName": "My Passthrough MCP Server",
"path": "my-mcp-passthrough",
"protocols": ["https"],
"serviceUrl": "https://mcp-backend.contoso.com",
"provisioningState": "InProgress",
"mcpProperties": {
"transportType": "streamable",
"endpoints": [ { "name": "message", "uriTemplate": "/mcp" } ]
}
}
}
Transporte SSE
Utilice sse para los backends que implementan el transporte HTTP+SSE (eventos enviados por el servidor). Defina dos puntos de conexión: uno para el flujo de eventos SSE y otro para el canal de mensajes.
MCP_SERVER_ID="my-mcp-sse"
curl -s -X PUT \
"${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "If-Match: *" \
-d '{
"properties": {
"type": "mcp",
"path": "my-mcp-sse",
"displayName": "My SSE MCP Server",
"description": "Passthrough MCP server using SSE transport",
"protocols": ["https"],
"serviceUrl": "https://mcp-backend.contoso.com",
"mcpProperties": {
"transportType": "sse",
"endpoints": [
{ "name": "sse", "uriTemplate": "/sse" },
{ "name": "message", "uriTemplate": "/messages" }
]
}
}
}'
Errores comunes:
-
400 Bad Request. No válidomcpProperties. CompruebetransportTypeque esstreamableossey cadauriTemplatecomienza por/. -
400 Bad Request. El transporte SSE requiere exactamente dos puntos de conexión (sseymessage). El transporte streamable requiere uno (message).
Agregar o actualizar una herramienta
Agrega una nueva herramienta a un servidor MCP respaldado por la API REST o actualiza uno existente. El operationId campo vincula la herramienta a una operación específica en un recurso de API REST de respaldo. Puede agregar, actualizar o quitar herramientas de forma independiente sin volver a crear el servidor primario.
Referencia: Herramienta de API: Crear o actualizar
MCP_SERVER_ID="my-mcp-server"
TOOL_ID="listOrders"
BACKING_API_ID="orders-api"
BACKING_OP_ID="list-orders"
OP_ID="/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ApiManagement/service/${APIM_NAME}/apis/${BACKING_API_ID}/operations/${BACKING_OP_ID}"
curl -s -X PUT \
"${BASE_URL}/apis/${MCP_SERVER_ID}/tools/${TOOL_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "If-Match: *" \
--data-raw "{
\"properties\": {
\"displayName\": \"listOrders\",
\"description\": \"List all orders for a customer\",
\"operationId\": \"${OP_ID}\"
}
}"
Respuesta (201 creado)
{
"id": "/subscriptions/.../apis/my-mcp-server/tools/listOrders",
"name": "listOrders",
"type": "Microsoft.ApiManagement/service/apis/tools",
"properties": {
"displayName": "listOrders",
"description": "List all orders for a customer",
"operationId": "/subscriptions/.../apis/orders-api/operations/list-orders"
}
}
Errores comunes:
-
400 Bad Request. LaoperationIdruta de acceso tiene un formato incorrecto o la operación a la que se hace referencia no existe. -
404 Not Found. El servidor MCP primario no existe. Cree el servidor antes de agregar herramientas.
Eliminar una herramienta
Quita una herramienta de un servidor MCP. Elimine las herramientas antes de eliminar las operaciones de la API REST subyacentes a las que hacen referencia; de lo contrario, la eliminación falla con un error de dependencia.
Referencia: Herramienta de API - Eliminar
MCP_SERVER_ID="my-mcp-server"
TOOL_ID="listOrders"
curl -s -X DELETE \
"${BASE_URL}/apis/${MCP_SERVER_ID}/tools/${TOOL_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "If-Match: *"
Respuesta:200 OK en caso de éxito.
Error común:412 Precondition Failed : If-Match es necesario para las eliminaciones. Utilice If-Match: * para que coincida con cualquier ETag.
Aplicar una directiva en el ámbito de MCP
Crea o reemplaza el documento de directiva adjunto a un servidor MCP. El servidor evalúa las directivas en este ámbito para cada invocación de herramienta. El rawxml formato acepta XML de directiva sin codificar.
Referencia: Directiva de API: crear o actualizar
MCP_SERVER_ID="my-mcp-server"
POLICY='<policies><inbound><base /><rate-limit calls="100" renewal-period="60" /></inbound><backend><forward-request /></backend><outbound><base /></outbound></policies>'
curl -s -X PUT \
"${BASE_URL}/apis/${MCP_SERVER_ID}/policies/policy?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "If-Match: *" \
--data-raw "{\"properties\":{\"format\":\"rawxml\",\"value\":\"${POLICY}\"}}"
Respuesta (200 OK)
{
"id": "/subscriptions/.../apis/my-mcp-server/policies/policy",
"name": "policy",
"type": "Microsoft.ApiManagement/service/apis/policies",
"properties": {
"value": "<policies>...</policies>"
}
}
Error común:400 Bad Request. XML de directiva con formato incorrecto. Valide el documento antes de enviarlo.
Enlace de un servidor MCP a un producto
Asocia el servidor MCP a un producto, por lo que los suscriptores de ese producto pueden llamar a las herramientas del servidor. La solicitud no tiene cuerpo.
Al enlazar el servidor MCP a un producto, lo hace disponible a través de ese producto, pero los clientes siguen necesitando acceso según la configuración del producto. Si el producto requiere suscripciones, el cliente debe usar una clave de suscripción válida para ese producto.
Referencia: API del producto - Crear o actualizar
MCP_SERVER_ID="my-mcp-server"
PRODUCT_ID="my-product"
curl -s -X PUT \
"${BASE_URL}/products/${PRODUCT_ID}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Length: 0"
Respuesta:201 Created con el contrato de API del servidor MCP en el cuerpo.
Error común:404 Not Found. Compruebe que productId y mcpServerId existan antes de crear la vinculación.
Eliminación de un servidor MCP
Elimina un servidor MCP y todos sus subrecursos de herramientas y directivas. Antes de eliminar el servidor, quite las herramientas que hagan referencia a las operaciones de respaldo de las API; De lo contrario, no puede eliminar esas operaciones mientras existe la referencia de la herramienta.
Referencia: Api - Delete
MCP_SERVER_ID="my-mcp-server"
curl -s -X DELETE \
"${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}" \
-H "If-Match: *"
Respuesta:200 OK en caso de éxito.
Error común:412 Precondition Failed. Se requiere If-Match para las eliminaciones. Use If-Match: * para omitir la comprobación de ETag.
Plantillas de ARM y Bicep
Las plantillas siguientes implementan una configuración completa del servidor MCP en una sola implementación. Cada plantilla supone una instancia de servicio de API Management existente y usa una tabla de parámetros para que pueda reutilizar el mismo archivo entre entornos cambiando solo los valores de parámetro.
Servidor MCP respaldado por la API REST
Estas plantillas crean un servidor MCP, definen una herramienta que se asigna a una operación en una API REST de respaldo existente, adjuntan una directiva de límite de velocidad en el ámbito del servidor y enlazan el servidor a un producto existente. Puede realizar todas estas tareas en una sola implementación.
Requisitos previos: un servicio DE API Management existente, una API REST (backingApiId) con al menos una operación (backingOperationId) y un producto existente (productId).
| Parameter | Obligatorio | Valor predeterminado | Description |
|---|---|---|---|
serviceName |
Sí | — | Nombre de la instancia del servicio API Management existente. |
mcpServerId |
No | orders-mcp |
Nombre del recurso para el nuevo servidor MCP. Debe ser único dentro del servicio. |
backingApiId |
Sí | — | Nombre de recurso de la API REST existente que respalda este servidor MCP. |
backingOperationId |
Sí | — | Nombre del recurso de la operación que se va a exponer como herramienta. |
toolId |
No | sampleTool |
Nombre del recurso y nombre para mostrar de la herramienta MCP que se va a crear. |
productId |
No | starter |
Nombre de recurso del producto existente al que se va a enlazar el servidor. |
@description('Name of the existing API Management service instance.')
param serviceName string
@description('Resource name for the new MCP server.')
param mcpServerId string = 'orders-mcp'
@description('Resource name of the existing REST API that backs this MCP server.')
param backingApiId string
@description('Resource name of the operation in the backing REST API to expose as a tool.')
param backingOperationId string
@description('Resource name and display name of the MCP tool to create.')
param toolId string = 'sampleTool'
@description('Resource name of the existing product to bind the MCP server to.')
param productId string = 'starter'
resource apimService 'Microsoft.ApiManagement/service@2025-09-01-preview' existing = {
name: serviceName
}
resource mcpServer 'Microsoft.ApiManagement/service/apis@2025-09-01-preview' = {
parent: apimService
name: mcpServerId
properties: {
type: 'mcp'
displayName: 'Orders MCP Server'
description: 'MCP server backed by the Orders REST API'
path: mcpServerId
protocols: [ 'https' ]
subscriptionRequired: true
}
}
resource mcpTool 'Microsoft.ApiManagement/service/apis/tools@2025-09-01-preview' = {
parent: mcpServer
name: toolId
properties: {
displayName: toolId
description: 'MCP tool backed by an API operation'
operationId: resourceId(
'Microsoft.ApiManagement/service/apis/operations',
serviceName, backingApiId, backingOperationId
)
}
}
resource mcpPolicy 'Microsoft.ApiManagement/service/apis/policies@2025-09-01-preview' = {
parent: mcpServer
name: 'policy'
properties: {
format: 'rawxml'
value: '''<policies>
<inbound>
<base />
<rate-limit calls="100" renewal-period="60" />
</inbound>
<backend>
<forward-request />
</backend>
<outbound>
<base />
</outbound>
</policies>'''
}
}
resource product 'Microsoft.ApiManagement/service/products@2025-09-01-preview' existing = {
parent: apimService
name: productId
}
resource productBinding 'Microsoft.ApiManagement/service/products/apis@2025-09-01-preview' = {
parent: product
name: mcpServerId
dependsOn: [ mcpServer ]
}
Para desplegar:
# Use orders-mcp.json if you're deploying the ARM template.
az deployment group create \
--resource-group <resource-group> \
--template-file orders-mcp.bicep \
--parameters serviceName=<api-management-name> \
backingApiId=orders-api \
backingOperationId=get-orders \
toolId=getOrders
Servidor MCP de paso directo
Estas plantillas crean un servidor MCP de paso que utiliza el transporte HTTP streamable. El ámbito del servidor tiene una directiva de límite de velocidad y el servidor se enlaza a un producto existente. Las plantillas no definen ningún subrecurso de herramientas. El back-end externo determina la superficie de la herramienta.
Note
Las plantillas siguientes usan transportType: streamable, que implementa la especificación HTTP actual que se puede transmitir con MCP. Para usar el transporte SSE en su lugar, establezca transportType en sse y reemplace el array endpoints por dos elementos: { "name": "sse", "uriTemplate": "/sse" } y { "name": "message", "uriTemplate": "/messages" }. En Bicep, utilice los mismos valores con cadenas entre comillas simples.
Requisitos previos: un servicio de API Management existente, una URL del backend de MCP accesible (backendUrl) que implemente las rutas del transporte y del punto de conexión seleccionados, y un producto existente (productId).
| Parameter | Obligatorio | Valor predeterminado | Description |
|---|---|---|---|
serviceName |
Sí | — | Nombre de la instancia del servicio API Management existente. |
mcpServerId |
No | external-mcp |
Nombre del recurso para el nuevo servidor MCP. Debe ser único dentro del servicio. |
backendUrl |
Sí | — | URL absoluta del servidor externo de MCP. |
productId |
No | starter |
Nombre de recurso del producto existente al que se va a enlazar el servidor. |
@description('Name of the existing API Management service instance.')
param serviceName string
@description('Resource name for the new MCP server.')
param mcpServerId string = 'external-mcp'
@description('Absolute URL of the external MCP backend.')
param backendUrl string
@description('Resource name of the existing product to bind the MCP server to.')
param productId string = 'starter'
resource apimService 'Microsoft.ApiManagement/service@2025-09-01-preview' existing = {
name: serviceName
}
resource mcpServer 'Microsoft.ApiManagement/service/apis@2025-09-01-preview' = {
parent: apimService
name: mcpServerId
properties: {
type: 'mcp'
displayName: 'External MCP Server'
description: 'Passthrough MCP server using streamable HTTP transport'
path: mcpServerId
protocols: [ 'https' ]
serviceUrl: backendUrl
subscriptionRequired: true
mcpProperties: {
transportType: 'streamable'
endpoints: [
{
name: 'message'
uriTemplate: '/mcp'
}
]
}
}
}
resource mcpPolicy 'Microsoft.ApiManagement/service/apis/policies@2025-09-01-preview' = {
parent: mcpServer
name: 'policy'
properties: {
format: 'rawxml'
value: '''<policies>
<inbound>
<base />
<rate-limit calls="100" renewal-period="60" />
</inbound>
<backend>
<forward-request />
</backend>
<outbound>
<base />
</outbound>
</policies>'''
}
}
resource product 'Microsoft.ApiManagement/service/products@2025-09-01-preview' existing = {
parent: apimService
name: productId
}
resource productBinding 'Microsoft.ApiManagement/service/products/apis@2025-09-01-preview' = {
parent: product
name: mcpServerId
dependsOn: [ mcpServer ]
}
Para desplegar:
# Use external-mcp.json if you're deploying the ARM template.
az deployment group create \
--resource-group <resource-group> \
--template-file external-mcp.bicep \
--parameters serviceName=<api-management-name> \
backendUrl=https://mcp-backend.contoso.com
CLI de Azure
Actualmente, puede usar az rest para llamar directamente a la API REST. El script siguiente crea un servidor MCP de acceso directo, adjunta una directiva de límite de velocidad y la enlaza a un producto. Este proceso cubre el mismo escenario que la plantilla de Bicep en la sección anterior.
Establezca variables y, a continuación, ejecute las cuatro az rest llamadas en orden.
Note
az rest usa las credenciales de tu sesión actual de az login. No necesita un paso de autenticación independiente.
# Variables. Edit these for your environment
SUBSCRIPTION_ID=$(az account show --query id -o tsv)
RESOURCE_GROUP="<your-resource-group>"
APIM_NAME="<your-apim-service-name>"
MCP_SERVER_ID="external-mcp"
BACKEND_URL="https://mcp-backend.contoso.com"
PRODUCT_ID="starter"
API_VERSION="2025-09-01-preview"
BASE="https://management.azure.com/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.ApiManagement/service/${APIM_NAME}"
# 1. Create the passthrough MCP server
az rest --method PUT \
--uri "${BASE}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
--headers "If-Match=*" \
--body '{
"properties": {
"type": "mcp",
"displayName": "External MCP Server",
"description": "Passthrough MCP server using streamable HTTP transport",
"path": "external-mcp",
"protocols": ["https"],
"serviceUrl": "'"${BACKEND_URL}"'",
"subscriptionRequired": true,
"mcpProperties": {
"transportType": "streamable",
"endpoints": [
{ "name": "message", "uriTemplate": "/mcp" }
]
}
}
}'
# 2. Attach a rate-limit policy at the server scope
az rest --method PUT \
--uri "${BASE}/apis/${MCP_SERVER_ID}/policies/policy?api-version=${API_VERSION}" \
--headers "If-Match=*" \
--body '{
"properties": {
"format": "rawxml",
"value": "<policies><inbound><base /><rate-limit calls=\"100\" renewal-period=\"60\" /></inbound><backend><forward-request /></backend><outbound><base /></outbound></policies>"
}
}'
# 3. Bind the server to a product
az rest --method PUT \
--uri "${BASE}/products/${PRODUCT_ID}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}"
Cada paso es idempotente. Al volver a ejecutar el script, se actualiza el recurso en su lugar. Para comprobar que se creó el servidor, ejecute el siguiente comando:
az rest --method GET \
--uri "${BASE}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}"
Terraform
El proveedor de Terraform de AzureRM aún no tiene recursos nativos para los servidores MCP. Actualmente, puede usar el azapi_resource tipo de recurso del proveedor AzAPI, que le permite administrar cualquier tipo de recurso Azure en cualquier versión de API. El siguiente ejemplo reproduce la plantilla Bicep del servidor MCP de paso.
Requisitos previos: un servicio de API Management existente, una dirección URL de back-end de MCP accesible y un producto existente. Añada el proveedor AzAPI en el bloque terraform si todavía no está presente.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.0"
}
azapi = {
source = "Azure/azapi"
version = ">= 1.13"
}
}
}
provider "azurerm" {
features {}
}
provider "azapi" {}
Variables
variable "resource_group_name" {
description = "Name of the resource group containing the API Management service."
type = string
}
variable "service_name" {
description = "Name of the existing API Management service instance."
type = string
}
variable "mcp_server_id" {
description = "Resource name for the new MCP server."
type = string
default = "external-mcp"
}
variable "backend_url" {
description = "Absolute URL of the external MCP backend."
type = string
}
variable "product_id" {
description = "Resource name of the existing product to bind the server to."
type = string
default = "starter"
}
Resources
# Reference the existing API Management service
data "azurerm_api_management" "apim" {
name = var.service_name
resource_group_name = var.resource_group_name
}
# 1. Create the passthrough MCP server
resource "azapi_resource" "mcp_server" {
type = "Microsoft.ApiManagement/service/apis@2025-09-01-preview"
name = var.mcp_server_id
parent_id = data.azurerm_api_management.apim.id
body = {
properties = {
type = "mcp"
displayName = "External MCP Server"
description = "Passthrough MCP server using streamable HTTP transport"
path = var.mcp_server_id
protocols = ["https"]
serviceUrl = var.backend_url
subscriptionRequired = true
mcpProperties = {
transportType = "streamable"
endpoints = [
{
name = "message"
uriTemplate = "/mcp"
}
]
}
}
}
}
# 2. Attach a rate-limit policy at the server scope
resource "azapi_resource" "mcp_policy" {
type = "Microsoft.ApiManagement/service/apis/policies@2025-09-01-preview"
name = "policy"
parent_id = azapi_resource.mcp_server.id
body = {
properties = {
format = "rawxml"
value = "<policies><inbound><base /><rate-limit calls=\"100\" renewal-period=\"60\" /></inbound><backend><forward-request /></backend><outbound><base /></outbound></policies>"
}
}
depends_on = [azapi_resource.mcp_server]
}
# 3. Bind the server to a product
resource "azapi_resource" "product_binding" {
type = "Microsoft.ApiManagement/service/products/apis@2025-09-01-preview"
name = var.mcp_server_id
parent_id = "${data.azurerm_api_management.apim.id}/products/${var.product_id}"
body = {}
depends_on = [azapi_resource.mcp_server]
}
Para desplegar:
Note
azapi_resource usa la autenticación del proveedor AzAPI, que utiliza la misma credencial az login que CLI de Azure. No es necesario configurar la autenticación independiente al ejecutarse localmente.
terraform init
terraform apply \
-var="resource_group_name=<resource-group>" \
-var="service_name=<api-management-name>" \
-var="backend_url=https://mcp-backend.contoso.com"
Patrones de CI/CD
Upserts idempotentes: envía solicitudes PUT con
If-Match: "*"para que se aplique la misma plantilla tanto si el recurso ya existe como si no.Promover configuraciones entre entornos: trate las definiciones de servidor MCP y las listas de herramientas como artefactos controlados por código fuente. Parametrizar solo valores específicos del entorno, como el nombre de instancia y la dirección URL de back-end.
Genere la lista de herramientas a partir de la especificación de API: impulse los subrecursos de herramientas desde el archivo OpenAPI de origen para que la superficie de herramientas permanezca sincronizada con la API de respaldo a medida que evoluciona.
Eliminar en el orden correcto: quite las referencias de la herramienta MCP antes de eliminar las API de respaldo o las operaciones a las que apuntan. De lo contrario, la eliminación generará un error al comprobar la clave foránea.