Skip to content

Commit a9dcee6

Browse files
Merge branch 'main' of https://github.com/MicrosoftDocs/azure-docs-pr into aca/migrate-functions
2 parents 25dd298 + 4b6aa9f commit a9dcee6

319 files changed

Lines changed: 5104 additions & 2122 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

articles/app-service/configure-authentication-ai-foundry-openapi-tool.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ author: cephalin
77
ms.author: cephalin
88
ms.service: azure-app-service
99
ms.collection: ce-skilling-ai-copilot
10+
ms.update-cycle: 180-days
1011
---
1112

1213
# Secure OpenAPI endpoints for Azure AI Foundry Agent Service
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Secure MCP servers with Microsoft Entra authentication
3+
description: Configure Microsoft Entra authentication to secure your MCP server on Azure App Service and access it from Visual Studio Code.
4+
ms.topic: how-to
5+
ms.date: 11/18/2025
6+
author: cephalin
7+
ms.author: cephalin
8+
ms.service: azure-app-service
9+
ms.collection: ce-skilling-ai-copilot
10+
ms.update-cycle: 180-days
11+
---
12+
13+
# Secure Model Context Protocol calls to Azure App Service from Visual Studio Code with Microsoft Entra authentication
14+
15+
This article shows you how to secure your Model Context Protocol (MCP) server hosted on Azure App Service using Microsoft Entra authentication. By enabling authentication, you ensure that only users authenticated with Microsoft Entra can access your MCP server through Copilot agent mode in Visual Studio Code.
16+
17+
For other authentication methods and general MCP server security concepts, see [Secure a Model Context Protocol server in Azure App Service](configure-authentication-mcp.md).
18+
19+
## Prerequisites
20+
21+
An App Service app that hosts an MCP server. If you need to create one, see one of the following tutorials:
22+
23+
- [Integrate an App Service app as an MCP Server for GitHub Copilot Chat (.NET)](tutorial-ai-model-context-protocol-server-dotnet.md)
24+
- [Integrate an App Service app as an MCP Server for GitHub Copilot Chat (Java)](tutorial-ai-model-context-protocol-server-java.md)
25+
- [Integrate an App Service app as an MCP Server for GitHub Copilot Chat (Python)](tutorial-ai-model-context-protocol-server-python.md)
26+
- [Integrate an App Service app as an MCP Server for GitHub Copilot Chat (Node.js)](tutorial-ai-model-context-protocol-server-node.md)
27+
28+
## Enable Microsoft Entra authentication
29+
30+
1. In the [Azure portal](https://portal.azure.com), navigate to your App Service app.
31+
32+
1. In the left menu, select **Settings** > **Authentication**, and then select **Add identity provider**.
33+
34+
1. On the **Add an identity provider** page, select **Microsoft** as the **Identity provider**.
35+
36+
1. Under **App Service authentication settings**, for **Client secret expiration**, select an expiration period (for example, **6 months**).
37+
38+
1. Accept all other default values and select **Add** to create the identity provider.
39+
40+
This creates a new app registration in Microsoft Entra ID with a client secret and configures your App Service app to use it for authentication.
41+
42+
## Authorize Visual Studio Code in App Service authentication
43+
44+
After enabling authentication, you need to authorize Visual Studio Code to access your MCP server.
45+
46+
1. On the **Authentication** page of your App Service app, under **Identity provider**, select **Edit** (the pencil icon) next to the Microsoft provider you created.
47+
48+
1. On the **Edit identity provider** page, under **Additional checks** > **Client application requirement**, select **Allow requests from specific client applications**.
49+
50+
1. Select the pencil widget to edit the allowed applications.
51+
52+
1. In the **Allowed client applications** field, add the Visual Studio Code client ID: `aebc6443-996d-45c2-90f0-388ff96faa56`.
53+
54+
1. Select **OK**, then select **Save**.
55+
56+
## Authorize Visual Studio Code in the app registration
57+
58+
Next, you need to configure the app registration to expose your API to Visual Studio Code.
59+
60+
1. Go back to the **Authentication** page of your App Service app.
61+
62+
1. Select the Microsoft provider in the **Identity provider** column to open the app registration page.
63+
64+
1. In the app registration page, select **Manage** > **Expose an API** from the left menu.
65+
66+
1. Under **Authorized client applications**, select **Add a client application**.
67+
68+
1. In the **Client ID** field, enter the Visual Studio Code client ID: `aebc6443-996d-45c2-90f0-388ff96faa56`.
69+
70+
1. Select the checkbox next to the **user_impersonation** scope to authorize this scope.
71+
72+
1. Select **Add application**.
73+
74+
1. Under **Scopes defined by this API**, find and copy the full scope value. It should look like `api://<app-registration-app-id>/user_impersonation`.
75+
76+
You need this scope value in the next section.
77+
78+
## Enable protected resource metadata by setting the authorization scope
79+
80+
To enable MCP server authorization, you need to configure the protected resource metadata (PRM) by setting the authorization scope in an app setting. This allows MCP clients to discover the authentication requirements through the `/.well-known/oauth-protected-resource` endpoint.
81+
82+
1. In the Azure portal, go back to your App Service app page.
83+
84+
1. In the left menu, select **Settings** > **Environment variables**.
85+
86+
1. Select **Add** to create a new application setting.
87+
88+
1. For **Name**, enter `WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES`.
89+
90+
1. For **Value**, paste the scope you copied from the app registration: `api://<app-registration-app-id>/user_impersonation`.
91+
92+
1. Select **Apply**, then select **Apply** again to confirm and restart your app.
93+
94+
This setting configures the PRM to include the required scope for MCP server authorization.
95+
96+
## Connect from Visual Studio Code
97+
98+
Now you can connect to your secured MCP server from Visual Studio Code.
99+
100+
1. Open Visual Studio Code on your local machine.
101+
102+
1. Open or create an MCP configuration file (`mcp.json`). For a workspace scoped MCP configuration, create it in the *.vscode* directory of your workspace.
103+
104+
1. Add your MCP server configuration:
105+
106+
```json
107+
{
108+
"servers": {
109+
"my-app-service-mcp": {
110+
"type": "http",
111+
"url": "https://<your-app-url>.azurewebsites.net/api/mcp"
112+
}
113+
}
114+
}
115+
```
116+
117+
Replace `<your-app-url>` with your actual App Service app URL. You can find your app's default domain on the **Overview** page in the Azure portal. In this example, the path is `/api/mcp`, but the actual path depends on your MCP code.
118+
119+
1. In Visual Studio Code, open the Command Palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS).
120+
121+
1. Type **MCP: List Servers** and press Enter.
122+
123+
1. Select your MCP server from the list and choose **Start Server**.
124+
125+
1. Visual Studio Code automatically prompts you to sign in with Microsoft Entra ID. Follow the authentication prompts.
126+
127+
The MCP extension handles the OAuth flow using the scope you configured, and Visual Studio Code obtains the necessary access token to call your MCP server.
128+
129+
> [!TIP]
130+
> If you see an unexpected authentication prompt or encounter errors, see [Troubleshooting](#troubleshooting).
131+
132+
1. Once authenticated, your MCP server is connected and ready to use in GitHub Copilot Chat agent mode or other MCP clients.
133+
134+
## Test the connection
135+
136+
To verify that your MCP server is properly secured and accessible:
137+
138+
1. Open GitHub Copilot Chat in Visual Studio Code (`Ctrl+Alt+I` or `Cmd+Option+I` on macOS).
139+
140+
1. Try using a feature from your MCP server. For example, if you're using the Todos sample:
141+
142+
```
143+
Show me all my tasks
144+
```
145+
146+
1. GitHub Copilot should successfully call your MCP server, and you should see the results in the chat. If you encounter any issues, see [Troubleshooting](#troubleshooting).
147+
148+
## Troubleshooting
149+
150+
When you start the MCP server in Visual Studio Code, the authentication prompt you see indicates whether your configuration is correct:
151+
152+
- **Correct configuration**: Visual Studio Code prompts you to **authenticate with Microsoft**. This means the protected resource metadata (PRM) is configured properly, and Visual Studio Code successfully discovered the authorization server and scope from the `/.well-known/oauth-protected-resource` endpoint.
153+
154+
- **Incorrect configuration**: Visual Studio Code prompts you to authenticate with an `/authorize` endpoint on your App Service app (for example, `https://<your-app-url>.azurewebsites.net/authorize`). This means the PRM is not configured properly. Visual Studio Code cannot find the authorization server and authorization scope, so it falls back to using your app's URL as the authorization endpoint, which doesn't exist.
155+
156+
If you see the incorrect authentication prompt, verify that:
157+
- Your app setting `WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES` is correctly configured with the full scope value `api://<app-registration-app-id>/user_impersonation`.
158+
- The App Service app has fully restarted after adding the app setting. It might take a few minutes to complete the restart.
159+
160+
If you see authentication errors after signing in, verify that:
161+
- The Visual Studio Code client ID (`aebc6443-996d-45c2-90f0-388ff96faa56`) is added to both the App Service authentication configuration (allowed client applications) and in the app registration (authorized client applications in **Expose an API**).
162+
- The scope value in the app setting matches exactly what's defined in your app registration.
163+
164+
## Related content
165+
166+
- [Secure a Model Context Protocol server in Azure App Service](configure-authentication-mcp.md)
167+
- [Configure your App Service or Azure Functions app to use Microsoft Entra sign-in](configure-authentication-provider-aad.md)
168+
- [Configure the Microsoft Entra provider with a managed identity instead of a secret (preview)](configure-authentication-provider-aad.md#use-a-managed-identity-instead-of-a-secret-preview)
169+
- [What is Model Context Protocol?](https://modelcontextprotocol.io/)

articles/app-service/configure-language-python.md

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ ms.custom:
2626

2727
This article describes how [Azure App Service](overview.md) runs Python apps, how you can migrate existing apps to Azure, and how you can customize the behavior of App Service when you need to. Python apps must be deployed with all the required [pip](https://pypi.org/project/pip/) modules.
2828

29-
The App Service deployment engine automatically activates a virtual environment and runs `pip install -r requirements.txt` when you deploy a [Git repository](deploy-local-git.md) or when you deploy a [zip package](deploy-zip.md) [with build automation enabled](deploy-zip.md#enable-build-automation-for-zip-deploy).
30-
31-
> [!NOTE]
32-
> App Service currently requires `requirements.txt` in your project's root directory even if you have a `pyproject.toml`. See [Generate requirements.txt from pyproject.toml](#generate-requirementstxt-from-pyprojecttoml) for recommended approaches.
29+
The App Service deployment engine automatically activates a virtual environment and installs dependencies from a `requirements.txt`, `pyproject.toml`, or `setup.py` file when you deploy a [Git repository](deploy-local-git.md) or when you deploy a [zip package](deploy-zip.md) [with build automation enabled](deploy-zip.md#enable-build-automation-for-zip-deploy).
3330

3431
This article provides key concepts and instructions for Python developers who use a built-in Linux container in App Service. If you've never used App Service, first complete the [Python quickstart](quickstart-python.md) and [Flask](tutorial-python-postgresql-app-flask.md), [Django](tutorial-python-postgresql-app-django.md), or [FastAPI](tutorial-python-postgresql-app-fastapi.md) with PostgreSQL tutorial.
3532

@@ -84,7 +81,17 @@ The App Service build system, called Oryx, performs the following steps when you
8481
8582
1. Run a custom pre-build script, if that step is specified by the `PRE_BUILD_COMMAND` setting. (The script can itself run other Python and Node.js scripts, pip and npm commands, and Node-based tools like Yarn, for example, `yarn install` and `yarn build`.)
8683
87-
1. Run `pip install -r requirements.txt`. The *requirements.txt* file must be in the project's root folder. If it's not, the build process reports the error "Could not find setup.py or requirements.txt; Not running pip install."
84+
1. Install dependencies. The build system checks for the following files in the project root:
85+
- *requirements.txt*: Runs `pip install -r requirements.txt`.
86+
- *pyproject.toml* with *uv.lock*: Uses `uv`.
87+
- *pyproject.toml* with *poetry.lock*: Uses `poetry`.
88+
- *pyproject.toml*: Uses `poetry`.
89+
- *setup.py*: Runs `pip install .`.
90+
91+
> [!NOTE]
92+
> If *pyproject.toml* is present but *uv.lock* is missing, App Service defaults to using Poetry, even if *poetry.lock* is also missing. To use `uv`, you must include *uv.lock* in your deployment.
93+
94+
If none of these files are found, the build process reports the error "Could not find setup.py or requirements.txt; Not running pip install."
8895
8996
1. If *manage.py* is found in the root of the repository (which indicates a Django app), run `manage.py collectstatic`. However, if the `DISABLE_COLLECTSTATIC` setting is `true`, this step is skipped.
9097
@@ -112,36 +119,13 @@ For more information on how App Service runs and builds Python apps in Linux, se
112119
> [!NOTE]
113120
> Always use relative paths in all pre-build and post-build scripts because the build container in which Oryx runs is different from the runtime container in which the app runs. Never rely on the exact placement of your app project folder within the container (for example, that it's placed under *site/wwwroot*).
114121
115-
## Generate requirements.txt from pyproject.toml
116-
117-
Currently, App Service doesn't directly support `pyproject.toml`. If you use tools like Poetry or uv, the recommended approach is to generate a compatible *requirements.txt* file before deployment in your project's root:
118-
119-
### Using Poetry
120-
121-
Generate *requirements.txt* by using [Poetry](https://python-poetry.org/) with the [export plugin](https://github.com/python-poetry/poetry-plugin-export):
122-
123-
```sh
124-
125-
poetry export -f requirements.txt --output requirements.txt --without-hashes
126-
127-
```
128-
129-
### Using uv
130-
131-
Generate *requirements.txt* by using [uv](https://docs.astral.sh/uv/concepts/projects/sync/#exporting-the-lockfile):
132-
133-
```sh
134-
135-
uv export --format requirements-txt --no-hashes --output-file requirements.txt
136-
137-
```
138122
139123
## Migrate existing applications to Azure
140124
141125
You can redeploy existing web applications to Azure as follows:
142126
143127
1. **Source repository**. Maintain your source code in a suitable repository, like GitHub, which enables you to set up continuous deployment later in this process.
144-
- Your *requirements.txt* file must be at the root of your repository if you want App Service to automatically install the necessary packages.
128+
- Your dependency file (such as *requirements.txt*, *pyproject.toml*, or *setup.py*) must be at the root of your repository if you want App Service to automatically install the necessary packages.
145129
146130
1. **Database**. If your app depends on a database, create the necessary resources on Azure as well.
147131
@@ -248,9 +232,9 @@ This container has the following characteristics:
248232

249233
- By default, the base container image includes only the Flask web framework, but the container supports other frameworks that are WSGI-compliant and compatible with Python 3.6 and later, such as Django.
250234

251-
- To install other packages, such as Django, create a [*requirements.txt*](https://pip.pypa.io/en/stable/user_guide/#requirements-files) file in the root of your project that specifies your direct dependencies. App Service then installs those dependencies automatically when you deploy your project.
235+
- To install other packages, such as Django, create a [*requirements.txt*](https://pip.pypa.io/en/stable/user_guide/#requirements-files), *pyproject.toml*, or *setup.py* file in the root of your project that specifies your direct dependencies. App Service then installs those dependencies automatically when you deploy your project.
252236

253-
The *requirements.txt* file must be in the project root or dependencies won't be installed. If this file isn't in the root, the build process reports the error "Could not find setup.py or requirements.txt; Not running pip install." If you encounter this error, check the location of your requirements file.
237+
The dependency file must be in the project root or dependencies won't be installed. If this file isn't in the root, the build process reports the error "Could not find setup.py or requirements.txt; Not running pip install." If you encounter this error, check the location of your requirements file.
254238

255239
- App Service automatically defines an environment variable named `WEBSITE_HOSTNAME` that contains the web app's URL, such as `msdocs-hello-world.azurewebsites.net`. It also defines `WEBSITE_SITE_NAME`, which contains the name of your app, such as `msdocs-hello-world`.
256240

@@ -403,7 +387,7 @@ Use the following steps to access the deployment logs:
403387
1. On the **Logs** tab, select the **Commit ID** for the most recent commit.
404388
1. On the **Log details** page that appears, select the **Show Logs** link that appears next to **Running oryx build**.
405389

406-
Build issues, like incorrect dependencies in *requirements.txt* and errors in pre-build or post-build scripts, appear in these logs. Errors also appear if your requirements file isn't named *requirements.txt* or doesn't appear in the root folder of your project.
390+
Build issues, like incorrect dependencies in your dependency file and errors in pre-build or post-build scripts, appear in these logs. Errors also appear if your dependency file isn't found in the root folder of your project.
407391

408392
## Open SSH session in a browser
409393

@@ -423,7 +407,7 @@ In general, the first step in troubleshooting is to use App Service diagnostics:
423407
1. Select **Availability and Performance**.
424408
1. Examine the information in **Application Logs**, **Container Crash**, and **Container Issues**, where the most common issues appear.
425409

426-
Next, examine both the [deployment logs](#access-deployment-logs) and the [app logs](#access-diagnostic-logs) for any error messages. These logs often identify specific issues that can prevent app deployment or app startup. For example, the build can fail if your *requirements.txt* file has the wrong file name or isn't present in your project root folder.
410+
Next, examine both the [deployment logs](#access-deployment-logs) and the [app logs](#access-diagnostic-logs) for any error messages. These logs often identify specific issues that can prevent app deployment or app startup. For example, the build can fail if your dependency file isn't present in your project root folder.
427411

428412
The following sections provide guidance for specific issues.
429413

@@ -459,9 +443,9 @@ The following sections provide guidance for specific issues.
459443

460444
#### Could not find setup.py or requirements.txt
461445

462-
- **The log stream shows "Could not find setup.py or requirements.txt; Not running pip install."** The Oryx build process failed to find your *requirements.txt* file.
446+
- **The log stream shows "Could not find setup.py or requirements.txt; Not running pip install."** The Oryx build process failed to find your *requirements.txt*, *pyproject.toml*, or *setup.py* file.
463447

464-
- Connect to the web app's container via [SSH](#open-ssh-session-in-a-browser) and verify that *requirements.txt* is named correctly and exists directly under *site/wwwroot*. If it doesn't exist, make sure the file exists in your repository and is included in your deployment. If it exists in a separate folder, move it to the root.
448+
- Connect to the web app's container via [SSH](#open-ssh-session-in-a-browser) and verify that your dependency file is named correctly and exists directly under *site/wwwroot*. If it doesn't exist, make sure the file exists in your repository and is included in your deployment. If it exists in a separate folder, move it to the root.
465449

466450
#### ModuleNotFoundError when app starts
467451

-119 KB
Loading
-8.04 KB
Loading
4.08 KB
Loading
-6.5 KB
Loading
-37.1 KB
Loading
-1.86 KB
Loading
234 Bytes
Loading

0 commit comments

Comments
 (0)