Getting Started with Remote MCP Servers using Azure Functions (.NET/C#)

Getting Started with Remote MCP Servers using Azure Functions (.NET/C#)

This is a quickstart template to easily build and deploy a custom remote MCP server to the cloud using Azure functions. You can clone/restore/run on your local machine with debugging, and `azd up` to have it in the cloud in a couple minutes. The MCP server is secured by design using

Azure-Samples

Cloud Platforms
Visit Server

README

<!--

name: Remote MCP with Azure Functions (.NET/C#) description: Run a remote MCP server on Azure functions.
page_type: sample languages:

  • csharp
  • bicep
  • azdeveloper products:
  • azure-functions
  • azure urlFragment: remote-mcp-functions-dotnet

-->

Getting Started with Remote MCP Servers using Azure Functions (.NET/C#)

This is a quickstart template to easily build and deploy a custom remote MCP server to the cloud using Azure functions. You can clone/restore/run on your local machine with debugging, and azd up to have it in the cloud in a couple minutes. The MCP server is secured by design using keys and HTTPs, and allows more options for OAuth using EasyAuth and/or API Management as well as network isolation using VNET.

If you're looking for this sample in more languages check out the Node.js/TypeScript and Python samples.

Open in GitHub Codespaces

Prerequisites

Below is the architecture diagram for the Remote MCP Server using Azure Functions:

Architecture Diagram

Prepare your local environment

An Azure Storage Emulator is needed for this particular sample because we will save and get snippets from blob storage.

  1. Start Azurite

    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. From the src folder, run this command to start the Functions host locally:

    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>

Use the MCP server from within a client/host

VS Code - Copilot Edits

  1. Add MCP Server from command palette and add URL to your running Function app's SSE endpoint:

    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
    
  2. List MCP Servers from command palette and start the server

  3. In Copilot chat agent mode enter a prompt to trigger the tool, e.g., select some code and enter this prompt

    Say Hello 
    
    Save this snippet as snippet1 
    
    Retrieve snippet1 and apply to NewFile.cs
    
  4. When prompted to run the tool, consent by clicking Continue

  5. When you're done, press Ctrl+C in the terminal window to stop the func.exe host process.

MCP Inspector

  1. In a new terminal window, install and run MCP Inspector

    npx @modelcontextprotocol/inspector node build/index.js
    
  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:

    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
    
  5. List Tools. Click on a tool and Run Tool.

Deploy to Azure for Remote MCP

Run this azd command to provision the function app, with any required Azure resources, and deploy your code:

azd up

You can opt-in to a VNet being used in the sample. To do so, do this before azd up

azd env set VNET_ENABLED true

Additionally, API Management can be used for improved security and policies over your MCP Server, and App Service built-in authentication can be used to set up your favorite OAuth provider including Entra.

Connect to your 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 or the CLI (az functionapp keys list --resource-group <resource_group> --name <function_app_name>). Obtain the system key named mcp_extension.

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:

{
    "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}"
            }
        }
    }
}

Redeploy your code

You can run the azd up command as many times as you need to both provision your Azure resources and deploy code updates to your function app.

[!NOTE] Deployed code files are always overwritten by the latest deployment package.

Clean up resources

When you're done working with your function app and related resources, you can use this command to delete the function app and its related resources from Azure and avoid incurring any further costs:

azd down

Source Code

The function code for the GetSnippet and SaveSnippet endpoints are defined in SnippetsTool.cs. The McpToolsTrigger attribute applied to the async Run method exposes the code function as an MCP Server.

This shows the code for a few MCP server examples (get string, get object, save object):

[Function(nameof(SayHello))]
public string SayHello(
    [McpToolTrigger(HelloToolName, HelloToolDescription)] ToolInvocationContext context
)
{
    logger.LogInformation("Saying hello");
    return "Hello I am MCP Tool!";
}

[Function(nameof(GetSnippet))]
public object GetSnippet(
    [McpToolTrigger(GetSnippetToolName, GetSnippetToolDescription)] ToolInvocationContext context,
    [BlobInput(BlobPath)] string snippetContent)
{
    return snippetContent;
}

[Function(nameof(SaveSnippet))]
[BlobOutput(BlobPath)]
public string SaveSnippet(
    [McpToolTrigger(SaveSnippetToolName, SaveSnippetToolDescription)] ToolInvocationContext context,
    [McpToolProperty(SnippetNamePropertyName, PropertyType, SnippetNamePropertyDescription)] string name,
    [McpToolProperty(SnippetPropertyName, PropertyType, SnippetPropertyDescription)] string snippet)
{
    return snippet;
}

Next Steps

Recommended Servers

contentful-mcp

contentful-mcp

Update, create, delete content, content-models and assets in your Contentful Space

Featured
TypeScript
Supabase MCP Server

Supabase MCP Server

A Model Context Protocol (MCP) server that provides programmatic access to the Supabase Management API. This server allows AI models and other clients to manage Supabase projects and organizations through a standardized interface.

Featured
JavaScript
Azure MCP Server

Azure MCP Server

Enables natural language interaction with Azure services through Claude Desktop, supporting resource management, subscription handling, and tenant selection with secure authentication.

Official
Local
TypeScript
SettleMint

SettleMint

Leverage SettleMint's Model Context Protocol server to seamlessly interact with enterprise blockchain infrastructure. Build, deploy, and manage smart contracts through AI-powered assistants, streamlining your blockchain development workflow for maximum efficiency.

Official
Local
TypeScript
Brev

Brev

Run, build, train, and deploy ML models on the cloud.

Official
Local
Python
Story SDK MCP Server

Story SDK MCP Server

This server provides MCP (Model Context Protocol) tools for interacting with Story's Python SDK. Features Get license terms Mint and register IP Asset with PIL Terms Mint license tokens Send $IP to a wallet Upload image to ipfs via Pinata [External] Upload ip and nft metadata via Pinata [External]

Official
Python
Tembo MCP Server

Tembo MCP Server

An MCP server that enables Claude to interact with Tembo Cloud platform API, allowing users to manage Tembo Cloud resources through natural language.

Official
TypeScript
Workers MCP

Workers MCP

A package that connects Claude Desktop and other MCP clients to Cloudflare Workers, enabling custom functionality to be accessed via natural language through the Model Context Protocol.

Official
TypeScript
Appwrite MCP Server

Appwrite MCP Server

A Model Context Protocol server that allows AI assistants to interact with Appwrite's API, providing tools to manage databases, users, functions, teams, and other resources within Appwrite projects.

Official
Python
MCP2Lambda

MCP2Lambda

Enables AI models to interact with AWS Lambda functions via the MCP protocol, allowing access to private resources, real-time data, and custom computation in a secure environment.

Official
Python