Mapsi Mcp
About
Geospatial API tools for AI agents — geocoding, reverse geocoding, routing, isochrone, distance matrix, static maps, H3 hexagons, elevation, GPS map-matching, point-in-polygon, address normalisation, timezone lookup, and batch geocoding. Built on OpenStreetMap infrastructure. Cos
Details
- Author
- algolayertechnologies
- Downloads
- 329
- Categories
- Media
Jump to
- 18 geospatial tools for geocoding, routing, places, and more
- OpenStreetMap-based data with self-hosted infrastructure
- Batch geocoding of up to 30,000 addresses in one call
- Real-time address autocomplete with minimum 2 characters
- Isochrone generation (time or distance) as GeoJSON
- Distance matrix for up to 50×50 origin-destination pairs
- Multiple routing modes: auto, truck, bicycle, pedestrian, motor_scooter
- Static map PNG URLs for emails and PDFs
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
Mapsi McpCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
Obtain a free API key at mapsi.dev/console/api-keys (1,000 calls/day, no credit card required). Add the server configuration to your IDE’s MCP settings (e.g., ~/.claude.json, ~/.cursor/mcp.json, or Windsurf’s mcp_config.json) using npx -y mapsi-mcp and the MAPSI_API_KEY environment variable. Restart your IDE, then ask your AI assistant in plain English.
geocode
Convert an address or place name into WGS84 coordinates (lat/lon). Returns: formatted_address (string), coordinates {lat, lon}, city, country, confidence (0–1). WHEN TO USE: When you have a human-readable address and need lat/lon. DO NOT USE: For coordinates-to-address (use reverse_geocode). For real-time user typing (use autocomplete). CONFIDENCE: Score below 0.6 means the result is ambiguous — ask the user to clarify the address before proceeding. Score above 0.85 is reliable. CACHING: Within an agent session, never re-geocode the same address string. Cache the result and reuse it. COUNTRY BIAS: Always pass countries when the user's region is known — dramatically improves accuracy for short or ambiguous addresses (e.g. "Springfield" returns the right one).
reverse_geocode
Convert geographic coordinates (lat/lon) into a human-readable address. Returns: formatted_address, street, housenumber, city, postcode, country, country_code. WHEN TO USE: When you have coordinates and need a readable address (e.g. from GPS, user map click, or API response). DO NOT USE: When you already have a formatted_address — no need to reverse geocode it. GRANULARITY: Use the layers parameter to control detail level. "address" returns street-level. "locality" returns city/suburb. "street" returns road name without housenumber. NOTE: Results may be approximate for remote areas with sparse address data.
autocomplete
Get real-time address suggestions as a user types in an input field. Returns: array of suggestions each with { text, label, lat, lon }. WHEN TO USE: ONLY for powering a live address input field in a UI. Minimum 2 characters. DO NOT USE IN AGENTS: Agents should call geocode directly with a complete address. Autocomplete is a UI tool, not an agent tool — it returns partial matches, not reliable coordinates. FOCUS: Always pass focus.lat/focus.lon when user location is available — returns local results first.
normalize_address
Normalize and standardize a messy or inconsistently formatted address string. Returns: { formatted_address, street, housenumber, city, postcode, country, country_code, lat, lon }. WHEN TO USE: When cleaning user-submitted data, deduplicating a CRM, or standardizing addresses before batch processing. Also geocodes the address as a side-effect (lat/lon included). DO NOT USE: If you just need coordinates — use geocode instead. normalize_address is for data quality, not navigation.
timezone
Get the IANA timezone for a geographic coordinate. Returns: { timezone (IANA name), utc_offset_hours, utc_offset_seconds, dst_active }. Examples of IANA timezone names: "Europe/Paris", "America/New_York", "Asia/Kolkata". WHEN TO USE: Scheduling delivery ETAs, converting server timestamps to local time, detecting user timezone from coordinates.
elevation
Get the elevation (altitude above sea level in metres) for a geographic coordinate. Returns: { elevation_m (number) }. WHEN TO USE: Fitness/hiking apps, drone routing (terrain clearance), flood risk analysis, gradient calculation for cycling routes. NOTE: Elevation data has ~30m horizontal resolution globally; higher resolution available in some regions.
route
Get turn-by-turn directions between two or more waypoints. Returns: { distance_km, duration_sec, legs: [{ steps: [{ instruction, distance_km, duration_sec }] }], geometry (GeoJSON LineString) }. WAYPOINT ORDER: First element = origin, last = destination. Intermediate elements are via-points in order. TRAVEL MODES: auto (car), truck (HGV — applies weight/height/hazmat restrictions), bicycle, pedestrian, motor_scooter. ETA: duration_sec is road-network travel time under normal conditions. Does not account for live traffic. MULTI-STOP: Add intermediate waypoints for optimized stop sequences.
isochrone
Generate a reachability polygon — the geographic area reachable from a point within a given time or distance. Returns: GeoJSON FeatureCollection with one Polygon per contour. Each polygon is the boundary of the reachable area. CONTOURS — you must provide EITHER contours_minutes OR contours_meters, not both and not neither: - contours_minutes: [5, 10, 15] returns 3 nested polygons for 5, 10, 15 min reach (max 4 values, max 60 min each) - contours_meters: [500, 1000, 2000] returns polygons for 500m, 1km, 2km reach (max 4 values) OUTPUT: Pass GeoJSON directly to MapLibre addSource/addLayer, Leaflet geoJSON(), or Turf.js. USE FOR: Delivery zone visualization, service area planning, "show restaurants within 15 min walk".
matrix
Calculate travel times and distances between multiple origins and destinations in a single request. Returns: { sources: [{lat,lon}], targets: [{lat,lon}], durations: [[sec,...]], distances: [[km,...]] } durations[i][j] = travel time in seconds from origin i to destination j. distances[i][j] = distance in km from origin i to destination j. PERFORMANCE: Always prefer matrix over calling route in a loop. One matrix call replaces N×M individual route calls. LIMITS: Up to 50 origins × 50 destinations (2500 pairs) per call. USE FOR: Nearest-store finder, multi-stop delivery planning, logistics optimization.
map_match
Snap a raw GPS trace to the road network to correct GPS drift and determine the actual route taken. Returns: { matched_points: [{lat,lon}], confidence (0–1), geometry (GeoJSON LineString of matched route) }. COORDINATE FORMAT — CRITICAL: The coordinates array uses [longitude, latitude] order (GeoJSON convention), NOT [latitude, longitude]. Correct: [[-0.1276, 51.5074], [-0.1279, 51.5078]] ← [lon, lat] Wrong: [[51.5074, -0.1276], [51.5078, -0.1279]] ← [lat, lon] — will match wrong roads MINIMUM: At least 2 coordinate pairs required. For best accuracy, use GPS points sampled every 5–30 seconds. USE FOR: Fleet tracking post-processing, trip analysis, mileage calculation, delivery verification.
nearest_road
Find the nearest point on the road network to a given coordinate. Returns: { lat, lon, distance_m (distance from input to snapped point), road_name }. WHEN TO USE: Snap waypoints to routable roads before calling route. Also call this if route returns "no route found" — the waypoint may be in a park, building, or off-road area. RECOVERY: If route fails, call nearest_road on origin and destination, then retry route with snapped coordinates.
places_search
Find points of interest, businesses, and landmarks near a geographic coordinate. Returns: array of { name, lat, lon, categories: [string], address, distance_m }. QUERY: Use category keywords (restaurant, pharmacy, hospital, supermarket, ATM, petrol station, parking) or specific names ("Starbucks", "IKEA"). RADIUS: Default 1000m (1km). Increase for rural areas, decrease for dense urban. Max ~50000m. RESULT ORDER: Sorted by distance from the search center, nearest first. USE FOR: "Find nearest X", store locators, POI search, route stop suggestions. DO NOT USE: For address lookups — use geocode instead. For administrative boundaries — use point_in_polygon.
get_tile_style_url
Get the MapLibre GL style URL for Mapsi map tiles. Returns: { style_url, usage_note, maplibre_example }. AUTH NOTE: Tile auth uses ?key= query param in the URL, NOT the X-API-Key header. This is intentional — tile URLs must be usable in browser <img> tags and MapLibre without exposing headers. STYLES: - light: Minimal, pale, ideal for data overlays (default) - dark: Dark mode, high contrast for dashboards - streets: Full street detail, labels, transit - topo: Terrain/elevation shading, ideal for outdoor apps - grayscale: Monochrome, for color-coded data layers - white/black: Blank canvas for custom styling - liberty: Colorful OSM-inspired style USE FOR: Initializing MapLibre GL JS, React Map GL, Mapbox-compatible libraries.
get_static_map_url
Build a URL for a static PNG map image centered on a location. Returns: { url, auth_note, html_example }. USE FOR: Email templates, PDF reports, social sharing previews, server-side image generation. No JavaScript needed. ZOOM GUIDE: - 1–4: Country/continent - 6–8: Region/state - 10–11: City - 12–13: Neighbourhood - 14–16: Street level (most common) - 17–19: Building/parcel AUTH: For server-side use, send X-API-Key header. For direct browser/img use, append &api_key=YOUR_KEY to the URL.
batch_geocode
Geocode multiple addresses in a single API request. Returns: { results: [{ input, formatted_address, lat, lon, confidence, status }] }. Results are in the same order as the input array. status is "ok" or "not_found". PERFORMANCE: Always use batch_geocode for 2+ addresses. Never loop geocode calls — batch is far faster and uses fewer API credits. CACHING: Deduplicate your address list before calling — identical strings waste quota. PLAN LIMITS: Max addresses per call — Free: 10, Growth: 5000, Business: 30000. COUNTRIES: Pass countries when all addresses are in the same country — significantly improves accuracy. USE FOR: Importing customer lists, processing address CSV files, bulk ETL pipelines.
batch_reverse_geocode
Reverse geocode multiple coordinates in a single API request. Returns: { results: [{ lat, lon, formatted_address, street, city, postcode, country, country_code }] }. Results are in the same order as the input array. PERFORMANCE: Always use batch_reverse_geocode for 2+ coordinates. Never loop reverse_geocode calls. USE FOR: Enriching GPS log exports, converting coordinate datasets to readable addresses, fleet reports.
point_in_polygon
Get the full administrative hierarchy for a geographic coordinate. Returns: { country, country_code (ISO 3166-1 alpha-2), region (state/province), county, city, suburb, neighbourhood }. Not all levels are present for every location — rural coordinates may return only country and region. USE FOR: Territory assignment, tax region detection, locale/language inference, delivery zone validation, "what country is this coordinate in?". DO NOT USE: For reverse geocoding a street address — use reverse_geocode instead.
h3_index
Convert a coordinate to an H3 hexagonal grid cell index at a given resolution. Returns: { h3_index (string), resolution, center_lat, center_lon }. Resolution guide (area per cell): - 5: ~250 km² — country/large region level - 7: ~5 km² — city neighbourhood level (most common for analytics) - 9: ~0.1 km² — city block level - 12: ~0.003 km² — building level USE FOR: Spatial aggregation, density heat maps, geospatial indexing, joining datasets by grid cell. NOTE: For bulk H3 indexing of many coordinates, call individually — do not attempt to derive adjacent cells manually.
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"mapsi mcp": {
"mapsi": {
"command": "npx",
"args": [
"-y",
"mapsi-mcp"
],
"env": {
"MAPSI_API_KEY": "msk_your_key_here"
}
}
}
}
}
McpServers
{
"mapsi": {
"command": "npx",
"args": [
"-y",
"mapsi-mcp"
],
"env": {
"MAPSI_API_KEY": "msk_your_key_here"
}
}
}
mapsi-mcp
MCP server for Mapsi — 18 geospatial tools for AI coding assistants. Connect Claude Code, Cursor, Windsurf, or any MCP-compatible IDE directly to Mapsi APIs.
OpenStreetMap-based · Self-hosted infrastructure · No Google Maps vendor lock-in
Quick Start
1. Get your API key at mapsi.dev/console/api-keys (free tier: 1,000 calls/day, no credit card)
2. Add the config to your IDE:
Claude Code / Claude Desktop
Add to~/.claude.json (or .mcp.json in your project root):
{
"mcpServers": {
"mapsi": {
"command": "npx",
"args": ["-y", "mapsi-mcp"],
"env": { "MAPSI_API_KEY": "msk_your_key_here" }
}
}
}
Cursor
Add to~/.cursor/mcp.json:
{
"mcpServers": {
"mapsi": {
"command": "npx",
"args": ["-y", "mapsi-mcp"],
"env": { "MAPSI_API_KEY": "msk_your_key_here" }
}
}
}
Windsurf
Add to~/.codeium/windsurf/mcp_config.json — same JSON format as Cursor above.
VS Code + Cline
Open Cline settings → MCP Servers → Add server → paste:{
"mapsi": {
"command": "npx",
"args": ["-y", "mapsi-mcp"],
"env": { "MAPSI_API_KEY": "msk_your_key_here" }
}
}
Zed
Add to your Zed settings under"context_servers":
{
"mapsi-mcp": {
"command": { "path": "npx", "args": ["-y", "mapsi-mcp"] },
"env": { "MAPSI_API_KEY": "msk_your_key_here" }
}
}
3. Restart your IDE — then ask your AI in plain English.
---
What You Can Ask Your AI
Geocode all addresses in my CSV and add lat/lon columns
Build an address autocomplete input for this React form using Mapsi
Draw a 20-minute drive isochrone from our warehouse at this coordinate
Find the 5 nearest hospitals to this coordinate
Migrate this Google Maps geocoding call to Mapsi
Add a MapLibre map with Mapsi light tiles and drop markers from this array
Calculate a distance matrix between 10 warehouses and 50 delivery stops
Snap this GPS trace to the road network and calculate total distance
---
Available Tools (18)
Geocoding
| Tool | Description | |------|-------------| |geocode | Address or place name → lat/lon. Returns confidence score (0–1); treat scores below 0.6 as ambiguous. |
| reverse_geocode | lat/lon → formatted address, street, city, postcode, country. |
| autocomplete | Real-time address suggestions as user types (min 2 chars). For UI input fields. |
| normalize_address | Standardize messy/inconsistent addresses. Returns structured fields + coordinates. |
| timezone | IANA timezone name + UTC offset + DST status for any coordinate. |
| elevation | Altitude in metres for any coordinate (~30m resolution globally). |
Routing
| Tool | Description | |------|-------------| |route | Turn-by-turn directions. Modes: auto, truck, bicycle, pedestrian, motor_scooter. |
| isochrone | Reachability polygon within N minutes or N metres. Returns GeoJSON for MapLibre/Leaflet. |
| matrix | Travel time + distance matrix for up to 50×50 origin-destination pairs in one call. |
| map_match | Snap a GPS trace to the road network. Coordinates are [lon, lat] order (GeoJSON). |
| nearest_road | Find nearest routable road point. Call this if route returns "no route found". |
Places
| Tool | Description | |------|-------------| |places_search | Find nearby POIs by category (restaurant, hospital, pharmacy, ATM…). Returns name, coords, categories. |
Spatial
| Tool | Description | |------|-------------| |point_in_polygon | Admin hierarchy for a coordinate: country, region, city, neighbourhood. |
| h3_index | Convert coordinate to H3 hexagonal grid cell at resolution 0–15. |
Batch
| Tool | Description | |------|-------------| |batch_geocode | Geocode up to 30,000 addresses in a single call. Never loop geocode for bulk data. |
| batch_reverse_geocode | Reverse geocode multiple coordinates in one call. |
Tiles
| Tool | Description | |------|-------------| |get_tile_style_url | MapLibre GL style URL. Styles: light, dark, streets, topo, grayscale, black, white, liberty. |
| get_static_map_url | Static PNG map URL for use in ` tags, emails, and PDFs. |
---
Auth
- API calls:
X-API-Key header (handled automatically by the MCP server)
- Tile URLs: ?key= query param (browser-safe; returned by get_tile_style_url`)
---
Common Patterns for Agents
Geocode once, reuse the result:
Don't re-geocode the same address twice within a session. Cache the lat/lon and pass it directly to route, isochrone, and places_search.
Bulk data → batch tools:
For more than 1 address or coordinate pair, always use batch_geocode / batch_reverse_geocode.
Route fails → nearest_road first:
If route returns an error near the origin or destination, call nearest_road to snap the point to a routable road, then retry route with the snapped coordinates.
Isochrone — time vs distance:
Use contours_minutes for time-based reachability (delivery ETAs, commute zones).
Use contours_meters for fixed-radius circles on the road network.
Provide only one, not both.
---
Pricing
| Plan | Calls/day | Batch size |
|------|-----------|------------|
| Free | 1,000 | 10 |
| Growth | 50,000 | 5,000 |
| Business | Unlimited | 30,000 |
Full pricing at mapsi.dev/pricing
---
Links
- Website: mapsi.dev
- API docs: mapsi.dev/docs
- AI prompts: mapsi.dev/prompts-for-ai
- npm: npmjs.com/package/mapsi-mcp
- GitHub: github.com/algolayer/mapsi-mcp
- Support: support@mapsi.dev
---
License
MIT — algolayer.com
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.
