GeoWire
Add real-world places to any AI agent in 5 minutes โ no API key required.
One place-search interface for every AI and map provider.
GeoWire is an open-source geo search gateway that sits between AI agents and
map/place data providers (OpenStreetMap, Google, your own data) and exposes them
through a single MCP server, REST API, and SDK โ with provider
fallback, multi-provider merge + dedup, cost budgets, and a policy engine that
enforces each provider's caching/attribution terms.
Status: v0.1 ("It works") โ published on npm. MCP ยท REST ยท CLI ยท SDK all functional.
Why GeoWire?
| Direct integration | Single-provider MCP | GeoWire |
|---|
| Unified place schema | โ per-provider code | โ | โ
|
| Provider fallback on failure | โ | โ | โ
|
| Multi-provider merge + dedup | โ | โ | โ
|
| Cost budgets & routing | โ | โ | โ
|
| Works without any API key | โ | depends | โ
(OSM by default) |
| Self-hosted | โ | depends | โ
|
| Your own place data as a provider | โ | โ | โ
|
| Transparent provenance (which source, what cost) | โ | โ | โ
(every response) |
Quickstart
1. MCP (Claude Desktop / Cursor) โ 30 seconds
Add this to your MCP client config (e.g. Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"geowire": { "command": "npx", "args": ["-y", "@geowirehq/mcp"] }
}
}
Then ask: "Find a 24-hour pharmacy near District 1, Ho Chi Minh City."
Works with zero API keys โ OpenStreetMap is the default provider.
Add "env": { "GOOGLE_MAPS_API_KEY": "..." } to enable Google.
2. CLI โ one-shot search & server
npx @geowirehq/cli search "Eiffel Tower"
npx @geowirehq/cli search "coffee" --near 37.4979,127.0276
npx @geowirehq/cli
npx @geowirehq/cli init
npx @geowirehq/cli test
3. Docker โ self-hosted server
docker run -p 4980:4980 geowire/geowire
curl -X POST http://localhost:4980/v1/places/search \
-H 'content-type: application/json' \
-d '{"query":"pharmacy","near":{"latitude":10.7769,"longitude":106.7009}}'
Or with docker compose up (see docker-compose.yml). API docs at /docs.
4. SDK (embedded)
import { createGeoWire } from "@geowirehq/core";
import { createNominatimProvider } from "@geowirehq/provider-nominatim";
const geo = createGeoWire({ providers: [createNominatimProvider()] });
const { results, meta } = await geo.searchPlaces({
query: "coffee",
near: { latitude: 37.5, longitude: 127.0 },
});
| Tool | Description |
|---|
search_places | Natural-language + coordinate/region place search |
get_place | Details by provider:providerPlaceId reference |
geocode_address | Address โ coordinates (+ normalized address) |
reverse_geocode | Coordinates โ nearest address |
list_geo_providers | Active providers, capabilities, status (agent self-awareness) |
Every response includes both a human-readable summary and structuredContent
(schema-valid JSON).
REST endpoints
| Method | Path | |
|---|
| POST | /v1/places/search | search |
| GET | /v1/places/{ref} | place details (provider:id) |
| GET | /v1/geocode?address= | geocode |
| GET | /v1/reverse-geocode?lat=&lon= | reverse geocode |
| GET | /v1/providers | list providers |
| GET | /v1/health | health check |
| GET | /metrics | Prometheus metrics |
| GET | /docs | Swagger UI (OpenAPI 3.1) |
| POST | /mcp | MCP over Streamable HTTP |
Optional Bearer auth: set GEOWIRE_API_KEYS=key1,key2.
Configuration (optional โ everything works without it)
geowire.config.yaml:
providers:
nominatim: { enabled: true }
google: { enabled: true, apiKey: ${GOOGLE_MAPS_API_KEY} }
internal: { enabled: true, source: ./my-places.csv, priority: 100 }
routing:
defaultStrategy: merge
budget:
perRequestMaxUSD: 0.10
Keys come from the environment (${VAR}), never committed in plaintext.
Providers
| Provider | Key? | Capabilities |
|---|
@geowirehq/provider-nominatim (OpenStreetMap) | none | search, geocode, reverseGeocode |
@geowirehq/provider-google (Maps Platform) | BYOK | search, geocode, reverseGeocode, getPlace |
@geowirehq/provider-internal (your CSV) | none | search |
Want another provider? See CONTRIBUTING.md โ
"Write a provider in 30 minutes".
Architecture
AI agent / app
โ MCP ยท REST ยท SDK
โผ
GeoWire core โโ pipeline: plan โ execute โ normalize โ dedup โ rank โ policy โ cache
โ GeoProvider contract
โผ
providers: nominatim ยท google ยท internal ยท (community)
Monorepo packages: schema ยท provider-sdk ยท provider-testkit ยท core ยท
providers/* ยท mcp ยท apps/server ยท cli.
Documentation
License
Apache-2.0. GeoWire's code license is separate from the terms of
third-party map/place data providers โ usage of Google, Mapbox, HERE, Kakao,
Naver, etc. is governed by each provider's own terms. OSM data is under ODbL;
GeoWire's policy engine enforces attribution and caching limits per provider.