GeoCroissant MCP Server
This server lets MCP clients discover, search, and turn Earth observation data into validated GeoCroissant ML-Ready metadata.
List registered STAC catalogs (Earth Search, NASA VEDA) and browse/search EO collections by topic or keyword.
Search satellite scenes by bounding box, date range, cloud cover, and collection, or count scenes before generating metadata.
Geocode place names to EPSG:4326 bounding boxes.
Generate validated GeoCroissant JSON-LD from live STAC searches (single source or multiple independent sources).
Create a standards-conformant GeoCroissant scaffold from dataset parameters.
Validate, inspect, and summarize Croissant/GeoCroissant documents, including geospatial properties, distributions, RecordSets, and fields.
Extract distribution URLs, media types, checksums, and file patterns for direct data access.
Preview actual dataset records by running the mlcroissant data pipeline.
Get structure graphs of dataset lineage and dependencies.
Read GeoCroissant specification reference documentation and Python API snippets.
Provides access to NASA's VEDA STAC catalog for discovering Earth observation collections and scenes and generating GeoCroissant metadata from them.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@GeoCroissant MCP Serversearch for Sentinel-2 flood scenes near Houston and generate GeoCroissant metadata"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
GeoCroissant MCP Server
The GeoCroissant MCP Server gives Model Context Protocol (MCP) clients access to GeoCroissant, the geospatial extension of MLCommons Croissant.
Through Model Context Protocol (MCP), a client can explore Earth observation
datasets in catalogs and create GeoCroissant ML-Ready Metadata from selected scenes,
validate metadata, inspect dataset structure, and preview records with
mlcroissant.
The server provides current catalog and dataset information. The connected MCP client uses this information to understand the request and choose a suitable catalog and collection.
GeoCroissant workflow
A client can create and explore a GeoCroissant dataset in one workflow:
List the registered STAC catalogs.
Search their current collections and review the most relevant results.
Resolve a place to an EPSG:4326 bounding box when coordinates are not already available.
Count matching scenes before requesting records.
Generate GeoCroissant JSON-LD for the chosen collections, area, dates, and optional cloud-cover limit.
Validate or inspect the resulting metadata and preview its records.
user request
-> select a catalog from list_eo_catalogs
-> find collections with search_eo_datasets
-> inspect candidates with get_eo_dataset_details
-> resolve a place with geocode_place, when needed
-> verify availability with count_eo_scenes
-> generate one source with create_geocroissant_from_stac
or multiple sources with create_geocroissant_from_stac_sources
-> use json_ld and asset_urls in the clientThe result describes the dataset's location, time range, coordinate reference system, raster bands, and available spectral properties. Each selected STAC scene becomes an inline record connected to its source assets.
Remote clients: Generation returns the complete document in json_ld.
A returned path refers to the server's filesystem, so a remote client
should use json_ld when it needs to store the document locally.
Related MCP server: Copernicus Earth Observation MCP Server
MCP tools
Tool | Purpose |
| Return |
| Create GeoCroissant JSON-LD from a STAC search and return the selected source asset URIs. |
| Compose independent searches from any registered catalogs into source-specific RecordSets. |
| Create a GeoCroissant starting point from dataset details and return its validation result. |
| Check a document and return validation errors, warnings, and conformance information. |
| Summarize the dataset, geospatial properties, distributions, RecordSets, and Fields. |
| Show the nodes and relationships in the metadata graph. |
| List RecordSets and their keys, records, examples, and Fields. |
| Read a small, optionally filtered sample from a RecordSet. |
| List distribution URIs, media types, checksums, archive links, and FileSet patterns. |
| Read the GeoCroissant overview, context, properties, example, or Python API reference. |
| List the STAC services in the active YAML configuration. |
| Browse collections from a selected STAC service. |
| Read the provider's details for one collection. |
| Find candidate EPSG:4326 bounding boxes for a place name. |
| Count scenes for the chosen collections, area, dates, and optional cloud-cover limit. |
| Find STAC scenes that match the selected collections and search options. |
Source assets
The generated metadata keeps each selected asset URI in the format published
by its STAC provider, including s3://, https://, and other supported URI
schemes. Clients can then access each source using the connection method and
credentials provided for that service.
Multiple sources
create_geocroissant_from_stac_sources accepts an arbitrary list of explicit
STAC searches. Each source requires catalog_id, collection_id, and an
EPSG:4326 bbox; it can also set source_id, datetime_range,
max_cloud_cover, and limit. Catalog IDs must exist in the active YAML
registry. Sources may use different catalogs or repeat one catalog with
different collections.
{
"name": "Combined observations",
"sources": [
{
"source_id": "source_a",
"catalog_id": "catalog-a",
"collection_id": "collection-a",
"bbox": [-53, -31, -50, -28],
"datetime_range": "2026-08-01/2026-08-25",
"limit": 10
},
{
"source_id": "source_b",
"catalog_id": "catalog-b",
"collection_id": "collection-b",
"bbox": [-53, -31, -50, -28],
"limit": 10
}
]
}The result contains one RecordSet per source, source and catalog provenance, provider-native asset URIs, and per-source search results. It records the selected observations without claiming that sources are spatially, temporally, spectrally, or tensor aligned. Downstream code must apply the dataset-specific access, alignment, and preprocessing required for its model.
Catalog registry
The bundled registry is
src/geocr_mcp_server/config/catalogs.yaml. It currently defines:
earth-search: Element84 Earth Search, the default catalog.veda: NASA Visualization, Exploration, and Data Analysis (VEDA).
Each entry contains an identifier, display name, STAC endpoint, description,
and a collection snapshot. Searches use the provider's current catalog, so
new collections can appear before the snapshot is updated. When catalog_id
is omitted, default_catalog selects the service.
To use another registry, copy the YAML file, add the required catalog entries, and set its absolute path in the server environment:
{
"env": {
"GEOCR_CATALOGS_CONFIG": "/path/to/catalogs.yaml"
}
}No Python change is required. The server checks the configuration when it loads the registry.
Installation
Python 3.10 or newer is required. For an MCP client, uvx can install and run
the server without a manual checkout:
uvx --from "geocr-mcp @ git+https://github.com/HarshShinde0/geocr_mcp.git@main" geocr-mcp-serverTo install the command in the active Python environment:
pip install git+https://github.com/HarshShinde0/geocr_mcp.git@mainThe installation includes the GeoCroissant-enabled mlcroissant dependency.
Docker
docker build -t geocr-mcp-server .
docker run -i --rm geocr-mcp-serverFor streamable HTTP:
docker run -p 8000:8000 geocr-mcp-server \
--transport streamable-http --host 0.0.0.0 --port 8000Client configuration
The clients below use different configuration filenames and remote-server keys. Use the example for your client rather than copying a configuration between clients unchanged.
Configuration references: VS Code, Cursor, Antigravity, Kiro, Claude Code, and OpenCode. Claude Desktop configures remote custom connectors through the Claude account.
VS Code
Use.vscode/mcp.json with the top-level servers key. Hosted servers use
type: "http"; local servers use type: "stdio" with command and args.
Hosted server
Add the hosted streamable HTTP server to .vscode/mcp.json:
{
"servers": {
"geocr-mcp": {
"type": "http",
"url": "https://geocr-mcp-server.onrender.com/mcp"
}
},
"inputs": []
}Local development checkout
Use the local project directory and stdio transport when testing server changes.
For this repository checkout, add the following to .vscode/mcp.json:
{
"servers": {
"geocr-mcp-local": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"${workspaceFolder}/geocr_mcp",
"run",
"geocr-mcp-server"
],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
},
"inputs": []
}When geocr_mcp itself is the workspace root, use ${workspaceFolder} instead.
Do not add the --transport stdio arguments: stdio is already the local default.
Run MCP: List Servers from the Command Palette to inspect the connection and server output.
Cursor
Use.cursor/mcp.json with the top-level mcpServers key. Hosted servers use
url; local servers use type: "stdio" with command and args.
Add project-specific servers to .cursor/mcp.json, or use
~/.cursor/mcp.json to make them available in every project.
Hosted server
{
"mcpServers": {
"geocr-mcp": {
"url": "https://geocr-mcp-server.onrender.com/mcp"
}
}
}Local development checkout
{
"mcpServers": {
"geocr-mcp-local": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"${workspaceFolder}/geocr_mcp",
"run",
"geocr-mcp-server"
],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
}
}When geocr_mcp itself is the project root, use ${workspaceFolder} instead.
Check Customize > MCP for server status, or select MCP Logs in Cursor's
Output panel.
Antigravity
Use.agents/mcp_config.json with the top-level mcpServers key. Hosted
servers must use serverUrl, while local servers use command and args.
Add project-specific servers to .agents/mcp_config.json, or use
~/.gemini/config/mcp_config.json to make them available globally.
Hosted server
Antigravity requires serverUrl for remote servers; url and httpUrl are not
supported.
{
"mcpServers": {
"geocr-mcp": {
"serverUrl": "https://geocr-mcp-server.onrender.com/mcp"
}
}
}Local development checkout
Replace /absolute/path/to/croissant with the path to this repository checkout.
{
"mcpServers": {
"geocr-mcp-local": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/croissant/geocr_mcp",
"run",
"geocr-mcp-server"
],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
}
}Open MCP Servers > Manage MCP Servers in the agent panel to reload the configuration and inspect connection status.
Kiro
Use.kiro/settings/mcp.json with the top-level mcpServers key. Hosted
servers use url; local servers use command and args.
Add project-specific servers to .kiro/settings/mcp.json, or use
~/.kiro/settings/mcp.json to make them available globally.
Hosted server
{
"mcpServers": {
"geocr-mcp": {
"url": "https://geocr-mcp-server.onrender.com/mcp"
}
}
}Local development checkout
Replace /absolute/path/to/croissant with the path to this repository checkout.
{
"mcpServers": {
"geocr-mcp-local": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/croissant/geocr_mcp",
"run",
"geocr-mcp-server"
],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
}
}Kiro reloads the file when it is saved. Check the MCP servers tab in the Kiro panel; connection logs are available under Kiro - MCP Logs in Output.
Claude Code
Use.mcp.json with the top-level mcpServers key. Hosted servers require
type: "http" and url; local servers use type: "stdio".
Add project-specific servers to .mcp.json in the project root.
Hosted server
{
"mcpServers": {
"geocr-mcp": {
"type": "http",
"url": "https://geocr-mcp-server.onrender.com/mcp"
}
}
}The equivalent project-scoped command is:
claude mcp add --transport http --scope project \
geocr-mcp https://geocr-mcp-server.onrender.com/mcpLocal development checkout
{
"mcpServers": {
"geocr-mcp-local": {
"type": "stdio",
"command": "uv",
"args": [
"--directory",
"${CLAUDE_PROJECT_DIR:-.}/geocr_mcp",
"run",
"geocr-mcp-server"
],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
}
}When geocr_mcp itself is the project root, use
${CLAUDE_PROJECT_DIR:-.} instead. Run claude mcp get geocr-mcp or use /mcp
inside Claude Code to verify the connection. Project-scoped servers require
approval when first loaded interactively.
Claude Desktop
Add hosted servers throughCustomize > Connectors. Use
claude_desktop_config.json only for local stdio servers.
For the hosted server, add the endpoint as a custom connector under
Customize > Connectors in Claude; remote connectors are configured through
the Claude account rather than claude_desktop_config.json:
https://geocr-mcp-server.onrender.com/mcpFor a local server, add a stdio entry to claude_desktop_config.json. Replace
/absolute/path/to/croissant with the path to this repository checkout:
{
"mcpServers": {
"geocr-mcp-local": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/croissant/geocr_mcp",
"run",
"geocr-mcp-server"
],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
}
}OpenCode
Useopencode.json in the project root (or ~/.config/opencode/opencode.json
for global scope) with the top-level mcp key — not mcpServers. Hosted
servers require type: "remote" and url; local servers use
type: "local" with a command array and environment.
Hosted server
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"geocr-mcp": {
"type": "remote",
"url": "https://geocr-mcp-server.onrender.com/mcp",
"timeout": 60000
}
}
}The timeout is optional but recommended for the hosted server: free-tier
hosting can cold-start for tens of seconds, exceeding OpenCode's default
5-second timeout.
Local development checkout
Replace /absolute/path/to/croissant with the path to this repository checkout.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"geocr-mcp-local": {
"type": "local",
"command": [
"uv",
"--directory",
"/absolute/path/to/croissant/geocr_mcp",
"run",
"geocr-mcp-server"
],
"environment": {
"FASTMCP_LOG_LEVEL": "ERROR"
}
}
}
}When geocr_mcp itself is the project root, point --directory at ..
Config is loaded once at startup, so quit and restart OpenCode after saving;
verify with opencode mcp list or by using a tool in a prompt.
Hosted server
Start a shared endpoint with the streamable HTTP transport:
geocr-mcp-server \
--transport streamable-http \
--host 0.0.0.0 \
--port "$PORT"The included render.yaml deploys the same command on Render. The current
hosted endpoint is:
https://geocr-mcp-server.onrender.com/mcpUse the client-specific hosted configuration above; remote-server keys are not portable between all clients.
When a reverse proxy provides TLS, bind the server withGEOCR_HOST=0.0.0.0 and set GEOCR_TRANSPORT=streamable-http.
Environment variables
Variable | Default | Purpose |
|
| Set stderr logging to |
| System temporary directory | Choose where generated files are written. Supplied filenames are reduced to their basename. |
| Bundled YAML registry | Load catalog definitions from another YAML file. |
|
| Set the bind address for SSE or streamable HTTP. |
|
| Set the port for SSE or streamable HTTP. |
|
| Select the MCP transport. |
Network and file handling
Catalog searches, scene requests, geocoding, URL inputs, and remote record previews connect to their configured services.
Scene and preview limits help keep requests manageable for large datasets.
Generated files are written inside
GEOCR_OUTPUT_DIR, and output names are reduced to their basename.The provided container runs as a non-root user by default.
Development
From the geocr_mcp directory:
uv venv
uv sync --all-groups
uv run ruff check src tests
uv run python -m pytest --cov --cov-branch
uv run python -m pytest -o addopts='' -m liveThe default test run covers local behavior and the MCP protocol. The live test group connects to Earth Search, NASA VEDA, and Nominatim.
For interactive protocol inspection:
npx @modelcontextprotocol/inspector geocr-mcp-serverAvailable Tools
12 toolscreate_geocroissant_from_stacA
Searches live EO data and generates VALIDATED GeoCroissant metadata from it.
This is the flagship end-to-end pipeline of this server:
1. Runs a real STAC search (bbox + collections + datetime + cloud cover).
2. Derives GeoCroissant properties from the results: schema.org spatial/
temporal coverage, CRS (EPSG:4326), record endpoint, band
configuration and spectral band metadata from `eo:bands`
(micrometers converted to nanometers), distribution FileObjects for
direct asset URLs, and a RecordSet with one inline row per scene.
3. Validates the document through the official `mlcroissant` library
before returning it.
Usage: THE tool for turning discovered EO data into GeoCroissant.
After generation use `inspect_geocroissant`, `get_records_preview`
and `extract_distribution_urls` on the output.
Returns:
--------
Dictionary containing:
- valid/errors/warnings: mlcroissant validation outcome.
- json_ld: The generated GeoCroissant document.
- path: Output file path when output_filename was given.
- search_summary: What was searched and how many scenes matched.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | Yes | Bounding box as [min_lon, min_lat, max_lon, max_lat]. | |
| name | Yes | Name for the generated dataset. | |
| limit | No | Number of scenes to include (1-50). | |
| license | No | License URL. | |
| creators | No | Creator names. | |
| modality | No | Modality used to pick default collections. | |
| collections | No | Explicit STAC collection ids. | |
| description | No | Description of the generated dataset. | |
| datetime_range | No | STAC datetime interval. | |
| max_cloud_cover | No | Max cloud cover percentage. | |
| output_filename | No | When provided, writes the validated JSON-LD into GEOCR_OUTPUT_DIR (or temp dir) and returns the path. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It openly discloses that this runs a real STAC search, derives specific metadata properties, validates through mlcroissant, returns a structured dictionary, and optionally writes to a file when output_filename is provided. This is far more than generic 'creates metadata' and gives the agent a reliable model of side effects and outcomes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than typical, but it deserves the length: a high-level summary, numbered pipeline steps, usage guidance, and a structured returns breakdown. It is scannable and avoids filler. The only minor issue is some near-duplication between the numbered pipeline and the Returns section, but overall the structure earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity with 11 parameters, no annotations, and a rich transformation pipeline, the description covers the key decision-relevant context: input search criteria, output validation, the return dictionary shape, and follow-up tool recommendations. Nothing critical is missing for an agent to decide to call it and interpret the result correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers every parameter with 100% description coverage, including defaults, ranges, and types. The tool description contributes little parameter-specific semantics beyond grouping bbox, collections, datetime, and cloud cover as search criteria, and mentioning output_filename in the return path. This meets the baseline but does not add substantial new parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Searches live EO data and generates VALIDATED GeoCroissant metadata from it.' It distinguishes itself from sibling tools by framing itself as the flagship end-to-end pipeline and naming follow-up inspection tools rather than other generators. This gives an agent a clear, unambiguous understanding of what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states this is the tool for turning discovered EO data into GeoCroissant and suggests follow-up sibling tools to use after generation. It does not explicitly contrast with create_geocroissant_scaffold or list search-only siblings, so no exclusionary guidance is given, but the context of when to invoke it is sufficiently clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_geocroissant_scaffoldA
Generates a validated GeoCroissant JSON-LD scaffold from parameters.
Produces a standards-conformant starting point modeled on the official
GeoCroissant example: correct @context (including the `geocr` prefix),
dual conformance (`croissant/1.1` + `geocr`), schema.org spatial/temporal
coverage, GeoCroissant properties (CRS, resolutions, band configuration,
spectral bands), distribution entries and a RecordSet wired to them via
proper cr:source/cr:extract declarations.
The generated document is then parsed and checked by the real
``mlcroissant`` validator, so `valid=True` means the scaffold already
passes the official library checks.
Usage: Call FIRST when creating new dataset metadata, then edit the
returned JSON-LD for domain specifics and re-check with
`validate_croissant`. Use `inspect_geocroissant` afterwards to review it.
Returns:
--------
ScaffoldResult containing:
- valid: Whether the scaffold passed mlcroissant validation.
- json_ld: The generated document.
- errors/warnings: Library messages when not fully clean.
- path: Output file path when output_filename was given.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | Spatial coverage as [min_lon, min_lat, max_lon, max_lat] in EPSG:4326 (standard GIS order). | |
| name | Yes | Name of the dataset. | |
| license | No | License URL, preferably SPDX, e.g. "https://creativecommons.org/licenses/by/4.0/". | |
| version | No | Dataset version, e.g. "1.0". | |
| creators | No | Creator names (rendered as sc:Organization entries). | |
| file_sets | No | List of FileSet specs: {"id": "images", "name": "Images", "encoding_format": "image/tiff", "includes": "images/**/*.tif"}. | |
| band_names | No | Ordered raster band names, e.g. ["Blue","Green","Red","NIR"]. | |
| field_name | No | Name of the main data Field inside the RecordSet. | data |
| description | No | Description of the dataset. | |
| file_objects | No | List of FileObject specs: {"id": "data.zip", "name": "data.zip", "content_url": "https://...", "encoding_format": "application/zip", "sha256": "...", "md5": "..."}. | |
| date_published | No | Publication date as YYYY-MM-DD. | |
| field_is_array | No | Whether the main Field is an array (raster/tensor). | |
| spectral_bands | No | Per-band spectral metadata entries like {"name": "Blue", "centerWavelength": {"value": 490, "unitText": "nm"}, "bandwidth": {...}}. | |
| field_data_type | No | Field dataType, e.g. "sc:ImageObject", "sc:Text", "sc:URL". | sc:ImageObject |
| output_filename | No | When provided, writes the validated JSON-LD to this filename inside GEOCR_OUTPUT_DIR (or the system temp dir) and returns the path. | |
| record_set_name | No | Name/@id of the scaffolded RecordSet. | records |
| field_array_shape | No | Array shape as comma-separated dims, e.g. "512,512,6" (requires field_is_array=True). | |
| temporal_coverage | No | Temporal coverage interval, e.g. "2018-01-01/2021-12-31". | |
| source_file_set_id | No | @id of the FileSet/FileObject the main Field reads from. Defaults to the first declared distribution entry. | |
| spatial_resolution | No | Ground sampling distance value (with unit below). | |
| record_set_description | No | Description of the scaffolded RecordSet. | |
| spatial_resolution_unit | No | Unit for spatial_resolution, e.g. "m". | m |
| temporal_resolution_unit | No | Unit for temporal cadence, e.g. "days". | days |
| temporal_resolution_value | No | Revisit cadence value (with unit below). | |
| coordinate_reference_system | No | CRS identifier, e.g. "EPSG:4326". |
Output Schema
| Name | Required | Description |
|---|---|---|
| path | No | File path when the scaffold was written to disk. |
| valid | Yes | Whether the generated JSON-LD passes mlcroissant validation. |
| errors | No | Validation errors on the generated file. |
| json_ld | Yes | The generated JSON-LD document. |
| warnings | No | Validation warnings on the generated file. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries full responsibility, and it delivers: it explains the scaffold passes mlcroissant validation, what valid=True means, that errors/warnings may be returned when not fully clean, and that an output file path is provided when output_filename is used. This is more than what annotations alone would have provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear purpose, detail section, usage instruction, and Returns list. It is somewhat long, and the Returns section overlaps with the existing output schema, so a small amount of redundancy prevents a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a highly parameterized tool with 25 parameters, the description is complete: it explains the generation workflow, validation guarantees, how to continue after creation, what the result contains, and the optional file-writing side effect. An agent has enough context to call and use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 25 parameters have schema descriptions, so the input schema already carries most semantic weight. The tool description adds context about how parameters map into the generated JSON-LD (CRS, resolutions, bands, RecordSet wiring), but it does not explain individual parameters beyond the schema. This matches the baseline for a schema with complete coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Generates a validated GeoCroissant JSON-LD scaffold from parameters.' It clearly differentiates from the STAC-based sibling by emphasizing 'from parameters' and stating the output is modeled on the official GeoCroissant example and validated by mlcroissant.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear workflow: call this first when creating new dataset metadata, then edit the scaffold and re-check with validate_croissant, and review with inspect_geocroissant. However, it does not explicitly mention the main alternative sibling create_geocroissant_from_stac or state when someone should use that instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_distribution_urlsA
Extracts downloadable URLs from a Croissant document's distribution.
Collects the `contentUrl` of every FileObject together with its encoding
formats, sizes and checksums, plus FileSet include patterns and archive
containers. These are the direct access points for the dataset bytes.
Usage: Use this tool to obtain concrete download links (e.g. GeoTIFF /
COG / ZIP assets) for ingestion code without parsing the JSON manually.
Returns:
--------
DistributionUrls containing:
- urls: One entry per distribution item (name, type, contentUrl,
encodingFormat, md5/sha256, includes/containedIn when present).
- count: Number of distribution items with at least one URL.
| Name | Required | Description | Default |
|---|---|---|---|
| jsonld_url | No | URL of a Croissant/GeoCroissant JSON-LD document. | |
| jsonld_path | No | Path to a local Croissant/GeoCroissant file. | |
| jsonld_content | No | Raw JSON string of a Croissant document. |
Output Schema
| Name | Required | Description |
|---|---|---|
| urls | Yes | One entry per FileObject/FileSet: name, contentUrl(s), encodingFormat and hashes when declared. |
| count | Yes | Number of distribution entries with URLs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility. It thoroughly explains what is extracted, the output structure, and the count semantics. Potential error conditions or network behavior are not mentioned, but for a pure extraction tool this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a one-sentence purpose, followed by a compact extraction details list, a usage note, and a structured return section. There is slight redundancy between 'downloadable URLs' and 'contentUrl', but every block adds useful context without excessive length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given three optional parameters and a defined output schema, the description provides all necessary context: the purpose of starting extraction, a compressed return value structure, and number of items. An agent can correctly invoke the tool with any of the three compatible input sources and interpret the output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All three input parameters (jsonld_url, jsonld_path, jsonld_content) already have descriptions in the schema, so schema coverage is 100%. The description does not add parameter-specific guidance; however, since the schema handles that, the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-object pair ('Extracts downloadable URLs from a Croissant document's distribution') and enumerates the exact data captured: contentUrl per FileObject, encoding formats, sizes, checksums, FileSet includes patterns. This fully differentiates it from sibling tools like inspect_geocroissant or get_structure_graph, which handle different aspects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Usage' sentence clearly states when to invoke this tool: to obtain concrete download links (e.g., GeoTIFF/COG/ZIP) for ingestion code without parsing the JSON manually. It does not explicitly list exclusions or alternative tools, but the primary use case is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_geocroissant_spec_referenceA
Returns the GeoCroissant specification reference documentation.
Provides the vocabulary cheat sheet distilled from the official GeoCroissant
specification: namespace IRIs and prefixes, conformance declarations, every
`geocr:` property with expected types/domains/cardinality, the canonical
JSON-LD @context, a full sample document, and Python snippets for the
``mlcroissant`` API (load, validate, iterate records).
Usage: Read this ONCE before authoring or editing GeoCroissant documents so
property names, types and cardinalities match the specification exactly.
Then use `create_geocroissant_scaffold` and `validate_croissant`.
Returns:
--------
Markdown-formatted reference documentation for the requested topic.
| Name | Required | Description | Default |
|---|---|---|---|
| topic | No | Which part of the specification to return. One of: "overview", "context" (@context snippet), "properties" (all geocr properties), "example" (full sample document), "python-api" (mlcroissant usage snippets), "all" (everything). | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. It clearly states the tool returns Markdown-formatted reference documentation and implies read-only behavior with 'Returns' and 'Read this once'. It does not explicitly state that it has no side effects, but nothing suggests mutation or external changes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but not bloated; the opening sentence states the primary purpose, followed by a useful content breakdown and a 'Usage' section. The RETURN section is a little redundant with the first line, but every part contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only documentation tool, the description provides enough detail: what to expect, what is included, when to use it, and what follows. An output schema is present, and the description already covers the return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single 'topic' parameter is fully documented in the schema with all of the valid options described. The description adds no information beyond the schema, so it meets but does not exceed the baseline for a fully covered parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Returns the GeoCroissant specification reference documentation'. It then details exactly what the documentation contains (properties, domains, cardinalities, JSON-LD context, sample, Python snippets), which fully distinguishes this from authoring, validation, and inspection siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit context: 'Read this ONCE before authoring or editing GeoCroissant documents' and then directs the agent to create_geocroissant_scaffold and validate_croissant. It does not strongly contrast with inspecting or searching tools, but it clearly places the reference tool in a workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_records_previewA
Materializes the first records of a RecordSet by executing the data pipeline.
This tool runs the real ``mlcroissant`` operation graph: it downloads (or
resolves locally) the declared FileObjects/FileSets, applies extracts and
transforms, and yields actual records - exactly what
``Dataset.records(record_set)`` yields in Python.
Usage: Use it to preview/sample a dataset's actual data before writing
training code, or to sanity-check that a generated Croissant description
produces the expected columns and values.
IMPORTANT: For remote distributions this may download data; keep `limit`
small on large datasets. Datasets with inline `cr:data` return those rows
directly without downloads.
Returns:
--------
RecordsPreview containing:
- record_set: The RecordSet @id that was read.
- columns: Column names found across returned records.
- rows: List of records keyed by fully-qualified field ids.
- truncated: True if more records exist beyond `limit`.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of records to return (1-100). | |
| filters | No | Optional single-entry filter {field_id: value}, e.g. {"my_recordset/split": "train"} (only supported for fields extracted via regex transformations). | |
| jsonld_url | No | URL of a Croissant/GeoCroissant JSON-LD document. | |
| record_set | Yes | The @id of the RecordSet to read (see `list_record_sets` for available ids). | |
| jsonld_path | No | Path to a local Croissant/GeoCroissant file. | |
| jsonld_content | No | Raw JSON string of a Croissant document. |
Output Schema
| Name | Required | Description |
|---|---|---|
| rows | Yes | The materialized records. |
| columns | Yes | Column names found across the records. |
| truncated | Yes | True when more records exist beyond the requested limit. |
| record_set | Yes | The RecordSet @id records were read from. |
| num_records | Yes | Number of records actually returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and handles it well. It discloses that the tool downloads or resolves FileObjects/FileSets, applies extracts and transforms, may download data for remote distributions, and that inline 'cr:data' rows are returned directly without downloads. It also explains the 'truncated' flag behavior, which is genuinely non-obvious execution context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core function. The Returns section duplicates some information likely provided by the documented output schema, but each section earns its place, and the page's important warning is clearly separated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for this tool's complexity: it names the necessary input record_set, describes the materialization pipeline, covers download side effects, directs users to 'list_record_sets' for IDs, and describes the outputs. The presence of an output schema reduces the burden of restating return types, and what the description adds — pipelining, download warnings, truncation — is exactly the contextual content an agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All 6 parameters are already documented in the input schema with 100% schema description coverage, so the description does not need to re-explain them. It adds practical parameter guidance for 'limit' ('keep `limit` small on large datasets'), and it indirectly reinforces the 'record_set' parameter via the return description, but it does not add substantial new parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it "Materializes the first records of a RecordSet by executing the data pipeline." It also clarifies that this yields actual data, equivalent to 'Dataset.records(record_set)', and is not just metadata inspection — distinguishing it from sibling tools like list_record_sets.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives concrete use cases: 'preview/sample a dataset's actual data before writing training code' and 'sanity-check that a generated Croissant description produces the expected columns and values.' It does not explicitly name alternative tools to avoid, but it clearly implies this is the data-content tool rather than structure/validation/list tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_structure_graphA
Extracts the internal structure graph of a Croissant document.
Builds the directed multigraph that ``mlcroissant`` uses internally for
static analysis: nodes are Metadata / FileObject / FileSet / RecordSet /
Field objects and edges connect fields to their data sources, record sets
to their fields, files to archives they are contained in, and referenced
(foreign-key) fields.
Usage: Use this tool to reason about dataset lineage and dependencies,
e.g. "which files feed this field?", "what does this join look like?",
or to explain a dataset's architecture before writing loading code.
Returns:
--------
StructureGraph containing:
- nodes: Every node with @id, type, name and parent @id.
- edges: Directed edges as {source, target} @id pairs.
| Name | Required | Description | Default |
|---|---|---|---|
| jsonld_url | No | URL of a Croissant/GeoCroissant JSON-LD document. | |
| jsonld_path | No | Path to a local Croissant/GeoCroissant file. | |
| jsonld_content | No | Raw JSON string of a Croissant document. |
Output Schema
| Name | Required | Description |
|---|---|---|
| edges | Yes | Directed edges (source @id -> target @id). |
| nodes | Yes | Graph nodes with @id, type and parent information. |
| edge_count | Yes | Number of edges in the graph. |
| node_count | Yes | Number of nodes in the graph. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden. It clearly explains what graph is built, what nodes and edges represent, and that it's the internal mlcroissant representation. This is sufficient for a read-only analysis tool, though it does not discuss failure modes or source-selection behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose, then detail, usage context, and return information. The Returns section is slightly redundant with the existing output schema, and the text is a bit long for what it conveys; but it earns its place by explaining the graph's internal semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no required parameters and an output schema, plus the description fully conveys the returned graph structure and usage context. The main gap is that three possible input sources are not explained as alternatives or prioritized, which is important for a tool that can take a URL, a path, or raw content.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all three parameters (jsonld_url, jsonld_path, jsonld_content) with 100% coverage. The description adds no parameter-specific guidance beyond the schema. It could have clarified that the three inputs are presumably alternative sources and whether exactly one is required, but it is not required at baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Extracts the internal structure graph of a Croissant document.' It further details the node and edge types, which clearly distinguishes this static-analysis/lineage tool from siblings like validate_croissant or get_records_preview.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool: reason about dataset lineage and dependencies, explain architecture before writing loading code, and answers questions like 'which files feed this field?' It provides clear context but does not name alternatives or exclusion conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_geocroissantA
Inspects a Croissant/GeoCroissant document and returns a structured summary.
Parses the document through the ``mlcroissant`` library (which also acts as
a strict syntax/schema check - invalid documents are rejected) and returns
a structured digest: core metadata, GeoCroissant extension properties
(CRS, resolutions, band configuration, spectral bands, record endpoint...),
distribution entries (FileObjects/FileSets with URLs, formats, hashes),
and every RecordSet with its Fields (data types, array shapes,
source/extract/transform chains).
Usage: Use this tool to READ and UNDERSTAND a dataset description before
consuming it, comparing datasets, or planning how to load records.
Returns:
--------
Dictionary containing:
- name/description/license/version/conformsTo and other core metadata.
- geospatial: All declared `geocr:` extension properties.
- distribution: FileObject/FileSet entries.
- record_sets: RecordSets with nested fields and geo properties.
| Name | Required | Description | Default |
|---|---|---|---|
| jsonld_url | No | URL of a Croissant/GeoCroissant JSON-LD document. | |
| jsonld_path | No | Path to a local Croissant/GeoCroissant file. | |
| jsonld_content | No | Raw JSON string of a Croissant document. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses an important behavioral trait beyond the annotations: it will reject invalid documents via strict syntax/schema check, which is critical for an agent to know. It also details what content will be returned (core metadata, geo extension properties, distributions, record sets, fields, etc.). Since annotations are absent, the description carries the burden, and it does an above-baseline job by describing the validation side effect and return shape, though it could be even richer about error handling and conflicts among the input parameters.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well structured with clear sections: the core purpose in the first line, the implementation detail in the next, an explicit 'Usage' block, and a 'Returns' section with a bulleted list. Every sentence earns its place and covers the key behavioral aspects. Front-loading is good: an agent can quickly answer 'What does this do?' and 'When do I call it?'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete given the tool complexity: an inspection tool with three mutually-exclusive inputs and a rich output that is fully described. It even goes slightly beyond the call by describing the return dictionary structure, which combines well with the output schema already present. The only limitation is param precedence, but that is a minor gap and the overall context is fully sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (all three parameters have descriptions: 'URL', 'Path', 'Raw JSON string'), so the baseline is 3. The description itself does not add much insight about parameter precedence or how to choose among the three parameters when multiple are provided, which is a meaningful gap an agent would face. It relies on the schema, which is adequate but not enhanced.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Inspects a Croissant/GeoCroissant document') and distinguishes it from siblings like validate_croissant, create_geocroissant_from_stac, and get_records_preview, which have different purposes. The mention of mlcroissant and 'strict syntax/schema check' and the structured return digest make the scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names when to use this tool ('to READ and UNDERSTAND a dataset description before consuming it, comparing datasets, or planning how to load records'). It doesn't list exclusions, but the ' 'Usage' sentence plus the sibling context provides clear enough guidance for an agent to select it over the alternative creation/validation/search tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_eo_catalogsA
Lists the Earth observation STAC catalogs registered on this server.
The registry is data-driven (config/catalogs.yaml): today it contains
Element84 Earth Search over AWS Open Data
(https://earth-search.aws.element84.com/v1) with its searchable
modalities, curated collections and topic keywords.
Usage: Call once to see where EO data can be discovered from before
using `search_eo_datasets` / `search_eo_scenes`.
Returns:
--------
Dictionary containing:
- catalogs: Registered catalogs with id, name, URL, description,
modalities, common collections and supported topics.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explains that the registry is data-driven via config/catalogs.yaml, names the current catalog and contents, and specifies the returned dictionary structure. For a read-only, no-argument list operation, this is strong transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence states the purpose immediately, and the 'Usage' and 'Returns' sections provide practical, scannable guidance. The listing of catalog contents is slightly redundant with the Returns section but not excessive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple zero-argument tool, and the description covers its trigger, output, and relationship to following search steps. There are no missing details that would prevent an agent from selecting or invoking it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the description has no parameter semantics to add. The baseline for zero-parameter tools is 4, and the description appropriately focuses on what the output represents instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Lists the Earth observation STAC catalogs registered on this server.' It also distinguishes itself from sibling search tools by stating this is the discovery step before using search_eo_datasets / search_eo_scenes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Call once to see where EO data can be discovered from before using search_eo_datasets / search_eo_scenes.' This gives clear sequencing and routing, making it obvious when this tool should be selected over its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_record_setsA
Lists the RecordSets of a Croissant/GeoCroissant document.
A RecordSet is a collection of records (rows/examples) produced by
applying the declared extraction pipeline to the distribution. This tool
returns each RecordSet's @id, name, description, key fields, enumeration
flag, number of inline records/examples and its Fields with their data
types and source chains.
Usage: Call this tool to discover what data a dataset exposes and which
RecordSet names to pass to `get_records_preview`.
Returns:
--------
List of dictionaries, one per RecordSet, each including:
- @id: The RecordSet identifier used by other tools.
- fields: Nested field summaries (dataType, isArray/arrayShape,
source extract/transform chain, geo band properties).
| Name | Required | Description | Default |
|---|---|---|---|
| jsonld_url | No | URL of a Croissant/GeoCroissant JSON-LD document. | |
| jsonld_path | No | Path to a local Croissant/GeoCroissant file. | |
| jsonld_content | No | Raw JSON string of a Croissant document. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the transparency burden. It unambiguously describes a read-only listing operation and enumerates exactly what is returned, including field data types and source chains. There is no misleading mutation or side-effect language; the non-destructive behavior is implicit but clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear purpose first, a helpful definition of RecordSet, and an explicit Usage note. There is some redundancy between the earlier sentence enumerating returned fields and the final Returns list, but overall the structure is logical and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's purpose, output, and relationship to `get_records_preview`, but it does not explain how to provide the input: whether one of `jsonld_url`, `jsonld_path`, or `jsonld_content` is required and whether exactly one should be supplied. Since the tool has three optional-looking inputs, this is a notable gap for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input parameters are already fully documented. The description adds no extra detail about how to choose between `jsonld_url`, `jsonld_path`, and `jsonld_content`, making this a baseline 3 rather than a higher score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists RecordSets in a Croissant/GeoCroissant document and defines what a RecordSet is. It also distinguishes this tool by noting that it returns high-level dataset structure rather than the actual record data, and explicitly points to `get_records_preview` as the next step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: call this tool to discover which RecordSet names to pass to `get_records_preview`. It does not contrast against every sibling tool, but it establishes a clear entry point in the workflow and implies this is the discovery/listing step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_eo_datasetsA
Searches Earth observation DATASETS (STAC collections) by keyword.
Performs collection-level search on the Earth Search STAC API
(AWS Open Data). Queries hit the topics map first ('flood' -> Sentinel-1
+ Sentinel-2, 'dem' -> Copernicus DEM...), then fall back to keyword
matching against live collection metadata; every hit is classified by
sensor modality (optical / radar / elevation).
Usage: Start here for dataset-level discovery ("find me flood/burn
scar/terrain datasets"). Then use the returned collection ids with
`search_eo_scenes`, or jump straight to `create_geocroissant_from_stac`
to get GeoCroissant metadata.
Returns:
--------
Dictionary containing:
- matched_topics: Topic-map hits for the query.
- count: Number of matching collections found.
- collections: Matches with catalog, collection id, title,
description snippet, modality, license and temporal extent.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Free-text query. Topics like 'flood', 'wildfire', 'ndvi', 'urban' resolve to curated collections; other words keyword-match collection metadata. Empty lists all. | |
| modality | No | Filter by sensor modality: optical | radar | elevation. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full transparency burden. It discloses the two-stage behavior: 'Queries hit the topics map first ... then fall back to keyword matching against live collection metadata'. It also states that 'every hit is classified by sensor modality' and lists the returned dictionary content, giving the agent a clear moidal picture of what will happen after invoking the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the core behavior, then organized into usage guidance and a return block with no repeated information. Each section earns its place, and code-styled references keep the text scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a search-only tool with two optional parameters, an output schema, and clear sibling routing, the description is complete. It states scope, how the query is interpreted, return fields, and recommended follow-up siblings. Missing details such as pagination or error handling are not needed for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema covers the parameters at 100%, so the baseline is 3. The description adds meaningful semantic context beyond the schema: it explains the query flows through a topics map and then keyword matching, and that every result is modality-annotated. This complements the schema's free-text and modality descriptions rather than merely repacing them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb and resource: 'Searches Earth observation DATASETS (STAC collections) by keyword' and clarifies it is a 'collection-level search' on the Earth Search STAC API. It also names the sibling operation `search_eo_scenes` and distinguishes dataset-level discovery from scene-level discovery, making this tool's scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to start here: 'Start here for dataet-level discovery'. It then guides next actions: 'Then use the returned collection ids with search_eo_scenes, or jump staraight to create_geocroissant_from_stac'. This gives clear context for when to use this tool versus its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_eo_scenesA
Searches satellite SCENES inside a bounding box on Earth Search.
Executes a real STAC item search (pystac-client) against
https://earth-search.aws.element84.com/v1 filtered by spatial extent,
time range and cloud cover. Scenes are the individual acquisitions
(tiles/granules) that become records of a GeoCroissant dataset.
Usage: Use after `search_eo_datasets` (or directly with known
collections) to check actual data availability for an area of interest.
Feed promising results into `create_geocroissant_from_stac`.
Returns:
--------
Dictionary containing:
- scene_count and scenes: Per-scene id, collection, acquisition
datetime, platform, cloud cover, native EPSG and asset keys.
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | Yes | Bounding box as [min_lon, min_lat, max_lon, max_lat]. | |
| limit | No | Max scenes returned (1-50). | |
| modality | No | Modality used to pick default collections. | |
| collections | No | Explicit STAC collection ids. Defaults to curated collections for the chosen modality. | |
| datetime_range | No | STAC datetime interval, e.g. "2023-06-01/2023-09-30". | |
| max_cloud_cover | No | Maximum eo:cloud_cover percentage for optical scenes (ignored when None). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It transparently states it executes a real STAC item search via pystac-client against the Earth Search endpoint and lists the filtering by spatial, temporal, and cloud-cover criteria. It also summarizes the return payload. It does not fully detail error cases or rate limits, but for a read-only search tool these are minor gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and efficiently front-loads the purpose, then usage context, and then return format. Each sentence adds value, with no repeated schema details or fluff. The Usage and Returns sections make it easy for an agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and all six parameters are documented in the input schema, this description provides sufficient high-level context. It explains what the tool does, the external service it reads, the intended workflow position, and the fields in the result. Nothing critical for selection or invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds limited value for parameter semantics but does map the filter concepts (spatial extent, time range, cloud cover) to the overall API behavior and mentions the curated default collections via 'modality'. It doesn't enrich individual parameter fields beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the operation ('Searches satellite SCENES inside a bounding box'), identifies the resource ('satellite scenes' vs datasets), and clarifies context by distinguishing them as individual acquisitions. It separates itself from sibling search_eo_datasets and routes to the create_geocroissant_from_stac.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly places the tool in a workflow: 'Use after search_eo_datasets ... to check actual data availability' and 'Feed promising results into create_geocroissant_from_stac'. This tells the agent when to use it and points to the related data availability tool, giving clear when/when-not context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_croissantA
Validates a Croissant or GeoCroissant JSON-LD document.
Runs the official MLCommons ``mlcroissant`` validator: JSON syntax check,
JSON-LD expansion, structure-graph construction (FileObjects/FileSets,
RecordSets, Fields, sources & joins) and full schema conformance checks.
Usage: Call this tool whenever a dataset description is created or edited,
BEFORE publishing it, and after any modification of an existing file.
Works for both plain Croissant documents and documents using the
GeoCroissant extension (`geocr:` properties).
Returns:
--------
Dictionary containing:
- valid: True when the document passes validation.
- errors: Blocking errors reported by the library (empty when valid).
- warnings: Non-blocking recommendations (e.g. missing license).
- is_geospatial: Whether GeoCroissant conformance is declared.
- conforms_to / dataset_name: Extracted metadata when loadable.
| Name | Required | Description | Default |
|---|---|---|---|
| jsonld_url | No | URL of a Croissant/GeoCroissant JSON-LD document. | |
| jsonld_path | No | Path to a local Croissant/GeoCroissant JSON(-LD) file. | |
| jsonld_content | No | Raw JSON string of a Croissant/GeoCroissant document. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full behavioral burden and it succeeds: it discloses delegation to the official MLCommons validator, the specific checks performed, support for the GeoCroissant extension, and the exact shape of the returned dictionary including errors vs. warnings. No behavior is hidden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The structure is logical and front-loaded: purpose, validation steps, usage timing, supported variants, then return values as a bulleted list. It is thorough but not padded; the only minor redundancy is the validation-steps list being slightly over-explained, which prevents a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a validation tool with three well-documented inputs and a documented output dictionary, the description is complete: it covers when to call, what is validated, which document variants are supported, and what will be returned. The provided output schema further reduces the need for the description to explain return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage with clear per-parameter explanations for jsonld_url, jsonld_path, and jsonld_content. The tool description adds no additional parameter-level meaning, such as interaction between them or whether exactly one must be provided, so it stays at the high-coverage baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with the specific verb+resource combination 'Validates a Croissant or GeoCroissant JSON-LD document' and enumerates the full validation pipeline (JSON syntax, JSON-LD expansion, structure-graph construction, schema conformance). This clearly distinguishes the tool from the sibling creation, search, and inspection tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage triggers: call it whenever the dataset description is created or edited, BEFORE publishing, and after any modification of an existing file. It does not name when-not-to-use cases or explicitly route to an alternative tool, which keeps it short of a full usage-and-exclusion statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v1.0.0- First observed
create_geocroissant_from_stac - First observed
create_geocroissant_scaffold - First observed
extract_distribution_urls - First observed
get_geocroissant_spec_reference - First observed
get_records_preview - First observed
get_structure_graph - First observed
inspect_geocroissant - First observed
list_eo_catalogs - First observed
list_record_sets - First observed
search_eo_datasets - First observed
search_eo_scenes - First observed
validate_croissant
TDQS
Scored across 12 tools
The main workflow stages are clearly separated: discovery tools distinguish catalogs, datasets, and scenes, while generation tools differ by their input source. There is some overlap among the inspection tools—inspect_geocroissant already reports RecordSets and distribution entries, making list_record_sets and extract_distribution_urls partially redundant—but the descriptions are detailed enough to guide selection.
All tool names follow a consistent snake_case verb_noun pattern: list, search, create, validate, inspect, get, and extract are used predictably. The naming also preserves resource hierarchy clearly, from catalogs to datasets to scenes, which helps agents infer relationships between tools.
Twelve tools is an appropriate size for this domain: a few discovery tools, two generation paths, one validator, and several inspection/preview/extraction utilities. The count supports the full workflow without bloating the surface or feeling thin.
The toolset covers the full lifecycle: EO catalog/dataset/scene discovery, GeoCroissant creation from live STAC data or manual parameters, validation, structured inspection, record-set preview, and distribution URL extraction. There are no obvious dead ends because outputs from generation flow naturally into the validation and inspection tools.
Maintenance
Related MCP Connectors
Search dynamical.org's open STAC catalog of weather & climate datasets (GFS, ECMWF, HRRR).
Discover, verify, and access NASA Earth science datasets via the Common Metadata Repository (CMR)
Search, sample and query open reproducible datasets published as immutable Parquet with schemas.
Search public Australian environmental evidence with provenance across authoritative catalogues.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables AI assistants to search and access geospatial datasets through STAC (SpatioTemporal Asset Catalog) APIs. Supports querying satellite imagery, weather data, and other geospatial assets with spatial, temporal, and attribute filters.1113MIT
- AlicenseBqualityDmaintenanceProvides tools to search, download, and manage satellite imagery from all Copernicus Sentinel missions via the Copernicus Data Space ecosystem. It enables advanced geospatial queries, temporal coverage analysis, and automated data management for Earth observation tasks.135LGPL 3.0
- FlicenseAqualityDmaintenanceProvides access to the OpenLandMap STAC catalog, offering over 100 global environmental datasets including soil, climate, and vegetation data. It enables AI agents to discover, search, and retrieve Cloud-Optimized GeoTIFFs for global geospatial analysis.27-
- AlicenseNot gradedqualityDmaintenanceProvides geospatial data intelligence tools for inspecting, querying, and converting geospatial data using DuckDB Spatial.1MIT