Skip to content

jpad5/mcp-remote-server-azure-func

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

6 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Remote MCP Weather Server β€” Azure Functions (.NET)

Open in GitHub Codespaces Open in Dev Containers

A remote Model Context Protocol (MCP) server built with Azure Functions and .NET 10 that exposes a weather tool powered by the free Open-Meteo API. No API key is required.

Use this template to quickly build, debug, and deploy your own remote MCP server to Azure. The server is secured by design with HTTPS and function keys, and supports optional network isolation via VNET.

πŸ“š Based on the Remote MCP Functions collection β€” This project is one of the language-specific implementations from the Azure-Samples/remote-mcp-functions repository, which provides quickstart templates for building remote MCP servers on Azure Functions across multiple languages (Python, TypeScript, C#, Java). Visit the overview repo for the full catalog and additional resources.

Background β€” Why Remote MCP on Azure Functions?

The Model Context Protocol (MCP) enables AI assistants to securely call external tools and access data. While MCP servers are often run locally (via stdio), running them remotely unlocks key advantages:

  • Shared access β€” A single deployed MCP server can serve multiple clients and users.
  • Server-side secrets β€” API keys, database connections, and credentials stay on the server, never exposed to clients.
  • Centralized updates β€” Update tool logic once; all connected clients get the change instantly.
  • Enterprise security β€” Leverage Azure networking (VNET, Private Endpoints), managed identity, and API Management / Entra ID for authentication.
  • Scalability β€” Azure Functions Flex Consumption plan scales to zero and up to 100 instances automatically.

The remote-mcp-functions collection demonstrates how to build these remote servers using two approaches: the MCP Extension for Azure Functions and self-hosted MCP SDK servers. This project uses the MCP Extension approach.

Solution Design β€” MCP Extension vs. MCP SDK

There are two distinct approaches to hosting MCP servers on Azure Functions. Understanding the trade-offs helps you choose the right one for your scenario.

flowchart TB
    subgraph ExtApproach["MCP Extension for Azure Functions"]
        direction TB
        E1["Your code: tool logic only(McpToolTrigger attribute)"]
        E2["MCP protocol handling: managed by Functions host"]
        E3["Transport: built-in SSE + Streamable HTTP"]
        E1 --> E2 --> E3
    end

    subgraph SDKApproach["Self-hosted MCP SDK"]
        direction TB
        S1["Your code: tool logic + server setup (MCP SDK)"]
        S2["MCP protocol handling: your responsibility"]
        S3["Transport: configured in your SDK setup"]
        S1 --> S2 --> S3
    end

    ExtApproach -.- note1["βœ… This project uses this approach"]

    style note1 fill:#d4edda,stroke:#28a745,color:#155724
    style ExtApproach fill:#e7f3ff,stroke:#0078d4
    style SDKApproach fill:#fff3e0,stroke:#f57c00
Loading

Comparison

MCP Extension (this project) MCP SDK (self-hosted)
Package Microsoft.Azure.Functions.Worker.Extensions.Mcp ModelContextProtocol (official C# SDK)
How you define tools Declarative β€” [McpToolTrigger] attribute on a function Programmatic β€” register tools with the MCP SDK server builder
Protocol handling Fully managed by the Azure Functions host You configure and manage the MCP server lifecycle
Transport Built-in SSE + Streamable HTTP at /runtime/webhooks/mcp You set up transport (SSE, stdio, etc.) in code
Lines of code Minimal β€” just write tool logic More setup β€” server init, DI, transport config
Flexibility Convention-based; great for standard tools Full control over server behavior, middleware, resources
Best for Rapid development, standard tool patterns, teams familiar with Azure Functions Custom MCP features, complex server logic, non-Functions hosting
Example repos C# Β· Python Β· TypeScript Β· Java C# Β· Python Β· TypeScript

Why this project uses the MCP Extension

This project uses the MCP Extension approach because:

  1. Minimal boilerplate β€” A single [McpToolTrigger] attribute turns any function into an MCP tool. No server setup, transport config, or protocol plumbing needed.
  2. Native Functions experience β€” Follows the same trigger/binding pattern as HTTP triggers, Timer triggers, etc. If you know Azure Functions, you already know how to build MCP tools.
  3. Production-ready infrastructure β€” The extension manages sessions, transport negotiation, and the /runtime/webhooks/mcp endpoint automatically, so you can focus on tool logic.

Features

  • MCP Tool β€” GetWeather: Returns current weather conditions (temperature, humidity, wind, condition) for any city name or zip code.
  • Built with the native Azure Functions MCP extension (McpToolTrigger).
  • Uses Open-Meteo geocoding + weather APIs β€” no API key needed.
  • Deployed on the Azure Functions Flex Consumption plan for cost-efficient, serverless scaling.
  • Infrastructure as Code with Bicep and one-command deployment via Azure Developer CLI (azd up).
  • Pre-configured VS Code MCP client config for local development.

Architecture

flowchart LR
    Client["πŸ–₯️ MCP Client\n(VS Code, Claude, etc.)"]
    Functions["⚑ Azure Functions Host\n(.NET Isolated Worker)"]
    Tool["🌀️ GetWeather Tool\n(McpToolTrigger)"]
    API["🌍 Open-Meteo API\n(geocoding + weather)"]

    Client -- "MCP (SSE / HTTP)\nJSON-RPC request" --> Functions
    Functions -- "JSON-RPC response" --> Client
    Functions --> Tool
    Tool -- "HTTP GET" --> API
Loading

Azure Deployment

flowchart TB
    subgraph Azure["☁️ Azure Subscription"]
        RG["πŸ“¦ Resource Group"]
        subgraph RG
            ASP["πŸ“‹ App Service Plan\n(Flex Consumption FC1)"]
            FA["⚑ Function App\n(dotnet-isolated v10)"]
            MI["πŸ”‘ Managed Identity"]
            SA["πŸ’Ύ Storage Account"]
            AI["πŸ“Š Application Insights"]
            LA["πŸ“ Log Analytics"]
            VNET["πŸ”’ Virtual Network\n(optional)"]
        end
    end

    ASP --> FA
    MI --> FA
    MI --> SA
    MI --> AI
    FA --> SA
    FA --> AI
    AI --> LA
    VNET -.-> FA
    VNET -.-> SA
Loading

Prerequisites

Requirement Install
.NET 10 SDK Download
Azure Functions Core Tools v4 Install
Azure Developer CLI (azd) Install (v1.23+)
Node.js (for Azurite) Download
Azure subscription Free account

Project Structure

β”œβ”€β”€ azure.yaml                       # Azure Developer CLI configuration
β”œβ”€β”€ infra/                           # Bicep infrastructure-as-code
β”‚   β”œβ”€β”€ main.bicep                   # Main deployment (subscription scope)
β”‚   β”œβ”€β”€ main.parameters.json         # Deployment parameters
β”‚   β”œβ”€β”€ abbreviations.json           # Resource naming abbreviations
β”‚   └── app/
β”‚       β”œβ”€β”€ api.bicep                # Function App (Flex Consumption)
β”‚       β”œβ”€β”€ rbac.bicep               # Managed identity role assignments
β”‚       β”œβ”€β”€ vnet.bicep               # Virtual network (optional)
β”‚       └── storage-PrivateEndpoint.bicep
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ McpWeatherServer.csproj      # .NET project file
β”‚   β”œβ”€β”€ Program.cs                   # Functions host entry point
β”‚   β”œβ”€β”€ WeatherFunction.cs           # MCP tool definition
β”‚   β”œβ”€β”€ WeatherService.cs            # Open-Meteo API client
β”‚   β”œβ”€β”€ host.json                    # Functions host configuration
β”‚   └── local.settings.json          # Local dev settings
└── .vscode/
    └── mcp.json                     # VS Code MCP client configuration

Quickstart β€” Run Locally

  1. Install Azurite (local storage emulator):

    npm install -g azurite
  2. Start Azurite in a separate terminal:

    azurite --silent
  3. Start the Functions host:

    cd src
    func start
  4. The MCP server is now running at:

    Transport URL
    SSE http://localhost:7071/runtime/webhooks/mcp/sse
    Streamable HTTP http://localhost:7071/runtime/webhooks/mcp
  5. Connect from VS Code: The .vscode/mcp.json is pre-configured β€” open Copilot Chat and ask something like "What's the weather in Seattle?".

Deploy to Azure

  1. Log in:

    azd auth login
  2. Provision and deploy (creates all resources and deploys code):

    azd up

    You'll be prompted for an environment name and Azure region. Deployment takes ~3–5 minutes.

  3. Get the deployed endpoint:

    azd env get-values

    Look for AZURE_FUNCTION_NAME β€” your remote MCP endpoint will be:

    https://<AZURE_FUNCTION_NAME>.azurewebsites.net/runtime/webhooks/mcp
    
  4. Retrieve the function key (required for remote access):

    az functionapp keys list -n <AZURE_FUNCTION_NAME> -g <RESOURCE_GROUP> --query "systemKeys.mcp_extension" -o tsv

    Append it as a query parameter: ?code=<KEY>.

Connect an MCP Client

VS Code β€” Local

Already configured in .vscode/mcp.json. Just run func start and use Copilot Chat.

VS Code β€” Remote (Azure)

Add a new entry to .vscode/mcp.json:

{
  "servers": {
    "remote-mcp-weather": {
      "type": "http",
      "url": "https://<FUNCTION_APP>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<MCP_EXTENSION_KEY>"
    }
  }
}

Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "weather": {
      "type": "sse",
      "url": "https://<FUNCTION_APP>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<MCP_EXTENSION_KEY>"
    }
  }
}

MCP Tools

GetWeather

Returns current weather conditions for a given location.

Parameter Type Description
location string City name or zip code (e.g., Seattle, 94568, New York)

Example response:

{
  "Location": "Dublin, California, United States",
  "Condition": "Clear sky",
  "TemperatureC": 16,
  "TemperatureF": 62,
  "HumidityPercent": 64,
  "WindKph": 22,
  "Wind": "22 km/h WNW",
  "ReportedAtUtc": "2026-03-05 05:15:00Z",
  "Source": "open-meteo"
}

Azure Resources

When deployed with azd up, the following resources are created:

Resource Purpose
Azure Functions (Flex Consumption FC1) Hosts the MCP server
Storage Account Function app state and deployment packages
Application Insights Monitoring and logging
Log Analytics Workspace Centralized logs
User-Assigned Managed Identity Secure access to storage and monitoring
Virtual Network (optional) Network isolation with private endpoints

Cost

The Flex Consumption plan charges only for actual execution time. For development and low-traffic scenarios, costs are minimal. See Azure Functions pricing for details.

Clean Up

To remove all Azure resources:

azd down

Contributing

License

This project is licensed under the MIT License β€” see LICENSE.md.

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors