A Model Context Protocol (MCP) server implementation that provides Azure Maps functionality as tools for Large Language Models (LLMs). This server exposes the full range of Azure Maps services including search, routing, rendering, and geolocation capabilities.
This project implements an MCP server using Azure Functions that integrates with Azure Maps services. It allows LLMs to perform a wide range of geographic operations including:
- Geocoding & Search: Convert addresses or place names to coordinates and vice versa
- Routing: Calculate routes, travel times, and reachable areas
- Map Rendering: Generate map tiles and static map images
- Geolocation: Determine country codes and location info from IP addresses
Convert street addresses, landmarks, or place names to geographic coordinates with detailed address information:
- Geocoding: Address β Coordinates with detailed properties
- Reverse Geocoding: Coordinates β Human-readable addresses
- Administrative Boundaries: Retrieve polygon boundaries for cities, postal codes, states, countries
- Confidence scores, match codes, and comprehensive address details
Calculate optimal routes and analyze travel patterns:
- Route Directions: Turn-by-turn navigation between multiple points
- Route Matrix: Calculate travel times/distances between multiple origins and destinations
- Route Range (Isochrone): Find areas reachable within time or distance budgets
- Support for multiple travel modes (car, truck, bicycle, pedestrian, etc.)
- Traffic-aware routing and route optimization options
Generate visual map content and tiles:
- Map Tiles: Retrieve individual map tiles for custom mapping applications
- Static Map Images: Generate map snapshots with custom markers and paths
- Tile Metadata: Access tile set information and coordinate systems
- Tile Coordinates: Convert between geographic and tile coordinate systems
- Support for road, satellite, and hybrid map styles
Determine geographic information from IP addresses:
- IP Geolocation: Get country codes from IPv4/IPv6 addresses
- Batch IP Processing: Process multiple IP addresses efficiently
- IP Validation: Validate IP address formats and get technical details
- Support for both public and private IP address analysis
- .NET 9.0 SDK
- Azure Functions Core Tools
- Azure Maps subscription key
- Create an Azure Maps account in the Azure Portal
- Create a new Azure Maps resource
- Copy the subscription key from the resource's authentication settings
Create or update the source/local.settings.json
file with your Azure Maps subscription key:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "None",
"AzureWebJobsSecretStorageType": "Files",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"AZURE_MAPS_SUBSCRIPTION_KEY": "your-azure-maps-subscription-key-here"
}
}
# Navigate to the project directory
cd source
# Clean the project
dotnet clean
# Restore dependencies and build
dotnet build
If you're using VS Code, you can use the predefined tasks:
Ctrl+Shift+P
β "Tasks: Run Task" β "build (functions)"
# Navigate to the source directory
cd source
# Build the project first
dotnet build
# Start the function host
cd bin/Debug/net9.0
func host start
- Press
F5
or use "Run and Debug" in VS Code - Or run the task:
Ctrl+Shift+P
β "Tasks: Run Task" β "func: host start"
# Navigate to the source directory
cd source
# Run the application
dotnet run
The server will start on the default port (typically 7071 for Azure Functions, or 7174 as configured in launch settings).
Deploy to Azure Functions for production use:
# Publish the project
dotnet publish --configuration Release
# Deploy using Azure Functions Core Tools
func azure functionapp publish your-function-app-name
Once running, the MCP server exposes the following tools organized by service category:
{
"name": "geocoding",
"description": "Convert street addresses or place names to longitude and latitude coordinates",
"parameters": {
"address": "string - Address or landmark name",
"maxResults": "number - Maximum results to return (1-100, default: 5)"
}
}
{
"name": "reverse_geocoding",
"description": "Convert longitude and latitude coordinates to a street address",
"parameters": {
"latitude": "number - Latitude coordinate",
"longitude": "number - Longitude coordinate"
}
}
{
"name": "get_polygon",
"description": "Get administrative boundary polygon for a specific location",
"parameters": {
"latitude": "number - Latitude coordinate",
"longitude": "number - Longitude coordinate",
"resultType": "string - locality|postalCode1|adminDistrict1|adminDistrict2|countryRegion",
"resolution": "string - small|medium|large"
}
}
{
"name": "get_route_directions",
"description": "Calculate route directions between coordinates with turn-by-turn instructions",
"parameters": {
"coordinates": "array - Array of lat/lng objects for waypoints",
"travelMode": "string - car|truck|bicycle|pedestrian (default: car)",
"routeType": "string - fastest|shortest|eco (default: fastest)",
"avoidTolls": "boolean - Avoid toll roads",
"avoidHighways": "boolean - Avoid highways"
}
}
{
"name": "get_route_matrix",
"description": "Calculate travel times and distances between multiple origins and destinations",
"parameters": {
"origins": "array - Array of origin coordinate objects",
"destinations": "array - Array of destination coordinate objects",
"travelMode": "string - car|truck|bicycle|pedestrian (default: car)",
"routeType": "string - fastest|shortest|eco (default: fastest)"
}
}
{
"name": "get_route_range",
"description": "Calculate reachable area within time or distance budget (isochrone)",
"parameters": {
"latitude": "number - Starting latitude",
"longitude": "number - Starting longitude",
"timeBudgetInSeconds": "number - Time budget (OR distanceBudgetInMeters)",
"distanceBudgetInMeters": "number - Distance budget (OR timeBudgetInSeconds)",
"travelMode": "string - car|truck|bicycle|pedestrian (default: car)"
}
}
{
"name": "get_map_tileset_metadata",
"description": "Get metadata for map tile sets including endpoints and zoom levels",
"parameters": {
"tileSetId": "string - microsoft.base.road|microsoft.imagery|microsoft.base.hybrid"
}
}
{
"name": "get_map_tile",
"description": "Get a map tile image as base64-encoded PNG",
"parameters": {
"latitude": "number - Tile center latitude",
"longitude": "number - Tile center longitude",
"zoomLevel": "number - Zoom level (1-22, default: 10)",
"tileSetId": "string - Map style (default: microsoft.base.road)",
"tileSize": "number - 256 or 512 pixels (default: 256)"
}
}
{
"name": "get_static_map_image",
"description": "Generate static map image with optional markers and paths",
"parameters": {
"boundingBox": "object - {west, south, east, north} coordinates",
"zoomLevel": "number - Zoom level (1-20, default: 10)",
"width": "number - Image width in pixels (1-8192, default: 512)",
"height": "number - Image height in pixels (1-8192, default: 512)",
"markers": "array - Optional markers with lat/lng/label/color",
"paths": "array - Optional paths with coordinates and styling"
}
}
{
"name": "get_tile_coordinates",
"description": "Calculate tile X,Y coordinates for geographic position",
"parameters": {
"latitude": "number - Latitude coordinate",
"longitude": "number - Longitude coordinate",
"zoomLevel": "number - Zoom level (1-22, default: 10)",
"tileSize": "number - 256 or 512 pixels (default: 256)"
}
}
{
"name": "get_country_code_by_ip",
"description": "Get country code and location info for an IP address",
"parameters": {
"ipAddress": "string - IPv4 or IPv6 address to look up"
}
}
{
"name": "get_country_code_batch",
"description": "Get country codes for multiple IP addresses",
"parameters": {
"ipAddresses": "array - Array of IP addresses (max 100)"
}
}
{
"name": "validate_ip_address",
"description": "Validate IP address format and get technical details",
"parameters": {
"ipAddress": "string - IP address to validate"
}
}
azure-maps-mcp/
βββ source/
β βββ azure-maps-mcp.csproj # Project file with dependencies
β βββ Program.cs # Application entry point and DI configuration
β βββ host.json # Azure Functions host configuration
β βββ local.settings.json # Local development settings (not in repo)
β βββ Services/
β β βββ IAzureMapsService.cs # Service interface
β β βββ AzureMapsService.cs # Azure Maps client implementation
β βββ Tools/
β βββ SearchTool.cs # MCP tools for geocoding and search
β βββ RenderTool.cs # (Reserved for future rendering tools)
βββ README.md
- Azure.Maps.Search (2.0.0-beta.5): Azure Maps Search SDK
- Microsoft.Azure.Functions.Worker (2.0.0): Azure Functions runtime
- Microsoft.Azure.Functions.Worker.Extensions.Mcp (1.0.0-preview.6): MCP support for Azure Functions
- .NET 9.0: Target framework
AZURE_MAPS_SUBSCRIPTION_KEY
: Your Azure Maps subscription key (required)
AzureWebJobsStorage
: Set to "None" for local developmentFUNCTIONS_WORKER_RUNTIME
: Set to "dotnet-isolated"
- Missing subscription key: Ensure
AZURE_MAPS_SUBSCRIPTION_KEY
is set in your environment - Build failures: Make sure you have .NET 9.0 SDK installed
- Function startup issues: Check that Azure Functions Core Tools are installed and up to date
The application uses structured logging. Check the console output for detailed error messages and operational information.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
This project is licensed under the terms specified in the LICENSE file.