Koskamo

Geocode AI MCP

An official MCP server operated by Meter for the Geocode AI product, allowing AI agents to query administrative boundaries, reverse-geocode locations, and generate complex area polygons from natural language descriptions. It provides tools for searching boundaries, exporting geometries, and managing account settings, supporting both HTTP and stdio transports for integration with Claude Code, Cursor, and other MCP hosts.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Geocode AI MCP logo, by MeterVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-06Operated by Meter
You need:Get a free API key
MCP endpoint (Streamable HTTP)
https://geocodeai.dev/mcp
Vendor documentation

What its tools do

43 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

43 of 43 have a description · 43 of 43 declare behavior hints · 26 of 34 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to geocodeai.dev ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search for administrative boundaries by name or point
  • Reverse geocode coordinates to find containing jurisdictions
  • Create area polygons from natural language descriptions
  • Check if points fall within specific administrative boundaries

Source and maintenance

Vendor evidenceRegistry 1.0.2

Protocol and capabilities

Server
geocode 1.0.0
MCP protocol negotiated in check
2025-11-25
Tools
43 advertised
Resources
1 advertised
Resource templates
0 advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  },
  "resources": {
    "listChanged": false
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Geocode AI. Boundaries and areas API for every place on Earth. Administrative boundaries come from OpenStreetMap and are cached, so repeat lookups are instant. Workflow: 1. A named place (country, state, county, city, district, postcode): search_boundaries with the name (add the country or parent to disambiguate), pick the result whose admin level and parents match, then get_boundary with its id for the polygon. Never guess an id. 2. A coordinate: reverse_boundaries returns every boundary containing it, country down to neighbourhood. 3. Everything inside a boundary (states of a country, counties of a state): list_children with the parent's id. 4. Which zone each of many points falls in: contains_points (one batch, not one call per point). 5. Several boundaries as one shape: union_boundaries with their ids. 6. A described area that is not one named place ("the Bay Area minus San Francisco", a service area clause from a contract): create_area with the text. It runs an AI agent for 30 s to a few minutes and costs 50 units, so use it only when search + get cannot answer. 7. A bug or missing feature: with the human's OK, report_issue (the failing call's request_id and op) or request_feature. On `similar` matches upvote_feedback instead. Boundary ids are r<OSM relation id> (r396499) or w<way id>; R62422, relation/62422 and osm.org URLs are accepted on input, the canonical form comes back. Reuse ids already in the conversation. Costs: one unit per boundary geometry, reverse lookup or point batch; searching and browsing are free; a described area is 50 units. The Free plan includes 1,000 units a month. On a 402 (quota) or 429 stop and tell the human: the error carries upgrades and checkout_url; never upgrade a plan on your own. get_pricing has the current plans, limits and features; get_account the plan in force and what is left this month. Without a key only the public tools work (20 calls a minute per IP). A free key (geo_…) from https://geocodeai.dev/dashboard?ref=mcp or `npx @meterapp/geocode login` unlocks the rest. Buying a plan, when the human asks: create_checkout_link with the plan from get_pricing returns a Stripe page for the human to pay on (without a key, Checkout collects their email and creates the account); give them the url with the plan and price (yearly: true bills ten months' price once a year), then get_account shows when it is active. get_billing_link: invoices, card, switching, cancelling. You never pay, switch or cancel yourself, and never take card details. Accounts are organizations: a key or connection acts in one organization (get_account names it and your role: viewer, member, admin or owner), and its plan, units, API keys and file library are shared by every member. Viewers can only read; billing needs an admin. To hand a boundary to the human's team: list_files, else save_file (1 unit), then share_file with a team from list_teams. Inviting or removing people and changing roles is done by a person at https://geocodeai.dev/dashboard/org?ref=mcp; never try to do it yourself. Results are GeoJSON (WGS84, lon/lat order). When you show a polygon to a human, say which boundary it is (name, admin level, parent) so they can confirm it is the right one. Feedback: a failed tool result names its request_id; pass it to report_issue so we can find the call. Issues are private to the human and our team; feature requests and comments are public, so never include keys or personal data. Filing, voting and commenting email the human a thank-you and every status change. list_my_feedback follows up on what they filed or voted for. submit_review posts the human's review of the product: only with their own rating and words, never invented. Tools: - search_boundaries (free, no key needed): Search boundaries. - get_boundary (1 unit, no key needed): Get boundary polygon. - export_boundary (1 unit): Export boundary file. - reverse_boundaries (1 unit): Boundaries at a point. - list_children (free, no key needed): List subdivisions. - contains_points (units vary with the input): Points in boundary. - union_boundaries (units vary with the input): Merge boundaries. - create_area (50 units): Create area from a description. - get_account (free): Get account. - update_profile (free): Update profile. - get_usage (free): Get usage. - list_api_keys (free): List API keys. - create_api_key (free): Create API key. - revoke_api_key (free): Revoke API key. - get_email_preferences (free): Get email preferences. - update_email_preferences (free): Update email preferences. - list_orgs (free): List organizations. - list_members (free): List members. - list_teams (free): List teams. - list_invites (free): List invites. - list_audit_log (free): List audit log. - save_file (1 unit): Save boundary file to the library. - list_files (free): List library files. - get_file (free): Get library file. - update_file (free): Rename or change visibility. - delete_file (free): Remove from the library. - share_file (free): Share library file. - unshare_file (free): Stop sharing library file. - get_subscription (free): Get subscription. - create_checkout_link (free, no key needed): Create checkout link. - get_billing_link (free): Get billing link. - list_feedback (free, no key needed): List feature requests and issues. - get_feedback (free, no key needed): Get a feature request or issue. - list_my_feedback (free): List my feedback and subscriptions. - request_feature (free): Request a feature. - report_issue (free): Report an issue. - upvote_feedback (free): Upvote a feature request or issue. - remove_feedback_vote (free): Remove an upvote. - comment_on_feedback (free): Comment on a feature request or issue. - list_reviews (free, no key needed): Read reviews. - get_my_review (free): Get my review. - submit_review (free): Post or edit a review. - get_pricing (free, no key needed): Get plans and prices. REST: https://geocodeai.dev/openapi.json · Docs for agents: https://geocodeai.dev/llms.txt

Tools

43 advertised

search_boundaries — Search boundaries
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Finds administrative boundaries (countries, states, counties, cities, districts) and postcode areas by name, in any language. Filter by country, kind or admin_level; bias toward a point with near. Free and public. Returns candidates with id, kind, admin_level, country, parents, bbox, centroid and population, but no polygon: pass the id to get_boundary for that.

search_boundaries input schema
{
  "type": "object",
  "required": [
    "q"
  ],
  "properties": {
    "q": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "A place name, e.g. \"Berlin\", \"Alameda County\", \"75011\"."
    },
    "kind": {
      "enum": [
        "country",
        "state",
        "region",
        "province",
        "county",
        "district",
        "municipality",
        "city",
        "borough",
        "ward",
        "neighbourhood",
        "postal_code"
      ],
      "type": "string",
      "description": "Only this kind (normalized across countries): country, state, region, province, county, district, municipality, city, borough, ward, neighbourhood, postal_code."
    },
    "near": {
      "type": "string",
      "pattern": "^\\s*-?\\d+(\\.\\d+)?\\s*,\\s*-?\\d+(\\.\\d+)?\\s*$",
      "description": "lat,lon to prefer results near, e.g. 37.77,-122.42."
    },
    "limit": {
      "type": "integer",
      "default": 10,
      "maximum": 40,
      "minimum": 1,
      "description": "At most this many results (1–40, default 10)."
    },
    "country": {
      "type": "string",
      "pattern": "^[A-Za-z]{2}(,[A-Za-z]{2})*$",
      "description": "Limit to countries: ISO 3166-1 alpha-2, comma-separated (e.g. US or de,at,ch)."
    },
    "admin_level": {
      "type": "integer",
      "maximum": 12,
      "minimum": 1,
      "description": "Only this OSM admin_level (2 = country; meaning varies by country below that)."
    }
  }
}
search_boundaries annotations
{
  "title": "Search boundaries",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_boundary — Get boundary polygon
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Returns one boundary as a GeoJSON Feature: its polygon at a chosen detail plus properties (name, kind, admin_level, parents, bbox, area_km2, population, wikidata). Fetched from OpenStreetMap the first time anyone asks, then served from cache. Costs 1 unit; detail=low is also public without a key (for map previews). include=parents adds the full hierarchy, include=children the direct subdivisions. If the polygon is too big for one response, geometry is null and download_url points to the file.

get_boundary input schema
{
  "type": "object",
  "required": [
    "id",
    "include"
  ],
  "properties": {
    "id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Boundary id: r<OSM relation id> (e.g. r62422 for Berlin) or w<way id>. Also accepts R62422, relation/62422, -62422, an openstreetmap.org URL, wikidata:Q64 or iso:US-CA."
    },
    "detail": {
      "enum": [
        "low",
        "medium",
        "high",
        "full"
      ],
      "type": "string",
      "description": "Simplification relative to the boundary's size: low (~1,000 points across; the default without a key), medium (the default with a key, ~5,000), high (~25,000), full (unsimplified OSM)."
    },
    "include": {
      "type": "array",
      "items": {
        "enum": [
          "parents",
          "children"
        ],
        "type": "string"
      },
      "description": "Comma-separated extras: parents, children."
    },
    "precision": {
      "type": "integer",
      "maximum": 7,
      "minimum": 3,
      "description": "Coordinate decimals (3–7). Defaults to what the detail level needs."
    }
  }
}
get_boundary annotations
{
  "title": "Get boundary polygon",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
export_boundary — Export boundary file
Advertised by the server during the last successful anonymous check.
Open-world

Builds a boundary's polygon as a file (geojson, kml, wkt, svg or gml) at a detail level and returns a permanent public URL on our CDN; the REST route redirects straight to it. Use it for large polygons, GIS tools and bulk downloads. Costs 1 unit; each file is built once and then shared. Needs an API key or a connected account.

export_boundary input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Boundary id: r<OSM relation id> (e.g. r62422 for Berlin) or w<way id>. Also accepts R62422, relation/62422, -62422, an openstreetmap.org URL, wikidata:Q64 or iso:US-CA."
    },
    "detail": {
      "enum": [
        "low",
        "medium",
        "high",
        "full"
      ],
      "type": "string",
      "default": "medium",
      "description": "Simplification relative to the boundary's size: low (~1,000 points across, maps and previews), medium (default, ~5,000), high (~25,000), full (unsimplified OSM)."
    },
    "format": {
      "enum": [
        "geojson",
        "kml",
        "wkt",
        "svg",
        "gml"
      ],
      "type": "string",
      "default": "geojson",
      "description": "geojson (a Feature), kml, wkt, svg or gml."
    }
  }
}
export_boundary annotations
{
  "title": "Export boundary file",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
reverse_boundaries — Boundaries at a point
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Every administrative boundary containing a point, country first down to the smallest district, plus postcode areas. Use it to tag an address, a store or a delivery with its country, state, county and city in one call. Costs 1 unit. Returns ids you can pass to get_boundary. Needs an API key or a connected account.

reverse_boundaries input schema
{
  "type": "object",
  "required": [
    "lat",
    "lon"
  ],
  "properties": {
    "lat": {
      "type": "number",
      "maximum": 90,
      "minimum": -90,
      "description": "Latitude, -90 to 90."
    },
    "lon": {
      "type": "number",
      "maximum": 180,
      "minimum": -180,
      "description": "Longitude, -180 to 180."
    }
  }
}
reverse_boundaries annotations
{
  "title": "Boundaries at a point",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
list_children — List subdivisions
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

The direct subdivisions of a boundary: a country's states, a state's counties, a city's districts. Without admin_level it picks the next level that exists. Free and public. Use it to build drill-down pickers or to cover a region with its parts.

list_children input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Boundary id: r<OSM relation id> (e.g. r62422 for Berlin) or w<way id>. Also accepts R62422, relation/62422, -62422, an openstreetmap.org URL, wikidata:Q64 or iso:US-CA."
    },
    "admin_level": {
      "type": "integer",
      "maximum": 12,
      "minimum": 3,
      "description": "Subdivision admin_level; default: the next level below the parent that exists."
    }
  }
}
list_children annotations
{
  "title": "List subdivisions",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
contains_points — Points in boundary
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Tests up to 10,000 points ([lon, lat] pairs) against one boundary and returns a boolean per point plus the inside count. Use it for geofencing, service-area checks and filtering customer lists. Costs 1 unit per 1,000 points. Needs an API key or a connected account.

contains_points input schema
{
  "type": "object",
  "required": [
    "id",
    "points"
  ],
  "properties": {
    "id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Boundary id: r<OSM relation id> (e.g. r62422 for Berlin) or w<way id>. Also accepts R62422, relation/62422, -62422, an openstreetmap.org URL, wikidata:Q64 or iso:US-CA."
    },
    "points": {
      "type": "array",
      "items": {
        "type": "array",
        "items": false,
        "maxItems": 2,
        "minItems": 2,
        "prefixItems": [
          {
            "type": "number",
            "maximum": 180,
            "minimum": -180
          },
          {
            "type": "number",
            "maximum": 90,
            "minimum": -90
          }
        ]
      },
      "maxItems": 10000,
      "minItems": 1,
      "description": "Points as [lon, lat] (GeoJSON order)."
    }
  }
}
contains_points annotations
{
  "title": "Points in boundary",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
union_boundaries — Merge boundaries
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Merges boundaries into one polygon: the union of include minus the union of exclude (e.g. three counties minus one city). Use it for sales territories, delivery zones and service areas. Up to 50 boundaries; costs 1 unit per boundary. Returns a GeoJSON Feature with area_km2. To describe an area in words instead, use create_area. Needs an API key or a connected account.

union_boundaries input schema
{
  "type": "object",
  "required": [
    "include"
  ],
  "properties": {
    "detail": {
      "enum": [
        "low",
        "medium",
        "high",
        "full"
      ],
      "type": "string",
      "default": "medium",
      "description": "Simplification relative to the boundary's size: low (~1,000 points across, maps and previews), medium (default, ~5,000), high (~25,000), full (unsimplified OSM)."
    },
    "exclude": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200,
        "minLength": 1,
        "description": "Boundary id: r<OSM relation id> (e.g. r62422 for Berlin) or w<way id>. Also accepts R62422, relation/62422, -62422, an openstreetmap.org URL, wikidata:Q64 or iso:US-CA."
      },
      "default": [],
      "maxItems": 50,
      "description": "Boundary ids to cut out."
    },
    "include": {
      "type": "array",
      "items": {
        "type": "string",
        "maxLength": 200,
        "minLength": 1,
        "description": "Boundary id: r<OSM relation id> (e.g. r62422 for Berlin) or w<way id>. Also accepts R62422, relation/62422, -62422, an openstreetmap.org URL, wikidata:Q64 or iso:US-CA."
      },
      "maxItems": 50,
      "minItems": 1,
      "description": "Boundary ids to merge."
    }
  }
}
union_boundaries annotations
{
  "title": "Merge boundaries",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
create_area — Create area from a description
Advertised by the server during the last successful anonymous check.
Open-world

Turns a plain-language description of an area ("Alameda and Contra Costa counties excluding San Jose, plus SFO") or wording from a contract or policy into one validated land-only polygon. An AI agent plans includes/excludes from real administrative boundaries; you get GeoJSON plus each part's source, or a 422 explaining what could not be mapped. Takes 30 s to a few minutes. For a single named place use search_boundaries + get_boundary instead: it is instant and costs 1 unit. Needs an API key or a connected account.

create_area input schema
{
  "type": "object",
  "required": [
    "text"
  ],
  "properties": {
    "seed": {
      "type": "object",
      "required": [
        "lat",
        "lon"
      ],
      "properties": {
        "lat": {
          "type": "number",
          "maximum": 90,
          "minimum": -90
        },
        "lon": {
          "type": "number",
          "maximum": 180,
          "minimum": -180
        }
      },
      "description": "A point that must be inside the area."
    },
    "text": {
      "type": "string",
      "maxLength": 3000,
      "minLength": 1,
      "description": "The description of the area."
    },
    "source": {
      "type": "string",
      "maxLength": 200,
      "description": "Who wrote the description (agency, company). Optional context."
    },
    "country": {
      "type": "string",
      "maxLength": 2,
      "minLength": 2,
      "description": "ISO 3166-1 alpha-2 country code, if known."
    }
  }
}
create_area annotations
{
  "title": "Create area from a description",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
get_account — Get account
Advertised by the server during the last successful anonymous check.
Advertised read-only

The signed-in account and the organization the call acts in: email and profile, the organization (id, slug, name, personal or shared) and the caller's role in it (viewer, member, admin or owner), how the call is authenticated (api_key, oauth or session), the organization's plan in force (status, renewal date, set to cancel or not), this month's use of every limit (units used and remaining, described areas remaining, API keys, requests a minute, when units reset), and what the next plan adds with its checkout_url. Plan, usage and limits belong to the organization and are shared by its members and keys. Free. Call it before a large batch to check it fits, and after a human pays to see the new plan. Needs an API key or a connected account.

get_account input schema
{
  "type": "object",
  "properties": {}
}
get_account annotations
{
  "title": "Get account",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
update_profile — Update profile
Advertised by the server during the last successful anonymous check.
Advertised destructive

Sets the account's name, company, use case (what you are building) and language (the language for emails and the dashboard). Send only the fields to change; an empty string clears a text field. Free. Returns the updated profile. Needs an API key or a connected account.

update_profile input schema
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 120,
      "description": "Your name, used in emails (\"Hey {first name},\")."
    },
    "locale": {
      "enum": [
        "en",
        "es",
        "de",
        "fr",
        "ja",
        "pt-BR"
      ],
      "type": "string",
      "description": "The language for emails and the dashboard: one of en, es, de, fr, ja, pt-BR. A language that isn't published yet reads in English until it is."
    },
    "company": {
      "type": "string",
      "maxLength": 120,
      "description": "Company or project."
    },
    "use_case": {
      "type": "string",
      "maxLength": 1000,
      "description": "What you are building with boundaries and areas."
    }
  }
}
update_profile annotations
{
  "title": "Update profile",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
get_usage — Get usage
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organization's daily usage for the last N days (default 30), by op, with cache hit counts, across every member and key. Use it to explain a bill or spot a runaway client. Needs an API key or a connected account.

get_usage input schema
{
  "type": "object",
  "properties": {
    "days": {
      "type": "integer",
      "default": 30,
      "maximum": 90,
      "minimum": 1,
      "description": "How many days back."
    }
  }
}
get_usage annotations
{
  "title": "Get usage",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_api_keys — List API keys
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organization's API keys (prefix, name, who created it, last use; never the secret). Members see the keys they created; admins and owners see every key, including those of people who left. Needs an API key or a connected account.

list_api_keys input schema
{
  "type": "object",
  "properties": {
    "include_revoked": {
      "type": "boolean",
      "default": false
    }
  }
}
list_api_keys annotations
{
  "title": "List API keys",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
create_api_key — Create API key
Advertised by the server during the last successful anonymous check.

Creates an API key for the organization and returns the secret once. Store it in an environment variable (GEOCODE_API_KEY); it cannot be shown again. The key acts in this organization only, with its creator's role (at most admin), and keeps working if the creator leaves until an admin revokes it. Needs an API key or a connected account.

create_api_key input schema
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "default": "Default key",
      "maxLength": 80,
      "minLength": 1,
      "description": "A label, e.g. the app or environment."
    }
  }
}
create_api_key annotations
{
  "title": "Create API key",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": false
}
revoke_api_key — Revoke API key
Advertised by the server during the last successful anonymous check.
Advertised destructive

Revokes an API key by id. Requests with it fail with 401 immediately. Members revoke the keys they created; admins and owners revoke any key in the organization. Needs an API key or a connected account.

revoke_api_key input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The key's id from list_api_keys."
    }
  }
}
revoke_api_key annotations
{
  "title": "Revoke API key",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
get_email_preferences — Get email preferences
Advertised by the server during the last successful anonymous check.
Advertised read-only

Which automated emails the account receives: the global subscription and one switch per kind (getting-started notes, first boundary, usage milestones, quota warnings, check-ins, monthly digest). Free. Sign-in codes are always sent. Needs an API key or a connected account.

get_email_preferences input schema
{
  "type": "object",
  "properties": {}
}
get_email_preferences annotations
{
  "title": "Get email preferences",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
update_email_preferences — Update email preferences
Advertised by the server during the last successful anonymous check.
Advertised destructive

Turns automated emails on or off: `subscribed: false` stops all of them (the same as the unsubscribe link), `subscribed: true` resubscribes, and `kinds` switches individual kinds. Kinds not named keep their setting. Free. Returns the preferences after the change. Needs an API key or a connected account.

update_email_preferences input schema
{
  "type": "object",
  "properties": {
    "kinds": {
      "type": "object",
      "properties": {
        "quota": {
          "type": "boolean",
          "description": "When you have used 80% and 100% of this month's plan."
        },
        "digest": {
          "type": "boolean",
          "description": "On the 1st: last month's requests, cache hits and top operations."
        },
        "journey": {
          "type": "boolean",
          "description": "A few short notes in your first month, each with the next step."
        },
        "winback": {
          "type": "boolean",
          "description": "A note if your API keys go quiet for a few weeks."
        },
        "feedback": {
          "type": "boolean",
          "description": "Thanks and status changes for feature requests, issues and reviews you filed, upvoted or commented on."
        },
        "milestone": {
          "type": "boolean",
          "description": "When your account passes 100, 1,000, 10,000 or 100,000 requests."
        },
        "first_boundary": {
          "type": "boolean",
          "description": "One note when you fetch your first boundary."
        }
      },
      "description": "Per-kind switches, e.g. {\"digest\": false}."
    },
    "subscribed": {
      "type": "boolean",
      "description": "false = unsubscribe from every automated email; true = resubscribe."
    }
  }
}
update_email_preferences annotations
{
  "title": "Update email preferences",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
list_orgs — List organizations
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organizations you belong to, with your role in each and which one this call acts in (current). Personal is the one made for you at signup. An API key acts in its own organization only, so with a key this lists that one. Free. Needs an API key or a connected account.

list_orgs input schema
{
  "type": "object",
  "properties": {}
}
list_orgs annotations
{
  "title": "List organizations",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_members — List members
Advertised by the server during the last successful anonymous check.
Advertised read-only

The people in the organization: email, name, role (viewer, member, admin, owner), when they joined and their teams. Free. Use it to find who to share a file with. Inviting, removing and changing roles is done by a person on the dashboard. Needs an API key or a connected account.

list_members input schema
{
  "type": "object",
  "properties": {}
}
list_members annotations
{
  "title": "List members",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_teams — List teams
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organization's teams: slug, name, description and members with their team role (maintainer or member). Free. Pass a team's slug to share_file to share a library file with everyone in it. Needs an API key or a connected account.

list_teams input schema
{
  "type": "object",
  "properties": {}
}
list_teams annotations
{
  "title": "List teams",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_invites — List invites
Advertised by the server during the last successful anonymous check.
Advertised read-only

Invitations to the organization: email, role, teams, status (pending, accepted, expired, revoked) and when they expire. Admins and owners only. Free. Sending, resending and revoking invites is done on the dashboard. Needs an API key or a connected account.

list_invites input schema
{
  "type": "object",
  "properties": {
    "include_closed": {
      "type": "boolean",
      "default": false,
      "description": "Also list accepted, expired and revoked invites."
    }
  }
}
list_invites annotations
{
  "title": "List invites",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
list_audit_log — List audit log
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organization's audit log, newest first: who (a person, an API key, an OAuth client or the system) changed membership, roles, teams, invites, API keys, billing or file sharing, and when. Admins and owners only. Free. Needs an API key or a connected account.

list_audit_log input schema
{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "default": 20,
      "maximum": 100,
      "minimum": 1,
      "description": "Page size, at most 100."
    },
    "action": {
      "type": "string",
      "maxLength": 60,
      "description": "Only this action, e.g. member.remove or api_key.create."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0
    }
  }
}
list_audit_log annotations
{
  "title": "List audit log",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
save_file — Save boundary file to the library
Advertised by the server during the last successful anonymous check.
Open-world

Exports a boundary (like export_boundary) and saves it in the organization's file library, so teammates find it on the dashboard and through list_files. visibility org (default) shares it with every member at their role; restricted keeps it to you, admins and whoever you share it with (share_file). Saving the same boundary, format and detail again returns the existing entry. Costs 1 unit. Returns the library entry with its permanent download url. Needs an API key or a connected account.

save_file input schema
{
  "type": "object",
  "required": [
    "boundary_id"
  ],
  "properties": {
    "name": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "A label for the library; default: the boundary's name, format and detail."
    },
    "detail": {
      "enum": [
        "low",
        "medium",
        "high",
        "full"
      ],
      "type": "string",
      "default": "medium"
    },
    "format": {
      "enum": [
        "geojson",
        "kml",
        "wkt",
        "svg",
        "gml"
      ],
      "type": "string",
      "default": "geojson"
    },
    "visibility": {
      "enum": [
        "org",
        "restricted"
      ],
      "type": "string",
      "default": "org"
    },
    "boundary_id": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1,
      "description": "Boundary id, as get_boundary accepts it (r62422, wikidata:Q64, iso:US-CA…)."
    }
  }
}
save_file annotations
{
  "title": "Save boundary file to the library",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
list_files — List library files
Advertised by the server during the last successful anonymous check.
Advertised read-only

The boundary files in the organization's library that you can see, newest first: org-visible ones plus restricted ones shared with you or a team you are in. Each has your access (read, write or admin). Free. Needs an API key or a connected account.

list_files input schema
{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "default": 20,
      "maximum": 100,
      "minimum": 1,
      "description": "Page size, at most 100."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0
    }
  }
}
list_files annotations
{
  "title": "List library files",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_file — Get library file
Advertised by the server during the last successful anonymous check.
Advertised read-only

One library file: its boundary, format, detail, visibility, your access, the permanent download url and, when you can manage it, who it is shared with. Free. Needs an API key or a connected account.

get_file input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The file's id from list_files or save_file."
    }
  }
}
get_file annotations
{
  "title": "Get library file",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
update_file — Rename or change visibility
Advertised by the server during the last successful anonymous check.
Advertised destructive

Renames a library file (write access) or sets its visibility (admin access on the file): org shares it with every member at their role, restricted keeps it to its creator, admins and explicit shares. Free. Needs an API key or a connected account.

update_file input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The file's id from list_files or save_file."
    },
    "name": {
      "type": "string",
      "maxLength": 200,
      "minLength": 1
    },
    "visibility": {
      "enum": [
        "org",
        "restricted"
      ],
      "type": "string"
    }
  }
}
update_file annotations
{
  "title": "Rename or change visibility",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
delete_file — Remove from the library
Advertised by the server during the last successful anonymous check.
Advertised destructive

Removes a file from the organization's library and its shares (admin access on the file). The exported file itself stays in the public cache; export_boundary rebuilds the url any time. Free. Needs an API key or a connected account.

delete_file input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The file's id from list_files or save_file."
    }
  }
}
delete_file annotations
{
  "title": "Remove from the library",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
share_file — Share library file
Advertised by the server during the last successful anonymous check.
Advertised destructive

Shares a library file with a team (by slug or id) or a person in the organization (by email or user id) at read, write or admin access; sharing again changes the access. Needs admin access on the file (its creator, an org admin, or an admin share). Viewers are capped at read whatever the share says. Free. Returns the file's shares. Needs an API key or a connected account.

share_file input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The file's id from list_files or save_file."
    },
    "team": {
      "type": "string",
      "maxLength": 100,
      "minLength": 1,
      "description": "Team slug or id."
    },
    "user": {
      "type": "string",
      "maxLength": 254,
      "minLength": 1,
      "description": "A member's email or user id."
    },
    "access": {
      "enum": [
        "read",
        "write",
        "admin"
      ],
      "type": "string",
      "default": "read"
    }
  }
}
share_file annotations
{
  "title": "Share library file",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
unshare_file — Stop sharing library file
Advertised by the server during the last successful anonymous check.
Advertised destructive

Removes one share of a library file by its grant id (from get_file). Needs admin access on the file. Org-visible files stay visible to every member; make it restricted with update_file to limit it to its shares. Free. Needs an API key or a connected account.

unshare_file input schema
{
  "type": "object",
  "required": [
    "id",
    "grant_id"
  ],
  "properties": {
    "id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
      "description": "The file's id from list_files or save_file."
    },
    "grant_id": {
      "type": "string",
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
    }
  }
}
unshare_file annotations
{
  "title": "Stop sharing library file",
  "readOnlyHint": false,
  "openWorldHint": false,
  "idempotentHint": false,
  "destructiveHint": true
}
get_subscription — Get subscription
Advertised by the server during the last successful anonymous check.
Advertised read-only

The organization's plan and subscription: plan, status, when the period renews or ends, whether it is set to cancel, the price, this month's use of every limit (units, described areas, API keys, rate) and what the next plan adds, with its checkout_url. Free. The same as get_account without the profile. Call it before suggesting an upgrade, and after handing a human a checkout link to see when the payment went through (plan changes from free to the plan bought, usually within seconds). Needs an API key or a connected account.

get_subscription input schema
{
  "type": "object",
  "properties": {}
}
get_subscription annotations
{
  "title": "Get subscription",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
create_checkout_link — Create checkout link
Advertised by the server during the last successful anonymous check.
Open-world

A link a human opens to buy a plan (pro or business) on a Stripe page branded Geocode AI. Free, and charges nothing: the person enters or confirms the card (never pass card details to a tool). With a key, the link is a Checkout page for that account (or, on a paid plan already, a page that confirms the switch, prorated). Without a key it is a Checkout page that collects the human's email and creates their account when they pay (kind guest_checkout), so an agent with no account can still hand its human one link. Give the url to the human as is, say the plan and price (monthly by default; yearly: true bills ten months' price once a year), then call get_account to see when it is paid. Never open or pay it yourself, and only call it when the human asked to buy or upgrade.

create_checkout_link input schema
{
  "type": "object",
  "required": [
    "plan"
  ],
  "properties": {
    "plan": {
      "enum": [
        "pro",
        "business"
      ],
      "type": "string",
      "description": "The plan to buy. get_pricing lists them with prices, limits and features."
    },
    "yearly": {
      "type": "boolean",
      "default": false,
      "description": "Bill once a year: ten months' price (two months free). get_pricing shows price.yearly."
    }
  }
}
create_checkout_link annotations
{
  "title": "Create checkout link",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
get_billing_link — Get billing link
Advertised by the server during the last successful anonymous check.
Open-world

A link for the account's owner to open Stripe's Customer Portal: download invoices, change the card or billing details, switch plans, or cancel (at the end of the period already paid for). Free. The link does not expire; it asks the person to sign in to Geocode AI, then opens the portal. Fails with no_subscription when the account never had a paid plan. Needs an API key or a connected account.

get_billing_link input schema
{
  "type": "object",
  "properties": {}
}
get_billing_link annotations
{
  "title": "Get billing link",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
list_feedback — List feature requests and issues
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

The feedback board: feature requests and published issues with their status and upvotes, most upvoted first (with a key, also your own private issues, and whether you voted). Free and needs no key. Call it before request_feature or report_issue to find an existing item to upvote instead of filing a duplicate, or when the human asks what is planned or shipped.

list_feedback input schema
{
  "type": "object",
  "properties": {
    "q": {
      "type": "string",
      "maxLength": 100,
      "description": "Words to find in the title or description."
    },
    "kind": {
      "enum": [
        "feature",
        "issue",
        "all"
      ],
      "type": "string",
      "default": "all",
      "description": "feature = feature requests, issue = bug reports."
    },
    "mine": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "Only items you filed (needs a key); list_my_feedback also lists what you follow."
    },
    "sort": {
      "enum": [
        "top",
        "new",
        "recent_activity"
      ],
      "type": "string",
      "default": "top",
      "description": "top = most upvoted, new = most recent, recent_activity = latest vote, comment or change."
    },
    "limit": {
      "type": "integer",
      "default": 20,
      "maximum": 100,
      "minimum": 1,
      "description": "Page size, at most 100."
    },
    "cursor": {
      "type": "string",
      "pattern": "^\\d+$",
      "description": "next_cursor from the previous page."
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0,
      "description": "Same as cursor, as a number."
    },
    "status": {
      "enum": [
        "active",
        "closed",
        "all",
        "open",
        "planned",
        "in_progress",
        "done",
        "declined",
        "duplicate"
      ],
      "type": "string",
      "default": "active",
      "description": "active = open, planned or in progress; closed = done, declined or duplicate."
    }
  }
}
list_feedback annotations
{
  "title": "List feature requests and issues",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_feedback — Get a feature request or issue
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

One feedback item with its status, upvotes, comments (official team responses marked) and timeline of status changes. Free and needs no key for public items; a private issue is visible to its reporter and the team.

get_feedback input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "The item's id from list_feedback, request_feature or report_issue (e.g. 42).",
      "exclusiveMinimum": 0
    }
  }
}
get_feedback annotations
{
  "title": "Get a feature request or issue",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
list_my_feedback — List my feedback and subscriptions
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

What you filed (including private issues), what you follow because you voted or commented, and your review, each with its current status. Free; needs a key. Use it to check on an issue you reported or a feature you asked for. Needs an API key or a connected account.

list_my_feedback input schema
{
  "type": "object",
  "properties": {
    "limit": {
      "type": "integer",
      "default": 50,
      "maximum": 100,
      "minimum": 1,
      "description": "Items per list, at most 100."
    }
  }
}
list_my_feedback annotations
{
  "title": "List my feedback and subscriptions",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
request_feature — Request a feature
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Files a feature request on the public board and upvotes it for you. Use it when the human wishes the API did something it cannot (a boundary type, export format, op or option). It first looks for similar requests: if any match it files nothing and returns them in `similar`, so you can upvote_feedback the right one; pass force: true to file anyway. Free; needs a key; 10 new items per account a day. The human gets a thank-you email and an email on every status change. Feature requests are public (never the author's email); issues are private to you and the team. Do not include API keys, personal data or customer data. Needs an API key or a connected account.

request_feature input schema
{
  "type": "object",
  "required": [
    "title"
  ],
  "properties": {
    "force": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "File even when similar requests exist."
    },
    "title": {
      "type": "string",
      "maxLength": 140,
      "minLength": 3,
      "description": "What you want, in one line."
    },
    "details": {
      "type": "string",
      "default": "",
      "maxLength": 5000,
      "description": "Why you need it and what you are building; concrete examples help it get planned."
    }
  }
}
request_feature annotations
{
  "title": "Request a feature",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}
report_issue — Report an issue
Advertised by the server during the last successful anonymous check.
Open-world

Reports a problem with Geocode AI: a failing or wrong API call, a wrong or missing boundary, a docs error. Call it after a call fails in a way that looks like our bug (5xx, a wrong polygon, a boundary that should exist), with the failing call's request_id (X-Request-Id header or the error's request_id) and op; add query, boundary_id and the error in context. Issues are private to you and the team. It first returns similar issues you can see, filing nothing; upvote_feedback the same one or pass force: true. Free; needs a key; 10 new items per account a day. The human gets an email with the reference and on every status change. Needs an API key or a connected account.

report_issue input schema
{
  "type": "object",
  "required": [
    "title"
  ],
  "properties": {
    "op": {
      "type": "string",
      "maxLength": 80,
      "description": "The op the failing call used, e.g. get_boundary (same as context.op)."
    },
    "force": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "File even when similar issues exist."
    },
    "title": {
      "type": "string",
      "maxLength": 140,
      "minLength": 3,
      "description": "What is wrong, in one line."
    },
    "context": {
      "type": "object",
      "properties": {
        "op": {
          "type": "string",
          "maxLength": 80,
          "description": "The op or endpoint, e.g. get_boundary or GET /v1/boundaries/{id}."
        },
        "error": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 2000
            },
            {
              "type": "object",
              "properties": {
                "code": {
                  "type": "string",
                  "maxLength": 80
                },
                "status": {
                  "type": "integer",
                  "maximum": 9007199254740991,
                  "minimum": -9007199254740991
                },
                "message": {
                  "type": "string",
                  "maxLength": 2000
                }
              }
            }
          ],
          "description": "The error you got: its code, HTTP status and message."
        },
        "input": {
          "type": "object",
          "description": "The op input you sent (no secrets).",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {}
        },
        "query": {
          "type": "string",
          "maxLength": 500,
          "description": "The search text or input that misbehaved."
        },
        "client": {
          "type": "string",
          "maxLength": 120,
          "description": "What made the call: geocode-cli, an MCP host, your app."
        },
        "status": {
          "type": "integer",
          "maximum": 599,
          "minimum": 100,
          "description": "HTTP status of the failing call."
        },
        "version": {
          "type": "string",
          "maxLength": 40,
          "description": "Its version."
        },
        "request_id": {
          "type": "string",
          "maxLength": 128,
          "description": "X-Request-Id of the failing call (or the error body's request_id)."
        },
        "boundary_id": {
          "type": "string",
          "maxLength": 200,
          "description": "The boundary concerned (r62422, R62422, an osm.org URL…)."
        }
      },
      "description": "What we need to reproduce it. Only you and the team see it."
    },
    "details": {
      "type": "string",
      "default": "",
      "maxLength": 5000,
      "description": "What you did, what you expected and what happened."
    },
    "request_id": {
      "type": "string",
      "maxLength": 128,
      "description": "The request_id of the failing call (same as context.request_id)."
    }
  }
}
report_issue annotations
{
  "title": "Report an issue",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
upvote_feedback — Upvote a feature request or issue
Advertised by the server during the last successful anonymous check.
Open-world

Adds your upvote to a feature request or issue (a "me too"); votes decide what gets built and fixed first, and you get an email when its status changes. Idempotent: one vote per account. A vote on a duplicate goes to the original. Free; needs a key. Returns the item with its new vote count. Needs an API key or a connected account.

upvote_feedback input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "The item's id from list_feedback, request_feature or report_issue (e.g. 42).",
      "exclusiveMinimum": 0
    }
  }
}
upvote_feedback annotations
{
  "title": "Upvote a feature request or issue",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}
remove_feedback_vote — Remove an upvote
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Takes back your upvote on a feature request or issue, and stops its emails unless you filed or commented on it. Free; needs a key. Returns the item with its new vote count. Needs an API key or a connected account.

remove_feedback_vote input schema
{
  "type": "object",
  "required": [
    "id"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "The item's id from list_feedback, request_feature or report_issue (e.g. 42).",
      "exclusiveMinimum": 0
    }
  }
}
remove_feedback_vote annotations
{
  "title": "Remove an upvote",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}
comment_on_feedback — Comment on a feature request or issue
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Adds context to an existing feature request or issue: your use case, another failing request id, a workaround. Prefer it (with upvote_feedback) over filing a near-duplicate. You then get its status emails; its author gets a daily digest of comments. Free; needs a key; 50 comments per account a day. Feature requests are public (never the author's email); issues are private to you and the team. Do not include API keys, personal data or customer data. Needs an API key or a connected account.

comment_on_feedback input schema
{
  "type": "object",
  "required": [
    "id",
    "body"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "maximum": 9007199254740991,
      "description": "The item's id from list_feedback, request_feature or report_issue (e.g. 42).",
      "exclusiveMinimum": 0
    },
    "body": {
      "type": "string",
      "maxLength": 5000,
      "minLength": 1,
      "description": "The comment."
    }
  }
}
comment_on_feedback annotations
{
  "title": "Comment on a feature request or issue",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}
list_reviews — Read reviews
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Published reviews of Geocode AI with the average rating and the distribution, and the team's response under each. Free and needs no key. Use it when the human asks what other users think.

list_reviews input schema
{
  "type": "object",
  "properties": {
    "sort": {
      "enum": [
        "new",
        "helpful",
        "highest",
        "lowest"
      ],
      "type": "string",
      "default": "new",
      "description": "new = newest, helpful = most detailed, highest / lowest = by rating."
    },
    "limit": {
      "type": "integer",
      "default": 20,
      "maximum": 100,
      "minimum": 1
    },
    "offset": {
      "type": "integer",
      "default": 0,
      "maximum": 9007199254740991,
      "minimum": 0
    },
    "rating": {
      "type": "integer",
      "maximum": 5,
      "minimum": 1,
      "description": "Only reviews with this many stars."
    }
  }
}
list_reviews annotations
{
  "title": "Read reviews",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
get_my_review — Get my review
Advertised by the server during the last successful anonymous check.
Advertised read-onlyOpen-world

Your review of the product, if you posted one, with its status (published, pending a check, or hidden with the reason) and the team's response. Free; needs a key. Needs an API key or a connected account.

get_my_review input schema
{
  "type": "object",
  "properties": {}
}
get_my_review annotations
{
  "title": "Get my review",
  "readOnlyHint": true,
  "openWorldHint": true,
  "idempotentHint": true,
  "destructiveHint": false
}
submit_review — Post or edit a review
Advertised by the server during the last successful anonymous check.
Advertised destructiveOpen-world

Posts the human's public review of Geocode AI (1–5 stars, what they like and dislike, what they use it for), or replaces their existing one; each account has one review and earlier versions are kept. Only call it with the human's own rating and words, never invented ones. Published at once unless it holds links or the account is under a day old (then pending). Free; needs a key; one edit an hour. The human gets a thank-you email. Needs an API key or a connected account.

submit_review input schema
{
  "type": "object",
  "required": [
    "rating"
  ],
  "properties": {
    "body": {
      "type": "string",
      "default": "",
      "maxLength": 2000,
      "description": "The review."
    },
    "likes": {
      "type": "string",
      "default": "",
      "maxLength": 1000,
      "description": "What works well."
    },
    "title": {
      "type": "string",
      "default": "",
      "maxLength": 120,
      "description": "A headline."
    },
    "rating": {
      "type": "integer",
      "maximum": 5,
      "minimum": 1,
      "description": "Stars, 1 to 5."
    },
    "dislikes": {
      "type": "string",
      "default": "",
      "maxLength": 1000,
      "description": "What should be better."
    },
    "use_case": {
      "type": "string",
      "default": "",
      "maxLength": 200,
      "description": "What they use it for."
    },
    "display_name": {
      "type": "string",
      "maxLength": 80,
      "minLength": 1,
      "description": "Name shown with the review (default: first name)."
    },
    "display_company": {
      "type": "string",
      "maxLength": 80,
      "description": "Company shown with it, if they want."
    },
    "marketing_consent": {
      "anyOf": [
        {
          "type": "boolean"
        },
        {
          "enum": [
            "true",
            "false"
          ],
          "type": "string"
        }
      ],
      "description": "May we quote it on our site and in marketing?"
    }
  }
}
submit_review annotations
{
  "title": "Post or edit a review",
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": true
}
get_pricing — Get plans and prices
Advertised by the server during the last successful anonymous check.
Advertised read-only

Every plan with its monthly price, included units, limits (units, described areas, requests a minute, API keys), features and checkout_url, plus what each call costs in units and what works without a key. Free and needs no key. Call it before a large batch, when the human asks what something costs, or before create_checkout_link; never quote prices from memory.

get_pricing input schema
{
  "type": "object",
  "properties": {}
}
get_pricing annotations
{
  "title": "Get plans and prices",
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

1 advertised

boundary-map — Boundary map

Advertised by the server during the last successful anonymous check.

Draws a boundary or area polygon on a map with its name, kind and area.

boundary-map URI
ui://geocode/boundary-map.16e78307effd.html

MIME type: text/html;profile=mcp-app

90-day uptime

A lightweight connection check about every six hours, sampled on hosts with many listings. It shows the server answered, not that its tools work.

Too few checks for a percentage yet (2 of 2 answered).

  1. 2026-11-07: 2 of 2 checks answered

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
1370 ms
95th percentile latency
1370 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 1370 ms · metadata changed · 43 tool(s), 1 resource(s), 0 resource template(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http geocode-ai-mcp https://geocodeai.dev/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add geocode-ai-mcp --url https://geocodeai.dev/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable geocode-ai-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "geocode-ai-mcp": {
      "url": "https://geocodeai.dev/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "geocode-ai-mcp": {
      "type": "streamableHttp",
      "url": "https://geocodeai.dev/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start geocode-ai-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "geocode-ai-mcp": {
      "type": "http",
      "url": "https://geocodeai.dev/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http geocode-ai-mcp https://geocodeai.dev/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://geocodeai.dev/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "geocode-ai-mcp": {
      "serverUrl": "https://geocodeai.dev/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Geocode AI MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Geocode AI MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing