OpenMeteoMCPServer

dstamand-msft/OpenMeteoMCPServer

3.2

If you are the rightful owner of OpenMeteoMCPServer and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

The OpenMeteo MCP Server is an Azure Functions-based server that provides comprehensive weather data through the Open-Meteo API, exposing multiple weather-related tools for various forecasting and environmental data needs.

Tools
5
Resources
0
Prompts
0

OpenMeteo MCP Server

An Azure Functions-based Model Context Protocol (MCP) server that provides comprehensive weather data through the Open-Meteo API. This server exposes multiple weather-related tools for forecasting, historical data, air quality, marine weather, and more.

Overview

The OpenMeteo MCP Server is built on Azure Functions using the isolated worker model with .NET 10.0. It implements the Model Context Protocol to expose weather data services as callable tools that can be integrated with AI assistants and other MCP-compatible clients.

Features

Available Tools

The server provides the following weather and geolocation tools:

  • Weather Forecast Tools

    • weather_forecast_hourly_variables_descriptions - Get descriptions of hourly weather variables
    • weather_forecast_daily_variables_descriptions - Get descriptions of daily weather variables
    • weather_forecast_models_descriptions - Get available weather forecast models
    • WeatherForecastTool - Get weather forecast data
  • Historical & Archive Data

    • WeatherArchiveTool - Access historical weather data
  • Environmental Data

    • AirQualityTool - Get air quality forecasts
    • MarineWeatherTool - Get marine weather forecasts
    • FloodForecastTool - Get river discharge and flood forecasts
  • Long-term Forecasts

    • SeasonalForecastTool - Get seasonal weather forecasts
    • ClimateProjectionTool - Get climate projection data
    • EnsembleForecastTool - Get ensemble forecast data
  • Geolocation

    • ElevationTool - Get elevation data for coordinates
    • GeocodingTool - Geocode location names to coordinates
  • Model-Specific Forecasts

    • DwdIconForecastTool - DWD ICON weather model
    • GfsForecastTool - GFS weather model
    • MeteoFranceForecastTool - Météo-France weather model
    • EcmwfForecastTool - ECMWF weather model
    • JmaForecastTool - JMA weather model
    • MetnoForecastTool - MET Norway weather model
    • GemForecastTool - GEM weather model

Architecture

Technology Stack

  • Runtime: .NET 10.0
  • Platform: Azure Functions v4 (Flex Consumption Plan)
  • Hosting: Azure App Service
  • Monitoring: Application Insights
  • Storage: Azure Storage Account
  • Infrastructure: Bicep

Project Structure

OpenMeteo-MCPServer/
├── infra/                          # Infrastructure as Code
│   ├── main.bicep                  # Main Bicep deployment template
│   ├── modules/
│   │   ├── monitoring.bicep        # Application Insights & Log Analytics
│   │   ├── rbac.bicep              # Role-based access control
│   │   └── web.bicep               # Function App & App Service Plan
│   └── abbreviations.json          # Azure resource naming conventions
├── src/
│   └── OpenMeteoMCPServer/
│       ├── Program.cs              # Application entry point
│       ├── OpenMeteoTool.cs        # MCP tool implementations
│       ├── OpenMeteoOptions.cs     # Configuration options
│       ├── Extensions/             # HttpClient extensions
│       ├── Models/                 # Request/response models
│       └── Services/
│           └── OpenMeteoClient.cs  # Open-Meteo API client
└── temp/
    └── deployment.bicepparam       # Deployment parameters

Prerequisites

Required Tools

Azure Subscription

You need an active Azure subscription with permissions to:

  • Create resource groups
  • Deploy Azure Functions
  • Create storage accounts
  • Create Application Insights resources

Local Development

Configuration

  1. Update local.settings.json with your settings:
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated"
  }
}

Optional: You can add an Open-Meteo API key for higher rate limits:

{
  "OpenMeteo__ApiKey": "<your-api-key>"
}

Running Locally

  1. Navigate to the project directory:

    cd src\OpenMeteoMCPServer
    
  2. Start the function app:

    func start
    
  3. The MCP server will be available at http://localhost:7071

Deployment

Step 1: Deploy Infrastructure

The infrastructure is deployed using Bicep templates with Azure PowerShell.

1.1 Login to Azure
Connect-AzAccount
1.2 Set Your Subscription
Set-AzContext -SubscriptionId "<your-subscription-id>"
1.3 Create Resource Group
$resourceGroupName = "<your-resourcegroup-name>"
$location = "<your-location>"

New-AzResourceGroup -Name $resourceGroupName -Location $location
1.4 Deploy Infrastructure

You can deploy using either inline parameters or a parameter file.

Option A: Using Inline Parameters

$deploymentParams = @{
    ResourceGroupName = $resourceGroupName
    TemplateFile = ".\infra\main.bicep"
    location = $location
    storageAccountName = "<your-storage-account-name>"  # Must be globally unique, or leave empty for auto-generated
    functionAppName = "<your-function-app-name>"  # Or leave empty for auto-generated
    functionPlanName = "<your-app-service-plan-name>"  # Or leave empty for auto-generated
    applicationInsightsName = "<your-app-insights-name>"  # Or leave empty for auto-generated
    logAnalyticsName = "<your-log-analytics-name>"  # Or leave empty for auto-generated
    maximumInstanceCount = 100
    instanceMemoryMB = 512
    allowUserIdentityPrincipal = $false
    principalId = "<your-principal-id>"  # Leave empty unless needed for dev/test
    tags = @{
        Environment = "<your-environment>"
        Project = "<your-project-name>"
    }
}

New-AzResourceGroupDeployment @deploymentParams -Verbose

Option B: Using Parameter File

  1. Create or update temp\deployment.bicepparam:
using '../infra/main.bicep'

param location = '<your-azure-region>'
param storageAccountName = '<your-storage-account-name>'  // Or leave empty for auto-generated
param functionAppName = '<your-function-app-name>'  // Or leave empty for auto-generated
param functionPlanName = '<your-app-service-plan-name>'  // Or leave empty for auto-generated
param applicationInsightsName = '<your-app-insights-name>'  // Or leave empty for auto-generated
param logAnalyticsName = '<your-log-analytics-name>'  // Or leave empty for auto-generated
param maximumInstanceCount = 100
param instanceMemoryMB = 512
param allowUserIdentityPrincipal = false
param principalId = ''  // Leave empty unless needed for dev/test
  1. Deploy using the parameter file:
New-AzResourceGroupDeployment `
    -ResourceGroupName $resourceGroupName `
    -TemplateFile ".\infra\main.bicep" `
    -TemplateParameterFile ".\temp\deployment.bicepparam" `
    -Verbose

Step 2: Build and Publish Function App

2.1 Build the Function App

Navigate to the project directory and build:

cd src\OpenMeteoMCPServer
dotnet build --configuration Release
2.2 Publish to Azure

Option A: Using Publish-AzWebApp (Direct Deployment)

# Set variables
$resourceGroupName = "<your-resourcegroup-name>"
$functionAppName = "<your-functionapp-name>"
$publishFolder = ".\bin\Release\net10.0\publish"

# Publish the function app locally first
dotnet publish --configuration Release --output $publishFolder

# Create a zip file from the publish folder
$zipFile = "$env:TEMP\functionapp.zip"
if (Test-Path $zipFile) { Remove-Item $zipFile -Force }

# Compress the published files
Compress-Archive -Path "$publishFolder\*" -DestinationPath $zipFile -Force

# Publish to Azure Function App
Publish-AzWebApp `
    -ResourceGroupName $resourceGroupName `
    -Name $functionAppName `
    -ArchivePath $zipFile `
    -Force

Option B: Using Azure Functions Core Tools

# From the src\OpenMeteoMCPServer directory
func azure functionapp publish $functionAppName
2.3 Configure Application Settings (Optional)

If you want to use an Open-Meteo API key for higher rate limits:

# Set application settings
$appSettings = @{
    "OpenMeteo__ApiKey" = "<your-api-key>"
}

Set-AzWebApp -ResourceGroupName $resourceGroupName -Name $functionAppName -AppSettings $appSettings
2.4 Restart the Function App
Restart-AzWebApp -ResourceGroupName $resourceGroupName -Name $functionAppName

Step 3: Verify Deployment

3.1 Check Function App Status
# Get Function App details
$functionApp = Get-AzWebApp -ResourceGroupName $resourceGroupName -Name $functionAppName
$functionApp.State  # Should show "Running"
$functionApp.DefaultHostName  # Your function app URL
3.2 Test the MCP Endpoint
# Get the function app URL
$functionAppUrl = "https://$($functionApp.DefaultHostName)"

# Test the MCP endpoint
Invoke-RestMethod -Uri "$functionAppUrl/mcp" -Method Get

Configuration

Application Settings

SettingDescriptionRequired
OpenMeteo__ApiKeyAPI key for Open-Meteo services (for higher rate limits)No

Infrastructure Parameters

ParameterDescriptionDefault
locationThe location where to deploy the resources.Required
applicationInsightsNameThe name of the Application Insights resource. Defaults to a generated name.''
logAnalyticsNameThe name of the Log Analytics resource. Defaults to a generated name.''
storageAccountNameThe name of the Storage Account to use for the Function App. If not provided, a new storage account will be created with a generated name.''
functionPlanNameThe name of the App Service Plan. If not provided, a new App Service Plan will be created with a generated name.''
functionAppNameThe name of the function app. If not provided, a new function app will be created with a generated name.''
maximumInstanceCountThe maximum number of instances for the Function App in Flex Consumption plan. (40-1000)100
instanceMemoryMBThe memory (in MB) allocated to each instance of the Function App in Flex Consumption plan. (512, 2048, 4096)512
allowUserIdentityPrincipalWhether to enable role assignments for a user identity for development/testing purposes.false
principalIdId of the user running this template, to be used for testing and debugging for access to Azure resources. This is not required in production. Leave empty if not needed.''
tagsTags to apply to all resources{}

Monitoring

Application Insights

Monitor your function app using Application Insights:

# Get Application Insights resource
$appInsights = Get-AzApplicationInsights -ResourceGroupName $resourceGroupName

# View metrics in Azure Portal
Start-Process "https://portal.azure.com/#resource$($appInsights.Id)"

View Logs

# Stream logs
$functionApp = Get-AzWebApp -ResourceGroupName $resourceGroupName -Name $functionAppName
Get-AzWebAppLog -ResourceGroupName $resourceGroupName -Name $functionAppName -Tail

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a Pull Request

License

[Specify your license here]

Resources

Support

For issues and questions:

  • GitHub Issues: Create an issue
  • Documentation: See the /docs folder for additional documentation

App Registration (Secure the MCP Server)

  • Purpose: Configure an Azure AD (Microsoft Entra) app registration to issue OAuth access tokens that secure the MCP server endpoints and allow trusted clients to call the API.
  • Application ID URI: https://<function_app_FQDN>runtime/webhooks/mcp
  • Trusted client example: Visual Studio Code (MCP tooling) client id aebc6443-996d-45c2-90f0-388ff96faa56.

Steps (Azure Portal)

  1. Create the API app registration

    • Azure Portal → Azure Active Directory → App registrations → New registration
    • Name: OpenMeteoMCPServer-API (or a name you prefer)
    • Supported account types: choose according to your tenant requirements
    • Redirect URI: not required for a server-only API
  2. Set the Application ID URI

    • App registration → Expose an API → Set Application ID URI
    • Value: https://<function_app_FQDN>runtime/webhooks/mcp
  3. Create an API scope

    • App registration → Expose an API → Add a scope
    • Example scope name: user_impersonation
    • Admin consent display name: User Impersonation
    • Who can consent: Admins and users (or restrict to admins)
    • Scope URI example: https://<function_app_FQDN>/runtime/webhooks/mcp/user_impersonation
  4. Authorize client applications (pre-authorize clients so they won't prompt for consent)

    • App registration → Expose an API → Authorized client applications → + Add a client application
    • Add Visual Studio Code client id: aebc6443-996d-45c2-90f0-388ff96faa56
    • Check the scope you want to grant and Add application
  5. Update the app manifest (optional but recommended)

    • App registration → Manifest
    • Change or add the property: "requestedAccessTokenVersion": 2
    • Why: aligns the app with v2 access token patterns and ensures clients request v2 tokens when needed.
  • Update the Function App Authentication blade

  • Open the Function App in the Azure Portal and select Settings → Authentication.

  • Select Add identity provider → Microsoft.

  • For Choose a tenant for your application and its users, use Workforce configuration (current tenant).

  • Under App registration use the existing API app registration you created in the steps above (do not create a different app here).

  • Under Additional checks you can later restrict access to specific client applications; for initial setup leave the check to allow any identity unless you already know which client identities should access the MCP server.

  • Under App Service authentication settings set:

    • Restrict access: Require authentication
    • Unauthenticated requests: HTTP 401 Unauthorized (recommended for APIs)
    • Token store: check the box (allows token refresh) Pre-authorize Visual Studio Code (optional but convenient)
  1. In the App registration for the API, go to Expose an API → Authorized client applications → + Add a client application and add aebc6443-996d-45c2-90f0-388ff96faa56.
  2. In the same view select the scope you created (for example, user_impersonation) before adding.

Configure Protected Resource Metadata (PRM) on the Function App (preview)

  • Copy the scope value from Expose an API (for example, https://<function_app_FQDN>runtime/webhooks/mcp/user_impersonation).
  • Run the AZ CLI command to set the PRM default with scopes (replace placeholders):
az functionapp config appsettings set --name <function-app-name> --resource-group <resource-group-name> --settings "WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES=<scope>"

Disable key-based authentication in the MCP server (when using built-in auth)

  • In host.json, set the MCP extension webhook authorization level to Anonymous so Function-level key-based auth is not required by the MCP extension:
{
  "version": "2.0",
  "extensions": {
    "mcp": {
      "system": {
        "webhookAuthorizationLevel": "Anonymous"
      }
    }
  }
}

Quick examples (Azure CLI)

  • Create the app (example):
az ad app create --display-name "OpenMeteoMCPServer-API" --identifier-uris "api://f2f6e0a1-ea16-492e-a287-0849136ecd24"
  • Set the PRM app setting (example):
az functionapp config appsettings set --name <function-app-name> --resource-group <resource-group-name> --settings "WEBSITE_AUTH_PRM_DEFAULT_WITH_SCOPES=api://f2f6e0a1-ea16-492e-a287-0849136ecd24/user_impersonation"

Reference


Note: Remember to replace placeholder values (like <your-subscription-id>, <your-openmeteo-api-key>) with your actual values before deploying.