This repo contains instructions and sample for running MCP server built with the Node 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.
Watch the video overview

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 latest version of the following installed:
- Azure Developer CLI
- Azure Functions Core Tools
- Visual Studio Code
- Azure Functions extension on Visual Studio Code
Note
The instructions below demonstrate hosting Anthropic's sample weather server on Azure Functions. If you have an existing MCP server that you want to host instead, follow instructions in the article for hosting an existing server.
- Clone the repo
git clone https://github.com/Azure-Samples/mcp-sdk-functions-hosting-node.git
- Open up the sample in VSCode, run
npm install
in the root directory. This will add a node_modules directory. - Run
npm run build
. This will add a dist directory. - Run
func start
to start the MCP server locally. - 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 one of the weather tools to help answer this question.
Before deploying, you need to register the Microsoft.App
resource provider:
az provider register --namespace 'Microsoft.App'
Wait a few seconds for registration to complete. You can check status by using:
az provider show -n Microsoft.App
Once registration state becomes "Registered", run azd up
in the root directory. 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.
When you're done working with your server, you can use this command to delete the resources created on Azure and avoid incurring any further costs:
azd down
Language (Stack) | Repo Location |
---|---|
C# (.NET) | mcp-sdk-functions-hosting-dotnet |
Python | mcp-sdk-functions-hosting-python |
The following are some common issues that come up.
-
InternalServerError: There was an unexpected InternalServerError. Please try again later.
Check if you have registered the
Microsoft.App
resource provider:az provider show -n Microsoft.App
If it's showing up as unregistered, register it:
az provider register --namespace 'Microsoft.App'
Successful registration should show:
Namespace RegistrationPolicy RegistrationState ------------- -------------------- ------------------- Microsoft.App RegistrationRequired Registered
Then run
azd up
again. -
Error: error executing step command 'deploy --all': getting target resource: resource not found: unable to find a resource tagged with 'azd-server-name: api'. Ensure the service resource is corrected tagged in your infrastructure configuration, and rerun provision
This is a known transient error. Try re-running
azd up
. -
Selected user account does not exist in tenant '{name}' and cannot access the application '{app ID}' in that tenant. The account needs to be added as an external user in the tenant first.
When authenticating to the server using the APIM endpoint, you must log with the email associated with the Azure account and subscription in which your resources are deployed.
-
[warning] Error populating auth metadata: Error: Failed to fetch authorization server metadata: 401
Ensure the Function app access key is correct when connecting to the server with the app endpoint.
-
Connection state: Error Error sending message to {endpoint}: TypeError: fetch failed
- Ensure the Function app name is correct when connecting to the server with the app endpoint.
- Ensure the APIM resource name is correct when connecting to the server with the APIM endpoint.
-
Ensure you have the latest version of Azure Functions Core Tools installed.
- You need version >=4.2.1. Check by running
func --version
.
- You need version >=4.2.1. Check by running