# Geocoding, Elevation & Postcode Lookup MCP Server (`mrbridge/geo-toolkit-mcp`) Actor

MCP server for geocoding in Claude, ChatGPT, Cursor and VS Code. 14 read-only tools geocode and reverse geocode on OpenStreetMap data, find nearby places, return elevations and profiles, measure straight-line distances, convert coordinates and look up postal codes in about 70 countries.

- **URL**: https://apify.com/mrbridge/geo-toolkit-mcp.md
- **Developed by:** [MrBridge](https://apify.com/mrbridge) (community)
- **Categories:** MCP servers, AI, Developer tools
- **Features:** Limited permissions, Single-tenant, Server interface
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 read operations

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 📍 Geocoding, Elevation & Postcode Lookup MCP Server

This MCP server gives Claude, ChatGPT, Cursor, VS Code and other MCP clients 14 read-only geography tools. It turns addresses into coordinates and coordinates back into addresses, finds pharmacies, cafes, stations and other places around a point, returns elevations and elevation profiles, measures straight-line distances, converts coordinates between formats and looks up postal codes in about 70 countries, with a deeper set of tools for UK postcodes outside Northern Ireland. No API key is needed beyond your Apify token, and every answer names its open-data sources. Place data © OpenStreetMap contributors, available under the Open Database License (https://www.openstreetmap.org/copyright).

Ask Claude "How far is Lyon from Paris as the crow flies, and in which direction?" It calls `geo_get_distance` with `from: "Paris"` and `to: "Lyon"`, geocodes both names and answers 391.8 km with the bearing, the compass direction and the midpoint. You skip the geocoding step and the haversine formula.

### What this server exposes

This server gives an AI client 14 read-only geography tools built on four open services. Photon, the geocoder komoot runs on OpenStreetMap data, turns names and addresses into coordinates, coordinates back into addresses, and finds places of one type (pharmacies, cafes, stations and 29 other categories, or any OpenStreetMap tag) around a point. The Open Topo Data public API gives the elevation above sea level of up to 100 points and elevation profiles with length, ascent and descent, from six elevation models (SRTM, ASTER, EU-DEM, ETOPO1, GEBCO). Zippopotam.us resolves postal and ZIP codes in about 70 countries from GeoNames data. Postcodes.io answers UK postcode questions: the council, ward, constituency and coordinates of up to 20 postcodes, the nearest postcodes to a point, partial postcode completion, postcode districts and British place names. Two tools need no upstream at all: straight-line distance and bearing, and coordinate conversion between decimal degrees, DMS, geohash and UTM. No account or API key is needed, and every answer names its sources. This server is not affiliated with komoot, the OpenStreetMap Foundation, Open Topo Data, Zippopotam.us, GeoNames, Postcodes.io or Ideal Postcodes.

### Tools

| Tool | What it answers | Billed event |
|---|---|---|
| `geo_geocode` | Geocode a place or address | `tool-read` |
| `geo_reverse_geocode` | Find the address at coordinates | `tool-read` |
| `geo_find_nearby_places` | Find places of a type near a point | `tool-read` |
| `geo_get_distance` | Distance and direction between two places | `tool-read` |
| `geo_get_elevation` | Elevation of points or of a place | `tool-read` |
| `geo_get_elevation_profile` | Elevation profile along a path | `tool-action` |
| `geo_convert_coordinates` | Convert coordinates between formats | `tool-read` |
| `geo_lookup_postal_code` | Look up a postal code | `tool-read` |
| `geo_find_postal_codes` | Find the postal codes of a town | `tool-read` |
| `geo_uk_lookup_postcodes` | Look up UK postcodes | `tool-read` |
| `geo_uk_nearest_postcodes` | Nearest UK postcodes to a point or postcode | `tool-read` |
| `geo_uk_autocomplete_postcode` | Complete a partial UK postcode | `tool-read` |
| `geo_uk_lookup_outcode` | Look up a UK postcode district | `tool-read` |
| `geo_uk_search_places` | Search UK place names | `tool-read` |

#### `geo_geocode`: Geocode a place or address

Use this when you need the coordinates and the full address of a place, an address, a landmark, a city or a region, for example "Eiffel Tower", "10 Downing Street, London" or "Lyon". Do not use for coordinates to address (geo_reverse_geocode), places of a type around a point (geo_find_nearby_places) or UK postcodes (geo_uk_lookup_postcodes). Parameters: `query` (text), `country_codes` (up to 5 ISO codes such as \["FR"]), `place_types` (house, street, locality, district, city, county, state, country, other), `language` (en, de, fr, default), `bias_latitude` and `bias_longitude` (prefer results near a point), `bbox` (\[west, south, east, north]), `limit` (1 to 20, default 5), `offset`, `response_format` ("detailed" adds address parts, OpenStreetMap ids, bounding box and tags). Results come ranked by relevance from OpenStreetMap data.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `query` | string | yes | `"Eiffel Tower"` |
| `country_codes` | array of string | no | `["FR"]` |
| `place_types` | array of string | no | `["city"]` |
| `language` | "en" or "de" or "fr" or "default" | no | `"en"` |
| `bias_latitude` | number | no | `45.764` |
| `bias_longitude` | number | no | `4.8357` |
| `bbox` | array of number | no | `[2.22,48.81,2.47,48.91]` |
| `limit` | integer | no | `5` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ query, places[], pagination, attribution[] }`. Upstream: Photon. Cache: daily (1 day). Read-only.

#### `geo_reverse_geocode`: Find the address at coordinates

Use this when you have coordinates and need the nearest address, street, town or place name, for example what is at 48.8584, 2.2945, optionally with the surface elevation there. Do not use for a place name to coordinates (geo_geocode), for a given type of place such as pharmacies (geo_find_nearby_places) or for UK postcodes around a point (geo_uk_nearest_postcodes). Parameters: `latitude`, `longitude` (decimal degrees), `radius_km` (0.01 to 5, search radius, default left to Photon), `limit` (1 to 10, default 1), `language` (en, de, fr, default), `include_elevation` (default false, adds the elevation from Open Topo Data), `response_format` ("detailed" adds address parts and OpenStreetMap ids). Each place comes with its distance from the point.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `latitude` | number | yes | `48.8584` |
| `longitude` | number | yes | `2.2945` |
| `radius_km` | number | no | `0.5` |
| `limit` | integer | no | `1` |
| `language` | "en" or "de" or "fr" or "default" | no | `"en"` |
| `include_elevation` | boolean | no | `false` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ point, places[], elevation, attribution[] }`. Upstream: Photon, Open Topo Data. Cache: daily (1 day). Read-only.

#### `geo_find_nearby_places`: Find places of a type near a point

Use this when you need places of one type around a point or a named place, sorted by distance, for example pharmacies within 1 km of Gare de Lyon or cafes near 51.5074, -0.1278. Do not use for a single named place (geo_geocode), the address at a point (geo_reverse_geocode) or an exhaustive list of every feature in an area (not offered). Parameters: `category` (pharmacy, hospital, restaurant, cafe, supermarket, hotel, museum, train_station, fuel, atm and 22 more) or `osm_tag` (an OpenStreetMap "key:value" such as "amenity:library"), the centre as `latitude` + `longitude` or as `near` (a place name or coordinates text), `radius_km` (0.05 to 10, default 1), `language`, `limit` (1 to 20, default 10), `offset`, `response_format` ("detailed" adds address parts, ids and tags). At most 20 places per centre and category, with distance in metres and direction.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `category` | "pharmacy" or "hospital" or "doctor" or "dentist" or "restaurant" or "cafe" or "bar" or "pub" or "fast_food" or "fuel" or "charging_station" or "parking" or "atm" or "bank" or "post_office" or "police" or "school" or "university" or "library" or "toilets" or "place_of_worship" or "supermarket" or "bakery" or "hotel" or "museum" or "attraction" or "viewpoint" or "camp_site" or "train_station" or "bus_stop" or "airport" or "park" | no | `"pharmacy"` |
| `osm_tag` | string | no | `"shop:bicycle"` |
| `latitude` | number | no | `48.8443` |
| `longitude` | number | no | `2.3743` |
| `near` | string | no | `"Gare de Lyon, Paris"` |
| `radius_km` | number | no | `1` |
| `language` | "en" or "de" or "fr" or "default" | no | `"en"` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ center, osm_tag, radius_km, places[], pagination, attribution[] }`. Upstream: Photon. Cache: daily (1 day). Read-only.

#### `geo_get_distance`: Distance and direction between two places

Use this when you need how far apart two places or points are as the crow flies, and in which direction, for example Paris to Lyon or two GPS points. Do not use for road or travel distance and duration (not offered), or for places around one point (geo_find_nearby_places). Parameters: `from` and `to` (each a place name or coordinates text), `from_country_code` and `to_country_code` (optional ISO codes that restrict the search of that one name to a country, for example "US" for Paris, Texas), `language`. Returns the great-circle distance in km, miles and nautical miles, the initial bearing with its compass direction, the midpoint and the points used. Names are resolved with Photon, coordinates cost no upstream call.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `from` | string | yes | `"Paris"` |
| `to` | string | yes | `"Lyon"` |
| `from_country_code` | string | no | `"US"` |
| `to_country_code` | string | no | `"FR"` |
| `language` | "en" or "de" or "fr" or "default" | no | `"en"` |

Returns `{ from, to, distance_km, distance_miles, distance_nautical_miles, initial_bearing_deg, direction, direction_abbreviation, midpoint, method, note, derived, attribution[] }`. Upstream: Photon. Cache: daily (1 day). Read-only.

#### `geo_get_elevation`: Elevation of points or of a place

Use this when you need the elevation above sea level of one place or of up to 100 points, for example the altitude of Mont Blanc or of a list of GPS fixes, or the sea depth with a bathymetric dataset. Do not use for an elevation profile along a route with ascent and descent (geo_get_elevation_profile) or for addresses (geo_reverse_geocode). Parameters: `points` (1 to 100 objects {latitude, longitude}) or `place` (one place name or coordinates text, geocoded with Photon), `dataset` (srtm30m default, srtm90m, aster30m, eudem25m, etopo1, gebco2020), `interpolation` (bilinear default, nearest, cubic), `response_format`. Elevations are in metres. SRTM, ASTER and EU-DEM are surface models: they include part or all of the height of buildings and trees, so they are not bare-ground values. A point outside the dataset coverage is refused before any call, with the dataset to use instead.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `points` | array of object | no | `[{"latitude":45.8326,"longitude":6.8652}]` |
| `place` | string | no | `"Mont Blanc"` |
| `dataset` | "srtm30m" or "srtm90m" or "aster30m" or "eudem25m" or "etopo1" or "gebco2020" | no | `"srtm30m"` |
| `interpolation` | "bilinear" or "nearest" or "cubic" | no | `"bilinear"` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ dataset, place, points[], missing_values, note, attribution[] }`. Upstream: Open Topo Data, Photon. Cache: reference (30 days). Read-only.

#### `geo_get_elevation_profile`: Elevation profile along a path

Use this when you need the elevation profile of a hike, ride or line between waypoints: length, highest and lowest points, total ascent and descent, and the elevation every so often along the way. Do not use for the elevation of separate points (geo_get_elevation) or for routing along roads or trails (not offered: the path joins the waypoints directly). Parameters: `path` (2 to 20 waypoints {latitude, longitude} in order), `samples` (2 to 100 evenly spaced points, default 50), `dataset` (srtm30m default, aster30m, eudem25m, srtm90m, etopo1, gebco2020), `interpolation`, `response_format` ("concise" returns the statistics and up to 25 samples, "detailed" every sample). Ascent and descent add up the steps between samples, so more samples find more small climbs.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `path` | array of object | yes | `[{"latitude":45.9237,"longitude":6.8694},{"latitude":45.8326,"longitude":6.8652}]` |
| `samples` | integer | no | `50` |
| `dataset` | "srtm30m" or "srtm90m" or "aster30m" or "eudem25m" or "etopo1" or "gebco2020" | no | `"srtm30m"` |
| `interpolation` | "bilinear" or "nearest" or "cubic" | no | `"bilinear"` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ dataset, waypoints, statistics, samples[], samples_total, samples_returned, derived, note, attribution[] }`. Upstream: Open Topo Data. Cache: reference (30 days). Read-only.

#### `geo_convert_coordinates`: Convert coordinates between formats

Use this when you need one position written in another format: decimal degrees, degrees minutes seconds (DMS), degrees and decimal minutes (DDM), geohash or UTM, for example 48°51'30"N 2°17'40"E to decimal and UTM. Do not use for finding a place (geo_geocode), an address (geo_reverse_geocode) or distances (geo_get_distance). Parameters: `coordinates` (text in any of the five formats, for example "48.8584, 2.2945", "u09tunquc" or "31U 448252 5411933") or `latitude` + `longitude` (decimal degrees), `geohash_precision` (1 to 12 characters, default 9, about 5 m). WGS84 only. UTM is null outside latitudes 80°S to 84°N. Computed by this server, no upstream call.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `coordinates` | string | no | `"48°51'30.2\"N 2°17'40.2\"E"` |
| `latitude` | number | no | `48.8584` |
| `longitude` | number | no | `2.2945` |
| `geohash_precision` | integer | no | `9` |

Returns `{ input_format, latitude, longitude, decimal, dms, ddm, geohash, utm, note, derived, attribution[] }`. Upstream: none. Cache: not cached. Read-only.

#### `geo_lookup_postal_code`: Look up a postal code

Use this when you need the town, region and approximate coordinates of a postal or ZIP code in one of about 70 countries, for example 75001 in France or 90210 in the United States. Do not use for the postal codes of a town (geo_find_postal_codes) or for detailed UK postcode geography such as wards and constituencies (geo_uk_lookup_postcodes). Parameters: `country_code` (ISO code, for example "FR", "US", "DE", "JP", "GB") and `postal_code` (as written locally, for example "75001", "100-0001" or "SW1A 2AA"). A full UK postcode is answered from Postcodes.io, other codes from GeoNames data through Zippopotam.us. Canada has only the first 3 characters, Great Britain outward codes, Brazil major codes. Northern Ireland (BT) is not served.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `country_code` | string | yes | `"FR"` |
| `postal_code` | string | yes | `"75001"` |

Returns `{ country, country_code, postal_code, places[], source, coverage_note, uk_postcode, attribution[] }`. Upstream: Zippopotam.us, Postcodes.io. Cache: reference (30 days). Read-only.

#### `geo_find_postal_codes`: Find the postal codes of a town

Use this when you need the postal or ZIP codes of a town or city, for example the ZIP codes of Belmont, Massachusetts or of Beverly Hills, California. Do not use for the place of a known code (geo_lookup_postal_code) or for UK postcode units (geo_uk_autocomplete_postcode, geo_uk_search_places). Parameters: `country_code` (ISO code, for example "US"), `state_code` (state, province or region code used by GeoNames, for example "MA" for Massachusetts, "ON" for Ontario, "ENG" for England), `place_name` (town, for example "Belmont"), `limit` (1 to 100, default 20), `offset`, `response_format` ("detailed" adds the state of each code). The place must have postal codes of its own. Northern Ireland (GB state "NIR") is not served.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `country_code` | string | yes | `"US"` |
| `state_code` | string | yes | `"MA"` |
| `place_name` | string | yes | `"Belmont"` |
| `limit` | integer | no | `20` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ country, country_code, place_name, state, state_code, postal_codes[], excluded_northern_ireland, pagination, attribution[] }`. Upstream: Zippopotam.us. Cache: reference (30 days). Read-only.

#### `geo_uk_lookup_postcodes`: Look up UK postcodes

Use this when you need what a UK postcode belongs to: district or council, county, ward, parish, region, country, parliamentary constituency and coordinates, for one postcode or up to 20 at once, for example "SW1A 2AA". Do not use for partial postcodes (geo_uk_autocomplete_postcode), outward codes such as "SW1A" (geo_uk_lookup_outcode), postcodes around a point (geo_uk_nearest_postcodes) or postal codes of other countries (geo_lookup_postal_code). Parameters: `postcodes` (1 to 20, any case and spacing, for example \["SW1A 2AA", "m320jg"]), `response_format` ("detailed" adds grid references, positional quality, NHS, police, census areas, deprivation rank and GSS codes). A single unknown postcode is an error, a terminated one gives its termination date. In a batch each postcode gets a status. Northern Ireland (BT) postcodes are not served.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `postcodes` | array of string | yes | `["SW1A 2AA"]` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ requested, found, results[], attribution[] }`. Upstream: Postcodes.io. Cache: reference (30 days). Read-only.

#### `geo_uk_nearest_postcodes`: Nearest UK postcodes to a point or postcode

Use this when you need the UK postcodes closest to a point or to another postcode, sorted by distance, for example the postcode of a GPS position in London or the postcodes around "SW1A 2AA". Do not use for the details of one known postcode (geo_uk_lookup_postcodes), for street addresses anywhere (geo_reverse_geocode) or outside the UK. Parameters: `postcode` or `latitude` + `longitude`, `radius_m` (1 to 2,000 metres, default 500), `limit` (1 to 50, default 10, at most 20 in detailed mode), `offset`, `response_format` ("concise": postcode, distance, district, ward, coordinates, "detailed": the full record). Northern Ireland (BT) postcodes are removed and counted.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `postcode` | string | no | `"SW1A 2AA"` |
| `latitude` | number | no | `51.5034` |
| `longitude` | number | no | `-0.1276` |
| `radius_m` | integer | no | `500` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ center, radius_m, postcodes[], excluded_northern_ireland, pagination, attribution[] }`. Upstream: Postcodes.io. Cache: reference (30 days). Read-only.

#### `geo_uk_autocomplete_postcode`: Complete a partial UK postcode

Use this when you have the start of a UK postcode and need the full postcodes that begin with it, for example "BR8 7R" or "SW1A 1". Do not use for a complete postcode (geo_uk_lookup_postcodes), a whole district summary (geo_uk_lookup_outcode) or postal codes of other countries (geo_lookup_postal_code). Parameters: `partial_postcode` (at least the outward code, for example "SW1A" or "BR87R", spaces ignored), `limit` (1 to 50, default 20), `offset`, `response_format` ("detailed" splits each postcode into outward and inward codes). At most 50 matches in alphabetical order. Northern Ireland (BT) postcodes are not served.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `partial_postcode` | string | yes | `"BR8 7R"` |
| `limit` | integer | no | `20` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ partial_postcode, postcodes[], pagination, attribution[] }`. Upstream: Postcodes.io. Cache: reference (30 days). Read-only.

#### `geo_uk_lookup_outcode`: Look up a UK postcode district

Use this when you need what a UK outward code (postcode district, the first half of a postcode) covers: its centre, councils, counties, wards, parishes and constituencies, and optionally the neighbouring districts, for example "SW1A" or "M1". Do not use for a full postcode (geo_uk_lookup_postcodes), for the postcodes inside a district (geo_uk_autocomplete_postcode) or outside the UK. Parameters: `outcode` (for example "SW1A", case-insensitive), `include_neighbours` (default false, true adds the nearest districts within 25 km with their distance), `neighbours_limit` (1 to 20, default 5). Northern Ireland (BT) districts are not served.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `outcode` | string | yes | `"SW1A"` |
| `include_neighbours` | boolean | no | `false` |
| `neighbours_limit` | integer | no | `5` |

Returns `{ district, neighbours, attribution[] }`. Upstream: Postcodes.io. Cache: reference (30 days). Read-only.

#### `geo_uk_search_places`: Search UK place names

Use this when you need a city, town, village, hamlet or suburb of Great Britain by name, with its council, county, region, postcode district and coordinates, for example "Welshpool" or "Bourton-on-the-Water". Do not use for addresses, landmarks or places outside Great Britain (geo_geocode) or for postcodes (geo_uk_lookup_postcodes). Parameters: `query` (place name, for example "Welshpool"), `place_type` (City, Town, Village, Hamlet, Suburban Area, Other Settlement), `limit` (1 to 50, default 10), `offset`, `response_format` ("detailed" adds the OS identifier, grid references and bounding box). Welsh and Gaelic names come with their English alternative. Data from OS Open Names, Great Britain only.

| Parameter | Type | Required | Example |
|---|---|---|---|
| `query` | string | yes | `"Welshpool"` |
| `place_type` | "City" or "Town" or "Village" or "Hamlet" or "Suburban Area" or "Other Settlement" | no | `"Town"` |
| `limit` | integer | no | `10` |
| `offset` | integer | no | `0` |
| `response_format` | "concise" or "detailed" | no | `"concise"` |

Returns `{ query, place_type, places[], pagination, attribution[] }`. Upstream: Postcodes.io. Cache: reference (30 days). Read-only.

### Connect

Endpoint (Streamable HTTP): `https://mrbridge--geo-toolkit-mcp.apify.actor/mcp`

Every client authenticates with your Apify API token, found in [Apify Console > Settings > API & Integrations](https://console.apify.com/settings/integrations). Clients that support custom headers send it as `Authorization: Bearer <token>`. The others use the `?token=` URL variant, which must be treated as a secret: keep it out of commits, screenshots and shared logs.

#### Claude Code

```bash
claude mcp add --transport http geo-toolkit "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp" --header "Authorization: Bearer ${APIFY_TOKEN}"
```

#### Cursor, VS Code and other JSON configurations

```json
{
  "mcpServers": {
    "geo-toolkit": {
      "type": "http",
      "url": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp",
      "headers": {
        "Authorization": "Bearer ${APIFY_TOKEN}"
      }
    }
  }
}
```

#### claude.ai and Claude Desktop

Add a custom connector with the URL `https://mrbridge--geo-toolkit-mcp.apify.actor/mcp?token=YOUR_APIFY_TOKEN` and no authentication. Prefilled link (replace the token placeholder before saving): [add Geocoding, Elevation & Postcode Lookup MCP Server to Claude](https://claude.ai/customize/connectors?modal=add-custom-connector\&connectorName=Geocoding%2C%20Elevation%20%26%20Postcode%20Lookup%20MCP%20Server\&connectorUrl=https%3A%2F%2Fmrbridge--geo-toolkit-mcp.apify.actor%2Fmcp%3Ftoken%3DYOUR_APIFY_TOKEN).

#### ChatGPT (developer mode)

Settings > Apps > Create, URL `https://mrbridge--geo-toolkit-mcp.apify.actor/mcp?token=YOUR_APIFY_TOKEN`, authentication "No authentication". ChatGPT snapshots the tool list: after a server update, an admin has to click Refresh on the app.

#### OpenAI Responses API

```json
{
  "type": "mcp",
  "server_label": "geo_toolkit",
  "server_url": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp",
  "headers": {
    "Authorization": "Bearer YOUR_APIFY_TOKEN"
  },
  "require_approval": "never"
}
```

Add `allowed_tools` to restrict the tool list. Tool calls must finish within about 60 seconds on this API, and every tool of this server answers in under 50 seconds.

#### Anthropic Messages API

```json
{
  "mcp_servers": [
    {
      "type": "url",
      "url": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp",
      "name": "geo-toolkit",
      "authorization_token": "YOUR_APIFY_TOKEN"
    }
  ],
  "tools": [
    {
      "type": "mcp_toolset",
      "mcp_server_name": "geo-toolkit"
    }
  ]
}
```

Send the beta header `anthropic-beta: mcp-client-2025-11-20`.

#### One-click OAuth alternative

`https://mcp.apify.com/?tools=mrbridge/geo-toolkit-mcp` connects through Apify OAuth without a token. It exposes the Actor as a single tool rather than the granular tools listed above.

#### Cost control

Each Standby run has a spending limit (`maxTotalChargeUsd`). When a call uses the last of it, the result is still returned, and later calls in that run answer `CHARGE_LIMIT_REACHED` until the limit is raised.

### Why use this MCP server?

A location question often needs two or three services in a row: a geocoder to turn a name into coordinates, then an elevation or postcode service, then a little geometry. These tools do the chaining, so an assistant can answer from a place name in a single call.

- **Names or coordinates.** The distance, elevation and nearby-place tools accept a place name and geocode it first.
- **Elevation beyond one point.** Up to 100 points per call, or a profile along up to 20 waypoints with its length, total ascent and descent, and highest and lowest points. Six elevation models are available, two of them covering the sea floor.
- **UK postcode geography.** Council, ward, parish, constituency and coordinates for up to 20 postcodes at once, the nearest postcodes to a point, partial postcode completion, postcode districts and British place names. Great Britain only: Northern Ireland postcodes are never served.
- **Conversions with no network call.** Decimal degrees, DMS, degrees and decimal minutes, geohash and UTM, computed by the server.
- **Credit lines included.** Each answer carries the attribution its sources require, ready to keep when you reuse the data.
- 🔌 **Model Context Protocol over Streamable HTTP** at a single endpoint, `https://mrbridge--geo-toolkit-mcp.apify.actor/mcp`, for Claude, ChatGPT, Cursor, VS Code and the OpenAI and Anthropic APIs.
- ⚡ **Apify Standby mode.** A cold start took 4.7 seconds on the platform (2026-10-05). The server then stays warm until it has been idle for 5 minutes.

### Pricing (Pay-per-Event)

| Event | Charged when | Price |
|---|---|---|
| `apify-actor-start` | run start (platform default) | see the Store page |
| `tool-read` (primary event) | each successful read tool call | see the Store page |
| `tool-action` | each successful call of a detailed or computed tool | see the Store page |

Never charged: initialize, tools/list, pings, readiness probes, and any call that ends in an error (invalid input, not found, upstream failure, timeout, spending limit).

Platform usage comes on top of these events. This server runs in Apify Standby mode, and you also pay the platform usage of your own Standby run, billed to your Apify account like any other run: the memory set for the Standby run, for as long as the server is up, idle time included, until the run stops at its idle timeout.
The [Apify pay-per-event documentation](https://docs.apify.com/actors/publishing/monetize/pay-per-event#platform-usage-costs) says so: "For runs in Standby mode, users always pay the platform usage costs in addition to the event charges."

### Limits, caveats and attribution

- **Attribution.** Every answer carries an `attribution` array with one block per source used: the provider, the source line, the licence, the terms URL and the notices below. Keep it when you reuse the results.
- **Geocoding and nearby places (Photon).** Data © OpenStreetMap contributors, under the Open Database License (https://www.openstreetmap.org/copyright). Results come from the public Photon instance run by komoot, which asks for reasonable use and throttles heavy traffic, so this server keeps to about one request per second and caches answers for a day. A search returns at most 20 places and a nearby search at most 20 places per point and category: this is not a way to download every feature of an area.
- **No routing.** Distances are great-circle distances as the crow flies, computed by this server. Travel distances, durations and turn-by-turn routes are not offered, and elevation profiles join the waypoints in straight lines.
- **Elevation (Open Topo Data).** The public API allows 1 call per second and 1,000 calls per day for all users of this server together, and one call covers up to 100 points. Answers are cached for 30 days, but heavy use can exhaust the daily quota (`UPSTREAM_RATE_LIMITED`). Once Open Topo Data answers that the quota is spent, the server pauses elevation calls until 00:00 UTC. SRTM covers land between 60°S and 60°N, ASTER up to 83°, EU-DEM Europe only, and ETOPO1 and GEBCO the whole globe including the sea floor at a coarse resolution. Values are interpolated between grid cells. SRTM, ASTER and EU-DEM are surface models: over buildings, towers and dense forest they include part or all of their height, so they are not bare-ground values (on SRTM the Eiffel Tower point reads 75 m where the ground is about 33 m), and their grids flatten sharp summits (SRTM reads 4,791 m on Mont Blanc against 4,805.59 m in the 2021 survey). Use them for planning and comparison, not for surveying, aviation or mountain safety. EU-DEM answers carry the Copernicus notices ("produced with funding by the European Union", no endorsement by the European Union).
- **Postal codes (Zippopotam.us).** GeoNames data, with approximate coordinates. Canada has only the first three characters of each code, the Netherlands only the four digits, Great Britain only outward codes (full UK postcodes are answered from Postcodes.io), Brazil only major codes. A full Canadian or Dutch code, or a US ZIP+4, is shortened to what the data has, and the answer says so.
- **UK postcodes (Postcodes.io).** Office for National Statistics and Ordnance Survey data under the Open Government Licence, updated quarterly. Northern Ireland postcodes (starting with BT) are never served: their commercial use needs a licence from Land & Property Services. They are refused on input and removed from lists, and the answer says how many were removed. Place names come from OS Open Names and cover Great Britain only.
- **Capped lists.** Photon returns at most 20 places per call and Postcodes.io at most 50 postcodes or places. When a list reaches that cap, the answer says that more may exist and how to narrow the call.
- **Freshness.** Geocoding answers are cached for a day, elevations, postal codes and UK postcodes for 30 days.

### Data terms

By using this server you agree to use the data it returns in line with the terms of each source, and to pass the same obligations on to anyone you share the data with.

- OpenStreetMap data (geocoding, reverse geocoding, nearby places): [Open Database License 1.0](https://opendatacommons.org/licenses/odbl/1-0/) and the [OpenStreetMap attribution guideline](https://osmfoundation.org/wiki/Licence/Attribution_Guidelines). Credit "© OpenStreetMap contributors" with a link to https://www.openstreetmap.org/copyright. If you build a database from these results and use it publicly, the ODbL asks you to share it under the same licence.
- Zippopotam.us and GeoNames data (postal codes): [Open Database License 1.0](https://opendatacommons.org/licenses/odbl/1-0/) for the database and [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) for the GeoNames content. Credit GeoNames (https://www.geonames.org).
- UK postcode data: [Open Government Licence v3.0](https://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/). Keep the statements "Contains OS data © Crown copyright and database right", "Contains Royal Mail data © Royal Mail copyright and database right" and "Source: Office for National Statistics licensed under the Open Government Licence v.3.0".
- Elevation data: keep the dataset line of each answer. EU-DEM falls under the Copernicus data policy (Regulation (EU) No 1159/2013): name the source, state any change you make, and do not suggest endorsement by the European Union. GEBCO asks you not to suggest official status or endorsement by GEBCO, the IHO or the IOC.

The fee for this server pays for the service (hosting, caching, parsing, the computed distances and profiles), not for a licence on the data.

### Use cases

**Checking an address before you save it.** Ask "Where exactly is 10 Downing Street, and which council and constituency is SW1A 2AA in?" `geo_geocode` returns the coordinates and the full address, and `geo_uk_lookup_postcodes` adds the council, ward and constituency.

**Hike and ride notes.** Give the assistant the waypoints of an outing and ask how long it is and how much it climbs. `geo_get_elevation_profile` samples up to 100 points along straight lines between up to 20 waypoints. The default model reads the top of trees and buildings, so treat the figures as planning estimates, never as safety information.

**Nearby answers.** "Find pharmacies within 1 km of Gare de Lyon in Paris." `geo_find_nearby_places` resolves the station name, then lists up to 20 pharmacies sorted by distance, each with its bearing from the station.

**Coordinates from field notes.** A position written as 48°51'30"N 2°17'40"E, a geohash or a UTM reference becomes decimal degrees and every other format with `geo_convert_coordinates`. Then `geo_reverse_geocode` says what stands there.

**ZIP code checks.** "Which ZIP codes cover Belmont, Massachusetts?" `geo_find_postal_codes` answers, and `geo_lookup_postal_code` goes the other way for a code such as 90210 or 75001.

**UK territory planning.** `geo_uk_lookup_outcode` describes a postcode district such as SW1A (councils, wards, parishes, constituencies) and lists its neighbouring districts on request.

### More weather, Earth and map tools

- [weather alerts and METAR for AI](https://apify.com/mrbridge/weather-mcp): 10-day forecasts for any coordinates, US alerts, airport METAR and TAF, and tide predictions.
- [rocket launch and earthquake data for AI](https://apify.com/mrbridge/space-earth-mcp): rocket launches, the ISS position, space weather, aurora forecasts and earthquakes.
- [French cadastre and PLU MCP server](https://apify.com/mrbridge/france-map-mcp-server): French cadastre parcels, PLU zoning, administrative boundaries and agricultural parcels.

### Frequently asked questions

#### Do I need an API key for the map data?

No. The four sources behind these tools are open and need no key. You need an Apify account and its API token, which your MCP client sends with each call.

#### How much does it cost?

Two things are billed to your Apify account. First, the tool calls: $0.01 per successful call to `geo_get_elevation_profile` (an action) and $0.005 per successful call to any other tool (a read). These are the prices on the Apify Free plan, and the discounts of paid plans lower them. Errors, invalid input, points outside a dataset's coverage, the spending-limit refusal and protocol messages such as initialize or ping are never charged. Second, the platform usage of your own Standby run, on top of the events: the memory set for the run (256 MB) for as long as the server is up, idle time included, until it stops 5 minutes after your last call, plus a small start event per new run. A 10-minute session of 20 calls, 2 of them actions, comes to $0.11 in tool calls on the Free plan plus 1 to 2 cents of platform usage. Live prices for your Apify plan are on the [Pricing tab](https://apify.com/mrbridge/geo-toolkit-mcp/pricing), and `maxTotalChargeUsd` caps the event charges of one run.

#### Can it give driving directions or travel times?

No. Distances are great-circle distances as the crow flies, computed by the server, and elevation profiles join the waypoints in straight lines. Use a routing service for roads, and do not rely on these tools for navigation.

#### How accurate are the elevations?

They come from global elevation grids, interpolated between cells. SRTM (the default) and ASTER are surface models: over buildings and dense forest they include part or all of the height of the buildings and trees, so they are not bare-ground values. The Eiffel Tower point reads 75 m where the ground is about 33 m, and the Mont Blanc summit reads 4,791 m against 4,805.59 m in the 2021 survey, because sharp peaks get flattened. That is fine for planning and comparison, and not fit for surveying, aviation or mountain safety.

#### Which countries do the postal code tools cover?

About 70 countries, from GeoNames data with approximate coordinates. Some are partial: Canada has only the first three characters of each code, the Netherlands only the four digits, Brazil only major codes. Full UK postcodes have their own tools, which cover Great Britain. Northern Ireland postcodes (BT) are never served, because their commercial use needs a separate licence.

#### Can I geocode thousands of addresses?

No. The server answers questions in a conversation and is not a batch geocoder. A search returns at most 20 places, the geocoder behind it asks for reasonable use, and all users share a daily elevation quota of 1,000 calls of up to 100 points each. Heavy use meets `UPSTREAM_RATE_LIMITED`.

#### How fresh is the data?

Geocoding answers are cached for a day. Elevations, postal codes and UK postcodes are cached for 30 days, and the UK postcode data itself is released quarterly.

#### Can I reuse the results?

Yes, within each source's licence. OpenStreetMap data is © OpenStreetMap contributors under the Open Database License: credit it, and share under the same licence any public database you build from it. Every answer carries an `attribution` array with the exact lines to keep, and the Data terms section above lists them source by source.

#### Is this server affiliated with OpenStreetMap or komoot?

No. It is an independent server, not affiliated with or endorsed by komoot, the OpenStreetMap Foundation, Open Topo Data, Zippopotam.us, GeoNames, Postcodes.io, Ordnance Survey, the ONS, the European Union or GEBCO.

#### Why is my first call slow?

Cold start. After 5 idle minutes the server stops, and the next call waits about 5 seconds (4.7 s measured) while Apify starts a new run.

#### Your feedback

Found a wrong place, an odd elevation or a broken tool? Open an issue on the [Issues tab](https://apify.com/mrbridge/geo-toolkit-mcp/issues/open). More MCP servers, scrapers and data studies from the same team are on [mr-bridge.com](https://mr-bridge.com).

### Changelog

- 0.1.5: Output, dataset and key-value store schemas, as Apify asks for publication: the Output tab of a run started from the Console shows the connection details and one row per tool.
- 0.1.4: the Input tab shows the endpoint and how to connect an AI client, and a run started from the Console outputs the connection details and the tool list
- 0.1.3: pricing events tool-read and tool-action. `geo_get_elevation_profile` bills one `tool-action` event ($0.01 on the Apify Free plan), every other tool one `tool-read` event ($0.005), and paid plans pay less
- 0.1.2: server name aligned with the Store title
- 0.1.1: the elevation texts no longer promise the height of the bare ground, since SRTM, ASTER and EU-DEM are surface models, and the limits explain what that means
- 0.1.0: initial build (private, unpublished)

# Actor input Schema

## `mcpEndpoint` (type: `string`):

Paste this URL into your MCP client (Streamable HTTP). It is shown here for copying only: the server ignores this form, and every parameter goes in your questions.

## Actor input object example

```json
{
  "mcpEndpoint": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp"
}
```

# Actor output Schema

## `connection` (type: `string`):

The item written by a run started from the Console: endpoint, token options, client recipes and the list of tools with the event each one bills.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mcpEndpoint": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrbridge/geo-toolkit-mcp").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "mcpEndpoint": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp" }

# Run the Actor and wait for it to finish
run = client.actor("mrbridge/geo-toolkit-mcp").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mcpEndpoint": "https://mrbridge--geo-toolkit-mcp.apify.actor/mcp"
}' |
apify call mrbridge/geo-toolkit-mcp --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mrbridge/geo-toolkit-mcp"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/xhCEvsQSSyzI1vHaz/builds/mUqgxL3W52VQ9WbuK/openapi.json
