Skip to content

Repo contains samples and instructions for remote hosting of MCP servers built with the official Anthropic MCP SDKs on Azure Functions.

License

Notifications You must be signed in to change notification settings

Azure-Samples/mcp-sdk-functions-hosting-dotnet

Host remote MCP servers built with official MCP SDKs on Azure Functions

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.

Running MCP server as custom handler on Azure Functions

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:

Diagram showing hosting of weather server built with official MCP SDKs.

More generally speaking, you can leverage custom handlers to host apps built with your choice of frameworks and SDKs on Azure Functions:

Diagram showing hosting of Function app and custom handler apps.

Prerequisites

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:

Run the server locally

  1. Clone the repo and open the sample in Visual Studio Code
    git clone https://github.com/Azure-Samples/mcp-sdk-functions-hosting-dotnet.git
    
  2. In the root directory, run func start
  3. Open mcp.json (in the vscode directory) and click the Start button above the local-mcp-server
  4. Click on the Copilot icon at the top and change to Agent mode in the question window.
  5. 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.

Deploy

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/

Connect to server on Visual Studio Code

  1. After deployment completes, navigate to the Function App resource in the Azure portal, as you will need the key from there.
  2. Open mcp.json in VS Code.
  3. Stop the local server by selecting the Stop button above the local-mcp-server
  4. Start the remote server by selecting the Start button above the remote-mcp-server
  5. VS Code will prompt you for the Function App name. Copy it from either the terminal output or the Portal.
  6. 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.

Server authorization using Azure API Management (APIM)

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:

  1. Open mcp.json in VS Code
  2. Stop the remote-mcp-server or local-mcp-server servers if still running
  3. Start the remote-mcp-server-apim server
  4. VS Code will prompt you for the APIM resource name
  5. Click Allow when a window pops up saying the MCP Server wants to authenticate to Microsoft.
  6. Sign into your Microsoft account to connect to the server

Support for other clients

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.

Next steps

Find this sample in other languages

Language (Stack) Repo Location
Python mcp-sdk-functions-hosting-python
Node mcp-sdk-functions-hosting-node

Bring-your-own MCP server

If you've already built an MCP server, follow the instructions in the document Host bring-your-own (BYO) MCP servers on Azure Functions .

About

Repo contains samples and instructions for remote hosting of MCP servers built with the official Anthropic MCP SDKs on Azure Functions.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •