Remote MCP with Azure Functions (Python)
by mafzal786
README.md
<!--
---
name: Remote MCP with Azure Functions (Python)
description: Run a remote MCP server on Azure functions.
page_type: sample
languages:
- python
- bicep
- azdeveloper
products:
- azure-functions
- azure
urlFragment: remote-mcp-functions-python
---
-->
# Remote MCP Servers using Azure Functions (Python)
This is a quickstart template to easily build and deploy a custom remote MCP server to the cloud using Azure Functions with Python. You can clone/restore/run on your local machine with debugging. The MCP server is secured by design using keys and HTTPS, and allows more options for OAuth using built-in auth and/or [API Management](https://aka.ms/mcp-remote-apim-auth) as well as network isolation using VNET.
## Prerequisites
+ [Python](https://www.python.org/downloads/) version 3.11 or higher
+ [Azure Functions Core Tools](https://learn.microsoft.com/azure/azure-functions/functions-run-local?pivots=programming-language-python#install-the-azure-functions-core-tools) >= `4.0.7030`
+ [Azure Developer CLI](https://aka.ms/azd)
+ To use Visual Studio Code to run and debug locally:
+ [Visual Studio Code](https://code.visualstudio.com/)
+ [Azure Functions extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions)
## Prepare your local environment
An Azure Storage Emulator is required for this particular sample.
1. Start Azurite
```shell
docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \
mcr.microsoft.com/azure-storage/azurite
```
>**Note** if you use Azurite coming from VS Code extension you need to run `Azurite: Start` now or you will see errors.
## Run your MCP Server locally from the terminal
1. Change to the src folder in a new terminal window:
```shell
cd src
```
1. Install Python dependencies:
```shell
pip install -r requirements.txt
```
>**Note** it is a best practice to create a Virtual Environment before doing the `pip install` to avoid dependency issues/collisions, or if you are running in CodeSpaces. See [Python Environments in VS Code](https://code.visualstudio.com/docs/python/environments#_creating-environments) for more information.
1. Start the Functions host locally:
```shell
cd .\src
func start
```
> **Note** by default this will use the webhooks route: `/runtime/webhooks/mcp/sse`. Later we will use this in Azure to set the key on client/host calls: `/runtime/webhooks/mcp/sse?code=<system_key>`
## Connect to the *local* MCP server from a client/host
### VS Code - Copilot agent mode
1. **Add MCP Server** from command palette and add URL to your running Function app's SSE endpoint:
```shell
http://0.0.0.0:7071/runtime/webhooks/mcp/sse
```
1. **List MCP Servers** from command palette and start the server
1. In Copilot chat agent mode enter a prompt to trigger the tool, e.g., select some code and enter this prompt
```plaintext
Say Hello
```
```plaintext
what is the stock price of tesla
```
```plaintext
hows the weather in New York city
```
1. When prompted to run the tool, consent by clicking **Continue**
1. When you're done, press Ctrl+C in the terminal window to stop the Functions host process.
### MCP Inspector
1. In a **new terminal window**, install and run MCP Inspector
```shell
npx @modelcontextprotocol/inspector
```
2. CTRL click to load the MCP Inspector web app from the URL displayed by the app (e.g. http://0.0.0.0:5173/#resources)
3. Set the transport type to `SSE`
4. Set the URL to your running Function app's SSE endpoint and **Connect**:
```shell
http://0.0.0.0:7071/runtime/webhooks/mcp/sse
```
>**Note** this step will not work in CodeSpaces. Please move on to Deploy to Remote MCP.
5. **List Tools**. Click on a tool and **Run Tool**.
<img width="2002" height="927" alt="Screenshot 2025-08-12 101327" src="https://github.com/user-attachments/assets/fe7aca16-fb41-4cf2-86dd-d135b782ebc2" />
## Deploy to Azure for Remote MCP from VSCode
you can deploy azure function from the vscode using azure extension. login to azure. Look for Function App in Resource, right click and click "Deploy to Function App". you can also use Azure CLI to deploy the function app to Azure.
<img width="1601" height="829" alt="Untitled" src="https://github.com/user-attachments/assets/87df23f7-8f3b-4a8b-8e35-ae3cb7c5f673" />
## Connect to your *remote* MCP server function app from a client
Your client will need a key in order to invoke the new hosted SSE endpoint, which will be of the form `https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse`. The hosted function requires a system key by default which can be obtained from the [portal](https://learn.microsoft.com/azure/azure-functions/function-keys-how-to?tabs=azure-portal) or the CLI (`az functionapp keys list --resource-group <resource_group> --name <function_app_name>`). Obtain the system key named `mcp_extension`.
### Connect to remote MCP server in MCP Inspector
For MCP Inspector, you can include the key in the URL:
```plaintext
https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<your-mcp-extension-system-key>
```
### Connect to remote MCP server in VS Code - GitHub Copilot
For GitHub Copilot within VS Code, you should instead set the key as the `x-functions-key` header in `mcp.json`, and you would just use `https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse` for the URL. The following example uses an input and will prompt you to provide the key when you start the server from VS Code. Note [mcp.json](.vscode/mcp.json) has already been included in this repo and will be picked up by VS Code. Click Start on the server to be prompted for values including `functionapp-name` (in your /.azure/*/.env file) and `functions-mcp-extension-system-key` which can be obtained from CLI command above or API Keys in the portal for the Function App.
```json
{
"inputs": [
{
"type": "promptString",
"id": "functions-mcp-extension-system-key",
"description": "Azure Functions MCP Extension System Key",
"password": true
},
{
"type": "promptString",
"id": "functionapp-name",
"description": "Azure Functions App Name"
}
],
"servers": {
"remote-mcp-function": {
"type": "sse",
"url": "https://${input:functionapp-name}.azurewebsites.net/runtime/webhooks/mcp/sse",
"headers": {
"x-functions-key": "${input:functions-mcp-extension-system-key}"
}
},
"local-mcp-function": {
"type": "sse",
"url": "http://0.0.0.0:7071/runtime/webhooks/mcp/sse"
}
}
}
```
For MCP Inspector, you can include the key in the URL: `https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<your-mcp-extension-system-key>`.
For GitHub Copilot within VS Code, you should instead set the key as the `x-functions-key` header in `mcp.json`, and you would just use `https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse` for the URL. The following example uses an input and will prompt you to provide the key when you start the server from VS Code:
```json
{
"inputs": [
{
"type": "promptString",
"id": "functions-mcp-extension-system-key",
"description": "Azure Functions MCP Extension System Key",
"password": true
}
],
"servers": {
"my-mcp-server": {
"type": "sse",
"url": "<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse",
"headers": {
"x-functions-key": "${input:functions-mcp-extension-system-key}"
}
}
}
}
```
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues