Skip to main content
Glama

openstreetmap-mcp-server

Geocode a place name or address

openstreetmap_search_places
Read-onlyIdempotent

Geocode a place name or address to coordinates and structured place data via Nominatim. Send either a free-form query or the structured address fields (street, city, county, state, country, postalcode), never both; results are the best-ranked matches, not every matching object, and matching never uses an OSM attribute tag, so filter or enumerate by tag with openstreetmap_query_nearby, openstreetmap_query_bbox, or openstreetmap_query_raw.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cityNoCity name (structured query).
layerNoFilter by data layer: 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: no restriction.
limitNoMaximum results to return. Nominatim may return fewer when additional results do not sufficiently match. Max 40.
queryNoFree-form search string, e.g. "Space Needle Seattle" or "1600 Pennsylvania Ave NW, Washington DC". Not combinable with the structured address fields. Nominatim reads commas as an address hierarchy, so give the name plus its city or region and nothing in between: "Beinecke Library, New Haven" matches where "Beinecke Library, Yale University, New Haven" returns nothing.
stateNoState or province (structured query).
countyNoCounty or district (structured query).
streetNoHouse number and street name (structured query). Use with city/state/country fields. Cannot be combined with query.
boundedNoRestrict results to the viewbox instead of merely biasing toward it. Requires viewbox — setting it alone is rejected rather than ignored. With it, a match outside the box is dropped even when it scores higher.
countryNoCountry name or ISO 3166-1 alpha-2 code (structured query).
viewboxNoRectangular area to bias results toward, disambiguating a name that repeats worldwide (a creek in one watershed, a street in one municipality). Narrower than countrycodes. Bias only by default: a better match outside the box is still returned. Set bounded for a hard restriction. Unlike openstreetmap_query_bbox this box may not cross the antimeridian — west must be less than east and south less than north, or the call is rejected.
languageNoPreferred language for result names (BCP 47 code or Accept-Language string, e.g., "en", "de", "fr,en"). Defaults to local OSM language.
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. Increases response size.
postalcodeNoPostal or ZIP code (structured query).
featureTypeNoRestrict results to a geographic feature type. Automatically implies the address layer.
countrycodesNoRestrict results to one or more countries: comma-separated ISO 3166-1 alpha-2 codes (e.g. "us,ca"), any casing, optional spaces around the commas. Any other form — alpha-3, a semicolon list, a country name — is rejected rather than silently dropped upstream. A well-formed code for a country that does not exist matches nothing. An empty value counts as omitted. Prefer this over the structured country field for filtering.
exclude_place_idsNoOSM refs (N/W/R + id) or Nominatim place_ids to drop from results; any other token form is rejected here rather than by Nominatim. Entries are trimmed, lowercase ref prefixes uppercased, a blank entry treated as absent. Page toward further matches by passing back a prior full page's nextExcludeIds, which prefers stable OSM refs over volatile place_ids; the walk ends when a page returns zero results with an exhaustion notice — a success, not an error. Best-effort, not a cursor: Nominatim ranking can reorder between calls, so already-seen results may shift.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
capNoThe limit applied to this request.
errorNoPresent when the call failed. Absent on success.
shownNoNumber of results returned.
totalNoNumber of results returned.
noticeNoPaging guidance, in two cases: results were capped at limit with a probe confirming a further match at the query's relevance cutoff (truncated true — keep paging with nextExcludeIds), or an exclude_place_ids walk was exhausted and the page came back empty (the query matched; the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field's presence. Absent when a page returns below the limit, and when it fills the limit with nothing past the cutoff — read nextExcludeIds for whether paging can continue.
resultsNoGeocoding results, ordered by Nominatim relevance (importance score descending).
truncatedNoTrue when the page filled the requested limit and a same-call probe confirmed another match at this query's relevance cutoff; absent otherwise. Absence is not exhaustion — excluding a full page's ids can still surface less accurate matches past that cutoff, which is why nextExcludeIds is offered on any full page. Nominatim reports no total, so this is a confirmed observation, not an inference from page size.
attributionNoRequired data attribution: Data © OpenStreetMap contributors, ODbL 1.0.
boundedAppliedNoTrue when the viewbox was a hard restriction (bounded=1 was sent), false when it biased ranking only and a match outside it could still be returned. Absent when no viewbox was supplied.
effectiveQueryNoThe effective query sent to Nominatim — the free-form query string, or a reconstructed string from the provided structured address fields.
nextExcludeIdsNoAccumulated exclude tokens (prior excludes plus this page) to pass as exclude_place_ids on the next call. Each is a stable OSM ref (N/W/R + osm_id) when the result carries one, the Nominatim place_id otherwise. Present whenever the page filled the requested limit, whether or not truncated is set: excluding a full page can surface less accurate matches past the probe's cutoff. Best-effort, not a cursor — ranking can reorder between calls, so a walk can end sooner than the page count suggests.
effectiveViewboxNoThe viewbox forwarded to Nominatim on this call, echoed so an ambiguous result can be read against the area that scoped it. Absent when no viewbox was supplied.
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 on every successful response.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedOutput schema / properties / results / items / 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 / results / items / 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 / results / items / properties / lat / description
      Previous value: -"Latitude (WGS84, as string from API)."New value: +"Latitude in WGS84 decimal degrees."
    • changedOutput schema / properties / results / items / properties / lat / type
      Previous value: -"string"New value: +"number"
    • changedOutput schema / properties / results / items / properties / lon / description
      Previous value: -"Longitude (WGS84, as string from API)."New value: +"Longitude in WGS84 decimal degrees."
    • changedOutput schema / properties / results / items / properties / lon / type
      Previous value: -"string"New value: +"number"
    • changedOutput schema / properties / results / items / 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. Changed15 schema fields changed
    • changedInput schema / properties / countrycodes / description
      Previous value: -"Restrict results to one or more countries. Comma-separated ISO 3166-1 alpha-2 codes (e.g., \"us,ca\"), in any casing and with optional spaces around the commas. Anything else — an alpha-3 code, a semicolon list, a country name — is rejected here rather than by Nominatim, which would discard it and silently return unfiltered results. A well-formed code for a country that does not exist is forwarded and matches nothing. An empty value is accepted and treated as omitted. Preferred over the structured country field when filtering."New value: +"Restrict results to one or more countries: comma-separated ISO 3166-1 alpha-2 codes (e.g. \"us,ca\"), any casing, optional spaces around the commas. Any other form — alpha-3, a semicolon list, a country name — is rejected rather than silently dropped upstream. A well-formed code for a country that does not exist matches nothing. An empty value counts as omitted. Prefer this over the structured country field for filtering."
    • changedInput schema / properties / exclude_place_ids / description
      Previous value: -"OSM refs (N/W/R + id) or Nominatim place_ids to drop from results, forwarded as the exclude_place_ids parameter. Each entry must be one of those two token forms — anything else is rejected here rather than by Nominatim. Entries are trimmed and lowercase ref prefixes uppercased before forwarding, and a blank entry is treated as absent. Pass the nextExcludeIds value from a prior full page to page toward further matches — it emits stable OSM refs when available, which page more reliably than volatile place_ids. When the walk runs out, the call succeeds with zero results and an exhaustion notice rather than failing — treat that as the loop-termination signal. Best-effort progressive retrieval, not a stable cursor — Nominatim ranking can reorder slightly between calls, so already-seen results may shift."New value: +"OSM refs (N/W/R + id) or Nominatim place_ids to drop from results; any other token form is rejected here rather than by Nominatim. Entries are trimmed, lowercase ref prefixes uppercased, a blank entry treated as absent. Page toward further matches by passing back a prior full page's nextExcludeIds, which prefers stable OSM refs over volatile place_ids; the walk ends when a page returns zero results with an exhaustion notice — a success, not an error. Best-effort, not a cursor: Nominatim ranking can reorder between calls, so already-seen results may shift."
    • 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. Increases response size."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. Increases response size."
    • changedInput schema / properties / layer / description
      Previous value: -"Filter by data layer. 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: no restriction."New value: +"Filter by data layer: 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: no restriction."
    • changedInput schema / properties / query / description
      Previous value: -"Free-form search string (e.g., \"Space Needle Seattle\" or \"1600 Pennsylvania Ave NW, Washington DC\"). Cannot be combined with structured address fields. Keep the query to a POI name plus its city or region. Do not insert a parent institution, campus, or building name between the name and the locality: Nominatim reads commas as an address hierarchy and returns nothing when an intermediate token is not a matching containment level. For example, use \"Beinecke Library, New Haven\", not \"Beinecke Library, Yale University, New Haven\"."New value: +"Free-form search string, e.g. \"Space Needle Seattle\" or \"1600 Pennsylvania Ave NW, Washington DC\". Not combinable with the structured address fields. Nominatim reads commas as an address hierarchy, so give the name plus its city or region and nothing in between: \"Beinecke Library, New Haven\" matches where \"Beinecke Library, Yale University, New Haven\" returns nothing."
    • changedInput schema / properties / viewbox / description
      Previous value: -"Rectangular area to bias results toward, for disambiguating a name that repeats worldwide — a creek inside one watershed, a street inside one municipal boundary. Finer-grained than countrycodes and more precise than adding locality words to the query. Bias only by default: a better match outside the box is still returned. Set bounded to make it a hard restriction. Unlike openstreetmap_query_bbox, this box may not cross the antimeridian: west must be less than east and south less than north, or the call is rejected."New value: +"Rectangular area to bias results toward, disambiguating a name that repeats worldwide (a creek in one watershed, a street in one municipality). Narrower than countrycodes. Bias only by default: a better match outside the box is still returned. Set bounded for a hard restriction. Unlike openstreetmap_query_bbox this box may not cross the antimeridian — west must be less than east and south less than north, or the call is rejected."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_results`: No places matched the query on a first page — no exclude_place_ids were supplied. An exhausted paging walk returns success with zero results instead. `conflicting_query_mode`: The free-form query and at least one structured address field are both provided — the two modes are mutually exclusive. `missing_query_mode`: Neither the free-form query nor any structured address field is provided. `bounded_without_viewbox`: bounded was set to true but no viewbox was supplied — there is no area for it to restrict results to. `invalid_viewbox`: The viewbox is inverted or degenerate on either axis — west at or beyond east, or south at or beyond north. `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_results`: No places matched, and no exclude_place_ids were supplied — an exhausted paging walk returns success with zero results instead. `conflicting_query_mode`: query and at least one structured address field were both supplied; the two modes are mutually exclusive. `missing_query_mode`: Neither query nor any structured address field was supplied. `bounded_without_viewbox`: bounded was set without a viewbox for it to restrict results to. `invalid_viewbox`: The viewbox is inverted or degenerate: west at or beyond east, or south at or beyond north. `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 / nextExcludeIds / description
      Previous value: -"Accumulated exclude tokens (prior excludes plus this page) to pass as exclude_place_ids on the next call, retrieving further matches. Each token is a stable OSM ref (N/W/R + osm_id) when the result carries one, falling back to the Nominatim place_id otherwise. Present whenever the page filled the requested limit, whether or not truncated is set — the probe reads the relevance cutoff, and excluding this page can still surface less accurate matches beyond it. Best-effort rather than a stable cursor: Nominatim ranking can reorder slightly between calls, so a walk can still end sooner than the page count suggests."New value: +"Accumulated exclude tokens (prior excludes plus this page) to pass as exclude_place_ids on the next call. Each is a stable OSM ref (N/W/R + osm_id) when the result carries one, the Nominatim place_id otherwise. Present whenever the page filled the requested limit, whether or not truncated is set: excluding a full page can surface less accurate matches past the probe's cutoff. Best-effort, not a cursor — ranking can reorder between calls, so a walk can end sooner than the page count suggests."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance for this page, covering two cases: results were capped at limit and a probe confirmed a further match at the query's relevance cutoff (truncated is true — keep paging with nextExcludeIds), or an exclude_place_ids paging walk is exhausted and the page came back empty (the query matched, the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field being present. Absent when a page returns below the limit, and absent when it fills the limit with nothing past the cutoff — that page still carries nextExcludeIds, which is the field to read for whether paging can continue. Carries paging guidance only — the tag-selection caveat has its own field so neither message can overwrite the other."New value: +"Paging guidance, in two cases: results were capped at limit with a probe confirming a further match at the query's relevance cutoff (truncated true — keep paging with nextExcludeIds), or an exclude_place_ids walk was exhausted and the page came back empty (the query matched; the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field's presence. Absent when a page returns below the limit, and when it fills the limit with nothing past the cutoff — read nextExcludeIds for whether paging can continue."
    • changedOutput schema / properties / results / items / properties / address / description
      Previous value: -"Structured address breakdown. Keys vary by feature type and country. Common keys: house_number, road, suburb, city, state, postcode, country, country_code."New value: +"Structured address breakdown, keys varying by feature type and country: house_number, road, suburb, city, state, postcode, country, country_code."
    • changedOutput schema / properties / results / items / properties / category / description
      Previous value: -"OSM feature category (e.g., \"amenity\", \"man_made\", \"boundary\")."New value: +"OSM feature category (e.g. \"amenity\", \"man_made\")."
    • changedOutput schema / properties / results / items / properties / name / description
      Previous value: -"Feature name if applicable (e.g., \"Space Needle\"). Absent for address-only results."New value: +"Feature name; absent for address-only results."
    • changedOutput schema / properties / results / items / properties / place_id / description
      Previous value: -"Nominatim internal place ID. Use osm_type+osm_id for stable cross-server references."New value: +"Nominatim internal place ID. Stable cross-server reference: osm_type+osm_id."
    • changedOutput schema / properties / results / items / properties / type / description
      Previous value: -"OSM feature type within category (e.g., \"hospital\", \"tower\", \"administrative\")."New value: +"OSM feature type within category (e.g. \"hospital\", \"tower\")."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the page filled the requested limit and a same-call probe for one further result confirmed another match at this query's relevance cutoff. Absent otherwise. Absence is not a claim that the set is exhausted: Nominatim applies its own relevance cutoff, so excluding a full page's ids can still surface further, less accurate matches — which is why nextExcludeIds is offered on any full page. Nominatim reports no total, so this is a confirmed observation rather than an inference from page size."New value: +"True when the page filled the requested limit and a same-call probe confirmed another match at this query's relevance cutoff; absent otherwise. Absence is not exhaustion — excluding a full page's ids can still surface less accurate matches past that cutoff, which is why nextExcludeIds is offered on any full page. Nominatim reports no total, so this is a confirmed observation, not an inference from page size."
  3. Changed3 schema fields changed
    • addedInput schema / properties / countrycodes / anyOf
      Added value: +[
      +  {
      +    "const": "",
      +    "type": "string"
      +  },
      +  {
      +    "description": "One ISO 3166-1 alpha-2 country code, or a comma-separated list of them, in any casing.",
      +    "pattern": "^\\s*(?:[A-Za-z]{2}\\s*)?(?:,\\s*(?:[A-Za-z]{2}\\s*)?)*$",
      +    "type": "string"
      +  }
      +]
    • changedInput schema / properties / countrycodes / description
      Previous value: -"Restrict results to one or more countries. Comma-separated ISO 3166-1 alpha-2 codes (e.g., \"us,ca\"). Preferred over the structured country field when filtering."New value: +"Restrict results to one or more countries. Comma-separated ISO 3166-1 alpha-2 codes (e.g., \"us,ca\"), in any casing and with optional spaces around the commas. Anything else — an alpha-3 code, a semicolon list, a country name — is rejected here rather than by Nominatim, which would discard it and silently return unfiltered results. A well-formed code for a country that does not exist is forwarded and matches nothing. An empty value is accepted and treated as omitted. Preferred over the structured country field when filtering."
    • removedInput schema / properties / countrycodes / type
      Removed value: -"string"
  4. Changed16 schema fields changed
    • addedInput schema / properties / bounded
      Added value: +{
      +  "description": "Restrict results to the viewbox instead of merely biasing toward it. Requires viewbox — setting it alone is rejected rather than ignored. With it, a match outside the box is dropped even when it scores higher.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / exclude_place_ids / description
      Previous value: -"OSM refs (N/W/R + id) or Nominatim place_ids to drop from results, forwarded as the exclude_place_ids parameter. Pass the nextExcludeIds value from a prior truncated response to page toward the next-best matches — it emits stable OSM refs when available, which page more reliably than volatile place_ids. When the walk runs out, the call succeeds with zero results and an exhaustion notice rather than failing — treat that as the loop-termination signal. Best-effort progressive retrieval, not a stable cursor — Nominatim ranking can reorder slightly between calls, so already-seen results may shift."New value: +"OSM refs (N/W/R + id) or Nominatim place_ids to drop from results, forwarded as the exclude_place_ids parameter. Each entry must be one of those two token forms — anything else is rejected here rather than by Nominatim. Entries are trimmed and lowercase ref prefixes uppercased before forwarding, and a blank entry is treated as absent. Pass the nextExcludeIds value from a prior full page to page toward further matches — it emits stable OSM refs when available, which page more reliably than volatile place_ids. When the walk runs out, the call succeeds with zero results and an exhaustion notice rather than failing — treat that as the loop-termination signal. Best-effort progressive retrieval, not a stable cursor — Nominatim ranking can reorder slightly between calls, so already-seen results may shift."
    • addedInput schema / properties / exclude_place_ids / items / anyOf
      Added value: +[
      +  {
      +    "const": "",
      +    "type": "string"
      +  },
      +  {
      +    "description": "An OSM ref (N/W/R plus the object id) or a bare Nominatim place_id.",
      +    "pattern": "^\\s*(?:[NWRnwr]\\d+|\\d+)?\\s*$",
      +    "type": "string"
      +  }
      +]
    • addedInput schema / properties / exclude_place_ids / items / description
      Added value: +"One exclusion token, or an empty value that excludes nothing."
    • removedInput schema / properties / exclude_place_ids / items / type
      Removed value: -"string"
    • 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: -"Filter by data layer. Comma-separated values: address, poi, railway, natural, manmade. Default: no restriction."New value: +"Filter by data layer. 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: no restriction."
    • removedInput schema / properties / layer / type
      Removed value: -"string"
    • addedInput schema / properties / viewbox
      Added value: +{
      +  "description": "Rectangular area to bias results toward, for disambiguating a name that repeats worldwide — a creek inside one watershed, a street inside one municipal boundary. Finer-grained than countrycodes and more precise than adding locality words to the query. Bias only by default: a better match outside the box is still returned. Set bounded to make it a hard restriction. Unlike openstreetmap_query_bbox, this box may not cross the antimeridian: west must be less than east and south less than north, or the call is rejected.",
      +  "properties": {
      +    "east": {
      +      "description": "Eastern boundary longitude. Must be strictly greater than west.",
      +      "maximum": 180,
      +      "minimum": -180,
      +      "type": "number"
      +    },
      +    "north": {
      +      "description": "Northern boundary latitude. Must be strictly greater than south.",
      +      "maximum": 90,
      +      "minimum": -90,
      +      "type": "number"
      +    },
      +    "south": {
      +      "description": "Southern boundary latitude. Must be strictly less than north.",
      +      "maximum": 90,
      +      "minimum": -90,
      +      "type": "number"
      +    },
      +    "west": {
      +      "description": "Western boundary longitude. Must be strictly less than east.",
      +      "maximum": 180,
      +      "minimum": -180,
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "west",
      +    "south",
      +    "east",
      +    "north"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / boundedApplied
      Added value: +{
      +  "description": "True when the viewbox was a hard restriction (bounded=1 was sent), false when it biased ranking only and a match outside it could still be returned. Absent when no viewbox was supplied.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / effectiveViewbox
      Added value: +{
      +  "additionalProperties": false,
      +  "description": "The viewbox forwarded to Nominatim on this call, echoed so an ambiguous result can be read against the area that scoped it. Absent when no viewbox was supplied.",
      +  "properties": {
      +    "east": {
      +      "description": "Eastern boundary longitude sent to Nominatim.",
      +      "type": "number"
      +    },
      +    "north": {
      +      "description": "Northern boundary latitude sent to Nominatim.",
      +      "type": "number"
      +    },
      +    "south": {
      +      "description": "Southern boundary latitude sent to Nominatim.",
      +      "type": "number"
      +    },
      +    "west": {
      +      "description": "Western boundary longitude sent to Nominatim.",
      +      "type": "number"
      +    }
      +  },
      +  "required": [
      +    "west",
      +    "south",
      +    "east",
      +    "north"
      +  ],
      +  "type": "object"
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `no_results`: No places matched the query on a first page — no exclude_place_ids were supplied. An exhausted paging walk returns success with zero results instead. `conflicting_query_mode`: The free-form query and at least one structured address field are both provided — the two modes are mutually exclusive. `missing_query_mode`: Neither the free-form query nor any structured address field is provided. `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_results`: No places matched the query on a first page — no exclude_place_ids were supplied. An exhausted paging walk returns success with zero results instead. `conflicting_query_mode`: The free-form query and at least one structured address field are both provided — the two modes are mutually exclusive. `missing_query_mode`: Neither the free-form query nor any structured address field is provided. `bounded_without_viewbox`: bounded was set to true but no viewbox was supplied — there is no area for it to restrict results to. `invalid_viewbox`: The viewbox is inverted or degenerate on either axis — west at or beyond east, or south at or beyond north. `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_results",
      -  "conflicting_query_mode",
      -  "missing_query_mode",
      -  "rate_limited",
      -  "upstream_error"
      -]New value: +[
      +  "no_results",
      +  "conflicting_query_mode",
      +  "missing_query_mode",
      +  "bounded_without_viewbox",
      +  "invalid_viewbox",
      +  "invalid_parameters",
      +  "rate_limited",
      +  "upstream_error"
      +]
    • changedOutput schema / properties / nextExcludeIds / description
      Previous value: -"Accumulated exclude tokens (prior excludes plus this page) to pass as exclude_place_ids on the next call, retrieving the next-best matches. Each token is a stable OSM ref (N/W/R + osm_id) when the result carries one, falling back to the Nominatim place_id otherwise. Present only when results were truncated. Nominatim reports no total, so a truncated page is not proof that more matches exist — the following page may come back exhausted (zero results plus a notice). Best-effort: Nominatim ranking is not perfectly stable across calls."New value: +"Accumulated exclude tokens (prior excludes plus this page) to pass as exclude_place_ids on the next call, retrieving further matches. Each token is a stable OSM ref (N/W/R + osm_id) when the result carries one, falling back to the Nominatim place_id otherwise. Present whenever the page filled the requested limit, whether or not truncated is set — the probe reads the relevance cutoff, and excluding this page can still surface less accurate matches beyond it. Best-effort rather than a stable cursor: Nominatim ranking can reorder slightly between calls, so a walk can still end sooner than the page count suggests."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance for this page, covering two cases: results were capped at limit (truncated is true — keep paging with nextExcludeIds), or an exclude_place_ids paging walk is exhausted and the page came back empty (the query matched, the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field being present. Absent when a page returns below the limit without being capped. Carries paging guidance only — the tag-selection caveat has its own field so neither message can overwrite the other."New value: +"Guidance for this page, covering two cases: results were capped at limit and a probe confirmed a further match at the query's relevance cutoff (truncated is true — keep paging with nextExcludeIds), or an exclude_place_ids paging walk is exhausted and the page came back empty (the query matched, the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field being present. Absent when a page returns below the limit, and absent when it fills the limit with nothing past the cutoff — that page still carries nextExcludeIds, which is the field to read for whether paging can continue. Carries paging guidance only — the tag-selection caveat has its own field so neither message can overwrite the other."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True if the result count equals the requested limit (Nominatim may have more)."New value: +"True when the page filled the requested limit and a same-call probe for one further result confirmed another match at this query's relevance cutoff. Absent otherwise. Absence is not a claim that the set is exhausted: Nominatim applies its own relevance cutoff, so excluding a full page's ids can still surface further, less accurate matches — which is why nextExcludeIds is offered on any full page. Nominatim reports no total, so this is a confirmed observation rather than an inference from page size."
  5. Changed3 schema fields changed
    • addedOutput schema / properties / results / items / properties / boundingbox / items
      Added value: +false
    • addedOutput schema / properties / results / items / properties / boundingbox / maxItems
      Added value: +4
    • addedOutput schema / properties / results / items / properties / boundingbox / minItems
      Added value: +4
  6. 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": [
      +      "results",
      +      "total",
      +      "attribution",
      +      "effectiveQuery"
      +    ]
      +  },
      +  {
      +    "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_results`: No places matched the query on a first page — no exclude_place_ids were supplied. An exhausted paging walk returns success with zero results instead. `conflicting_query_mode`: The free-form query and at least one structured address field are both provided — the two modes are mutually exclusive. `missing_query_mode`: Neither the free-form query nor any structured address field is provided. `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_results",
      +            "conflicting_query_mode",
      +            "missing_query_mode",
      +            "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 / results / items / properties / boundingbox / items
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "string"
      -  }
      -]
    • addedOutput schema / properties / results / items / properties / boundingbox / prefixItems
      Added value: +[
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  },
      +  {
      +    "type": "string"
      +  }
      +]
    • removedOutput schema / required
      Removed value: -[
      -  "results",
      -  "total",
      -  "attribution",
      -  "effectiveQuery"
      -]
  7. Changed5 schema fields changed
    • addedInput schema / anyOf
      Added value: +[
      +  {
      +    "required": [
      +      "query"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "required": [
      +      "street"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "required": [
      +      "city"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "required": [
      +      "county"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "required": [
      +      "state"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "required": [
      +      "country"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "required": [
      +      "postalcode"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / properties / extratags / description
      Previous value: -"Include extra OSM tags when available (e.g., phone, website, opening_hours, wikidata). Increases response size."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. Increases response size."
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance for this page, covering two cases: results were capped at limit (truncated is true — keep paging with nextExcludeIds), or an exclude_place_ids paging walk is exhausted and the page came back empty (the query matched, the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field being present. Absent when a page returns below the limit without being capped."New value: +"Guidance for this page, covering two cases: results were capped at limit (truncated is true — keep paging with nextExcludeIds), or an exclude_place_ids paging walk is exhausted and the page came back empty (the query matched, the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field being present. Absent when a page returns below the limit without being capped. Carries paging guidance only — the tag-selection caveat has its own field so neither message can overwrite the other."
    • changedOutput schema / properties / results / items / 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 on every successful response.",
      +  "type": "string"
      +}
  8. Changed1 schema field changed
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when the page came back empty. Present when an exclude_place_ids paging walk is exhausted — the query matched, the walk simply ended, so no rewrite is needed. Absent when results were returned."New value: +"Guidance for this page, covering two cases: results were capped at limit (truncated is true — keep paging with nextExcludeIds), or an exclude_place_ids paging walk is exhausted and the page came back empty (the query matched, the walk simply ended, so no rewrite is needed). Tell them apart by truncated and the result count, not by this field being present. Absent when a page returns below the limit without being capped."
  9. Added

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the readOnly/openWorld/idempotent annotations, the description discloses that results are best-ranked matches rather than every matching object, that structured and free-form inputs must not be combined, and that matching never uses OSM attribute tags. This gives an agent accurate expectations about completeness and selection behavior.

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

Conciseness5/5

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

Two sentences carry the purpose, the key usage constraint, the non-exhaustive result behavior, and the routing to alternative tools. Every clause earns its place, and the core purpose is front-loaded.

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

Completeness5/5

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

For a 16-parameter tool with an output schema, the description plus schema is complete: the description clarifies the query modes, result ranking, and sibling alternatives, while the schema and annotations cover parameters, defaults, validation, and read-only behavior. An agent has what it needs to invoke the tool correctly.

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

Parameters4/5

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

The schema already documents every parameter in detail (100% coverage), so the baseline is 3. The description adds meaningful top-level semantics by grouping the structured address fields and explicitly stating the mutual exclusivity between them and the free-form query, a constraint not fully enforced by the schema's anyOf structure.

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 and resource: geocode a place name or address into coordinates and structured place data. It also distinguishes this tool from the sibling query tools by noting that matching never uses an OSM attribute tag, so an agent can tell it apart.

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 the tool (geocoding a place name or address), how to choose between free-form and structured query modes, and when not to use it: when tag-based filtering or enumeration is needed, use openstreetmap_query_nearby, openstreetmap_query_bbox, or openstreetmap_query_raw.

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.