A Model Context Protocol (MCP) server providing geospatial tools for AI agents. Enables Claude, GPT, and other LLMs to perform geocoding, routing, spatial analysis, and file operations.
- Geocoding: Convert addresses to coordinates and vice versa (via Nominatim/OSM or Pelias)
- Batch Geocoding: Geocode multiple addresses in a single request (up to 10)
- Elevation Data: Get altitude for points and elevation profiles along paths
- Routing: Calculate routes between points with distance, duration, and geometry (via OSRM)
- Spatial Analysis: Buffer, intersection, union, distance calculations
- File I/O: Read/write Shapefiles, GeoJSON, GeoPackage
- CRS Transformation: Convert between coordinate reference systems
# From PyPI (when published)
pip install locusync-server
# From source
git clone https://github.com/matbel91765/locusync-server.git
cd locusync-server
pip install -e .Add to your claude_desktop_config.json:
{
"mcpServers": {
"locusync": {
"command": "uvx",
"args": ["locusync-server"]
}
}
}# Run the server
locusync-serverConvert an address to coordinates.
Input: "1600 Pennsylvania Avenue, Washington DC"
Output: {lat: 38.8977, lon: -77.0365, display_name: "White House..."}
Convert coordinates to an address.
Input: lat=48.8566, lon=2.3522
Output: {display_name: "Paris, Île-de-France, France", ...}
Geocode multiple addresses at once (max 10).
Input: addresses=["Paris, France", "London, UK", "Berlin, Germany"]
Output: {results: [...], summary: {total: 3, successful: 3, failed: 0}}
Get altitude for a point.
Input: lat=48.8566, lon=2.3522
Output: {elevation_m: 35, location: {lat: 48.8566, lon: 2.3522}}
Get elevations along a path.
Input: coordinates=[[2.3522, 48.8566], [2.2945, 48.8584]]
Output: {profile: [...], stats: {min: 28, max: 42, gain: 14}}
Calculate distance between two points.
Input: lat1=48.8566, lon1=2.3522, lat2=51.5074, lon2=-0.1278
Output: {distance: {meters: 343556, kilometers: 343.56, miles: 213.47}}
Create a buffer zone around a geometry.
Input: geometry={type: "Point", coordinates: [2.3522, 48.8566]}, distance_meters=1000
Output: {geometry: {type: "Polygon", ...}, area_km2: 3.14}
Perform spatial operations (intersection, union, contains, within, etc.).
Input: geometry1={...}, geometry2={...}, operation="intersection"
Output: {geometry: {...}}
Transform coordinates between CRS.
Input: geometry={...}, source_crs="EPSG:4326", target_crs="EPSG:3857"
Output: {geometry: {...}}
Calculate route between two points.
Input: start_lat=48.8566, start_lon=2.3522, end_lat=48.8606, end_lon=2.3376
Output: {distance: {...}, duration: {...}, geometry: {...}, steps: [...]}
Calculate area reachable within a time limit.
Input: lat=48.8566, lon=2.3522, time_minutes=15, profile="driving"
Output: {geometry: {type: "Polygon", ...}}
Read geospatial files (Shapefile, GeoJSON, GeoPackage).
Input: file_path="data/cities.shp"
Output: {type: "FeatureCollection", features: [...]}
Write features to geospatial files.
Input: features={...}, file_path="output.geojson", driver="GeoJSON"
Output: {file_path: "...", feature_count: 10}
Environment variables:
| Variable | Default | Description |
|---|---|---|
NOMINATIM_URL |
https://nominatim.openstreetmap.org |
Nominatim API URL |
NOMINATIM_USER_AGENT |
locusync-server/1.0.0 |
User agent for Nominatim |
OSRM_URL |
https://router.project-osrm.org |
OSRM API URL |
OSRM_PROFILE |
driving |
Default routing profile |
PELIAS_URL |
(empty) | Pelias geocoding API URL |
PELIAS_API_KEY |
(empty) | Pelias API key (optional) |
OPEN_ELEVATION_URL |
https://api.open-elevation.com |
Open-Elevation API URL |
GIS_DEFAULT_CRS |
EPSG:4326 |
Default CRS |
GIS_TEMP_DIR |
/tmp/locusync |
Temporary directory |
All tools return a consistent JSON structure:
{
"success": true,
"data": { ... },
"metadata": {
"source": "nominatim",
"confidence": 0.95
},
"error": null
}- Nominatim: 1 request/second (enforced automatically)
- OSRM Demo: Best effort, consider self-hosting for production
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run with coverage
pytest --cov=src/locusync --cov-report=html
# Type checking
mypy src/locusync
# Linting
ruff check src/locusyncsrc/locusync/
├── server.py # MCP server entry point
├── config.py # Configuration management
├── utils.py # Common utilities
└── tools/
├── geocoding.py # geocode, reverse_geocode, batch_geocode
├── elevation.py # get_elevation, get_elevation_profile
├── routing.py # route, isochrone
├── geometry.py # buffer, distance, spatial_query, transform_crs
└── files.py # read_file, write_file
MIT License - see LICENSE for details.
Contributions welcome! Please read the contributing guidelines before submitting PRs.
- Pelias geocoding support (higher accuracy)
- Elevation/terrain data
- Batch geocoding
- Valhalla routing integration (native isochrones)
- PostGIS spatial queries
- Real-time traffic data
- ESRI FileGDB full support