Skip to main content
Glama

osm-mcp

An MCP (Model Context Protocol) server that exposes read-only query tools over osm2pgsql-imported OpenStreetMap data in PostGIS (planet_osm_* tables).

Quick start

uv sync --extra dev              # creates .venv + uv.lock
cp .env.example .env             # then set OSM_MCP_DSN
docker compose up -d             # optional: demo PostGIS with seed data on localhost:55432

.env.example documents the settings:

  • OSM_MCP_DSN — required libpq connection string. Use a read-only DB role (see the comment in .env.example for the recommended GRANTs).

  • OSM_MCP_SRID — SRID of the way geometry column (default 3857).

  • OSM_MCP_STATEMENT_TIMEOUT_MS — per-query statement timeout (default 5000).

  • OSM_MCP_MAX_ROWS — row cap applied to result sets (default 200).

Related MCP server: mcp-db-server

Running the server

uv run osm-mcp

Runs over stdio by default (how local MCP clients launch it).

HTTP streaming transport

Set OSM_MCP_TRANSPORT=streamable-http (alias http) to serve over HTTP instead of stdio; sse is also supported. Host/port come from OSM_MCP_HOST / OSM_MCP_PORT (default 127.0.0.1:8000); the endpoint path is /mcp.

OSM_MCP_TRANSPORT=http OSM_MCP_HOST=127.0.0.1 OSM_MCP_PORT=8000 \
OSM_MCP_DSN=postgresql://osm_readonly:secret@localhost:5432/osm \
uv run osm-mcp
# -> serves on http://127.0.0.1:8000/mcp

An HTTP-capable MCP client then connects with:

{ "mcpServers": { "osm": { "type": "http", "url": "http://127.0.0.1:8000/mcp" } } }

Unlike stdio, the HTTP/SSE transports print a startup line to stderr showing the URL. (stdio stays silent — its stdout is the protocol channel.)

MCP client config (stdio)

{
  "mcpServers": {
    "osm": {
      "command": "osm-mcp",
      "env": {
        "OSM_MCP_DSN": "postgresql://osm_readonly:secret@localhost:5432/osm"
      }
    }
  }
}

Tools

Tool

Purpose

describe_schema

List available planet_osm_* tables, their tag columns, and geometry SRID.

list_categories

Top values (with counts) of key OSM tags, to discover filters.

search_features

Search features by name (ILIKE) and/or tag filters, optional bbox.

find_nearby

Features within N meters of a lat/lon, ordered by distance (points + POI polygons; excludes admin/boundary polygons).

features_in_area

Features inside a bbox or a named/osm_id polygon.

count_by_category

Counts of features per tag value, optionally scoped to an area.

run_sql

Escape hatch: run a single read-only SELECT/WITH query against the OSM tables.

Full reference — parameters, return shapes, and worked examples for every tool: docs/TOOLS.md.

Performance notes

list_categories and area-less count_by_category do full-table scans over unindexed tag columns; prefer scoping them with an area/table, or use them only on modest-size datasets.

Coordinates, SRID, and read-only access

  • Public tool coordinates (lat/lon in arguments and results) are always WGS84 (EPSG:4326). The DB geometry column (way) is stored in OSM_MCP_SRID (default 3857) and reprojected at the query boundary.

  • Distance calculations (find_nearby) use PostGIS geography, so distance_m is a true geodesic distance in meters.

  • Read-only access is enforced at two layers: the DB role used for OSM_MCP_DSN should itself be read-only, and every query additionally runs inside a READ ONLY transaction. run_sql is further restricted to a single SELECT/WITH statement.

Testing

uv run pytest                      # unit + integration
uv run pytest -m "not integration" # unit only, no DB required
uv run pytest tests/unit/test_config.py::test_defaults_applied -v  # single test

Integration tests need a live PostGIS (docker compose up -d); they skip automatically if the DB at OSM_MCP_TEST_DSN (defaults to postgresql://osm:osm@localhost:55432/osm) is unreachable.

Available Tools

7 tools
count_by_categoryB

Count features per value of a tag (default amenity), optionally within an area.

Inputs: area, group_by.

describe_schemaA

List available planet_osm_* tables, their tag columns, and geometry SRID.

Inputs: no named parameters.

features_in_areaC

Features inside a bbox [min_lon,min_lat,max_lon,max_lat] or a named/osm_id polygon.

Inputs: area (required), limit, filters.

find_nearbyB

Features within radius_m meters of (lat, lon), ordered by distance.

Inputs: lat (required), lon (required), limit, filters, +1 more.

list_categoriesC

Top values (with counts) of key OSM tags, to discover filters.

Inputs: limit, table.

run_sqlC

Run a single read-only SELECT/WITH query against the OSM tables.

Inputs: sql_text (required), params.

search_featuresA

Search OSM features by name (ILIKE) and/or tag filters, optional bbox.

Inputs: bbox, limit, query, filters.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 7 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose: counting, schema description, spatial querying, nearby search, category listing, SQL execution, and general search. No overlap in functionality.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern in snake_case (e.g., count_by_category, search_features). No mixing of styles or unconventional names.

    Tool Count5/5

    With 7 tools, the set is well-scoped for OSM data querying. Each tool serves a distinct operation, and the count is neither too small nor overwhelming for the domain.

    Completeness4/5

    Covers key OSM query patterns: spatial filters, text search, counts, schema introspection, and custom SQL. A minor gap is the lack of a dedicated tool to fetch a single feature by ID, but run_sql can handle it.

    Maintenance

    ActivityInactive
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables natural language and geospatial queries on PostGIS databases, with 32 tools for spatial analysis, geometry operations, and database management.
      5
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      Enables querying PostgreSQL and MySQL databases using natural language, with RESTful endpoints for listing tables, describing schemas, and executing read-only queries.
      1
      -
    • A
      license
      A
      quality
      D
      maintenance
      Enables natural language querying of PostgreSQL databases under read-only mode, returning results as structured XML.
      1
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      A read-only PostgreSQL MCP server that translates natural language queries into SQL, enforcing database routing, table/column whitelists, and safety checks. It offers schema inspection and query tools with optional output as SQL or results.
      -