google-maps-mcp-server

ettysekhon/google-maps-mcp-server

3.3

If you are the rightful owner of google-maps-mcp-server 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 Google Maps MCP Server is a production-ready server that provides a standardized MCP interface for accessing Google Maps Platform APIs, enabling AI agents to leverage real-world location intelligence.

Tools
7
Resources
0
Prompts
0

Google Maps MCP Server

PyPI Python Version License Tests codecov Code style: black Ruff

Production-ready Model Context Protocol (MCP) server for Google Maps Platform APIs.

Empower your AI agents with real-world location intelligence: directions, places, geocoding, traffic analysis, and road network data—all through a standardised MCP interface.


Features

  • Production-Ready: Robust error handling, automatic retries with exponential backoff, structured logging
  • Universal Integration: Works with Claude Desktop, Google ADK, and any MCP-compatible client
  • Comprehensive API Coverage: 11 tools spanning all major Google Maps APIs
  • Type-Safe: Full type annotations with Pydantic validation and mypy compliance
  • Zero Configuration: Sensible defaults, works out of the box
  • Thoroughly Tested: >90% code coverage with unit and integration tests
  • Docker Support: Ready-to-deploy container images
  • Excellent Documentation: Extensive examples, API reference, and best practices
  • Modern Python: Built for Python 3.10+ using uv package manager

Supported APIs & Tools

APIToolDescriptionUse Cases
Places APIsearch_placesFind points of interest near a locationRestaurant recommendations, gas station finder, POI search
Places APIget_place_detailsGet comprehensive details for a placeOpening hours, websites, phone numbers, accessibility info
Directions APIget_directionsGet routes with real-time trafficRoute planning, ETA calculation, alternative routes
Directions APIget_traffic_conditionsAnalyse real-time traffic congestionCommute monitoring, delay estimation, fleet routing
Geocoding APIgeocode_addressConvert addresses to coordinatesAddress validation, location lookup
Geocoding APIreverse_geocodeConvert coordinates to addressesLocation identification, address lookup
Distance Matrix APIcalculate_distance_matrixMulti-origin/destination distancesFleet routing, delivery optimisation, travel planning
Roads APIsnap_to_roadsSnap GPS points to road networkGPS trace cleaning, route reconstruction
Roads APIget_speed_limitsRetrieve speed limit dataFleet safety monitoring, compliance checking
Elevation APIget_route_elevation_gainCalculate elevation gain and profileCycling/hiking planning, fuel efficiency
Compoundcalculate_route_safety_factorsAssess route safety risksFleet safety, insurance scoring, driver assistance

Quick Start

Prerequisites

  • Python 3.10 or higher (3.14+ recommended)
  • Google Maps API key
  • uv package manager (optional but recommended)

Installation

Using uv (Recommended)
uv pip install google-maps-mcp-server
Using pip
pip install google-maps-mcp-server
From Source
git clone https://github.com/ettysekhon/google-maps-mcp-server.git
cd google-maps-mcp-server
uv sync

Setup Google Maps API Key

  1. Visit the Google Cloud Console
  2. Create a new project or select an existing one
  3. Enable the following APIs:
    • Places API
    • Directions API
    • Geocoding API
    • Distance Matrix API
    • Roads API
  4. Create credentials (API Key)
  5. Restrict your API key (recommended):
    • Application restrictions: HTTP referrers or IP addresses
    • API restrictions: Select only the APIs listed above

Configuration

Create a .env file in your working directory:

GOOGLE_MAPS_API_KEY=your_maps_api_key_here

LOG_LEVEL=INFO
MAX_RESULTS=20

Or set environment variables:

export GOOGLE_MAPS_API_KEY="your_maps_api_key_here"

Run the Server

# Using the installed command
google-maps-mcp-server

# Or using Python module
python -m google_maps_mcp_server

# Or using uv
uv run google-maps-mcp-server

Deployment

See for full instructions, troubleshooting, and architecture details.

Local Docker Testing

# Set your API key (or create a .env file)
export GOOGLE_MAPS_API_KEY=your-key

# Build and run
make docker-run

# Verify (in another terminal)
make verify-local

GKE Deployment

# Set environment
export GOOGLE_CLOUD_PROJECT=your-project-id
export GOOGLE_CLOUD_REGION=europe-west2

# First time: create secret
make deploy-secret

# Deploy (build, push, apply)
make deploy-all

# Check status
make deploy-status

Redeploying After Code Changes

# Rebuild and push new image
make deploy-build

# Force pod to pull new image
kubectl delete pod -l app=google-maps-mcp-server

# Watch for new pod to be ready
kubectl get pods -l app=google-maps-mcp-server -w

Testing with MCP Inspector

Verify your deployment using the official MCP Inspector:

npx @modelcontextprotocol/inspector
  • Transport Type: SSE
  • URL: http://<EXTERNAL-IP>/sse (or http://localhost:8080/sse for local)
  • Should see 11 tools listed

MCP Inspector - Verifying Remote Deployment

MCP Inspector - Making Remote Tool Call

Run make help to see all available commands.


Usage Examples

With Claude Desktop

Add to your Claude Desktop configuration file:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "google-maps": {
      "command": "uvx",
      "args": ["google-maps-mcp-server"],
      "env": {
        "GOOGLE_MAPS_API_KEY": "your_api_key_here"
      }
    }
  }
}

Or if installed globally:

{
  "mcpServers": {
    "google-maps": {
      "command": "google-maps-mcp-server",
      "env": {
        "GOOGLE_MAPS_API_KEY": "your_api_key_here"
      }
    }
  }
}

Now you can ask Claude:

  • "Find the best coffee shops near The Strand, London"
  • "What are the opening hours for the Natural History Museum?"
  • "How is the traffic from London to Manchester right now?"
  • "Is the route from Edinburgh to Glasgow safe for night driving?"
  • "Convert the address '10 Downing Street, London' to coordinates"
  • "What's the address for coordinates 51.5074, -0.1278?"
  • "Find petrol stations within 2km of my current location at 51.5074,-0.1278"

With Google ADK

from google.adk.agents import Agent
from google.adk.tools.mcp_tool import MCPToolset
from mcp.client.stdio import StdioServerParameters

async def create_location_agent():
    # Connect to Google Maps MCP server
    maps_tools = await MCPToolset.from_server(
        connection_params=StdioServerParameters(
            command='google-maps-mcp-server',
            env={"GOOGLE_MAPS_API_KEY": "your_api_key_here"}
        )
    )

    # Create agent with Maps tools
    agent = Agent(
        name="location_intelligence_agent",
        model="gemini-2.0-flash",
        instruction="""You are a location intelligence assistant with access to
        Google Maps data. Help users with directions, place searches, and location queries.""",
        tools=[maps_tools]
    )

    return agent

# Use the agent
agent = await create_location_agent()
response = await agent.run("Find Italian restaurants near Hyde Park, London")
print(response)

Programmatic Usage

import asyncio
from google_maps_mcp_server import GoogleMapsMCPServer, Settings

async def main():
    # Initialise with custom settings
    settings = Settings(
        google_maps_api_key="your_api_key_here",
        log_level="DEBUG",
        max_results=10
    )

    server = GoogleMapsMCPServer(settings)

    # Run the server
    await server.run()

if __name__ == "__main__":
    asyncio.run(main())

Direct Tool Usage

from google_maps_mcp_server.tools import PlacesTool, DirectionsTool
from google_maps_mcp_server.config import Settings

async def find_nearby_restaurants():
    settings = Settings(google_maps_api_key="your_key")
    places_tool = PlacesTool(settings)

    result = await places_tool.execute({
        "location": "51.5118,-0.1175",  # The Strand, London
        "keyword": "pizza",
        "radius": 1000
    })

    print(f"Found {result['data']['count']} pizza places")
    for place in result['data']['places']:
        print(f"- {place['name']}: {place['rating']}⭐")

asyncio.run(find_nearby_restaurants())

Docker Usage

# Build the image
docker build -t google-maps-mcp .

# Run the container
docker run -it \
  -e GOOGLE_MAPS_API_KEY=your_maps_key_here \
  google-maps-mcp

# Or use docker-compose
docker-compose up

Configuration Options

All configuration can be set via environment variables or .env file:

VariableTypeDefaultDescription
GOOGLE_MAPS_API_KEYstringrequiredGoogle Maps Platform API key (for Maps tools)
LOG_LEVELstringINFOLogging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
MAX_RESULTSinteger20Maximum results to return (1-60)
DEFAULT_RADIUS_METERSinteger5000Default search radius in meters
MAX_RADIUS_METERSinteger50000Maximum allowed search radius
MAX_RETRIESinteger3Maximum retry attempts for failed requests
RETRY_MIN_WAITfloat1.0Minimum wait between retries (seconds)
RETRY_MAX_WAITfloat10.0Maximum wait between retries (seconds)

Tool Documentation

search_places

Find places near a location.

Parameters:

  • location (required): Coordinates as "lat,lng" or address string
  • keyword (required): Search keyword (e.g., "restaurant", "petrol station")
  • radius (optional): Search radius in meters (default: 5000, max: 50000)
  • type (optional): Place type filter (e.g., "restaurant", "gas_station")

Example:

{
  "location": "51.5118,-0.1175",
  "keyword": "coffee shop",
  "radius": 1000,
  "type": "cafe"
}

get_place_details

Get detailed information about a specific place.

Parameters:

  • place_id (required): The unique Place ID
  • fields (optional): Specific fields to retrieve (e.g., ["name", "phone", "hours"])

Example:

{
  "place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
  "fields": ["name", "website", "hours"]
}

get_directions

Get route directions with real-time traffic.

Parameters:

  • origin (required): Start location (address or coordinates)
  • destination (required): End location (address or coordinates)
  • mode (optional): Travel mode - "driving" (default), "walking", "bicycling", "transit"
  • departure_time (optional): ISO 8601 timestamp for traffic estimation
  • alternatives (optional): Return alternative routes (default: true)
  • avoid (optional): Features to avoid - ["tolls", "highways", "ferries", "indoor"]
  • traffic_model (optional): "best_guess" (default), "optimistic", "pessimistic"

Example:

{
  "origin": "London, UK",
  "destination": "Manchester, UK",
  "mode": "driving",
  "alternatives": true,
  "avoid": ["tolls"]
}

get_traffic_conditions

Analyze real-time traffic conditions between two locations.

Parameters:

  • origin (required): Starting location
  • destination (required): Ending location
  • departure_time (optional): ISO 8601 timestamp (defaults to now)
  • traffic_model (optional): "best_guess" (default), "optimistic", "pessimistic"

Example:

{
  "origin": "London, UK",
  "destination": "Oxford, UK",
  "traffic_model": "best_guess"
}

geocode_address

Convert an address to coordinates.

Parameters:

  • address (required): Street address to geocode
  • components (optional): Component filters (e.g., {"country": "GB"})
  • region (optional): Region bias (ISO 3166-1 country code)

Example:

{
  "address": "10 Downing Street, London, UK"
}

reverse_geocode

Convert coordinates to an address.

Parameters:

  • lat (required): Latitude (-90 to 90)
  • lng (required): Longitude (-180 to 180)
  • result_type (optional): Filter by result types

Example:

{
  "lat": 51.5034,
  "lng": -0.1276
}

calculate_distance_matrix

Calculate distances and times between multiple locations.

Parameters:

  • origins (required): Array of origin locations
  • destinations (required): Array of destination locations
  • mode (optional): Travel mode (default: "driving")
  • avoid (optional): Features to avoid
  • units (optional): "metric" (default) or "imperial"

Example:

{
  "origins": ["London, UK", "Manchester, UK"],
  "destinations": ["Birmingham, UK", "Leeds, UK"],
  "mode": "driving"
}

snap_to_roads

Snap GPS coordinates to the nearest road.

Parameters:

  • path (required): Array of GPS points with lat/lng (2-100 points)
  • interpolate (optional): Fill gaps between points (default: true)

Example:

{
  "path": [
    {"lat": 51.5034, "lng": -0.1276},
    {"lat": 51.5035, "lng": -0.1275}
  ],
  "interpolate": true
}

get_speed_limits

Get speed limit data for road segments.

Parameters:

  • place_ids (required): Array of place IDs from snap_to_roads

Example:

{
  "place_ids": ["ChIJwQ2rKwAEdkgRo7h2RYD1oUM"]
}

calculate_route_safety_factors

Calculate safety scores for a route based on traffic, road conditions, and speed limits.

Parameters:

  • origin (required): Starting location
  • destination (required): Ending location
  • departure_time (optional): ISO 8601 timestamp (defaults to now)
  • traffic_model (optional): "best_guess", "optimistic", "pessimistic" (default)

Example:

{
  "origin": "London, UK",
  "destination": "Oxford, UK",
  "departure_time": "2023-10-27T23:00:00Z",
  "traffic_model": "pessimistic"
}

get_route_elevation_gain

Calculate elevation gain and retrieve elevation profile for a route.

Parameters:

  • origin (required): Starting location
  • destination (required): Ending location
  • mode (optional): "driving", "walking", "bicycling" (default)
  • samples (optional): Number of elevation samples (default: 50, max: 512)

Example:

{
  "origin": "London, UK",
  "destination": "Brighton, UK",
  "mode": "bicycling",
  "samples": 100
}

Development

Setup Development Environment

# Clone the repository
git clone https://github.com/ettysekhon/google-maps-mcp-server.git
cd google-maps-mcp-server

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install dependencies with dev extras
uv sync --extra dev

# Set up pre-commit hooks
uv run pre-commit install

Run Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=src --cov-report=html

# Run only unit tests
uv run pytest -m "not integration"

# Run specific test file
uv run pytest tests/unit/test_places.py

# Run with verbose output
uv run pytest -v

Code Quality

# Format code
uv run black src tests

# Lint code
uv run ruff check src tests

# Fix linting issues automatically
uv run ruff check src tests --fix

# Type checking
uv run mypy src

# Run all checks
uv run black src tests && \
uv run ruff check src tests && \
uv run mypy src && \
uv run pytest

Building and Publishing

# Build package
uv build

# Publish to PyPI (requires authentication)
uv publish

# Build Docker image
docker build -t google-maps-mcp-server:latest .

Contributing

We welcome contributions! Please see for guidelines.

Quick Contribution Guide

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for your changes
  5. Ensure all tests pass (uv run pytest)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

API Limits and Pricing

This MCP server uses Google Maps Platform APIs which have the following considerations:

  • Free Tier: $200 monthly credit (covers ~28,000 geocoding requests or ~40,000 directions requests)
  • Pay-as-you-go: Pricing varies by API
  • Rate Limits: Default quotas apply; can be increased via Google Cloud Console

Cost Optimisation Tips:

  • Cache results when appropriate
  • Use alternatives=false for directions when not needed
  • Limit max_results for place searches
  • Implement client-side caching for repeated queries

See Google Maps Platform Pricing for details.


Security Best Practices

  1. API Key Security:

    • Never commit API keys to version control
    • Use environment variables or secret management
    • Restrict API keys by API, HTTP referrer, or IP address
    • Rotate keys regularly
  2. API Key Restrictions (Recommended):

    Application restrictions: HTTP referrers or IP addresses
    API restrictions:
      - Places API
      - Directions API
      - Geocoding API
      - Distance Matrix API
      - Roads API
    
  3. Monitoring:

    • Enable billing alerts in Google Cloud Console
    • Monitor API usage regularly
    • Set up quota alerts

Troubleshooting

Common Issues

Problem: ValidationError: google_maps_api_key cannot be empty

  • Solution: Ensure GOOGLE_MAPS_API_KEY environment variable is set

Problem: REQUEST_DENIED error

  • Solution: Enable required APIs in Google Cloud Console and check API key restrictions

Problem: OVER_QUERY_LIMIT error

  • Solution: You've exceeded API quota. Check usage in Google Cloud Console or implement rate limiting

Problem: Server won't start

  • Solution: Check logs for errors, verify Python version (3.10+), ensure all dependencies installed

Enable Debug Logging

export LOG_LEVEL=DEBUG
google-maps-mcp-server

Getting Help


License

This project is licensed under the Apache License 2.0 - see the file for details.


Acknowledgments

  • Built with MCP by Anthropic
  • Powered by Google Maps Platform
  • Developed using uv by Astral
  • Inspired by the amazing MCP community