Skip to content

Commit 0915619

Browse files
Deploy MongoDB MCP Server on Azure Container Apps
1 parent 567d497 commit 0915619

File tree

4 files changed

+357
-0
lines changed

4 files changed

+357
-0
lines changed

deploy/azure/README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Deploy MongoDB MCP Server on Azure Container Apps
2+
3+
## Overview
4+
This directory contains an Azure Bicep template (`bicep/main.bicep`) and supporting parameter files for deploying the infrastructure required to run the MongoDB MCP (Model Context Protocol) server. Use this guide to prepare prerequisites, select the appropriate parameter file, and run the deployment end-to-end.
5+
6+
## Prerequisites
7+
- Azure CLI (2.55.0 or later) installed and signed in (`az login`).
8+
- Azure subscription with permissions to deploy the required resources.
9+
- Docker installed locally for building container images.
10+
- Azure Container Registry (ACR) to host the MongoDB MCP server image.
11+
- MongoDB MCP server container image available in your registry (instructions below).
12+
13+
## Prepare the MongoDB MCP Docker Image
14+
If you already have a tagged image in your ACR, skip this section. Otherwise, build and push the image using the official Dockerfile:
15+
16+
```powershell
17+
# 1. Clone the MongoDB MCP server repository
18+
git clone https://github.com/mongodb-js/mongodb-mcp-server.git
19+
cd mongodb-mcp-server
20+
21+
# 2. Log in to your Azure Container Registry
22+
$acrName = "<your-acr-name>" # without the .azurecr.io suffix
23+
az acr login --name $acrName
24+
25+
# 3. Build the MongoDB MCP server image
26+
$tag = "$acrName.azurecr.io/mongodb-mcp-server:latest"
27+
docker build -f Dockerfile -t $tag .
28+
29+
# 4. Push the image to your ACR
30+
docker push $tag
31+
```
32+
33+
Record the fully qualified image name (FQIN) for later use in your parameter file, e.g. `myregistry.azurecr.io/mongodb-mcp-server:latest`.
34+
35+
## Parameter Files
36+
Two sample parameter files are provided to help you tailor deployments:
37+
38+
- `bicep/params.json`: Baseline configuration that deploys the MongoDB MCP server with authentication disabled or using default settings. Use this when testing in development environments or when external authentication is not required.
39+
- `bicep/paramsWithAuthEnabled.json`: Extends the baseline deployment and enables explicit authentication configuration (for example, username/password, secrets, or identity inputs). Use this when you want the server protected with credentials.
40+
41+
> **Tip:** Update the image reference, secrets, networking, and any other environment-specific values in the chosen parameter file before deployment.
42+
43+
## Deploy the Bicep Template
44+
1. **Set common variables (PowerShell example):**
45+
```powershell
46+
$location = "eastus"
47+
$resourceGroup = "mongodb-mcp-demo-rg"
48+
$templateFile = "bicep/main.bicep"
49+
$parameterFile = "bicep/params.json" # or bicep/paramsWithAuthEnabled.json
50+
```
51+
52+
2. **Create the resource group (if it does not exist):**
53+
```powershell
54+
az group create --name $resourceGroup --location $location
55+
```
56+
57+
3. **Validate the deployment (optional but recommended):**
58+
```powershell
59+
az deployment group what-if \
60+
--resource-group $resourceGroup \
61+
--template-file $templateFile \
62+
--parameters @$parameterFile
63+
```
64+
65+
4. **Run the deployment:**
66+
```powershell
67+
az deployment group create \
68+
--resource-group $resourceGroup \
69+
--template-file $templateFile \
70+
--parameters @$parameterFile
71+
```
72+
73+
5. **Monitor outputs:** Review the deployment outputs and logs for connection endpoints, credential references, or other values needed to complete integration.
74+
75+
## Post-Deployment Checklist
76+
- Confirm the container instance or orchestration target pulled the correct MongoDB MCP image from your ACR.
77+
- Verify networking rules (firewalls, VNet integrations, etc.) allow intended clients to reach the server endpoint.
78+
- If using the auth-enabled parameters, validate that credentials/secrets are stored securely (Key Vault, managed identity) and tested end-to-end.
79+
- Document any additional operational steps (scaling, logging, maintenance) based on your environment requirements.
80+
81+
## Updating the Deployment
82+
To apply changes:
83+
1. Update the parameter file or `main.bicep` as needed.
84+
2. Re-run the `az deployment group create` command with the same resource group.
85+
3. Use `az deployment group what-if` to preview differences before applying them.
86+
87+
## Cleanup
88+
Remove the deployed resources when no longer needed:
89+
90+
```powershell
91+
az group delete --name $resourceGroup --yes --no-wait
92+
```
93+
94+
> **Reminder:** Deleting the resource group removes all resources inside it. Ensure any persistent data or backups are retained elsewhere before running the cleanup command.

deploy/azure/bicep/main.bicep

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
@description('Name of the Container Apps Environment. Leave blank to create a new one.')
2+
param containerAppEnvName string = ''
3+
4+
@description('Location of resources')
5+
param location string = resourceGroup().location
6+
7+
@description('Name of the Container App')
8+
param containerAppName string = 'mongo-mcp-server-app'
9+
10+
@description('Docker image to deploy')
11+
param containerImage string = '<your-docker-registry>/mongo-mcp-server:latest'
12+
13+
@description('Container CPU (vCPU) as string. Allowed: 0.25 - 2.0 in 0.25 increments')
14+
@allowed([
15+
'0.25'
16+
'0.5'
17+
'0.75'
18+
'1.0'
19+
'1.25'
20+
'1.5'
21+
'1.75'
22+
'2.0'
23+
])
24+
param containerCpu string = '1.0'
25+
26+
// Convert CPU string to number (Bicep lacks float type; json() parses to number)
27+
var containerCpuNumber = json(containerCpu)
28+
29+
@description('Container Memory (GB)')
30+
@allowed([
31+
'0.5Gi'
32+
'1Gi'
33+
'2Gi'
34+
'4Gi'
35+
])
36+
param containerMemory string = '2Gi'
37+
38+
@description('Container App Environment Variables')
39+
param appEnvironmentVars object = {
40+
MDB_MCP_READ_ONLY: 'true' // set to 'false' to enable write operations
41+
MDB_MCP_HTTP_PORT: '8080'
42+
MDB_MCP_HTTP_HOST: '::'
43+
MDB_MCP_TRANSPORT: 'http'
44+
MDB_MCP_LOGGERS: 'disk,mcp,stderr'
45+
MDB_MCP_LOG_PATH: '/tmp/mongodb-mcp'
46+
}
47+
48+
@description('Authentication mode toggle for the Container App. NOAUTH disables platform auth; MicrosoftMIBasedAuth enables Azure AD auth and enforces 401 for unauthenticated requests.')
49+
@allowed([
50+
'NOAUTH'
51+
'MicrosoftMIBasedAuth'
52+
])
53+
param authMode string = 'NOAUTH'
54+
55+
@description('Azure AD Application (client) ID used when authMode is MicrosoftMIBasedAuth. Leave blank for NOAUTH.')
56+
param authClientId string = ''
57+
58+
@description('Issuer URL (OpenID issuer) when authMode is MicrosoftMIBasedAuth. Example: https://login.microsoftonline.com/<tenant-id>/v2.0 or https://sts.windows.net/<tenant-id>/v2.0')
59+
param authIssuerUrl string = ''
60+
61+
@description('Azure AD Tenant ID (GUID) used when authMode is MicrosoftMIBasedAuth. Provided separately to avoid hard-coded cloud endpoints in template logic.')
62+
param authTenantId string = ''
63+
64+
@description('Optional array of allowed client application IDs. If empty, all applications are allowed (not recommended).')
65+
param authAllowedClientApps array = []
66+
67+
@secure()
68+
@description('MongoDB Connection String')
69+
param mdbConnectionString string
70+
71+
// Create Container App Environment if not provided
72+
resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-02-02-preview' = if (empty(containerAppEnvName)) {
73+
name: 'mcp-env-${uniqueString(resourceGroup().id)}'
74+
location: location
75+
properties: {}
76+
}
77+
78+
// Get the Container App Environment resource ID (either existing or newly created)
79+
var envResourceId = empty(containerAppEnvName)
80+
? containerAppEnv.id
81+
: resourceId('Microsoft.App/managedEnvironments', containerAppEnvName)
82+
83+
// Build environment variables array
84+
var envVarsArray = [
85+
for item in items(appEnvironmentVars): {
86+
name: item.key
87+
value: string(item.value)
88+
}
89+
]
90+
91+
// Additional environment variables injected when MicrosoftMIBasedAuth is enabled (merged after user-provided vars so user can override if desired)
92+
var authEnvVars = authMode == 'MicrosoftMIBasedAuth'
93+
? concat([
94+
{
95+
name: 'MDB_MCP_HTTP_AUTH_MODE'
96+
value: 'azure-managed-identity'
97+
}
98+
{
99+
// Tenant ID of the Azure AD tenant
100+
name: 'MDB_MCP_AZURE_MANAGED_IDENTITY_TENANT_ID'
101+
value: authTenantId
102+
}
103+
{
104+
// Client ID of the Azure AD App representing the your container app
105+
name: 'MDB_MCP_AZURE_MANAGED_IDENTITY_CLIENT_ID'
106+
value: authClientId
107+
}
108+
], length(authAllowedClientApps) > 0 ? [
109+
{
110+
// Comma-separated list of allowed Client App IDs for access
111+
// (only listed Client Apps are allowed if client apps specified)
112+
name: 'MDB_MCP_AZURE_MANAGED_IDENTITY_ALLOWED_APP_IDS'
113+
value: join(authAllowedClientApps, ',')
114+
}
115+
] : [])
116+
: [
117+
{
118+
name: 'MDB_MCP_HTTP_AUTH_MODE'
119+
value: 'none'
120+
}
121+
]
122+
123+
// Deploy Container App
124+
resource containerApp 'Microsoft.App/containerApps@2024-02-02-preview' = {
125+
name: containerAppName
126+
location: location
127+
identity: {
128+
type: 'SystemAssigned'
129+
}
130+
properties: {
131+
managedEnvironmentId: envResourceId
132+
configuration: {
133+
ingress: {
134+
external: true
135+
targetPort: int(appEnvironmentVars.MDB_MCP_HTTP_PORT)
136+
transport: 'auto'
137+
}
138+
secrets: [
139+
{
140+
name: 'mdb-mcp-connection-string'
141+
value: mdbConnectionString
142+
}
143+
]
144+
}
145+
template: {
146+
containers: [
147+
{
148+
name: 'mcpserver'
149+
image: containerImage
150+
resources: {
151+
cpu: containerCpuNumber
152+
memory: containerMemory
153+
}
154+
env: concat(
155+
envVarsArray,
156+
authEnvVars,
157+
[
158+
{
159+
name: 'MDB_MCP_CONNECTION_STRING'
160+
secretRef: 'mdb-mcp-connection-string'
161+
}
162+
]
163+
)
164+
}
165+
]
166+
scale: {
167+
minReplicas: 1
168+
maxReplicas: 1
169+
rules: [] // disables autoscaling
170+
}
171+
}
172+
}
173+
}
174+
175+
// Container App Authentication (child resource) - only deployed when MicrosoftMIBasedAuth selected
176+
resource containerAppAuth 'Microsoft.App/containerApps/authConfigs@2024-10-02-preview' = if (authMode == 'MicrosoftMIBasedAuth') {
177+
name: 'current'
178+
parent: containerApp
179+
properties: {
180+
platform: {
181+
enabled: true
182+
// runtimeVersion optional
183+
}
184+
globalValidation: {
185+
unauthenticatedClientAction: 'Return401'
186+
redirectToProvider: 'azureActiveDirectory'
187+
}
188+
identityProviders: {
189+
azureActiveDirectory: {
190+
enabled: true
191+
registration: {
192+
clientId: authClientId
193+
openIdIssuer: authIssuerUrl
194+
}
195+
validation: {
196+
allowedAudiences: [
197+
authClientId
198+
]
199+
// defaultAuthorizationPolicy allows restriction to specific client applications
200+
defaultAuthorizationPolicy: length(authAllowedClientApps) > 0 ? {
201+
allowedApplications: authAllowedClientApps
202+
} : null
203+
jwtClaimChecks: length(authAllowedClientApps) > 0 ? {
204+
allowedClientApplications: authAllowedClientApps
205+
} : null
206+
}
207+
}
208+
}
209+
}
210+
}
211+
212+
output containerAppUrl string = containerApp.properties.configuration.ingress.fqdn

deploy/azure/bicep/params.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"containerImage": { "value": "<your-docker-registry>/mongo-mcp-server:latest" },
6+
"containerCpu": { "value": "1.0" },
7+
"containerMemory": { "value": "2Gi" },
8+
"appEnvironmentVars": {
9+
"value": {
10+
"MDB_MCP_READ_ONLY": "false",
11+
"MDB_MCP_HTTP_PORT": "8080",
12+
"MDB_MCP_HTTP_HOST": "::",
13+
"MDB_MCP_TRANSPORT": "http",
14+
"MDB_MCP_LOGGERS": "disk,mcp,stderr",
15+
"MDB_MCP_LOG_PATH": "/tmp/mongodb-mcp",
16+
"MDB_MCP_DISABLED_TOOLS": "explain,export,atlas-create-access-list,atlas-create-db-user,drop-database,drop-collection,delete-many"
17+
}
18+
},
19+
"authMode": { "value": "NOAUTH" },
20+
"mdbConnectionString": { "value": "<MONGODB_CONNECTION_STRING>" }
21+
}
22+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"containerAppEnvName": { "value": "mcp-env-wlm2rwwpyzafw" },
6+
"containerAppName": { "value": "mongo-mcp-server-app-with-auth" },
7+
"containerImage": { "value": "<your-docker-registry>/mongo-mcp-server:latest" },
8+
"containerCpu": { "value": "1.0" },
9+
"containerMemory": { "value": "2Gi" },
10+
"appEnvironmentVars": {
11+
"value": {
12+
"MDB_MCP_READ_ONLY": "false",
13+
"MDB_MCP_HTTP_PORT": "8080",
14+
"MDB_MCP_HTTP_HOST": "::",
15+
"MDB_MCP_TRANSPORT": "http",
16+
"MDB_MCP_LOGGERS": "disk,mcp,stderr",
17+
"MDB_MCP_LOG_PATH": "/tmp/mongodb-mcp",
18+
"MDB_MCP_DISABLED_TOOLS": "explain,export,atlas-create-access-list,atlas-create-db-user,drop-database,drop-collection,delete-many"
19+
}
20+
},
21+
"mdbConnectionString": { "value": "<MONGODB_CONNECTION_STRING>" },
22+
23+
"authMode": { "value": "MicrosoftMIBasedAuth" },
24+
"authClientId": { "value": "97251c0f-95cd-4a6f-8414-ae34319fbb29" },
25+
"authIssuerUrl": { "value": "https://login.microsoftonline.com/888d76fa-54b2-4ced-8ee5-aac1585adee7/v2.0" },
26+
"authTenantId": { "value": "888d76fa-54b2-4ced-8ee5-aac1585adee7" },
27+
"authAllowedClientApps": { "value": ["6553980f-5268-4494-b1b2-233ba381fb6e"] }
28+
}
29+
}

0 commit comments

Comments
 (0)