Skip to main content
Glama

resample_raster

Resample raster datasets by scaling resolution with specified methods to adjust spatial detail for analysis or display needs.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sourceYes
scale_factorYes
resamplingYes
destinationYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The core handler function for the 'resample_raster' tool. It opens a source raster (local or URL), resamples it by a given scale_factor using the specified resampling method (e.g., nearest, bilinear), computes new dimensions and transform, and writes the result to a destination file using rasterio.
    @gis_mcp.tool()
    def resample_raster(
        source: str,
        scale_factor: float,
        resampling: str,
        destination: str
    ) -> Dict[str, Any]:
        """
        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.
        """
        try:
            import numpy as np
            import rasterio
            from rasterio.enums import Resampling
            from rasterio.transform import Affine
    
            # Strip backticks if present
            src_clean = source.replace("`", "")
            dst_clean = destination.replace("`", "")
    
            # Open source (remote or local)
            if src_clean.lower().startswith("https://"):
                src = rasterio.open(src_clean)
            else:
                src_path = os.path.expanduser(src_clean)
                if not os.path.isfile(src_path):
                    raise FileNotFoundError(f"Source raster not found at '{src_path}'.")
                src = rasterio.open(src_path)
    
            # Validate scale factor
            if scale_factor <= 0:
                raise ValueError("Scale factor must be positive.")
    
            # Compute new dimensions
            new_width  = int(src.width  * scale_factor)
            new_height = int(src.height * scale_factor)
    
            if new_width == 0 or new_height == 0:
                raise ValueError("Resulting raster dimensions are zero. Check scale_factor.")
    
            # Map resampling method string to Resampling enum
            resampling_enum = getattr(Resampling, resampling.lower(), Resampling.nearest)
    
            # Read and resample all bands
            data = src.read(
                out_shape=(src.count, new_height, new_width),
                resampling=resampling_enum
            )
    
            # Validate resampled data
            if data is None or data.size == 0:
                raise ValueError("No data was resampled.")
    
            # Calculate the new transform to reflect the resampling
            new_transform = src.transform * Affine.scale(
                (src.width  / new_width),
                (src.height / new_height)
            )
    
            # Update profile
            profile = src.profile.copy()
            profile.update({
                "height":    new_height,
                "width":     new_width,
                "transform": new_transform
            })
            src.close()
    
            # Ensure destination directory exists
            dst_path = os.path.expanduser(dst_clean)
            os.makedirs(os.path.dirname(dst_path) or ".", exist_ok=True)
    
            # Write the resampled raster
            with rasterio.open(dst_path, "w", **profile) as dst:
                dst.write(data)
    
            return {
                "status":      "success",
                "destination": str(dst_path),
                "message":     f"Raster resampled by factor {scale_factor} using '{resampling}' and saved to '{dst_path}'."
            }
    
        except Exception as e:
            # Log error and raise for MCP to report
            logger.error(f"Error resampling raster '{source}': {e}")
            raise ValueError(f"Failed to resample raster: {e}")
  • MCP resource that lists available rasterio operations, including 'resample_raster', serving as a discovery/registration mechanism for the tool.
    @gis_mcp.resource("gis://operation/rasterio")
    def get_rasterio_operations() -> Dict[str, List[str]]:
        """List available rasterio operations."""
        return {
            "operations": [
                "metadata_raster",
                "get_raster_crs",
                "clip_raster_with_shapefile",
                "resample_raster",
                "reproject_raster",
                "weighted_band_sum",
                "concat_bands",
                "raster_algebra",
                "compute_ndvi",
                "raster_histogram",
                "tile_raster",
                "raster_band_statistics",
                "extract_band",
                "zonal_statistics",
                "reclassify_raster",
                "focal_statistics",
                "hillshade",
                "write_raster"
            ]
        }
  • Definition of the gis_mcp FastMCP instance used for tool and resource registration via decorators (@gis_mcp.tool(), @gis_mcp.resource()). All tools in rasterio_functions.py are registered to this instance.
    # MCP imports using the new SDK patterns
    from fastmcp import FastMCP
    
    
    gis_mcp = FastMCP("GIS MCP")
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden. It mentions saving the result, implying a write operation, but doesn't disclose critical behavioral traits like whether it overwrites existing files at the destination, what file formats are supported, memory/performance considerations, or error handling. The description is minimal beyond the basic operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly structured and concise: a clear purpose statement followed by a bulleted list of parameters with helpful explanations. Every sentence earns its place, with no redundant information, and the key information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has an output schema (which handles return values), 4 parameters with 0% schema coverage, and no annotations, the description does well by fully documenting parameters. However, for a tool that performs file operations (reading and writing), it lacks context about file formats, overwrite behavior, or error conditions, leaving some gaps in completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by explaining all 4 parameters clearly. It defines 'source' as a local path or HTTPS URL, 'scale_factor' with examples (0.5 to halve, 2.0 to double), 'resampling' with method names, and 'destination' as a local filesystem path. This adds essential meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Resample a raster dataset') and resource ('raster dataset'), distinguishing it from siblings like 'reproject_raster', 'clip_raster_with_shapefile', or 'tile_raster' that involve different raster operations. It explicitly mentions saving the result, which further clarifies the tool's purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With siblings like 'reproject_raster' (which changes coordinate systems) and 'tile_raster' (which divides rasters), there is no indication of when resampling is appropriate versus these other operations, nor any prerequisites or exclusions mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mahdin75/gis-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server