Skip to main content
Glama

geocode

Turn a place (address, POI, town) into coordinates. Ask two ways, and they combine: query is free text — one run-together string, the way a person types into a search box — and street, housenumber, city, postcode and country name the parts of an address separately. At least one of the two is required. Pass the parts whenever you already hold the address in parts (a form, a CRM row, a manifest): components are REQUIREMENTS, not hints, so city: "London" means a result outside London cannot come back at all, where "London" inside query only reorders. country takes an ISO 3166-1 alpha-2 code or a country name ("GB", "United Kingdom"); a value naming no country is refused rather than silently matching nothing. Returns up to limit (default 10) candidates with name, one-line label, lat/lon, type and address parts. Pass focus {lat, lon} to rank results near a location higher. Each hit also carries match: a per-component matched/inferred/unmatched verdict, the score_gap to the runner-up, and which backend answered. READ IT before acting on an address — an unmatched or inferred postcode on the top hit means the answer does not carry the address you asked for, and a small score_gap means the ranking barely chose, so show the alternatives instead of picking one. Use verify_places when the address came from a model or a user and needs checking rather than using. Results are matched in lang (default "en"), so English exonyms — "Munich", "Cologne", "Geneva" — resolve to the place meant; pass lang when querying in another language, or "default" for each place's local name.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
cityNoStructured component: town or city, e.g. "London". Matches the containing city as well as the immediate locality, so a suburb name works here too.
langNoLanguage of the place names to match and return, as a two-letter code. Defaults to "en", which is what makes English exonyms ("Munich", "Cologne", "Geneva") resolve to the place meant rather than a same-named town elsewhere. Set it to the language your query is written in; "default" asks for each place's own local name. Deployments support a fixed set (this one: "en", "de", "fr"), and anything outside it is refused.
focusNoOptional location bias: results near this point rank higher.
limitNoMaximum number of results (1–50, default 10).
queryNoFree-text place query, e.g. "Dover ferry terminal". Required unless at least one structured component is supplied.
streetNoStructured component: street name, e.g. "Downing Street". Matches the street of addresses and POIs (transliterated street names included) as well as the street itself.
countryNoStructured component: ISO 3166-1 alpha-2 code or country name — "GB", "gb", "United Kingdom" and "UK" all mean the same country. A value naming no country is refused rather than quietly applied as a filter that matches nothing.
postcodeNoStructured component: postcode in any spacing or case — "SW1A 2AA" and "sw1a2aa" are one query. A bare UK outward code ("SW1A") selects the whole district.
housenumberNoStructured component: house number, e.g. "10" or "221B". Only meaningful alongside `street` — a house number on its own excludes nearly everything and identifies nothing.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultsYesMatching places, best first.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed11 schema fields changed
    • addedInput schema / properties / city
      Added value: +{
      +  "description": "Structured component: town or city, e.g. \"London\". Matches the\ncontaining city as well as the immediate locality, so a suburb name\nworks here too.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / country
      Added value: +{
      +  "description": "Structured component: ISO 3166-1 alpha-2 code or country name —\n\"GB\", \"gb\", \"United Kingdom\" and \"UK\" all mean the same country.\nA value naming no country is refused rather than quietly applied as\na filter that matches nothing.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / housenumber
      Added value: +{
      +  "description": "Structured component: house number, e.g. \"10\" or \"221B\". Only\nmeaningful alongside `street` — a house number on its own excludes\nnearly everything and identifies nothing.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / postcode
      Added value: +{
      +  "description": "Structured component: postcode in any spacing or case — \"SW1A 2AA\"\nand \"sw1a2aa\" are one query. A bare UK outward code (\"SW1A\")\nselects the whole district.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedInput schema / properties / query / description
      Previous value: -"Free-text place query, e.g. \"Dover ferry terminal\"."New value: +"Free-text place query, e.g. \"Dover ferry terminal\". Required unless\nat least one structured component is supplied."
    • changedInput schema / properties / query / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • addedInput schema / properties / street
      Added value: +{
      +  "description": "Structured component: street name, e.g. \"Downing Street\". Matches\nthe street of addresses and POIs (transliterated street names\nincluded) as well as the street itself.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • removedInput schema / required
      Removed value: -[
      -  "query"
      -]
    • addedOutput schema / $defs / GeocodeHit / properties / match
      Added value: +{
      +  "anyOf": [
      +    {
      +      "$ref": "#/$defs/GeocodeMatch"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "How far this hit can be trusted to be the place that was asked\nfor — see [`GeocodeMatch`]. Present whenever the MapMap gateway\nanswered; absent on a deployment falling back to the direct Photon\ngeocoder, and absent on the gateway's own fast paths (a pasted\ncoordinate pair, a bare UK outward code, a category browse), which\nanswer without a ranking to report on."
      +}
    • addedOutput schema / $defs / GeocodeMatch
      Added value: +{
      +  "description": "How well one geocoding result answers what was actually asked.\n\nGeocoding's real failure mode is not \"no answer\" but a confident answer\nto a different question: a plausible row on the wrong street, with\nnothing in the response to say so. This object is that missing say-so,\nand an agent should read it before acting on an address.\n\nHow to read it:\n\n* Any component `unmatched` or `inferred` on the TOP hit means the\n  answer does not carry the address that was asked for — an `unmatched`\n  postcode means the result has no postcode at all, `inferred` means it\n  has a different one. Neither is a match. Say so rather than presenting\n  the hit as the address, and reach for `verify_places` when the address\n  came from a model or a user and needs checking rather than using.\n* A small `score_gap` means the ranking barely chose between this hit\n  and the runner-up, which is exactly when to show the alternatives\n  instead of picking one for the user.",
      +  "properties": {
      +    "components": {
      +      "$ref": "#/$defs/GeocodeMatchComponents",
      +      "description": "Per-component verdict on this hit: one entry for each structured\ncomponent supplied, and empty when the query was free text only."
      +    },
      +    "score_gap": {
      +      "description": "The top result's score minus the runner-up's, rounded to 3 decimal\nplaces. `0` for a single result, and `0` from the `photon` source,\nwhich publishes no per-result score — so a `0` is \"no signal\", not\n\"a tie\".",
      +      "format": "double",
      +      "type": "number"
      +    },
      +    "source": {
      +      "description": "Which backend answered: \"mapmap-index\" (the first-party index) or\n\"photon\".",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "components",
      +    "score_gap",
      +    "source"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / $defs / GeocodeMatchComponents
      Added value: +{
      +  "description": "Per-component verdicts inside a [`GeocodeMatch`]. Each is one of\n\"matched\", \"inferred\" or \"unmatched\"; a component that was not supplied\nis absent entirely.\n\n* \"matched\" — the result's own field carries the value asked for (case-\n  and accent-insensitive, and by containment, so `city: \"London\"`\n  matches \"City of London\").\n* \"inferred\" — the result carries a value for that component, but not\n  the one asked for. It reached the page through ranking, as when a\n  street is found by its transliterated name and displayed under its\n  canonical one.\n* \"unmatched\" — the result carries no value for that component at all.",
      +  "properties": {
      +    "city": {
      +      "description": "Verdict on the supplied `city`.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "country": {
      +      "description": "Verdict on the supplied `country`.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "housenumber": {
      +      "description": "Verdict on the supplied `housenumber`.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "postcode": {
      +      "description": "Verdict on the supplied `postcode`.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "street": {
      +      "description": "Verdict on the supplied `street`.",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
  2. First observed

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It explains that structured components are REQUIREMENTS not hints, that invalid countries are refused, that English exonyms resolve under the default lang, and that each result includes match verdicts, score_gap, and backend. This goes far beyond the schema.

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?

The description is long but each sentence carries substantive guidance: operation, dual query modes, strictness semantics, result fields, match interpretation, and language behavior. It is front-loaded with the core purpose and maintains a logical progression from invocation to interpretation.

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?

Given zero annotations and nine parameters, the description is remarkably complete. It explains return contents, candidate ranking, match semantics, language handling, and when to prefer a sibling tool. With a rich input schema and output schema also present, nothing essential appears missing for an agent to call and interpret this 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?

Schema coverage is 100% and the schema already explains most parameters, so the baseline is 3. The description adds valuable semantics on top: the requirement that at least one of query/structured components is supplied, the contrast between requirements and hints, and the practical implications of focus and language choice. Some parameter detail duplicates the schema, so it is not a perfect 5.

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 opens with a specific verb and resource: 'Turn a place (address, POI, town) into coordinates.' It clearly distinguishes geocode from sibling tools by naming verify_places as the alternative for checking addresses and framing this tool as the conversion of places into coordinates.

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 gives explicit when-to-use guidance: pass structured parts when you already hold an address in parts, use verify_places when the address came from a model or user and needs checking, and show alternatives instead of picking a top hit when score_gap is small. This is direct usage routing, not just implied context.

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.

TDQS

A4/5.0
Disambiguation4/5

Most tools target a distinct action and resource pair, and descriptions are explicit about which tool fits which scenario. The closest overlaps—plan_ev_route vs cheapest_charging_along_route, and route vs plan_day vs order_stops vs optimise_routes—are mitigated by clear guidance, so an agent can usually pick correctly.

Naming Consistency4/5

Tool names overwhelmingly follow a verb_noun snake_case pattern (plan_ev_route, set_palette, list_style_layers) with a consistent geo_ prefix for geometry helpers. Minor deviations like elevation, route, and matrix are short and readable but break the strict verb_noun convention.

Tool Count2/5

At 39 tools, this surface is well past the 25+ threshold and feels heavy even for a broad mapping platform. The set spans routing, geocoding, places, styles, EV/fuel, telematics, usage, and feedback, which would be easier for an agent to navigate if split into smaller domain-focused servers.

Completeness4/5

For the stated breadth, coverage is strong: routing, multi-stop planning, VRP, EV/fuel detours, geocoding, places, geometry, style lifecycle, and telematics all have workable primary paths. Minor gaps like no style deletion, no route alternatives, and no batch geocoding are present but do not create dead ends for core workflows.

Resources