Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questo articolo illustra come creare e gestire server MCP in Gestione API di Azure usando l'API REST, i modelli arm, Bicep, i interfaccia della riga di comando di Azure e Terraform.
Importante
Le funzionalità per la gestione dei server MCP descritte in questo articolo richiedono l'API REST di API Management versione 2025-09-01-preview o successiva. Aggiungere questa versione in ogni richiesta.
Per informazioni sulle funzionalità del server MCP, vedere Informazioni sui server MCP in Gestione API di Azure.
Prerequisiti
La tua identità deve disporre delle autorizzazioni necessarie per leggere il servizio di Gestione API e creare o aggiornare API, strumenti API, criteri API e associazioni tra prodotti e API. In Terraform, l'identità deve anche avere accesso in lettura al servizio API Management esistente usato dall'origine dati
azurerm_api_management.Per la CLI di Azure:
È possibile utilizzare l'ambiente Bash in Azure Cloud Shell. Per altre informazioni, vedere Introduzione a Azure Cloud Shell.
Se preferisci eseguire localmente i comandi di riferimento della CLI, installa la CLI di Azure. Se si esegue in Windows o macOS, è consigliabile eseguire interfaccia della riga di comando di Azure in un contenitore Docker. Per altre informazioni, vedere Come eseguire il interfaccia della riga di comando di Azure in un contenitore Docker.
Se usi un'installazione locale, accedi all'interfaccia della riga di comando di Azure usando il comando az login. Per completare il processo di autenticazione, seguire la procedura visualizzata nel terminale. Per altre opzioni di accesso, vedere Eseguire l'autenticazione ad Azure con l'interfaccia della riga di comando di Azure.
Quando ti viene richiesto, installa l'estensione interfaccia della riga di comando di Azure al primo utilizzo. Per altre informazioni sulle estensioni, vedere Usare e gestire le estensioni con interfaccia della riga di comando di Azure.
Esegui az version per trovare la versione e le librerie dipendenti installate. Per eseguire l'aggiornamento alla versione più recente, avviare az upgrade.
Con Azure PowerShell:
- Se scegli di utilizzare Azure PowerShell localmente:
- Installare la versione più recente del modulo Az PowerShell.
- Connettersi all'account Azure con il cmdlet Connect-AzAccount.
- Se si sceglie di usare Azure Cloud Shell:
- Per altre informazioni, vedere Panoramica di Azure Cloud Shell.
- Se scegli di utilizzare Azure PowerShell localmente:
Per Terraform: Installare e configurare Terraform
Modello di risorsa
Azure Resource Manager rappresenta i server MCP come indicato di seguito:
Server passthrough: Fa riferimento a un backend MCP esterno esistente. La risorsa del server MCP dichiara l'URL del backend e il tipo di trasporto (HTTP con streaming oppure SSE).
Strumento: Sotto-risorsa dello strumento API di un server MCP. È possibile gestire in modo sicuro le risorse degli strumenti da CI/CD. È possibile aggiungere, rinominare o rimuovere strumenti senza ricreare il server MCP.
Politiche: Come per le API standard, associa a un server MCP le sotto-risorse criterio API o criterio.
Prodotti: l'associazione di prodotto è una relazione figlio separata (
products/{productId}/apis/{mcpServerId}), che consente la distribuzione indipendente e l'associazione di più prodotti.
Esempi REST
Per maggiore chiarezza, gli esempi seguenti mostrano corpi di risposta abbreviati. Per gli schemi completi delle risposte, vedi il riferimento dell'API REST di API Management.
L'aggiunta dell'intestazione If-Match: * negli esempi di chiamata PUT e DELETE rende le richieste idempotenti. Questa intestazione si applica indipendentemente dal fatto che la risorsa esista già oppure no, che è l'approccio consigliato per le pipeline CI/CD.
Prima di iniziare
Impostare le variabili seguenti prima di eseguire qualsiasi esempio. Tutti gli esempi in questa sezione fanno riferimento a queste variabili.
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)
Elencare i servers MCP
Restituisce tutte le API presenti nell'istanza filtrate per tipo mcp. Utilizzare i parametri di query $top e $skip per scorrere set di risultati di grandi dimensioni.
Riferimento: Api - Elenco per servizio
curl -sG "${BASE_URL}/apis" \
--data-urlencode "api-version=${API_VERSION}" \
--data-urlencode "\$filter=type eq 'mcp'" \
-H "Authorization: Bearer ${TOKEN}"
Risposta (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" ]
}
}
]
}
Errore comune:401 Unauthorized. Il token di connessione è scaduto. Eseguire di nuovo il comando di acquisizione del token.
Ottenere un singolo server MCP
Riferimento: Api - Get
MCP_SERVER_ID="my-mcp-server"
curl -s "${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}"
Risposta (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"
}
}
Errore comune:404 Not Found. Verificare che mcpServerId corrisponda al name campo restituito dall'operazione Elenco.
Creare un server MCP supportato dall'API REST
Crea la risorsa server MCP. Dopo la creazione, aggiungere gli strumenti singolarmente usando l'operazione Aggiungi o aggiorna uno strumento . Ogni strumento fa riferimento a un'operazione specifica in una risorsa API REST di supporto.
Riferimento: Api - Creare o aggiornare
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"]
}
}'
Risposta (201 creato)
{
"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"
}
}
Annotazioni
provisioningState: InProgress è previsto per le operazioni PUT asincrone. Eseguire il polling dell'URL restituito nell'intestazione di risposta Azure-AsyncOperation per verificare il completamento.
Errore comune:400 Bad Request. Assicurarsi che type sia "mcp" e che path sia univoco all'interno dell'istanza del servizio.
Creare un server MCP pass-through
Un server pass-through inoltra tutte le richieste MCP direttamente a un back-end MCP esterno. Impostare mcpProperties.transportType in modo che corrisponda al trasporto implementato dal back-end.
Prima di creare un server pass-through, verificare che il back-end sia raggiungibile dal gateway di Gestione API e implementi il trasporto MCP selezionato nei percorsi endpoint configurati. Se il back-end richiede l'autenticazione, configura le credenziali o gli header necessari usando i criteri di API Management o la configurazione del back-end.
Riferimento: Api - Creare o aggiornare
Trasporto HTTP trasmissibile
Usa streamable per i backend che implementano la specifica attuale del trasporto HTTP streamable di MCP. È necessaria una singola definizione di endpoint.
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" }
]
}
}
}'
Risposta (201 creato)
{
"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" } ]
}
}
}
Trasporto tramite SSE
Utilizzare sse per i back-end che implementano il trasporto HTTP+SSE (Server-Sent Events). Definire due endpoint: uno per il flusso di eventi SSE e uno per il canale di messaggi.
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" }
]
}
}
}'
Errori comuni:
-
400 Bad Request. Non validomcpProperties. Verificare chetransportTypesiastreamableossee che ogniuriTemplateinizi con/. -
400 Bad Request. Il trasporto SSE richiede esattamente due endpoint (sseemessage). Il trasporto in streaming richiede un elemento (message).
Aggiungere o aggiornare uno strumento
Aggiunge un nuovo strumento a un server MCP supportato dall'API REST o ne aggiorna uno esistente. Il operationId campo collega lo strumento a un'operazione specifica in una risorsa API REST sottostante. È possibile aggiungere, aggiornare o rimuovere strumenti in modo indipendente senza ricreare il server padre.
Riferimento: Strumento API - Creare o aggiornare
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}\"
}
}"
Risposta (201 creato)
{
"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"
}
}
Errori comuni:
-
400 Bad Request. IloperationIdpercorso non è valido o l'operazione a cui si fa riferimento non esiste. -
404 Not Found. Il server MCP padre non esiste. Creare il server prima di aggiungere strumenti.
Eliminare uno strumento
Rimuove uno strumento da un server MCP. Eliminare gli strumenti prima di eliminare le operazioni dell'API REST sottostante a cui fanno riferimento; in caso contrario, l'eliminazione non riesce a causa di un errore di dipendenza.
Riferimento: Strumento API - Eliminazione
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: *"
Risposta:200 OK in caso di esito positivo.
Errore comune:412 Precondition Failed — If-Match è necessario per le eliminazioni. Usare If-Match: * per trovare le corrispondenze con qualsiasi ETag.
Applicare un criterio all'ambito MCP
Crea o sostituisce il documento dei criteri collegato a un server MCP. Il server valuta i criteri in questo ambito per ogni chiamata allo strumento. Il rawxml formato accetta il codice XML dei criteri non codificati.
Riferimento: Criteri API - Creare o aggiornare
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}\"}}"
Risposta (200 OK)
{
"id": "/subscriptions/.../apis/my-mcp-server/policies/policy",
"name": "policy",
"type": "Microsoft.ApiManagement/service/apis/policies",
"properties": {
"value": "<policies>...</policies>"
}
}
Errore comune:400 Bad Request. XML dei criteri non valido. Convalidare il documento prima dell'invio.
Associare un server MCP a un prodotto
Associa il server MCP a un prodotto, in modo che i sottoscrittori del prodotto possano chiamare gli strumenti del server. La richiesta non ha corpo.
Quando si associa il server MCP a un prodotto, lo si rende disponibile tramite tale prodotto, ma i client devono comunque accedere in base alla configurazione del prodotto. Se il prodotto richiede sottoscrizioni, il client deve usare una chiave di sottoscrizione valida per tale prodotto.
Riferimento: Api prodotto - Creazione o aggiornamento
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"
Risposta:201 Created con il contratto API del server MCP nel corpo.
Errore comune:404 Not Found. Verificare che sia productId che mcpServerId esistano prima di creare l'associazione.
Eliminare un server MCP
Elimina un server MCP e tutte le relative sottorisorse dello strumento e dei criteri. Prima di eliminare il server, rimuovere tutti gli strumenti che fanno riferimento alle operazioni nelle API di backup; in caso contrario, non è possibile eliminare tali operazioni mentre il riferimento allo strumento esiste.
Riferimento: 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: *"
Risposta:200 OK in caso di esito positivo.
Errore comune:412 Precondition Failed.
If-Match è obbligatorio per le eliminazioni. Usare If-Match: * per ignorare il controllo ETag.
Modelli ARM e Bicep
I modelli seguenti distribuiscono una configurazione completa del server MCP in una singola distribuzione. Ogni modello presuppone un'istanza del servizio Gestione API esistente e usa una tabella dei parametri in modo da poter riutilizzare lo stesso file in ambienti modificando solo i valori dei parametri.
Server MCP supportato dall'API REST
Questi modelli creano un server MCP, definiscono uno strumento che esegue il mapping a un'operazione in un'API REST di backup esistente, collega un criterio di limite di velocità all'ambito del server e associa il server a un prodotto esistente. È possibile eseguire tutte queste attività in una singola distribuzione.
Prerequisiti: un servizio Gestione API esistente, un'API REST (backingApiId) con almeno un'operazione (backingOperationId) e un prodotto esistente (productId).
| Parametro | Richiesto | Predefinito | Description |
|---|---|---|---|
serviceName |
Sì | — | Nome dell'istanza del servizio Gestione API esistente. |
mcpServerId |
No | orders-mcp |
Nome della risorsa per il nuovo server MCP. Deve essere univoco all'interno del servizio. |
backingApiId |
Sì | — | Nome della risorsa dell'API REST esistente che esegue il backup del server MCP. |
backingOperationId |
Sì | — | Nome della risorsa dell’operazione da rendere disponibile come strumento. |
toolId |
No | sampleTool |
Nome della risorsa e nome visualizzato dello strumento MCP da creare. |
productId |
No | starter |
Nome della risorsa del prodotto esistente a cui associare il server. |
@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 ]
}
Per distribuire:
# 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
Server MCP pass-through
Questi modelli creano un server MCP passante che utilizza il trasporto HTTP in streaming. L'ambito del server ha un criterio di limite di frequenza e il server viene associato a un prodotto esistente. I modelli non definiscono alcuna risorsa secondaria dello strumento. Il back-end esterno determina la superficie degli strumenti.
Annotazioni
I seguenti modelli usano transportType: streamable, che implementa l'attuale specifica HTTP streamable di MCP. Per usare invece il trasporto SSE, impostare transportType su sse e sostituire l'array endpoints con due elementi: { "name": "sse", "uriTemplate": "/sse" } e { "name": "message", "uriTemplate": "/messages" }. In Bicep usare gli stessi valori con stringhe racchiuse tra virgolette singole.
Prerequisiti: un servizio Gestione API esistente, un URL back-end MCP raggiungibile (backendUrl) che implementa i percorsi di trasporto ed endpoint selezionati e un prodotto esistente (productId).
| Parametro | Richiesto | Predefinito | Description |
|---|---|---|---|
serviceName |
Sì | — | Nome dell'istanza del servizio Gestione API esistente. |
mcpServerId |
No | external-mcp |
Nome della risorsa per il nuovo server MCP. Deve essere univoco all'interno del servizio. |
backendUrl |
Sì | — | URL assoluto del backend MCP esterno. |
productId |
No | starter |
Nome della risorsa del prodotto esistente a cui associare il server. |
@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 ]
}
Per distribuire:
# 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
interfaccia della riga di comando di Azure
Attualmente, è possibile usare az rest per chiamare direttamente l'API REST. Lo script seguente crea un server MCP pass-through, collega un criterio di limite di frequenza e lo associa a un prodotto. Questo processo illustra lo stesso scenario del modello di Bicep nella sezione precedente.
Impostare le variabili e quindi eseguire le quattro az rest chiamate in ordine.
Annotazioni
az rest usa le credenziali della sessione corrente az login . Non è necessario un passaggio di autenticazione separato.
# 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}"
Ogni passaggio è idempotente. Eseguire nuovamente lo script per aggiornare la risorsa in posizione. Per verificare che il server sia stato creato, eseguire il comando seguente:
az rest --method GET \
--uri "${BASE}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}"
Terraform
Il provider Terraform di AzureRM non dispone ancora di risorse native per i server MCP. Attualmente, è possibile usare il azapi_resource tipo di risorsa del provider AzAPI, che consente di gestire qualsiasi tipo di risorsa Azure in qualsiasi versione dell'API. L'esempio seguente riproduce il modello Bicep del server MCP passthrough.
Prerequisiti: un servizio Gestione API esistente, un URL back-end MCP raggiungibile e un prodotto esistente. Aggiungi il provider AzAPI al blocco terraform, se non è già 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]
}
Per distribuire:
Annotazioni
azapi_resource utilizza l'autenticazione del provider AzAPI, che attinge alla stessa credenziale az login dell'interfaccia della riga di comando di Azure. Non è necessario configurare l'autenticazione separata durante l'esecuzione in locale.
terraform init
terraform apply \
-var="resource_group_name=<resource-group>" \
-var="service_name=<api-management-name>" \
-var="backend_url=https://mcp-backend.contoso.com"
Modelli CI/CD
Upsert idempotenti: inviare richieste PUT con
If-Match: "*"in modo che venga applicato lo stesso modello, indipendentemente dal fatto che la risorsa esista già o meno.Alzare di livello le configurazioni tra ambienti: considerare le definizioni e gli elenchi di strumenti del server MCP come artefatti controllati dal codice sorgente. Parametrizzare solo valori specifici dell'ambiente, ad esempio il nome dell'istanza e l'URL back-end.
Generare l'elenco degli strumenti dalla specifica dell'API: guidare la sotto-risorsa degli strumenti dal file OpenAPI di origine in modo che l'area degli strumenti rimanga sincronizzata con l'API di supporto man mano che si evolve.
Elimina nell'ordine corretto: rimuovere i riferimenti allo strumento MCP prima di eliminare le API di backup o le operazioni a cui puntano. In caso contrario, l'eliminazione non riesce durante il controllo della chiave esterna.