Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste artigo, aprende a criar e gerir servidores MCP no API Management do Azure usando a API REST, templates ARM, Bicep, CLI do Azure e Terraform.
Importante
As funcionalidades de gestão de servidores MCP descritas neste artigo requerem API Management REST API versão 2025-09-01-preview ou posterior. Afixe esta versão em todas as solicitações.
Para informações sobre as capacidades dos servidores MCP, veja Sobre os servidores MCP no API Management do Azure.
Pré-requisitos
A sua identidade precisa de permissões para ler o serviço de Gestão de APIs e criar ou atualizar APIs, ferramentas de API, políticas de API e ligações de APIs de produto. Para o Terraform, a identidade também necessita de acesso de leitura ao serviço de Gestão de API existente utilizado pela
azurerm_api_managementfonte de dados.Para CLI do Azure:
Usa o ambiente Bash em Azure Cloud Shell. Para mais informações, veja Get started with Azure Cloud Shell.
Se preferires executar comandos de referência de CLI localmente, instala o CLI do Azure. Se estiver a usar Windows ou macOS, considere executar o CLI do Azure num contentor Docker. Para mais informações, veja Como executar o CLI do Azure num contentor Docker.
Se você estiver usando uma instalação local, entre na CLI do Azure usando o comando az login . Para concluir o processo de autenticação, siga os passos exibidos no seu terminal. Para outras opções de iniciação de sessão, veja Autenticar para Azure usando CLI do Azure.
Quando solicitado, instale a extensão do CLI do Azure na primeira utilização. Para mais informações sobre extensões, veja Usar e gerir extensões com a CLI do Azure.
Execute az version para descobrir a versão e as bibliotecas dependentes que estão instaladas. Para atualizar para a versão mais recente, execute az upgrade.
Para o Azure PowerShell:
- Se você optar por usar o Azure PowerShell localmente:
- Instale a versão mais recente do módulo Az PowerShell.
- Ligue-se à sua conta Azure usando o cmdlet Connect-AzAccount.
- Se você optar por usar o Azure Cloud Shell:
- Consulte Visão geral de Azure Cloud Shell para mais informações.
- Se você optar por usar o Azure PowerShell localmente:
Para o Terraform: Instale e configure o Terraform
Modelo de recursos
Azure Resource Manager representa os servidores MCP da seguinte forma:
Servidor MCP: Um recurso API de Gestão de APIs do tipo
MCP.Servidor de passagem: Aponta para um backend MCP externo existente. O recurso do servidor MCP declara o URL do servidor de backend e o tipo de transporte (HTTP com streaming ou SSE).
Ferramenta: Um sub-recurso de ferramenta API de um servidor MCP. Podes gerir recursos de ferramentas em segurança a partir do CI/CD. Pode adicionar, renomear ou remover ferramentas sem recriar o servidor MCP.
Políticas: Tal como nas APIs normais, anexe os sub-recursos política de API ou política a um servidor MCP.
Produtos: A associação de produto é uma relação subordinada autónoma (
products/{productId}/apis/{mcpServerId}), permitindo a implementação autónoma e a associação a vários produtos.
Exemplos REST
Para maior clareza, os exemplos seguintes mostram corpos de resposta abreviados. Para esquemas completos de resposta, consulte a referência da API REST do API Management.
Adicionar o cabeçalho If-Match: * nos exemplos de pedidos PUT e DELETE torna os pedidos idempotentes. Este cabeçalho aplica-se independentemente de o recurso já existir ou não, que é o padrão recomendado para pipelines CI/CD.
Antes de começares
Defina as seguintes variáveis antes de executar qualquer exemplo. Todos os exemplos nesta secção fazem referência a estas variáveis.
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)
Listar servidores MCP
Devolve todas as APIs da instância filtradas para o tipo mcp. Utilize os parâmetros de consulta $top e $skip para paginar grandes conjuntos de resultados.
Referência: Api - Lista por Serviço
curl -sG "${BASE_URL}/apis" \
--data-urlencode "api-version=${API_VERSION}" \
--data-urlencode "\$filter=type eq 'mcp'" \
-H "Authorization: Bearer ${TOKEN}"
Resposta (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" ]
}
}
]
}
Erro comum:401 Unauthorized O token de portador está expirado. Reexecute o comando de aquisição de tokens.
Arranja um único servidor MCP
Referência: Api - Get
MCP_SERVER_ID="my-mcp-server"
curl -s "${BASE_URL}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}" \
-H "Authorization: Bearer ${TOKEN}"
Resposta (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"
}
}
Erro comum:404 Not Found Confirme que mcpServerId corresponde ao name campo devolvido pela operação Lista.
Criar um servidor MCP apoiado por API REST
Cria o recurso do servidor MCP. Após a criação, adicione ferramentas individualmente usando a operação Adicionar ou atualizar uma ferramenta . Cada ferramenta faz referência a uma operação específica num recurso de API REST de apoio.
Referência: API - Criar ou Atualizar
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"]
}
}'
Resposta (201 Criada)
{
"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
provisioningState: InProgress espera-se para operações de PUT assíncronas. Consulte o URL devolvido no cabeçalho de resposta Azure-AsyncOperation para confirmar a conclusão.
Erro comum:400 Bad Request Certifique-se de que type é "mcp" e de que path é única dentro da instância de serviço.
Criar um servidor MCP de passagem
Um servidor passthrough encaminha todos os pedidos MCP diretamente para um backend MCP externo. Define mcpProperties.transportType para corresponder ao transporte que o teu backend implementa.
Antes de criar um servidor de passagem, confirme que o sistema de back-end está acessível a partir do gateway do API Management e implementa o transporte MCP selecionado nos caminhos dos pontos finais que configurar. Se o backend exigir autenticação, configure as credenciais ou cabeçalhos necessários usando políticas de gestão de API ou configuração do backend.
Referência: API - Criar ou Atualizar
Transporte HTTP transmissível
Utilize streamable para back-ends que implementem a especificação atual do MCP para transporte HTTP por fluxo. É necessária uma única definição de 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" }
]
}
}
}'
Resposta (201 Criada)
{
"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
Utilize sse para back-ends que implementam o transporte HTTP+SSE (Eventos Enviados pelo Servidor). Defina dois endpoints: um para o fluxo de eventos SSE e outro para o canal de mensagens.
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" }
]
}
}
}'
Erros comuns:
-
400 Bad Request. InválidomcpProperties. VerifiquetransportTypese éstreamableousse, e todosuriTemplatecomeçam por/. -
400 Bad Request. O transporte SSE requer exatamente dois pontos finais (sseemessage). O transporte por streaming requer um (message).
Adicionar ou atualizar uma ferramenta
Adiciona uma nova ferramenta a um servidor MCP apoiado por API REST, ou atualiza um existente. O operationId campo liga a ferramenta a uma operação específica num recurso de API REST de apoio. Pode adicionar, atualizar ou remover ferramentas de forma independente sem recriar o servidor principal.
Referência: Ferramenta API - Criar ou Atualizar
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}\"
}
}"
Resposta (201 Criada)
{
"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"
}
}
Erros comuns:
-
400 Bad Request. OoperationIdcaminho está malformado ou a operação referenciada não existe. -
404 Not Found. O servidor MCP principal não existe. Crie o servidor antes de adicionar ferramentas.
Eliminar uma ferramenta
Remove uma ferramenta de um servidor MCP. Elimine as ferramentas antes de eliminar as operações da API REST subjacentes a que estas fazem referência; caso contrário, a operação de eliminação falhará com um erro de dependência.
Referência: Ferramenta 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: *"
Resposta:200 OK em caso de sucesso.
Erro comum:412 Precondition Failed — If-Match é necessária para eliminações. Utilize If-Match: * para corresponder a qualquer ETag.
Aplicar uma política ao nível do MCP
Cria ou substitui o documento de política associado a um servidor MCP. O servidor avalia as políticas neste âmbito para cada invocação de ferramenta. O rawxml formato aceita XML de política não codificada.
Referência: Api Policy - Criar ou Atualizar
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}\"}}"
Resposta (200 OK)
{
"id": "/subscriptions/.../apis/my-mcp-server/policies/policy",
"name": "policy",
"type": "Microsoft.ApiManagement/service/apis/policies",
"properties": {
"value": "<policies>...</policies>"
}
}
Erro comum:400 Bad Request Política mal formada em XML. Valide o documento antes de o enviar.
Vincular um servidor MCP a um produto
Associa o servidor MCP a um produto, para que os assinantes desse produto possam aceder às ferramentas do servidor. O pedido não tem corpo.
Quando vincula o servidor MCP a um produto, torna-o disponível através desse produto, mas os clientes ainda precisam de acesso de acordo com a configuração do produto. Se o produto exigir subscrições, o cliente deve usar uma chave de subscrição válida para esse produto.
Referência: Product API - Criar ou Atualizar
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"
Resposta:201 Created com o contrato de API do servidor MCP no corpo.
Erro comum:404 Not Found Verifique se ambos productId e mcpServerId existem antes de criar a ligação.
Eliminar um servidor MCP
Elimina um servidor MCP e todos os seus subrecursos de ferramentas e políticas. Antes de eliminar o servidor, remova quaisquer ferramentas que referenciam operações de backing APIs; caso contrário, não pode apagar essas operações enquanto a referência da ferramenta existir.
Referência: Api - Eliminar
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: *"
Resposta:200 OK em caso de sucesso.
Erro comum:412 Precondition Failed É necessário If-Match para eliminar. Use If-Match: * para ignorar a verificação de ETag.
Modelos ARM e Bicep
Os modelos seguintes implementam uma configuração completa de servidor MCP numa única implementação. Cada modelo assume uma instância existente de serviço de Gestão de API e utiliza uma tabela de parâmetros para que possa reutilizar o mesmo ficheiro entre ambientes alterando apenas os valores dos parâmetros.
Servidor MCP apoiado por API REST
Estes templates criam um servidor MCP, definem uma ferramenta que corresponde a uma operação numa API REST de suporte existente, anexam uma política de limite de taxa no âmbito do servidor e associam o servidor a um produto existente. Podes fazer todas estas tarefas numa única implementação.
Pré-requisitos: um serviço de gestão de API existente, uma API REST (backingApiId) com pelo menos uma operação (backingOperationId), e um produto existente (productId).
| Parâmetro | Obrigatório | Predefinição | Description |
|---|---|---|---|
serviceName |
Sim | — | Nome da instância existente do serviço de Gestão de APIs. |
mcpServerId |
No | orders-mcp |
Nome do recurso para o novo servidor MCP. Tem de ser único dentro do serviço. |
backingApiId |
Sim | — | Nome do recurso da API REST existente que suporta este servidor MCP. |
backingOperationId |
Sim | — | Nome do recurso da operação a expor como uma ferramenta. |
toolId |
No | sampleTool |
Nome do recurso e nome de exibição da ferramenta MCP a criar. |
productId |
No | starter |
Nome do recurso do produto existente ao qual associar o 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 implementar:
# 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 passagem
Estes modelos criam um servidor MCP de passagem que utiliza transporte HTTP transmissível em fluxo. O âmbito do servidor tem uma política de limite de taxa, e o servidor vincula-se a um produto existente. Os templates não definem sub-recursos de ferramentas. O backend externo determina a superfície da ferramenta.
Note
Os modelos seguintes utilizam transportType: streamable, que implementa a especificação HTTP transmissível atual do MCP. Para usar o transporte SSE em vez disso, defina transportType e sse substitua o endpoints array por duas entradas: { "name": "sse", "uriTemplate": "/sse" } e { "name": "message", "uriTemplate": "/messages" }. No Bicep, usa os mesmos valores com cadeias de aspas simples.
Pré-requisitos: um serviço de Gestão de API existente, uma URL de backend MCP acessível (backendUrl) que implementa os caminhos selecionados de transporte e endpoint, e um produto existente (productId).
| Parâmetro | Obrigatório | Predefinição | Description |
|---|---|---|---|
serviceName |
Sim | — | Nome da instância existente do serviço de Gestão de APIs. |
mcpServerId |
No | external-mcp |
Nome do recurso para o novo servidor MCP. Tem de ser único dentro do serviço. |
backendUrl |
Sim | — | URL absoluta do backend MCP externo. |
productId |
No | starter |
Nome do recurso do produto existente ao qual associar o 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 implementar:
# 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 do Azure
Atualmente, pode usar az rest para aceder diretamente à API REST. O script seguinte cria um servidor MCP passthrough, anexa uma política de limite de taxa e liga-a a um produto. Este processo cobre o mesmo cenário do modelo Bicep na secção anterior.
Define variáveis e depois executa as quatro az rest chamadas por ordem.
Note
az rest Usa a credencial da tua sessão atual az login . Não precisas de um passo de autenticação separado.
# 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 passo é idempotente. Reexecutar o script atualiza o recurso no local. Para verificar se o servidor foi criado, execute o seguinte comando:
az rest --method GET \
--uri "${BASE}/apis/${MCP_SERVER_ID}?api-version=${API_VERSION}"
Terraform
O fornecedor AzureRM Terraform ainda não tem recursos nativos para servidores MCP. Atualmente, pode usar o azapi_resource tipo de recurso do fornecedor AzAPI, que lhe permite gerir qualquer tipo de recurso Azure contra qualquer versão da API. O exemplo seguinte espelha o modelo Bicep do servidor MCP passthrough.
Pré-requisitos: um serviço de gestão de API existente, um URL de backend MCP acessível e um produto existente. Adicione o fornecedor AzAPI ao bloco terraform se ainda não estiver presente.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.0"
}
azapi = {
source = "Azure/azapi"
version = ">= 1.13"
}
}
}
provider "azurerm" {
features {}
}
provider "azapi" {}
Variáveis
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 implementar:
Note
azapi_resource utiliza a autenticação do provedor AzAPI, que recorre à mesma az login credencial que a CLI do Azure. Não precisas de configurar autenticação separada ao correr 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"
Padrões CI/CD
Upserts idempotentes: Enviar pedidos PUT com
If-Match: "*"para que o mesmo modelo se aplique independentemente de o recurso já existir ou não.Promover configurações em diferentes ambientes: Tratar as definições de servidores MCP e as listas de ferramentas como artefactos controlados por código-fonte. Parametrize apenas valores específicos do ambiente, como nome da instância e URL do backend.
Gera a lista de ferramentas a partir da especificação da tua API: Conduz o sub-recurso de ferramentas a partir do teu ficheiro OpenAPI de origem para que a superfície da ferramenta se mantenha sincronizada com a API de suporte à medida que esta evolui.
Apagar pela ordem correta: Remover referências às ferramentas MCP antes de eliminar as APIs de backup ou operações para as quais apontam. Caso contrário, a eliminação falha numa verificação de chave estrangeira.