You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -129,7 +129,7 @@ az containerapp ingress cors update \
129
129
--max-age 3600
130
130
```
131
131
132
-
Key headers to allow:
132
+
The following headers are key to allow:
133
133
134
134
-`Content-Type`: required for JSON-RPC requests
135
135
-`Authorization`: required for bearer token auth
@@ -138,7 +138,7 @@ Key headers to allow:
138
138
> [!NOTE]
139
139
> GitHub Copilot connects to remote MCP servers from the VS Code desktop app, not from a browser. CORS is only needed if you intend to support browser-based MCP clients or VS Code for the Web. The standalone tutorials use wildcard CORS origins for simplicity; for production, restrict to specific trusted origins as shown here.
140
140
141
-
### Security recommendations
141
+
### Security recommendations for standalone MCP servers
142
142
143
143
Apply the following best practices to harden your standalone MCP server.
144
144
@@ -150,15 +150,18 @@ Apply the following best practices to harden your standalone MCP server.
150
150
151
151
## Dynamic sessions with API key authentication
152
152
153
+
> [!IMPORTANT]
154
+
> The platform-managed MCP server for dynamic sessions is in **preview**. The API version `2025-02-02-preview` and `mcpServerSettings` properties are subject to change.
155
+
153
156
The platform-managed MCP server in dynamic sessions uses API key authentication. The key is scoped to the session pool and grants access to all tools and sessions in the pool.
154
157
155
-
### Authentication flow
158
+
### API key authentication flow
156
159
157
160
The following steps describe how API key authentication works for dynamic sessions.
158
161
159
162
1. The client sends a JSON-RPC request with the `x-ms-apikey` header.
160
163
1. The session pool proxy validates the key against the Azure control plane.
161
-
1. If the key is valid, the request is forwarded to the session. If not, a `401 Unauthorized` response is returned.
164
+
1. If the key is valid, the request is forwarded to the session. If not, an authentication error is returned.
162
165
163
166
### Retrieve the API key
164
167
@@ -171,9 +174,9 @@ API_KEY=$(az rest --method POST \
171
174
--query "apiKey" -o tsv)
172
175
```
173
176
174
-
### Key rotation and caching
177
+
### Rotate and cache the API key
175
178
176
-
You can regenerate the API key at any time. The platform caches validation results, so previously valid keys might continue to work for several minutes after regeneration while the cache expires.
179
+
You can regenerate the API key at any time. The platform caches validation results for up to five minutes, so previously valid keys might continue to work after regeneration until the cache expires.
177
180
178
181
To rotate the API key, call the `regenerateCredentials` action on the session pool:
179
182
@@ -185,7 +188,7 @@ az rest --method POST \
185
188
186
189
After regeneration, retrieve the new key by using `fetchMCPServerCredentials` as shown earlier.
187
190
188
-
### Security recommendations
191
+
### Security recommendations for dynamic sessions
189
192
190
193
Apply the following best practices to secure your dynamic sessions MCP deployment.
191
194
@@ -195,7 +198,7 @@ Apply the following best practices to secure your dynamic sessions MCP deploymen
195
198
-**Session lifetime**: Configure `coolDownPeriodInSeconds` to automatically destroy idle sessions. This setting limits the window of exposure if a session is compromised.
196
199
-**Secret storage**: Store the API key in [Azure Key Vault](/azure/key-vault/general/overview) or [Container Apps secrets](/azure/container-apps/manage-secrets) rather than in code or configuration files.
197
200
198
-
## Authentication model comparison
201
+
## Common authentication mismatches
199
202
200
203
A common mistake is using the API key header (`x-ms-apikey`) with a standalone container app, or using a bearer token with the sessions MCP endpoint. The following table shows what happens when you mix them up.
Copy file name to clipboardExpand all lines: articles/container-apps/mcp-choosing-azure-service.md
+7-6Lines changed: 7 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,7 @@ ms.topic: conceptual
6
6
ms.service: azure-container-apps
7
7
ms.collection: ce-skilling-ai-copilot
8
8
ms.custom: cross-service
9
-
ms.date: 02/18/2026
9
+
ms.date: 02/19/2026
10
10
author: craigshoemaker
11
11
ms.author: cshoe
12
12
ms.reviewer: cshoe
@@ -37,7 +37,7 @@ Add an MCP endpoint to an existing or new web app. App Service supports code-bas
37
37
38
38
### Azure Functions
39
39
40
-
Map function triggers to MCP tools using the [Azure Functions MCP extension](/azure/azure-functions/scenario-custom-remote-mcp-server). Azure Functions is optimized for stateless, event-driven tool execution with per-invocation pricing.
40
+
Map function triggers to MCP tools by using the [Azure Functions MCP extension](/azure/azure-functions/scenario-custom-remote-mcp-server). Azure Functions is optimized for stateless, event-driven tool execution with per-invocation pricing.
41
41
42
42
## Compare hosting options
43
43
@@ -60,7 +60,7 @@ The following table summarizes the key differences between hosting options.
60
60
61
61
Use the following guidance to narrow your decision based on common workload patterns.
62
62
63
-
### Build a custom MCP server
63
+
### Build a custom MCP server with Azure
64
64
65
65
**Recommended: Azure Container Apps (standalone) or Azure App Service**
66
66
@@ -82,10 +82,11 @@ Tutorials:
82
82
83
83
Session pools with MCP enabled provide Hyper-V-isolated environments for running untrusted or LLM-generated code. The platform manages the MCP server, so you don't write or deploy server code. The built-in tools cover code execution scenarios without custom development:
Copy file name to clipboardExpand all lines: articles/container-apps/mcp-overview.md
+6-7Lines changed: 6 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,17 +1,17 @@
1
1
---
2
-
title: MCP servers on Azure Container Apps
3
-
description: Learn how to host Model Context Protocol (MCP) servers on Azure Container Apps as standalone container apps or with platform-managed dynamic sessions.
2
+
title: Host MCP servers on Azure Container Apps
3
+
description: Learn how to host MCP servers on Azure Container Apps as standalone container apps or with dynamic sessions.
4
4
#customer intent: As a developer, I want to deploy an MCP server as a standalone container app so that I can expose custom tools and connect to backend services.
5
5
ms.topic: conceptual
6
6
ms.service: azure-container-apps
7
7
ms.collection: ce-skilling-ai-copilot
8
-
ms.date: 02/18/2026
8
+
ms.date: 02/19/2026
9
9
author: craigshoemaker
10
10
ms.author: cshoe
11
11
ms.reviewer: cshoe
12
12
---
13
13
14
-
# MCP servers on Azure Container Apps
14
+
# Host MCP servers on Azure Container Apps
15
15
16
16
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/) is an open standard that connects AI applications to external data sources and tools. By using MCP, AI clients like GitHub Copilot can discover and invoke capabilities you expose, turning your APIs, databases, and business logic into tools an AI agent can use through natural language.
17
17
@@ -80,13 +80,12 @@ In this model, the platform manages the MCP server. You don't write or deploy MC
80
80
81
81
| Tool | Description |
82
82
|---|---|
83
-
|`launchShell`| Creates a new shell environment and returns an `environmentId`|
84
-
|`launchPythonEnvironment`| Creates a new Python environment and returns an `environmentId`|
83
+
|`launchShell`| Creates a new environment and returns an `environmentId`|
85
84
|`runShellCommandInRemoteEnvironment`| Executes a shell command in an existing environment |
86
85
|`runPythonCodeInRemoteEnvironment`| Executes Python code in an existing environment |
87
86
88
87
> [!NOTE]
89
-
> The available tools depend on the session pool's `containerType`. Shell pools expose `launchShell`and `runShellCommandInRemoteEnvironment`. Python pools expose `launchPythonEnvironment`and `runPythonCodeInRemoteEnvironment`.
88
+
> The platform-managed MCP server exposes all three tools regardless of the session pool's `containerType`. Use `launchShell`to create an environment for both shell and Python pools.
MCP supports multiple transports. Ensure your client and server use the same transport.
117
117
@@ -123,6 +123,9 @@ MCP supports multiple transports. Ensure your client and server use the same tra
123
123
124
124
Most modern MCP SDKs default to streamable HTTP. If you're connecting to a server that uses SSE (common with older examples), switch your client to SSE mode.
125
125
126
+
> [!NOTE]
127
+
> The [Java tutorial](tutorial-mcp-server-java.md) uses the SSE transport (`WebMvcSseServerTransportProvider`) because the MCP Java SDK doesn't yet offer a stable streamable HTTP transport. When connecting from VS Code, select SSE and use `"type": "sse"` in `.vscode/mcp.json`.
128
+
126
129
## Deployment and scaling
127
130
128
131
Deployment issues prevent your container from starting or responding correctly. These problems typically relate to health probes, port configuration, or scaling settings.
@@ -221,15 +224,15 @@ Authentication problems typically happen when you use the wrong credential type
221
224
1. Check that the Microsoft Entra app registration's `audience` matches the resource you requested.
222
225
1. Verify the `--unauthenticated-client-action` setting. `Return401` blocks unauthenticated requests; `AllowAnonymous` lets them through.
223
226
224
-
### 401 Unauthorized: dynamic sessions MCP
227
+
### Authentication error: dynamic sessions MCP
225
228
226
-
**Symptoms**: `401 Unauthorized` when calling the platform-managed MCP endpoint.
229
+
**Symptoms**: Authentication error when calling the platform-managed MCP endpoint. The error might appear as an HTTP `401` response or as a JSON-RPC error message in the response body. The type of error depends on where in the request pipeline the failure occurs.
227
230
228
231
**Checklist**:
229
232
230
233
1. Verify the API key is sent via the `x-ms-apikey` header (not `Authorization`).
231
234
1. Verify the key is from `fetchMCPServerCredentials`, not from a different API.
232
-
1. If you recently regenerated the key, wait several minutes for the old key's cache to expire.
235
+
1. If you recently regenerated the key, wait up to five minutes for the old key's cache to expire.
233
236
1. Check that `mcpServerSettings.isMCPServerEnabled` is `true` on the session pool.
234
237
235
238
For more information, see the [authentication guide](mcp-authentication.md).
@@ -245,10 +248,10 @@ Issues in this section apply only to the platform-managed MCP server in [dynamic
245
248
**Causes**:
246
249
247
250
- The session expired (exceeded `coolDownPeriodInSeconds`).
248
-
- The `environmentId` wasn't extracted correctly from the `launchShell` or `launchPythonEnvironment` response.
251
+
- The `environmentId` wasn't extracted correctly from the `launchShell` response.
249
252
- You're using an environment ID from a different session pool.
250
253
251
-
**Solution**: Call `launchShell` or `launchPythonEnvironment` again to create a new environment.
254
+
**Solution**: Call `launchShell` again to create a new environment.
> The `launchPythonEnvironment` tool generates a unique environment identifier. The actual session is allocated "lazily". When you execute your first command, the session pool assigns a Hyper-V-isolated container to handle it.
200
+
> The `launchShell` tool generates a unique environment identifier. The actual session is allocated "lazily". When you execute your first command, the session pool assigns a Hyper-V-isolated container to handle it.
0 commit comments