-
Notifications
You must be signed in to change notification settings - Fork 167
chore: How to Deploy MongoDB MCP Server on Azure Container Apps? #680
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
kmruiz
merged 6 commits into
mongodb-js:main
from
anshulkhantwal:akhantwal/updateReadme
Oct 29, 2025
Merged
Changes from 1 commit
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
0915619
Deploy MongoDB MCP Server on Azure Container Apps
anshulkhantwal b9e8c1c
Using official hub.docker.com/r/mongodb/mongodb-mcp-server
anshulkhantwal defce20
review comments - copilot
anshulkhantwal bb79b08
review comments feedback
anshulkhantwal 1fc50ab
review comments feedback
anshulkhantwal f788e47
chore: fix formatting
kmruiz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Deploy MongoDB MCP Server on Azure Container Apps | ||
|
|
||
| ## Overview | ||
| 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. | ||
|
|
||
| ## Prerequisites | ||
| - Azure CLI (2.55.0 or later) installed and signed in (`az login`). | ||
| - Azure subscription with permissions to deploy the required resources. | ||
| - Docker installed locally for building container images. | ||
| - Azure Container Registry (ACR) to host the MongoDB MCP server image. | ||
| - MongoDB MCP server container image available in your registry (instructions below). | ||
|
|
||
| ## Prepare the MongoDB MCP Docker Image | ||
| If you already have a tagged image in your ACR, skip this section. Otherwise, build and push the image using the official Dockerfile: | ||
|
|
||
| ```powershell | ||
| # 1. Clone the MongoDB MCP server repository | ||
| git clone https://github.com/mongodb-js/mongodb-mcp-server.git | ||
| cd mongodb-mcp-server | ||
|
|
||
| # 2. Log in to your Azure Container Registry | ||
| $acrName = "<your-acr-name>" # without the .azurecr.io suffix | ||
| az acr login --name $acrName | ||
|
|
||
| # 3. Build the MongoDB MCP server image | ||
| $tag = "$acrName.azurecr.io/mongodb-mcp-server:latest" | ||
| docker build -f Dockerfile -t $tag . | ||
|
|
||
| # 4. Push the image to your ACR | ||
| docker push $tag | ||
| ``` | ||
|
|
||
| Record the fully qualified image name (FQIN) for later use in your parameter file, e.g. `myregistry.azurecr.io/mongodb-mcp-server:latest`. | ||
|
|
||
| ## Parameter Files | ||
| Two sample parameter files are provided to help you tailor deployments: | ||
|
|
||
| - `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. | ||
| - `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. | ||
|
|
||
| > **Tip:** Update the image reference, secrets, networking, and any other environment-specific values in the chosen parameter file before deployment. | ||
|
|
||
| ## Deploy the Bicep Template | ||
| 1. **Set common variables (PowerShell example):** | ||
| ```powershell | ||
| $location = "eastus" | ||
| $resourceGroup = "mongodb-mcp-demo-rg" | ||
| $templateFile = "bicep/main.bicep" | ||
| $parameterFile = "bicep/params.json" # or bicep/paramsWithAuthEnabled.json | ||
| ``` | ||
|
|
||
| 2. **Create the resource group (if it does not exist):** | ||
| ```powershell | ||
| az group create --name $resourceGroup --location $location | ||
| ``` | ||
|
|
||
| 3. **Validate the deployment (optional but recommended):** | ||
| ```powershell | ||
| az deployment group what-if \ | ||
| --resource-group $resourceGroup \ | ||
| --template-file $templateFile \ | ||
| --parameters @$parameterFile | ||
| ``` | ||
|
|
||
| 4. **Run the deployment:** | ||
| ```powershell | ||
| az deployment group create \ | ||
| --resource-group $resourceGroup \ | ||
| --template-file $templateFile \ | ||
| --parameters @$parameterFile | ||
| ``` | ||
|
|
||
| 5. **Monitor outputs:** Review the deployment outputs and logs for connection endpoints, credential references, or other values needed to complete integration. | ||
|
|
||
| ## Post-Deployment Checklist | ||
| - Confirm the container instance or orchestration target pulled the correct MongoDB MCP image from your ACR. | ||
| - Verify networking rules (firewalls, VNet integrations, etc.) allow intended clients to reach the server endpoint. | ||
| - If using the auth-enabled parameters, validate that credentials/secrets are stored securely (Key Vault, managed identity) and tested end-to-end. | ||
| - Document any additional operational steps (scaling, logging, maintenance) based on your environment requirements. | ||
|
|
||
| ## Updating the Deployment | ||
| To apply changes: | ||
| 1. Update the parameter file or `main.bicep` as needed. | ||
| 2. Re-run the `az deployment group create` command with the same resource group. | ||
| 3. Use `az deployment group what-if` to preview differences before applying them. | ||
|
|
||
| ## Cleanup | ||
| Remove the deployed resources when no longer needed: | ||
|
|
||
| ```powershell | ||
| az group delete --name $resourceGroup --yes --no-wait | ||
| ``` | ||
|
|
||
| > **Reminder:** Deleting the resource group removes all resources inside it. Ensure any persistent data or backups are retained elsewhere before running the cleanup command. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,212 @@ | ||
| @description('Name of the Container Apps Environment. Leave blank to create a new one.') | ||
| param containerAppEnvName string = '' | ||
|
|
||
| @description('Location of resources') | ||
| param location string = resourceGroup().location | ||
|
|
||
| @description('Name of the Container App') | ||
| param containerAppName string = 'mongo-mcp-server-app' | ||
|
|
||
| @description('Docker image to deploy') | ||
| param containerImage string = '<your-docker-registry>/mongo-mcp-server:latest' | ||
|
|
||
| @description('Container CPU (vCPU) as string. Allowed: 0.25 - 2.0 in 0.25 increments') | ||
| @allowed([ | ||
| '0.25' | ||
| '0.5' | ||
| '0.75' | ||
| '1.0' | ||
| '1.25' | ||
| '1.5' | ||
| '1.75' | ||
| '2.0' | ||
| ]) | ||
| param containerCpu string = '1.0' | ||
|
|
||
| // Convert CPU string to number (Bicep lacks float type; json() parses to number) | ||
| var containerCpuNumber = json(containerCpu) | ||
|
|
||
| @description('Container Memory (GB)') | ||
| @allowed([ | ||
| '0.5Gi' | ||
| '1Gi' | ||
| '2Gi' | ||
| '4Gi' | ||
| ]) | ||
| param containerMemory string = '2Gi' | ||
|
|
||
| @description('Container App Environment Variables') | ||
| param appEnvironmentVars object = { | ||
| MDB_MCP_READ_ONLY: 'true' // set to 'false' to enable write operations | ||
| MDB_MCP_HTTP_PORT: '8080' | ||
| MDB_MCP_HTTP_HOST: '::' | ||
| MDB_MCP_TRANSPORT: 'http' | ||
| MDB_MCP_LOGGERS: 'disk,mcp,stderr' | ||
| MDB_MCP_LOG_PATH: '/tmp/mongodb-mcp' | ||
| } | ||
|
|
||
| @description('Authentication mode toggle for the Container App. NOAUTH disables platform auth; MicrosoftMIBasedAuth enables Azure AD auth and enforces 401 for unauthenticated requests.') | ||
| @allowed([ | ||
| 'NOAUTH' | ||
| 'MicrosoftMIBasedAuth' | ||
| ]) | ||
| param authMode string = 'NOAUTH' | ||
|
|
||
| @description('Azure AD Application (client) ID used when authMode is MicrosoftMIBasedAuth. Leave blank for NOAUTH.') | ||
| param authClientId string = '' | ||
|
|
||
| @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') | ||
| param authIssuerUrl string = '' | ||
|
|
||
| @description('Azure AD Tenant ID (GUID) used when authMode is MicrosoftMIBasedAuth. Provided separately to avoid hard-coded cloud endpoints in template logic.') | ||
| param authTenantId string = '' | ||
|
|
||
| @description('Optional array of allowed client application IDs. If empty, all applications are allowed (not recommended).') | ||
| param authAllowedClientApps array = [] | ||
|
|
||
| @secure() | ||
| @description('MongoDB Connection String') | ||
| param mdbConnectionString string | ||
|
|
||
| // Create Container App Environment if not provided | ||
| resource containerAppEnv 'Microsoft.App/managedEnvironments@2024-02-02-preview' = if (empty(containerAppEnvName)) { | ||
| name: 'mcp-env-${uniqueString(resourceGroup().id)}' | ||
| location: location | ||
| properties: {} | ||
| } | ||
|
|
||
| // Get the Container App Environment resource ID (either existing or newly created) | ||
| var envResourceId = empty(containerAppEnvName) | ||
| ? containerAppEnv.id | ||
| : resourceId('Microsoft.App/managedEnvironments', containerAppEnvName) | ||
|
|
||
| // Build environment variables array | ||
| var envVarsArray = [ | ||
| for item in items(appEnvironmentVars): { | ||
| name: item.key | ||
| value: string(item.value) | ||
| } | ||
| ] | ||
|
|
||
| // Additional environment variables injected when MicrosoftMIBasedAuth is enabled (merged after user-provided vars so user can override if desired) | ||
| var authEnvVars = authMode == 'MicrosoftMIBasedAuth' | ||
| ? concat([ | ||
| { | ||
| name: 'MDB_MCP_HTTP_AUTH_MODE' | ||
| value: 'azure-managed-identity' | ||
| } | ||
| { | ||
| // Tenant ID of the Azure AD tenant | ||
| name: 'MDB_MCP_AZURE_MANAGED_IDENTITY_TENANT_ID' | ||
| value: authTenantId | ||
| } | ||
| { | ||
| // Client ID of the Azure AD App representing the your container app | ||
anshulkhantwal marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| name: 'MDB_MCP_AZURE_MANAGED_IDENTITY_CLIENT_ID' | ||
| value: authClientId | ||
| } | ||
| ], length(authAllowedClientApps) > 0 ? [ | ||
| { | ||
| // Comma-separated list of allowed Client App IDs for access | ||
| // (only listed Client Apps are allowed if client apps specified) | ||
| name: 'MDB_MCP_AZURE_MANAGED_IDENTITY_ALLOWED_APP_IDS' | ||
| value: join(authAllowedClientApps, ',') | ||
| } | ||
| ] : []) | ||
| : [ | ||
| { | ||
| name: 'MDB_MCP_HTTP_AUTH_MODE' | ||
| value: 'none' | ||
| } | ||
| ] | ||
|
|
||
| // Deploy Container App | ||
| resource containerApp 'Microsoft.App/containerApps@2024-02-02-preview' = { | ||
| name: containerAppName | ||
| location: location | ||
| identity: { | ||
| type: 'SystemAssigned' | ||
| } | ||
| properties: { | ||
| managedEnvironmentId: envResourceId | ||
| configuration: { | ||
| ingress: { | ||
| external: true | ||
| targetPort: int(appEnvironmentVars.MDB_MCP_HTTP_PORT) | ||
| transport: 'auto' | ||
| } | ||
| secrets: [ | ||
| { | ||
| name: 'mdb-mcp-connection-string' | ||
| value: mdbConnectionString | ||
| } | ||
| ] | ||
| } | ||
| template: { | ||
| containers: [ | ||
| { | ||
| name: 'mcpserver' | ||
| image: containerImage | ||
| resources: { | ||
| cpu: containerCpuNumber | ||
| memory: containerMemory | ||
| } | ||
| env: concat( | ||
| envVarsArray, | ||
| authEnvVars, | ||
| [ | ||
| { | ||
| name: 'MDB_MCP_CONNECTION_STRING' | ||
| secretRef: 'mdb-mcp-connection-string' | ||
| } | ||
| ] | ||
| ) | ||
| } | ||
| ] | ||
| scale: { | ||
| minReplicas: 1 | ||
| maxReplicas: 1 | ||
| rules: [] // disables autoscaling | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Container App Authentication (child resource) - only deployed when MicrosoftMIBasedAuth selected | ||
| resource containerAppAuth 'Microsoft.App/containerApps/authConfigs@2024-10-02-preview' = if (authMode == 'MicrosoftMIBasedAuth') { | ||
| name: 'current' | ||
| parent: containerApp | ||
| properties: { | ||
| platform: { | ||
| enabled: true | ||
| // runtimeVersion optional | ||
| } | ||
| globalValidation: { | ||
| unauthenticatedClientAction: 'Return401' | ||
| redirectToProvider: 'azureActiveDirectory' | ||
| } | ||
| identityProviders: { | ||
| azureActiveDirectory: { | ||
| enabled: true | ||
| registration: { | ||
| clientId: authClientId | ||
| openIdIssuer: authIssuerUrl | ||
| } | ||
| validation: { | ||
| allowedAudiences: [ | ||
| authClientId | ||
| ] | ||
| // defaultAuthorizationPolicy allows restriction to specific client applications | ||
| defaultAuthorizationPolicy: length(authAllowedClientApps) > 0 ? { | ||
| allowedApplications: authAllowedClientApps | ||
| } : null | ||
| jwtClaimChecks: length(authAllowedClientApps) > 0 ? { | ||
| allowedClientApplications: authAllowedClientApps | ||
| } : null | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| output containerAppUrl string = containerApp.properties.configuration.ingress.fqdn | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| { | ||
| "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", | ||
| "contentVersion": "1.0.0.0", | ||
| "parameters": { | ||
| "containerImage": { "value": "<your-docker-registry>/mongo-mcp-server:latest" }, | ||
| "containerCpu": { "value": "1.0" }, | ||
| "containerMemory": { "value": "2Gi" }, | ||
| "appEnvironmentVars": { | ||
| "value": { | ||
| "MDB_MCP_READ_ONLY": "false", | ||
| "MDB_MCP_HTTP_PORT": "8080", | ||
| "MDB_MCP_HTTP_HOST": "::", | ||
| "MDB_MCP_TRANSPORT": "http", | ||
| "MDB_MCP_LOGGERS": "disk,mcp,stderr", | ||
| "MDB_MCP_LOG_PATH": "/tmp/mongodb-mcp", | ||
| "MDB_MCP_DISABLED_TOOLS": "explain,export,atlas-create-access-list,atlas-create-db-user,drop-database,drop-collection,delete-many" | ||
| } | ||
| }, | ||
| "authMode": { "value": "NOAUTH" }, | ||
| "mdbConnectionString": { "value": "<MONGODB_CONNECTION_STRING>" } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", | ||
| "contentVersion": "1.0.0.0", | ||
| "parameters": { | ||
| "containerAppEnvName": { "value": "mcp-env-wlm2rwwpyzafw" }, | ||
| "containerAppName": { "value": "mongo-mcp-server-app-with-auth" }, | ||
| "containerImage": { "value": "<your-docker-registry>/mongo-mcp-server:latest" }, | ||
| "containerCpu": { "value": "1.0" }, | ||
| "containerMemory": { "value": "2Gi" }, | ||
| "appEnvironmentVars": { | ||
| "value": { | ||
| "MDB_MCP_READ_ONLY": "false", | ||
| "MDB_MCP_HTTP_PORT": "8080", | ||
| "MDB_MCP_HTTP_HOST": "::", | ||
| "MDB_MCP_TRANSPORT": "http", | ||
| "MDB_MCP_LOGGERS": "disk,mcp,stderr", | ||
| "MDB_MCP_LOG_PATH": "/tmp/mongodb-mcp", | ||
| "MDB_MCP_DISABLED_TOOLS": "explain,export,atlas-create-access-list,atlas-create-db-user,drop-database,drop-collection,delete-many" | ||
| } | ||
| }, | ||
| "mdbConnectionString": { "value": "<MONGODB_CONNECTION_STRING>" }, | ||
|
|
||
| "authMode": { "value": "MicrosoftMIBasedAuth" }, | ||
| "authClientId": { "value": "97251c0f-95cd-4a6f-8414-ae34319fbb29" }, | ||
| "authIssuerUrl": { "value": "https://login.microsoftonline.com/888d76fa-54b2-4ced-8ee5-aac1585adee7/v2.0" }, | ||
| "authTenantId": { "value": "888d76fa-54b2-4ced-8ee5-aac1585adee7" }, | ||
| "authAllowedClientApps": { "value": ["6553980f-5268-4494-b1b2-233ba381fb6e"] } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.