This repo contains instructions and sample for running MCP server built with the C# (.NET) MCP SDK on Azure Functions. The repo uses the weather sample server to demonstrate how this can be done. You can clone to run and test the server locally, follow by easy deploy with azd up
to have it in the cloud in a few minutes.
Recently Azure Functions released the Functions MCP extension, allowing developers to build MCP servers using Functions programming model, which is essentially Function's event-driven framework, and host them remotely on the serverless platform.
For those who have already built servers with Anthropic's MCP SDKs, it's also possible to host the servers on Azure Functions by running them as custom handlers, which are lightweight web servers that receive events from the Functions host. They allow you to host your already-built MCP servers with minimal code change and benefit from Function's bursty scale, serverless pricing model, and security features.
This repo focuses on the second hosting scenario:
More generally speaking, you can leverage custom handlers to host apps built with your choice of frameworks and SDKs on Azure Functions:
You'll need an Azure subscription. If you don't already have an account, create a free one before you begin.
Ensure you have the following installed:
- Azure Developer CLI
- Azure Functions Core Tools
- Visual Studio Code
- Azure Functions extension on Visual Studio Code
- Clone the repo and open the sample in Visual Studio Code
git clone https://github.com/Azure-Samples/mcp-sdk-functions-hosting-dotnet.git
- In the root directory, run
func start
- Open mcp.json (in the vscode directory) and click the Start button above the local-mcp-server
- Click on the Copilot icon at the top and change to Agent mode in the question window.
- Ask "What is the weather in NYC?" Copilot should call the weather tools to help answer this question.
Note
You may see logs saying Request reached the end of the middleware pipeline without being handled by application code. Request path: GET http://127.0.0.1:63164/, Response status code: 404
. This is expected and does not affect the running server.
In the root directory, and run azd up
. This command will create and deploy the app, plus other required resources.
When the command finishes, your terminal will display output similar to the following:
(✓) Done: Deploying service api
- Endpoint: https://{functionapp-name}.azurewebsites.net/
- After deployment completes, navigate to the Function App resource in the Azure portal, as you will need the key from there.
- Open mcp.json in VS Code.
- Stop the local server by selecting the Stop button above the local-mcp-server
- Start the remote server by selecting the Start button above the remote-mcp-server
- VS Code will prompt you for the Function App name. Copy it from either the terminal output or the Portal.
- VS Code will next prompt you for the Function App key. Copy that from the default key on the Functions -> App keys page in the Azure portal.
Tip
In addition to starting an MCP server in mcp.json, you can see output of a server by clicking More..._ -> _Show Output. The output provides useful information like why a connection might've failed.
In addition to protecting server access through function keys, you can also add APIM in front of the Function app to add an extra layer of security. This sample leverages APIM's policy feature to redirect a client to authenticate with Entra ID before connecting to the MCP server. Specifically, this is achieved by creating two policies on the APIM resource that follow the MCP authorization specification. One policy checks access tokens from incoming requests, and if validation fails, returns a 404 with header containining the path to Protected Resource Metadata (PRM). Another policy returns the PRM, which a client can use to figure out the authorization server (Entra ID in this case) that provides access tokens to the MCP server.
To see the above in action, test connecting to the server using the APIM endpoint instead of the Function app endpoint:
- Open mcp.json in VS Code
- Stop the remote-mcp-server or local-mcp-server servers if still running
- Start the remote-mcp-server-apim server
- VS Code will prompt you for the APIM resource name
- Click Allow when a window pops up saying the MCP Server wants to authenticate to Microsoft.
- Sign into your Microsoft account to connect to the server
Since Entra ID doesn't provide native support for DCR (Dynamic Client Registration) and PKCE (Proof Key for Code Exchange) today,the above authorization flow is only supported on VS Code. If you use other clients (like Claude or Cursor), the easier option is to access the MCP server using the Function App endpoint and access key. The other option is to try out an experimental approach that provides a workaround, which also leverages APIM.
Language (Stack) | Repo Location |
---|---|
Python | mcp-sdk-functions-hosting-python |
Node | mcp-sdk-functions-hosting-node |
If you've already built an MCP server, follow the instructions in the document Host bring-your-own (BYO) MCP servers on Azure Functions .