Skip to main content
Glama

openstreetmap-mcp-server

Reverse geocode coordinates to an address

openstreetmap_reverse_geocode
Read-onlyIdempotent

Convert a latitude/longitude pair to the nearest address or named place via Nominatim. The result is the closest indexed OSM object at the requested zoom (18 building, 10 city), which in dense areas can be a neighbouring feature rather than the one containing the coordinate; proximity and layer pick it, never an OSM attribute tag, so find features by tag with openstreetmap_query_nearby, openstreetmap_query_bbox, or openstreetmap_query_raw.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
latYesLatitude in WGS84 decimal degrees.
lonYesLongitude in WGS84 decimal degrees.
zoomNoAddress detail level, roughly corresponding to map zoom. 18=building, 16=street, 14=neighbourhood, 12=town, 10=city, 8=county, 5=state, 3=country.
layerNoRestrict which OSM layer is matched: one of address, poi, railway, natural, manmade, or a comma-separated list of them, in any casing. Any other name is rejected here, not upstream; an empty value counts as omitted. Default: address,poi.
languageNoPreferred language for the result (BCP 47 code or Accept-Language string).
extratagsNoInclude the matched object's extra OSM tags — contact and metadata (phone, website, opening_hours, wikidata) and physical attributes (surface, tracktype, sac_scale, ele, access). An absent tag describes that object, not OpenStreetMap.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
resultNoThe closest matching OSM object at the given coordinates.
attributionNoRequired data attribution.
tagSelectionCaveatNoStanding caveat: tag-based selection lives on the Overpass tools (openstreetmap_query_nearby, openstreetmap_query_bbox, openstreetmap_query_raw), never here. extratags decorates the returned objects rather than selecting them, so a missing tag is not evidence the tag is missing from OpenStreetMap. Present when extratags was requested.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedOutput schema / properties / result / properties / boundingbox / description
      Previous value: -"Bounding box as [south, north, west, east] strings."New value: +"Bounding box as [south, north, west, east] in WGS84 decimal degrees."
    • changedOutput schema / properties / result / properties / boundingbox / prefixItems
      Previous value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  }
      -]New value: +[
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "type": "number"
      +  },
      +  {
      +    "type": "number"
      +  }
      +]
    • changedOutput schema / properties / result / properties / lat / description
      Previous value: -"Latitude of the matched OSM object."New value: +"Latitude in WGS84 decimal degrees."
    • changedOutput schema / properties / result / properties / lat / type
      Previous value: -"string"New value: +"number"
    • changedOutput schema / properties / result / properties / lon / description
      Previous value: -"Longitude of the matched OSM object."New value: +"Longitude in WGS84 decimal degrees."
    • changedOutput schema / properties / result / properties / lon / type
      Previous value: -"string"New value: +"number"
    • changedOutput schema / properties / result / properties / osm_id / description
      Previous value: -"OSM object ID. Combine with osm_type for openstreetmap_lookup_objects."New value: +"OSM object ID. Combine with osm_type for openstreetmap_lookup_objects, or pass \"R\"/\"W\" + this id as within on openstreetmap_query_bbox to search inside this boundary. The same scope in openstreetmap_query_raw is rel(<osm_id>);map_to_area->.a; or way(<osm_id>);map_to_area->.a; then (area.a) on each statement."
  2. Changed6 schema fields changed
    • changedInput schema / properties / extratags / description
      Previous value: -"Include the extra OSM tags the matched object carries — contact and metadata tags (phone, website, opening_hours, wikidata) and physical attribute tags alike (surface, tracktype, sac_scale, ele, access). Opportunistic, not selective: it reports whatever the matched object happens to carry, so an absent tag describes that object rather than OpenStreetMap, and no value here can steer which object is matched."New value: +"Include the matched object's extra OSM tags — contact and metadata (phone, website, opening_hours, wikidata) and physical attributes (surface, tracktype, sac_scale, ele, access). An absent tag describes that object, not OpenStreetMap."
    • changedInput schema / properties / layer / description
      Previous value: -"Restrict which OSM layer is matched. One value or a comma-separated list drawn from: address, poi, railway, natural, manmade, in any casing. An undocumented layer name is rejected here rather than by Nominatim; an empty value is accepted and treated as omitted. Default: address,poi."New value: +"Restrict which OSM layer is matched: one of address, poi, railway, natural, manmade, or a comma-separated list of them, in any casing. Any other name is rejected here, not upstream; an empty value counts as omitted. Default: address,poi."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_coverage`: Nominatim returns an error indicating no OSM data at the given coordinates (e.g., open ocean or unmapped territory). `invalid_parameters`: Nominatim returned HTTP 400 — it refused one of the forwarded parameters. Its own message names the parameter and is carried in this error. `rate_limited`: Nominatim returned HTTP 429, or answered HTTP 200 with a throttle document instead of JSON — the one request per second usage policy was exceeded. `upstream_error`: Nominatim returned an unexpected non-2xx status other than 429, or answered HTTP 200 with a body that is not JSON and carries no throttle signature. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_coverage`: Nominatim reported no OSM data at the coordinates — open ocean or unmapped territory. `invalid_parameters`: Nominatim returned HTTP 400, refusing one of the forwarded parameters; its own message names which one. `rate_limited`: Nominatim returned HTTP 429, or HTTP 200 with a throttle document in place of JSON — the one request per second policy was exceeded. `upstream_error`: Nominatim returned a non-2xx status other than 429, or HTTP 200 with a non-JSON body carrying no throttle signature. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / result / properties / address / description
      Previous value: -"Structured address. Keys vary by feature type. Common: house_number, road, suburb, city, state, postcode, country, country_code."New value: +"Structured address, keys varying by feature type: house_number, road, suburb, city, state, postcode, country, country_code."
    • changedOutput schema / properties / result / properties / category / description
      Previous value: -"OSM feature category (e.g., \"amenity\", \"building\")."New value: +"OSM feature category (e.g. \"amenity\", \"building\")."
    • changedOutput schema / properties / result / properties / name / description
      Previous value: -"Feature name if the result is a named place."New value: +"Feature name when the object is named."
  3. Changed5 schema fields changed
    • addedInput schema / properties / layer / anyOf
      Added value: +[
      +  {
      +    "const": "",
      +    "type": "string"
      +  },
      +  {
      +    "description": "One documented layer name, or a comma-separated list of them, in any casing.",
      +    "pattern": "^\\s*(?:(?:[aA][dD][dD][rR][eE][sS][sS]|[pP][oO][iI]|[rR][aA][iI][lL][wW][aA][yY]|[nN][aA][tT][uU][rR][aA][lL]|[mM][aA][nN][mM][aA][dD][eE])(?:\\s*,\\s*(?:[aA][dD][dD][rR][eE][sS][sS]|[pP][oO][iI]|[rR][aA][iI][lL][wW][aA][yY]|[nN][aA][tT][uU][rR][aA][lL]|[mM][aA][nN][mM][aA][dD][eE]))*)?\\s*$",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / layer / description
      Previous value: -"Restrict which OSM layer is matched. Comma-separated: address, poi, railway, natural, manmade. Default: address,poi."New value: +"Restrict which OSM layer is matched. One value or a comma-separated list drawn from: address, poi, railway, natural, manmade, in any casing. An undocumented layer name is rejected here rather than by Nominatim; an empty value is accepted and treated as omitted. Default: address,poi."
    • removedInput schema / properties / layer / type
      Removed value: -"string"
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_coverage`: Nominatim returns an error indicating no OSM data at the given coordinates (e.g., open ocean or unmapped territory). `rate_limited`: Nominatim returned HTTP 429, or answered HTTP 200 with a throttle document instead of JSON — the one request per second usage policy was exceeded. `upstream_error`: Nominatim returned an unexpected non-2xx status other than 429, or answered HTTP 200 with a body that is not JSON and carries no throttle signature. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `no_coverage`: Nominatim returns an error indicating no OSM data at the given coordinates (e.g., open ocean or unmapped territory). `invalid_parameters`: Nominatim returned HTTP 400 — it refused one of the forwarded parameters. Its own message names the parameter and is carried in this error. `rate_limited`: Nominatim returned HTTP 429, or answered HTTP 200 with a throttle document instead of JSON — the one request per second usage policy was exceeded. `upstream_error`: Nominatim returned an unexpected non-2xx status other than 429, or answered HTTP 200 with a body that is not JSON and carries no throttle signature. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "no_coverage",
      -  "rate_limited",
      -  "upstream_error"
      -]New value: +[
      +  "no_coverage",
      +  "invalid_parameters",
      +  "rate_limited",
      +  "upstream_error"
      +]
  4. Changed3 schema fields changed
    • addedOutput schema / properties / result / properties / boundingbox / items
      Added value: +false
    • addedOutput schema / properties / result / properties / boundingbox / maxItems
      Added value: +4
    • addedOutput schema / properties / result / properties / boundingbox / minItems
      Added value: +4
  5. Changed8 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "result",
      +      "attribution"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `no_coverage`: Nominatim returns an error indicating no OSM data at the given coordinates (e.g., open ocean or unmapped territory). `rate_limited`: Nominatim returned HTTP 429, or answered HTTP 200 with a throttle document instead of JSON — the one request per second usage policy was exceeded. `upstream_error`: Nominatim returned an unexpected non-2xx status other than 429, or answered HTTP 200 with a body that is not JSON and carries no throttle signature. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "no_coverage",
      +            "rate_limited",
      +            "upstream_error"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / properties / result / properties / boundingbox / items
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  }
      -]
    • addedOutput schema / properties / result / properties / boundingbox / prefixItems
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  }
      +]
    • removedOutput schema / required
      Removed value: -[
      -  "result",
      -  "attribution"
      -]
  6. Changed3 schema fields changed
    • changedInput schema / properties / extratags / description
      Previous value: -"Include extra OSM tags when available (phone, website, opening_hours, wikidata, etc.)."New value: +"Include the extra OSM tags the matched object carries — contact and metadata tags (phone, website, opening_hours, wikidata) and physical attribute tags alike (surface, tracktype, sac_scale, ele, access). Opportunistic, not selective: it reports whatever the matched object happens to carry, so an absent tag describes that object rather than OpenStreetMap, and no value here can steer which object is matched."
    • changedOutput schema / properties / result / properties / extratags / description
      Previous value: -"Additional OSM tags (phone, website, opening_hours, wikidata). Present only when extratags was requested."New value: +"Extra OSM tags this object carries — contact and metadata (phone, website, opening_hours, wikidata) and physical attributes (surface, tracktype, sac_scale, ele, access). Present only when extratags was requested; an absent tag describes this object, not OpenStreetMap."
    • addedOutput schema / properties / tagSelectionCaveat
      Added value: +{
      +  "description": "Standing caveat: tag-based selection lives on the Overpass tools (openstreetmap_query_nearby, openstreetmap_query_bbox, openstreetmap_query_raw), never here. extratags decorates the returned objects rather than selecting them, so a missing tag is not evidence the tag is missing from OpenStreetMap. Present when extratags was requested.",
      +  "type": "string"
      +}
  7. Added

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, and idempotentHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: the result is the closest indexed OSM object at the requested zoom, proximity and layer pick it (never an OSM attribute tag), and in dense areas it can be a neighbouring feature. It also discloses that invalid layer names are rejected locally. This is meaningful behavioral disclosure that goes beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, information-dense sentence that front-loads the core purpose and then adds the key behavioral caveat and sibling routing. Every clause earns its place. It is slightly long but not bloated; the density is justified by the complexity of the tool's behavior. A 4 rather than 5 because the sentence is quite long and packs many concepts, but it remains well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (6 params, output schema present, annotations covering safety), the description is largely complete. It explains the core behavior, the zoom semantics, the layer restriction, and routes to siblings for tag-based queries. The only minor gap is that it doesn't describe the output format, but an output schema exists, so that burden is lifted. It also doesn't mention the language parameter's effect, but the schema covers it. This is a strong, complete description for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters thoroughly. The description adds some context beyond the schema: it explains the zoom levels with examples (18 building, 10 city), clarifies that layer restricts which OSM layer is matched, and notes that an empty layer value counts as omitted. However, most parameter meaning is already in the schema, so the description's added value is moderate. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Convert'), resource ('latitude/longitude pair'), and outcome ('nearest address or named place via Nominatim'). It also distinguishes itself from sibling query tools by explicitly naming them and the condition that selects them ('find features by tag with openstreetmap_query_nearby, openstreetmap_query_bbox, or openstreetmap_query_raw'). This is a clear, specific purpose that an agent can act on.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says when to use this tool (reverse geocoding a coordinate to an address/place) and when not to (finding features by tag, which should use the named sibling query tools). It also provides a concrete behavioral caveat: in dense areas the result may be a neighbouring feature rather than the one containing the coordinate. This is explicit routing guidance with alternatives named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.