# mahdin75/gis-mcp [Health: Active]

**Category:** 🗺️ Location Services  
**Repository:** https://github.com/mahdin75/gis-mcp  
**GitHub Stars:** 199  
**Views:** 1  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/mahdin75-gis-mcp

## Description
A Model Context Protocol (MCP) server implementation that connects Large Language Models (LLMs) to GIS operations using GIS libraries, enabling AI assistants to perform accurate geospatial operations and transformations.

## Tools
Capabilities this server exposes over MCP:

- **read_file_gpd** — Reads a geospatial file and returns stats and a data preview.
- **append_gpd** — Reads two shapefiles directly, concatenates them vertically.
- **merge_gpd** — Merges two shapefiles based on common attribute columns,
This function performs a database-style join, not a spatial join.
Args:
    left_shapefile_path: Path to the left shapefile. The geometry from this file is preserved.
    right_shapefile_path: Path to the right shapefile to merge.
    output_path: Path to save the merged output shapefile.
    how: Type of merge. One of 'left', 'right', 'outer', 'inner'. Defaults to 'inner'.
    on: Column name to join on. Must be found in both shapefiles.
    left_on: Column name to join on in the left shapefile.
    right_on: Column name to join on in the right shapefile.
    suffixes: Suffix to apply to overlapping column names.
- **overlay_gpd** — Overlay two GeoDataFrames using geopandas.overlay.
Args:
    gdf1_path: Path to the first geospatial file.
    gdf2_path: Path to the second geospatial file.
    how: Overlay method ('intersection', 'union', 'identity', 'symmetric_difference', 'difference').
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **dissolve_gpd** — Dissolve geometries by attribute using geopandas.dissolve.
Args:
    gdf_path: Path to the geospatial file.
    by: Column to dissolve by (optional).
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **explode_gpd** — Split multi-part geometries into single parts using geopandas.explode.
Args:
    gdf_path: Path to the geospatial file.
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **clip_vector** — Clip vector geometries using geopandas.clip.
Args:
    gdf_path: Path to the input geospatial file.
    clip_path: Path to the clipping geometry file.
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **sjoin_gpd** — Spatial join between two GeoDataFrames using geopandas.sjoin.
Args:
    left_path: Path to the left geospatial file.
    right_path: Path to the right geospatial file.
    how: Type of join ('left', 'right', 'inner').
    predicate: Spatial predicate ('intersects', 'within', 'contains', etc.).
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **sjoin_nearest_gpd** — Nearest neighbor spatial join using geopandas.sjoin_nearest.
Args:
    left_path: Path to the left geospatial file.
    right_path: Path to the right geospatial file.
    how: Type of join ('left', 'right').
    max_distance: Optional maximum search distance.
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **point_in_polygon** — Check if points are inside polygons using spatial join (predicate='within').
Args:
    points_path: Path to the point geospatial file.
    polygons_path: Path to the polygon geospatial file.
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output info.
- **write_file_gpd** — Export a GeoDataFrame to a file (Shapefile, GeoJSON, GPKG, etc.).
Args:
    gdf_path: Path to the input geospatial file.
    output_path: Path to save the exported file.
    driver: Optional OGR driver name (e.g., 'ESRI Shapefile', 'GeoJSON', 'GPKG').
Returns:
    Dictionary with status and message.
- **buffer** — Create a buffer around a geometry.
- **intersection** — Find intersection of two geometries.
- **union** — Combine two geometries.
- **difference** — Find difference between geometries.
- **symmetric_difference** — Find symmetric difference between geometries.
- **convex_hull** — Calculate convex hull of a geometry.
- **envelope** — Get bounding box of a geometry.
- **minimum_rotated_rectangle** — Get minimum rotated rectangle of a geometry.
- **get_centroid** — Get the centroid of a geometry.
- **get_bounds** — Get the bounds of a geometry.
- **get_coordinates** — Get the coordinates of a geometry.
- **get_geometry_type** — Get the type of a geometry.
- **rotate_geometry** — Rotate a geometry.
- **scale_geometry** — Scale a geometry.
- **translate_geometry** — Translate a geometry.
- **triangulate_geometry** — Create a triangulation of a geometry.
- **voronoi** — Create a Voronoi diagram from points.
- **unary_union_geometries** — Create a union of multiple geometries.
- **get_length** — Get the length of a geometry.
- **get_area** — Get the area of a geometry.
- **is_valid** — Check if a geometry is valid.
- **make_valid** — Make a geometry valid.
- **simplify** — Simplify a geometry.
- **snap_geometry** — Snap one geometry to another using shapely.ops.snap.
Args:
    geometry1: WKT string of the geometry to be snapped.
    geometry2: WKT string of the reference geometry.
    tolerance: Distance tolerance for snapping.
Returns:
    Dictionary with status, message, and snapped geometry as WKT.
- **nearest_point_on_geometry** — Find the nearest point on geometry2 to geometry1 using shapely.ops.nearest_points.
Args:
    geometry1: WKT string of the first geometry (e.g., a point).
    geometry2: WKT string of the second geometry.
Returns:
    Dictionary with status, message, and the nearest point as WKT.
- **normalize_geometry** — Normalize the orientation/order of a geometry using shapely.normalize.
Args:
    geometry: WKT string of the geometry.
Returns:
    Dictionary with status, message, and normalized geometry as WKT.
- **geometry_to_geojson** — Convert a Shapely geometry (WKT) to GeoJSON using shapely.geometry.mapping.
Args:
    geometry: WKT string of the geometry.
Returns:
    Dictionary with status, message, and GeoJSON representation.
- **geojson_to_geometry** — Convert GeoJSON to a Shapely geometry using shapely.geometry.shape.
Args:
    geojson: GeoJSON dictionary.
Returns:
    Dictionary with status, message, and geometry as WKT.
- **zonal_statistics** — Calculate statistics of raster values within polygons (zonal statistics).
Args:
    raster_path: Path to the raster file.
    vector_path: Path to the vector file (polygons).
    stats: List of statistics to compute (e.g., ["mean", "min", "max", "std"]).
Returns:
    Dictionary with status, message, and statistics per polygon.
- **reclassify_raster** — Reclassify raster values using a mapping dictionary.
Args:
    raster_path: Path to the input raster.
    reclass_map: Dictionary mapping old values to new values (e.g., {1: 10, 2: 20}).
    output_path: Path to save the reclassified raster.
Returns:
    Dictionary with status and message.
- **focal_statistics** — Compute focal (moving window) statistics on a raster.
Args:
    raster_path: Path to the input raster.
    statistic: Statistic to compute ('mean', 'min', 'max', 'std').
    size: Window size (odd integer).
    output_path: Optional path to save the result.
Returns:
    Dictionary with status, message, and output path if saved.
- **hillshade** — Generate hillshade from a DEM raster.
Args:
    raster_path: Path to the DEM raster.
    azimuth: Sun azimuth angle in degrees.
    angle_altitude: Sun altitude angle in degrees.
    output_path: Optional path to save the hillshade raster.
Returns:
    Dictionary with status, message, and output path if saved.
- **write_raster** — Write a numpy array to a raster file using metadata from a reference raster.
Args:
    array: 2D or 3D list (or numpy array) of raster values.
    reference_raster: Path to a raster whose metadata will be copied.
    output_path: Path to save the new raster.
    dtype: Optional data type (e.g., 'float32', 'uint8').
Returns:
    Dictionary with status and message.
- **metadata_raster** — Open a raster dataset in read-only mode and return metadata.

This tool supports two modes based on the provided string:
1. A local filesystem path (e.g., "D:\Data\my_raster.tif").
2. An HTTPS URL (e.g., "https://example.com/my_raster.tif").

The input must be a single string that is either a valid file path
on the local machine or a valid HTTPS URL pointing to a raster.
- **get_raster_crs** — Retrieve the Coordinate Reference System (CRS) of a raster dataset.

Opens the raster (local path or HTTPS URL), reads its DatasetReader.crs
attribute as a PROJ.4-style dict, and also returns the WKT representation.
- **clip_raster_with_shapefile** — Clip a raster dataset using polygons from a shapefile and write the result.
Converts the shapefile's CRS to match the raster's CRS if they are different.

Parameters:
- raster_path_or_url: local path or HTTPS URL of the source raster.
- shapefile_path:     local filesystem path to a .shp file containing polygons.
- destination:        local path where the masked raster will be written.
- **resample_raster** — Resample a raster dataset by a scale factor and save the result.

Parameters:
- source:       local path or HTTPS URL of the source raster.
- scale_factor: multiplicative factor for width/height 
                (e.g., 0.5 to halve resolution, 2.0 to double).
- resampling:   resampling method name: "nearest", "bilinear", "cubic", etc.
- destination:  local filesystem path for the resampled raster.
- **reproject_raster** — Reproject a raster dataset to a new CRS and save the result.

Parameters:
- source:      local path or HTTPS URL of the source raster.
- target_crs:  target CRS string (e.g., "EPSG:4326").
- destination: local filesystem path for the reprojected raster.
- resampling:  resampling method: "nearest", "bilinear", "cubic", etc.
- **extract_band** — Extract a specific band from a multi-band raster and save it as a single-band GeoTIFF.

Parameters:
- source:      path or URL of the input raster.
- band_index:  index of the band to extract (1-based).
- destination: path to save the extracted band raster.
- **raster_band_statistics** — Calculate min, max, mean, and std for each band of a raster.

Parameters:
- source: path to input raster (local or URL).
- **tile_raster** — Split a raster into square tiles of a given size and save them individually.

Parameters:
- source:         input raster path.
- tile_size:      size of each tile (e.g., 256 or 512).
- destination_dir: directory to store the tiles.
- **raster_histogram** — Compute histogram of pixel values for each band.

Parameters:
- source: path to input raster.
- bins:   number of histogram bins.
- **compute_ndvi** — Compute NDVI (Normalized Difference Vegetation Index) and save to GeoTIFF.

Parameters:
- source:            input raster path.
- red_band_index:    index of red band (1-based).
- nir_band_index:    index of near-infrared band (1-based).
- destination:       output NDVI raster path.
- **raster_algebra** — Perform algebraic operations (addition or subtraction) on two raster bands, 
handling alignment issues automatically.

Parameters:
- raster1:     Path to the first raster (.tif).
- raster2:     Path to the second raster (.tif).
- band_index:  Index of the band to process (1-based index).
- operation:   Either "add" or "subtract" to specify the calculation.
- destination: Path to save the result as a new raster.

The function aligns rasters if needed, applies the selected operation, and saves the result.
- **concat_bands** — Concatenate multiple single-band raster files into one multi-band raster, 
handling alignment issues automatically.

Parameters:
- folder_path:   Path to folder containing input raster files (e.g. GeoTIFFs).
- destination:   Path to output multi-band raster file.

Notes:
- Files are read in sorted order by filename.
- If rasters have mismatched CRS, resolution, or dimensions, they are aligned automatically.
- **weighted_band_sum** — Compute a weighted sum of all bands in a raster using specified weights.

Parameters:
- source:      Path to the input multi-band raster file.
- weights:     List of weights (must match number of bands and sum to 1).
- destination: Path to save the output single-band raster.
- **transform_coordinates** — Transform coordinates between CRS.
- **project_geometry** — Project a geometry between CRS.
- **get_crs_info** — Get information about a CRS.
- **get_available_crs** — Get list of available CRS.
- **get_geod_info** — Get information about a geodetic calculation.
- **calculate_geodetic_distance** — Calculate geodetic distance between points.
- **calculate_geodetic_point** — Calculate point at given distance and azimuth.
- **calculate_geodetic_area** — Calculate area of a polygon using geodetic calculations.
- **get_utm_zone** — Get UTM zone for given coordinates.
- **get_utm_crs** — Get UTM CRS for given coordinates.
- **get_geocentric_crs** — Get geocentric CRS for given coordinates.
- **getis_ord_g** — Compute Getis-Ord G for global hot spot analysis.
- **morans_i** — Compute Moran's I Global Autocorrelation Statistic.
- **gearys_c** — Compute Global Geary's C Autocorrelation Statistic.
- **gamma_statistic** — Compute Gamma Statistic for spatial autocorrelation.
- **moran_local** — Local Moran's I.
- **getis_ord_g_local** — Local Getis-Ord G.
- **join_counts** — Global Binary Join Counts.
- **join_counts_local** — Local Join Counts.
- **adbscan** — Adaptive DBSCAN clustering (requires coordinates, no dependent_var).
- **weights_from_shapefile** — Create a spatial weights (W) from a shapefile using contiguity.

- contiguity: 'queen' or 'rook' (default 'queen')
- id_field: optional attribute name to use as observation IDs
- **distance_band_weights** — Create a distance-based spatial weights (W) object from point data.

- data_path: path to point shapefile or GeoPackage
- threshold: distance threshold for neighbors (in CRS units, e.g., meters)
- binary: True for binary weights, False for inverse distance weights
- id_field: optional attribute name to use as observation IDs
- **knn_weights** — Create a k-nearest neighbors spatial weights (W) object from point data.

- data_path: path to point shapefile or GeoPackage
- k: number of nearest neighbors
- id_field: optional attribute name to use as observation IDs
- **build_transform_and_save_weights** — Pipeline: Read shapefile, build spatial weights, optionally transform, and save to file.

Parameters:
- data_path: Path to point shapefile or GeoPackage
- method: 'queen', 'rook', 'distance_band', 'knn'
- id_field: Optional field name for IDs
- threshold: Distance threshold (required if method='distance_band')
- k: Number of neighbors (required if method='knn')
- binary: True for binary weights, False for inverse distance (DistanceBand only)
- transform_type: 'r', 'v', 'b', 'o', or 'd' (optional)
- output_path: File path to save weights
- format: 'gal' or 'gwt'
- overwrite: Allow overwriting if file exists
- **ols_with_spatial_diagnostics_safe** — Safe MCP pipeline: Read shapefile, build/load W, convert numeric, check NaNs, run OLS.

Parameters:
- data_path: path to shapefile or GeoPackage
- y_field: dependent variable column name
- x_fields: list of independent variable column names
- weights_path: optional path to existing weights file (.gal or .gwt)
- weights_method: 'queen', 'rook', 'distance_band', or 'knn' (used if weights_path not provided)
- id_field: optional attribute name to use as observation IDs
- threshold: required if method='distance_band'
- k: required if method='knn'
- binary: True for binary weights (DistanceBand only)
- **build_and_transform_weights** — Build and transform spatial weights in one step.

Parameters:
- data_path: Path to point shapefile or GeoPackage
- method: 'queen', 'rook', 'distance_band', or 'knn'
- id_field: Optional field name for IDs
- threshold: Distance threshold (required if method='distance_band')
- k: Number of neighbors (required if method='knn')
- binary: True for binary weights, False for inverse distance (DistanceBand only)
- transform_type: 'r', 'v', 'b', 'o', or 'd'
- **spatial_markov** — Run giddy Spatial Markov on a panel (n regions x t periods) from a shapefile.
- **dynamic_lisa** — Run dynamic LISA (directional LISA) with giddy.directional.Rose.

Returns sector counts, angles, vector lengths, and (optionally) permutation p-values.
- **gm_lag** — Run spreg.GM_Lag (spatial 2SLS / GMM-IV spatial lag model) on a cross-section.

Returns coefficients with SE/z/p, fit metrics, (optional) AK test, and a small data preview.
- **save_results** — MCP Tool: Save any GIS-MCP result dict to files, only when the user requests.

Args:
    data: The dictionary returned by any GIS-MCP tool.
    filename: Base filename without extension.
    formats: List of formats to save (default = all).
    folder: Target folder (relative to configured storage directory, or absolute path).

Returns:
    Dict with 'saved_files' mapping format -> path.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `uvx` (confidence: high):

```json
"mcpServers": {
  "gis-mcp": {
    "command": "uvx",
    "args": ["gis-mcp"]
  }
}
```

## Documentation

## What mahdin75/gis-mcp does

The mahdin75/gis-mcp MCP server connects large language models and AI assistants with GIS libraries and geospatial workflows. Its toolset covers spatial analysis, data processing, coordinate transformations, spatial statistics, visualization, and mapping. The project describes more than 92 tools across established Python GIS packages and several domain-specific data areas.

Supported capability areas include vector operations through Shapely and GeoPandas, coordinate work through PyProj, raster processing through Rasterio, and spatial statistics through PySAL. The server also lists satellite imagery, climate, ecology, movement, land-cover, biodiversity, and administrative-boundary data sources.

## How it works

An MCP-compatible client connects to the server and presents its GIS operations as callable agent tools. The repository advertises both HTTP and stdio transport, allowing the deployment style to match the client or environment. Agents can use the exposed operations for geospatial analysis and transformations rather than treating GIS work as text-only reasoning.

The project includes examples for building geospatial agents with LangChain in Python and the OpenAI Agents SDK in Node.js. These examples indicate that the server can be used either from an MCP client or as part of an agent application that supports MCP connections.

## Setup and configuration

The package is published on PyPI as `gis-mcp`, and the project also provides Docker installation documentation. Deployment can use either the advertised HTTP or stdio transport. Storage documentation covers a local filesystem option and Google Cloud Storage.

Consult the project documentation for those details before deploying a particular storage backend or transport.

## Tools and capabilities

The mahdin75/gis-mcp MCP server groups its tools across the following areas:

- Vector operations using Shapely and GeoPandas
- Raster operations using Rasterio
- Coordinate transformations using PyProj
- Spatial statistics using PySAL
- Visualization and mapping
- Satellite imagery access
- Climate, ecology, biodiversity, movement, and land-cover data
- Administrative-boundary data

This combination fits workflows that need both general-purpose geometry processing and domain-specific geospatial data gathering.

## Limitations and notes

The available description does not enumerate every tool name, input schema, output format, supported coordinate reference systems, or data-provider requirements. It also does not establish performance characteristics or production-readiness guarantees. Treat the beta status as relevant when evaluating the server for critical workloads, and verify the official documentation for exact operation behavior and configuration requirements.

The listed storage choices are local filesystem and Google Cloud Storage.

_Full upstream README: https://allmcps.com/mcp/mahdin75-gis-mcp/readme_

