Skip to main content
ClaudeWave

One place-search interface for every AI and map provider. MCP + REST + SDK, provider fallback, merge+dedup, zero API key needed.

MCP ServersRegistry oficial0 estrellas1 forksTypeScriptApache-2.0Actualizado today
Install in Claude Code / Claude Desktop
Method: NPX · @geowirehq/cli
Claude Code CLI
claude mcp add geowire -- npx -y @geowirehq/cli
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "geowire": {
      "command": "npx",
      "args": ["-y", "@geowirehq/cli"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Casos de uso

Resumen de MCP Servers

# 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.

<p align="center">
  <img src="docs/media/geowire-mcp.gif" alt="geowire MCP server — tools/list and a geocode_address call over stdio" width="760">
</p>

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.**

> **Honest by design:** OpenStreetMap (the zero-key default) is a great
> *geocoder* — strong on place names, addresses, and landmarks — but thin on
> category words ("coffee", "pharmacy"), opening hours, and coverage outside
> Europe. Add a Google key for full business data; GeoWire merges both and tells
> you which source every field came from.

**Contents:** [Why](#why-geowire) · [Quickstart](#quickstart) · [MCP tools](#mcp-tools) · [REST](#rest-endpoints) · [Anatomy of a response](#anatomy-of-a-response) · [Config](#configuration-optional--everything-works-without-it) · [Providers](#providers) · [Recipes & examples](#recipes--examples) · [Roadmap](#roadmap) · [Architecture](#architecture)

## 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) |

**Not a Google replacement — it *uses* Google.** The thing no single provider can
do: merge **your own store data + Google + OSM** into one deduped record, with
per-field provenance (your name is authoritative, Google adds ratings, OSM adds
coordinates). Real run below:

<p align="center">
  <img src="docs/media/geowire-merge.gif" alt="GeoWire merging a private store DB, Google, and OpenStreetMap into one record with per-field provenance" width="760">
</p>

## Quickstart

### 1. MCP (Claude Desktop / Cursor) — 30 seconds

Add this to your MCP client config (e.g. Claude Desktop `claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "geowire": { "command": "npx", "args": ["-y", "@geowirehq/mcp"] }
  }
}
```

Then ask: *"Where is the Eiffel Tower?"* or *"Find a Starbucks within 3 km of
37.4979, 127.0276."* Works with **zero API keys** — OpenStreetMap is the default.
Add `"env": { "GOOGLE_MAPS_API_KEY": "..." }` for business listings and hours
(e.g. *"Find a 24-hour pharmacy near me"*). See [more MCP client configs](./examples/mcp-clients.md).

### 2. CLI — one-shot search & server

<p align="center">
  <img src="docs/media/geowire-search.gif" alt="geowire search in the terminal, with source attribution and response time" width="720">
</p>

```bash
npx @geowirehq/cli search "Eiffel Tower"          # terminal search with a results table
npx @geowirehq/cli search "Starbucks" --near 37.4979,127.0276 --radius 3000   # near a coordinate
npx @geowirehq/cli reverse 37.5665,126.9780       # coordinate → nearest place
npx @geowirehq/cli route 37.5665,126.9780 37.4979,127.0276   # driving directions (no key, OSRM)
npx @geowirehq/cli get google:ChIJ...             # one place by reference (getPlace-capable provider)
npx @geowirehq/cli                                # start the REST + MCP server (zero-config)
npx @geowirehq/cli init                           # interactive setup wizard (.env + config)
npx @geowirehq/cli test                           # check provider connections
```

Add `--json` to any command for the full response (results + provenance `meta`).

### 3. Docker — self-hosted server

```bash
docker run -p 4980:4980 geowire/geowire
# then:
curl -X POST http://localhost:4980/v1/places/search \
  -H 'content-type: application/json' \
  -d '{"query":"Starbucks","near":{"latitude":37.4979,"longitude":127.0276},"radiusMeters":3000}'
```

Or with `docker compose up` (see `docker-compose.yml`). API docs at `/docs`.

### 4. SDK (embedded)

```ts
import { createGeoWire } from "@geowirehq/core";
import { createNominatimProvider } from "@geowirehq/provider-nominatim";

const geo = createGeoWire({ providers: [createNominatimProvider()] });
const { results, meta } = await geo.searchPlaces({
  query: "Starbucks",
  near: { latitude: 37.4979, longitude: 127.0276 },
  radiusMeters: 3000,
});
```

Full embedded-SDK guide: [`examples/typescript-sdk.md`](./examples/typescript-sdk.md).

## MCP tools

| 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 |
| `get_directions` | Route between waypoints (distance, time, legs) — no key (OSRM) |
| `distance_matrix` | N×M travel distances/times — rank candidates by drive time — no key |
| `analyze_area` | Commercial-area analysis: category density, competition, rating landscape |
| `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 |
| POST | `/v1/directions` | directions between waypoints (no key) |
| POST | `/v1/distance-matrix` | N×M travel distance/time matrix (no key) |
| POST | `/v1/analyze-area` | commercial-area analysis (density, competition, ratings) |
| 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`.

## Anatomy of a response

No black box. Every response carries a `meta` block: which providers were
**used / skipped / failed** (and why), dedup counts, cache status, estimated
cost, and per-field sourcing — so you always know where each value came from.

```jsonc
{
  "results": [{
    "id": "gwp_CvWvRZrFtegkJPxP9CW0",
    "name": "경복궁",
    "location": { "latitude": 37.579754, "longitude": 126.9766818 },
    "sources": [{
      "provider": "nominatim",
      "providerPlaceId": "relation/5501517",
      "fields": ["name", "location", "categories", "address"]   // ← what this source contributed
    }],
    "attributions": ["© OpenStreetMap contributors"]
  }],
  "meta": {
    "providersUsed":   [{ "provider": "nominatim", "resultCount": 1, "latencyMs": 2449 }],
    "providersSkipped": [],   // e.g. { provider: "google", reason: "MISSING_CREDENTIALS" | "QUOTA_EXCEEDED" }
    "providersFailed":  [],   // e.g. { provider: "google", reason: "TIMEOUT" }
    "strategy": "first-success",
    "cache": { "hit": false }
    // merging adds:  "dedup": { "before": 3, "after": 1 }
    // paid provider: "estimatedCostUSD": 0.032
  }
}
```

After a merge, `sources[].fields` shows (say) the phone came from Google while
the coordinates came from OSM. Walkthrough: [docs/recipes.md](./docs/recipes.md#4-read-a-response-provenance--transparency).

## Configuration (optional — everything works without it)

`geowire.config.yaml`:

```yaml
providers:
  nominatim: { enabled: true }                       # default ON, no key
  google:    { enabled: true, apiKey: ${GOOGLE_MAPS_API_KEY} }
  kakao:     { enabled: true }                        # env KAKAO_REST_API_KEY (KR)
  naver:     { enabled: true }                        # env NAVER_CLIENT_ID + NAVER_CLIENT_SECRET (KR)
  internal:  { enabled: true, source: ./my-places.csv, priority: 100 }
routing:
  defaultStrategy: merge          # first-success | merge | cost-aware | weighted | fastest
  providerWeights:                # for `weighted`: order by priority·cost·coverage
    priority: 0.5
    cost: 0.3
    coverage: 0.2
budget:
  perRequestMaxUSD: 0.10          # over-budget paid providers are skipped, free ones used
```

Keys come from the environment (`${VAR}`), never committed in plaintext.

## Providers

| Provider | Key? | Capabilities |
|---|---|---|
| `@geowirehq/provider-nominatim` (OpenStreetMap) | none | search, geocode, reverseGeocode |
| `@geowirehq/provider-osrm` (OpenStreetMap routing) | none | route, distanceMatrix |
| `@geowirehq/provider-google` (Maps Platform) | BYOK | search, geocode, reverseGeocode, getPlace, route, distanceMatrix |
| `@geowirehq/provider-kakao` (카카오맵, KR) | BYOK `KAKAO_REST_API_KEY` | search, geocode, reverseGeocode |
| `@geowirehq/provider-naver` (네이버 지역검색, KR) | BYOK `NAVER_CLIENT_ID`+`NAVER_CLIENT_SECRET` | search, geocode |
| `@geowirehq/provider-baidu` (百度地图, CN) | BYOK `BAIDU_MAP_AK` | search, geocode, reverseGeocode |
| `@geowirehq/provider-foursquare` (global POI) | BYOK `FOURSQUARE_API_KEY` | search, getPlace |
| `@geowirehq/provider-internal` (your CSV) | none | search |

Regional providers make Korea (Kakao/Naver) and China (Baidu) coverage
first-class where OSM is thin and Google has gaps — Baidu returns BD-09
coordinates, which GeoWire converts to WGS84 automatically. Merge them all +
your own store data into one deduped record.

### Provider roles — each provider does what it's best at

Providers aren't interchangeable; they're **complementary**. When `merge` combines
duplicates, GeoWire doesn't just pick the highest-prior
ai-agentsgeocodinggeospatialllm-toolsmcpmodel-context-protocolopenstreetmapplacestypescript

Lo que la gente pregunta sobre geowire

¿Qué es geowire/geowire?

+

geowire/geowire es mcp servers para el ecosistema de Claude AI. One place-search interface for every AI and map provider. MCP + REST + SDK, provider fallback, merge+dedup, zero API key needed. Tiene 0 estrellas en GitHub y se actualizó por última vez today.

¿Cómo se instala geowire?

+

Puedes instalar geowire clonando el repositorio (https://github.com/geowire/geowire) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar geowire/geowire?

+

geowire/geowire aún no ha sido auditado por nuestro agente de seguridad. Revisa el repositorio original en GitHub antes de usarlo en producción.

¿Quién mantiene geowire/geowire?

+

geowire/geowire es mantenido por geowire. La última actividad registrada en GitHub es de today, con 21 issues abiertos.

¿Hay alternativas a geowire?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega geowire en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: geowire/geowire
[![Featured on ClaudeWave](https://claudewave.com/api/badge/geowire-geowire)](https://claudewave.com/repo/geowire-geowire)
<a href="https://claudewave.com/repo/geowire-geowire"><img src="https://claudewave.com/api/badge/geowire-geowire" alt="Featured on ClaudeWave: geowire/geowire" width="320" height="64" /></a>

Más MCP Servers

Alternativas a geowire