Google Maps MCP Server
Enables location-aware AI agents to search for nearby places, get detailed place information including hours and ratings, and calculate routes with turn-by-turn directions using Google Maps APIs.
README
Google Maps MCP Server
Streamable HTTP MCP server for Google Maps — search places, get details, and plan routes.
Repository: github.com/iceener/maps-streamable-mcp-server
Author: overment
Use Case
This MCP server is designed for location-aware AI agents running on mobile devices like Apple Watch or iPhone. Your client provides the current position, and the AI can:
- Find nearby places (restaurants, stores, gas stations)
- Get directions with turn-by-turn navigation
- Compare distances to multiple destinations
- Check opening hours and ratings before you arrive
<img src="docs/watch.png" width="400" />
It also pairs well with other MCP tools — for example, combining with a Tesla MCP to set navigation destinations directly in your car.
Notice
This repo works in two ways:
- As a Node/Hono server for local workflows
- As a Cloudflare Worker for remote interactions
Features
- ✅ Places — Search nearby places, restaurants, landmarks by text or type
- ✅ Details — Get hours, ratings, reviews, photos, contact info
- ✅ Routes — Calculate walking, driving, transit directions
- ✅ Distance Matrix — Compare distances to multiple destinations
- ✅ Location-aware — All tools work with your current position
- ✅ Dual Runtime — Node.js/Bun or Cloudflare Workers
Design Principles
- LLM-friendly: Unified tools, not 1:1 API mirrors
- Watch-ready: Designed for AI agents with location context
- Smart defaults: 1km radius, 10 results, walking mode
- Clear feedback: Place IDs visible for follow-up queries
Installation
Prerequisites: Bun, Google Cloud project.
0. Client Setup
Your client needs to be aware of the current time and your current location, as both values will be used for searching and planning.
1. Get Google Maps API Key
- Go to Google Cloud Console
- Create a new project (or select existing)
- Navigate to APIs & Services > Library
- Enable Places API (New) and Routes API
- Go to APIs & Services > Credentials
- Click Create Credentials > API Key
- (Recommended) Restrict key to Places API and Routes API
2. Local Development
cd google-maps-mcp
bun install
cp .env.example .env
Edit .env:
PORT=3000
AUTH_ENABLED=true
AUTH_STRATEGY=bearer
# Generate with: openssl rand -hex 32
BEARER_TOKEN=your-random-auth-token
# Your Google Maps API key
API_KEY=your-google-maps-api-key
Run:
bun dev
# MCP: http://127.0.0.1:3000/mcp
3. Cloudflare Worker (Deploy)
- Create KV namespace:
wrangler kv:namespace create TOKENS
-
Update
wrangler.tomlwith your KV namespace ID -
Set secrets:
# Auth token for clients (generate it using: openssl rand -hex 32). This makes the connection to your MCP not open to everyone, but only to those who have this API key.
wrangler secret put BEARER_TOKEN
# Your Google Maps API key
wrangler secret put API_KEY
- Deploy:
wrangler deploy
Endpoint: https://<worker-name>.<account>.workers.dev/mcp
Client Configuration
Claude Desktop / Cursor (Local)
{
"mcpServers": {
"google-maps": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:3000/mcp", "--transport", "http-only"],
"env": { "NO_PROXY": "127.0.0.1,localhost" }
}
}
}
Claude Desktop / Cursor (Cloudflare Worker)
{
"mcpServers": {
"google-maps": {
"command": "npx",
"args": ["mcp-remote", "https://your-worker.workers.dev/mcp", "--transport", "http-only"]
}
}
}
Alice App
Add as MCP server with:
- URL:
https://your-worker.workers.dev/mcp - Type:
streamable-http - Header:
Authorization: Bearer <your-BEARER_TOKEN>
Tools
search_places
Find places by text query or type near a location.
// Input
{
query?: string; // "sushi near Central Park"
location: { // Required: your current position
latitude: number;
longitude: number;
};
types?: string[]; // ["restaurant", "cafe"]
radius?: number; // Meters (default: 1000, max: 50000)
filters?: {
open_now?: boolean;
min_rating?: number; // 0-5
price_levels?: string[]; // PRICE_LEVEL_INEXPENSIVE, etc.
};
max_results?: number; // Default: 10, max: 20
sort_by?: "distance" | "rating" | "relevance";
}
// Output
- Restaurant Name (500m) ★4.5(234) $$ 🟢 Open
123 Main St, New York
ID: ChIJN1t_tDeuEmsRUsoyG83frY4
Use
queryfor text search, ortypesfor category-based nearby search.
get_place
Get detailed information about a specific place.
// Input
{
place_id: string; // From search_places results
fields?: string[]; // ["basic", "contact", "hours", "reviews", "photos"]
}
// Output
Name: Central Park
Address: New York, NY, USA
Rating: 4.8 (50000 reviews)
Open Now: Yes
Hours: Monday: 6:00 AM – 1:00 AM, ...
Phone: +1 212-310-6600
Website: https://centralparknyc.org
Google Maps: https://maps.google.com/?cid=...
get_route
Calculate routes or distance matrix.
// Single destination → detailed route
{
origin: { latitude: 40.7128, longitude: -74.0060 };
destinations: [{ latitude: 40.7580, longitude: -73.9855 }];
mode?: "walk" | "drive" | "transit"; // Default: "walk"
options?: {
departure_time?: string; // ISO 8601 or "now"
include_steps?: boolean; // Turn-by-turn instructions
include_polyline?: boolean;
};
}
// Multiple destinations → distance matrix
{
origin: { latitude: 40.7128, longitude: -74.0060 };
destinations: [
{ latitude: 40.7580, longitude: -73.9855 },
{ latitude: 40.7484, longitude: -73.9857 },
"Empire State Building" // Address or place ID also works
];
mode?: "walk";
}
// Output (single)
Route Summary: via 5th Ave
Total Distance: 5.2 km
Total Duration: 62 minutes
Steps:
1.1. Head north on Broadway
1.2. Turn right onto E 42nd St
...
// Output (matrix)
Distances from origin to 3 destinations:
- To Times Square: 4.8 km, 58 min
- To Empire State: 3.2 km, 38 min
- To Central Park: 6.1 km, 73 min
Examples
1. Find nearby coffee shops
{
"name": "search_places",
"arguments": {
"types": ["cafe"],
"location": { "latitude": 40.7128, "longitude": -74.0060 },
"filters": { "open_now": true },
"sort_by": "distance"
}
}
2. Search by text
{
"name": "search_places",
"arguments": {
"query": "best pizza in Manhattan",
"location": { "latitude": 40.7128, "longitude": -74.0060 },
"max_results": 5
}
}
3. Get place details
{
"name": "get_place",
"arguments": {
"place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
"fields": ["basic", "hours", "reviews"]
}
}
4. Walking directions
{
"name": "get_route",
"arguments": {
"origin": { "latitude": 40.7128, "longitude": -74.0060 },
"destinations": [{ "latitude": 40.7580, "longitude": -73.9855 }],
"mode": "walk",
"departure_time": "now",
"include_steps": true
}
}
5. Compare distances to multiple places
{
"name": "get_route",
"arguments": {
"origin": { "latitude": 40.7128, "longitude": -74.0060 },
"destinations": [
"Times Square, NYC",
"Central Park, NYC",
"Brooklyn Bridge, NYC"
],
"mode": "walk"
}
}
HTTP Endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/mcp |
POST | MCP JSON-RPC 2.0 |
/health |
GET | Health check |
Environment Variables
Node.js (.env)
| Variable | Required | Description |
|---|---|---|
API_KEY |
✓ | Google Maps Platform API key |
BEARER_TOKEN |
✓ | Auth token for MCP clients |
PORT |
Server port (default: 3000) | |
AUTH_ENABLED |
Enable auth (default: true) | |
AUTH_STRATEGY |
bearer (default) |
Cloudflare Workers
wrangler.toml:
AUTH_ENABLED = "true"
AUTH_STRATEGY = "bearer"
Secrets (set via wrangler secret put):
BEARER_TOKEN— Random auth token for clientsAPI_KEY— Google Maps Platform API key
KV Namespace:
[[kv_namespaces]]
binding = "TOKENS"
id = "your-kv-namespace-id"
Troubleshooting
| Issue | Solution |
|---|---|
| 401 Unauthorized | Check BEARER_TOKEN is set and client sends Authorization: Bearer <token> |
| "API key not configured" | Set API_KEY secret: wrangler secret put API_KEY |
| "Places API error 403" | Enable Places API (New) in Google Cloud Console |
| "Routes API error 404" | Enable Routes API in Google Cloud Console |
| Invalid Place ID | Place IDs expire. Search again to get fresh IDs |
| KV namespace error | Run wrangler kv:namespace create TOKENS and update wrangler.toml |
Development
bun dev # Start with hot reload
bun run typecheck # TypeScript check
bun run lint # Lint code
bun run build # Production build
bun start # Run production
Architecture
src/
├── shared/
│ └── tools/
│ ├── search-places.ts # Unified place search
│ ├── get-place.ts # Place details
│ └── get-route.ts # Routes & distance matrix
├── services/
│ └── google-maps.ts # Google Maps API client
├── config/
│ └── metadata.ts # Server & tool descriptions
├── index.ts # Node.js entry
└── worker.ts # Workers entry
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。