Skip to main content
Glama
geolens-io

geolens-mcp

Official

English · Español · Français · Deutsch · 简体中文

Latest release CI status License: Apache-2.0 OpenSSF Scorecard

GeoLens is for teams whose spatial data is spread across file shares, PostGIS databases, web services and STAC catalogs. It puts that data in one searchable catalog, records where each dataset came from and checks whether the source is still current. Teams build and share maps in the browser, and QGIS, scripts and AI agents read the same data through OGC API and STAC. It runs on your own servers with Docker Compose, sends no telemetry and is licensed under Apache 2.0.

The demo needs no install or account; sign in with Google, GitHub or Microsoft to use the map builder. Demo data may be wiped at any time.

A closer look

Related MCP server: FastAPI Database MCP Server

How it fits together

flowchart LR
    subgraph IN ["Bring data in"]
      F["Files<br/>GeoPackage · Shapefile · GeoParquet<br/>GeoTIFF · COPC · 3D Tiles"]
      DB["Existing PostGIS tables"]
      SVC["Services<br/>ArcGIS · WFS · OGC API Features"]
      ST["Remote STAC assets"]
    end
    subgraph GL ["GeoLens"]
      CAT["Catalog<br/>search · metadata · provenance"]
      MB["Map builder<br/>styles · 3D · analysis · sharing"]
      STD["Open APIs<br/>OGC API · STAC · DCAT · tiles"]
    end
    subgraph OUT ["Use it anywhere"]
      WEB["Browsers and embeds"]
      GIS["QGIS · ArcGIS · CesiumJS"]
      CODE["curl · Python · TypeScript · DuckDB"]
      AG["AI agents via MCP"]
    end
    F & DB & SVC & ST --> CAT
    CAT --> MB --> WEB
    CAT --> STD --> GIS & CODE & AG

One catalog for scattered data

  • Upload Shapefile, GeoPackage, GeoJSON, GeoParquet, FlatGeobuf, KML/KMZ, zipped File Geodatabase, CSV, Excel or GeoTIFF (converted to Cloud-Optimized GeoTIFF). 3D Tiles and COPC point clouds are hosted for CesiumJS, QGIS and Potree.

  • Serve tables already in GeoLens's PostGIS database in place, import WFS, ArcGIS and OGC API Features layers and refresh them on demand, or reference remote STAC assets without copying them.

  • Draw new datasets in the browser.

  • Find data with fuzzy search, or by meaning once an embedding provider is configured. Filter by type, place and time, group datasets into collections, edit metadata and restore a dataset's previous version after a replacement.

Know where every dataset came from

Each dataset records where it came from: an uploaded file, a database table, a service, a STAC item or a drawing in the browser. Imported datasets also record when they were last refreshed, and with an update cadence GeoLens marks them fresh, due or overdue. For services and STAC sources, GeoLens also checks that the source still answers, and for services it flags upstream schema changes before they reach your maps. If a service disappears, the imported copy keeps working.

Build and share maps

  • Point, symbol, heatmap, cluster, line, arrow, fill, 3D extrusion, raster and hillshade layers, with data-driven styles, labels, icons, patterns, filters and popups. Terrain comes from your own elevation models.

  • Buffer, centroid, clip, dissolve, spatial join, select by location, measure and intersect. Most operations preview on the map, and each result is saved as a new dataset, from the builder or the CLI.

  • Public links show the map's title and image when pasted into Slack, Teams or social posts, and maps embed in other sites with private tokens.

  • The interface is in English, Spanish, French, German and Simplified Chinese.

Use the data from anywhere

Vector datasets are OGC API Features collections, the catalog is OGC API Records and STAC, and every layer has a tile URL. You can try this against the demo without an account (the second command needs jq):

# Search the catalog (OGC API Records)
curl "https://demo.getgeolens.com/api/collections/datasets/items?q=volcanic%20eruptions"

# Read the top match with a CQL2 filter (OGC API Features): eruptions of VEI 6 or larger
ID=$(curl -s "https://demo.getgeolens.com/api/collections/datasets/items?q=volcanic%20eruptions&limit=1" | jq -r '.features[0].id')
curl -G "https://demo.getgeolens.com/api/collections/$ID/items" \
  --data-urlencode "filter=vei >= 6" -d limit=3

QGIS adds the same API as an OGC API Features connection, as the QGIS guide shows. The GeoLens plugin for QGIS adds catalog search, private datasets and edits that sync back to GeoLens.

Standard

Where

Use it with

OGC API Features, with CQL2 filtering and queryables

/api/collections/{id}/items

QGIS, ArcGIS, GDAL/OGR and other OGC API clients

OGC API Records

/api/collections/datasets/items

Catalog search from other portals and tools

STAC API 1.0

/api/stac/

STAC clients such as pystac-client and STAC Browser

DCAT 3, DCAT-US 3.0 and GeoDCAT-AP as JSON-LD

/api/datasets/dcat/, /api/datasets/dcat-us/3.0/, /api/datasets/geodcat-ap/

Harvesting into national and EU open-data portals

Vector tiles and COG raster tiles

a tile URL on every layer

MapLibre, OpenLayers, Leaflet

3D Tiles and COPC

each 3D dataset's page

CesiumJS, QGIS, Potree

Data exports as GeoJSON, Shapefile, GeoPackage, CSV, FlatGeobuf, GeoParquet, PMTiles or Cloud-Optimized GeoTIFF.

The geolens CLI publishes files and applies catalog manifests, Python and TypeScript SDKs cover the API, and a read-only MCP server lets AI agents search the catalog. The API reference and SDK guides document them, and the examples gallery has runnable code for MapLibre, Leaflet, OpenLayers, the ArcGIS Maps SDK, QGIS and DuckDB.

Optional AI

GeoLens can answer questions about a dataset, edit maps from plain-language requests, draft metadata and search in natural language. It works with any OpenAI-compatible endpoint, including a local server such as Ollama, and with Claude through Anthropic, Microsoft Foundry, Amazon Bedrock or Google Vertex AI. AI stays off until an administrator configures a provider, and every workflow works without it.

Install

You need Git, curl and Docker with the Compose plugin. The Install Guide lists the versions, memory and ports it expects.

curl -fsSL https://getgeolens.com/install.sh | sh    # clone, generate secrets, start the stack
cd geolens
grep '^GEOLENS_ADMIN_PASSWORD=' .env                  # the generated admin password

Open http://localhost:8080 and sign in as admin with that password. Each release includes a SHA256SUMS file for checking install.sh before you run it. To build from source instead, clone the repository and run bash scripts/install.sh; the first build takes 5-10 minutes.

For production, read the cloud deployment guide, which also lists what an external database needs. Docker Compose is the supported path, and geolens-deployments has a community-maintained Helm chart and Terraform recipes for AWS ECS Fargate and Azure Container Apps.

The bundled database is backed up daily, and the backup guide covers off-site copies and restores. UPGRADING.md covers upgrades and rollback, RUNBOOK.md covers operations, and the Configuration Reference lists every setting.

Your first dataset

With the CLI installed, publish the sample file from the install directory:

geolens login http://localhost:8080/api               # your admin username and password
geolens publish examples/manifests/first-catalog/city-parks.geojson --name "City Parks"

geolens publish prints the new dataset's URL. To manage a whole catalog, describe the sources in a geolens.yaml manifest and run geolens apply; examples/manifests/ has templates.

To load the demo's maps and datasets, export GEOLENS_ADMIN_PASSWORD from .env and run python scripts/seed-showcase.py --username admin. The script needs Python 3.10+ and httpx and downloads public data from about a dozen sources; scripts/README.md has the sizes and options.

Privacy and access

  • GeoLens sends no telemetry. Apart from the default basemap tiles and the remote services or STAC sources your users register, it makes outbound calls only for features an administrator turns on. EGRESS.md lists them and explains how to run air-gapped.

  • Your data stays readable without GeoLens. Vector datasets are ordinary PostGIS tables in a data schema, rasters are Cloud-Optimized GeoTIFFs in your own storage (local disk, S3/MinIO or Azure Blob), and the catalog exports through OGC API, STAC and DCAT.

  • Sign-in uses local accounts or OAuth 2.0/OIDC (Google, Microsoft, GitHub or a generic provider), with roles, per-dataset permissions, per-user API keys and an audit log. Self-registration is off by default.

  • Features released in this repository stay free. EDITIONS.md describes the optional paid support and add-ons.

Known limitations

  • The supported install, Docker Compose, runs on one host. For high availability, run several replicas of the API, worker, frontend and Titiler against a managed PostgreSQL with automatic failover, shared object storage and one Valkey or Redis cache. With Azure Blob or local storage, API and worker replicas also need a shared staging volume, since only S3 keeps uploads in the bucket. Local storage keeps every file on that volume, so Titiler replicas mount it too. geolens-deployments has a community-maintained Helm chart, Terraform recipes for AWS and Azure, and guides for AWS, Azure, Google Cloud and DigitalOcean. GeoLens itself doesn't cluster the database or read from replicas.

  • One organization per deployment.

  • Terrain rendering assumes elevation in meters; other vertical units render exaggerated.

  • GeoLens's own REST API can change between minor releases (the standards endpoints follow their specifications). The CHANGELOG lists contract changes, and a breaking change keeps the old form working for one more minor release.

Contributing

Bug reports, fixes, translations and docs are welcome. CONTRIBUTING covers setup and tests, and ARCHITECTURE maps the code. The QGIS plugin, examples and deployments repositories take issues and pull requests too. Ask questions in GitHub Discussions, report bugs in Issues, and report security problems privately as described in SECURITY.md. The roadmap shows what's planned.

Built on

GeoLens is built on these open source projects. Thanks to everyone who maintains them.

  • PostgreSQL and PostGIS hold the catalog and every vector dataset, and pgvector stores the embeddings behind search by meaning.

  • GDAL reads the files and services GeoLens imports and writes the formats it exports, and PROJ handles coordinate transformations.

  • TiTiler serves raster tiles from Cloud Optimized GeoTIFFs.

  • FastAPI serves the API, and Procrastinate runs background jobs with PostgreSQL as the queue.

  • MapLibre GL JS draws the maps, deck.gl and loaders.gl render 3D Tiles and point clouds, and Terra Draw handles drawing and editing.

  • The web app is written in React.

These names belong to their owners, and listing them doesn't mean they endorse GeoLens; see TRADEMARKS.md.

License

GeoLens is licensed under the Apache License 2.0. The GeoLens name, logo and brand assets are not covered by this license; see TRADEMARKS.md. Sample-data attribution is in THIRD_PARTY_DATA.md. The web app serves the license notices for the code it bundles at /third-party-licenses.txt, and the backend image's copyleft notices are in backend/licenses.

Project policies: editions · support · governance · maintainers · security · release process · egress &amp; air-gap

Available Tools

6 tools
get_dataset_schemaA

Get a dataset's schema and source trust metadata.

Returns columns (name/type/role), geometry type, CRS/SRID, feature count, spatial extent, and the safe source_origin. source_health is healthy, missing, inaccessible, or unknown: inaccessible means GeoLens could not determine whether the source still exists, while unknown means it was never probed or cannot be probed. source_health_detail is a fixed GeoLens reason code, not provider text. last_checked_at records the latest probe attempt; last_refreshed_at records only the latest successful committed refresh. source_freshness is advisory; overdue means two declared update intervals elapsed without a successful refresh. Raw provider URLs, origin pointers, and credentials are excluded. Call this before writing spatial questions so you know both the available columns and whether the source may be stale.

Args: dataset_id: Dataset id (e.g. from search_datasets).

NameRequiredDescriptionDefault
dataset_idYes

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations, the description carries the full disclosure burden and does so richly: it decodes the source_health enum (including the subtle inaccessible vs unknown distinction), clarifies that source_health_detail is a fixed reason code rather than provider text, distinguishes last_checked_at from last_refreshed_at, defines the advisory 'overdue' freshness rule, and confirms raw provider URLs and credentials are excluded.

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

Conciseness4/5

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

The opening sentence front-loads the purpose, and each subsequent sentence carries real semantic content about return fields rather than filler. It is dense and slightly long for a one-parameter read tool, but no sentence is redundant.

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

Completeness5/5

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

Given no output schema, no annotations, and a minimal input schema, the description supplies everything an agent needs: what the call returns, how to interpret the trust/freshness fields, and when in the workflow to invoke it. Nothing material is missing.

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

Parameters4/5

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

There is a single parameter with 0% schema description coverage, so the description must compensate. It does, by annotating dataset_id with a concrete source ("e.g. from search_datasets"), which is exactly the guidance the bare string schema lacks.

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?

States a specific verb and resource ("Get a dataset's schema") and immediately enumerates the returned surface (columns, geometry type, CRS/SRID, feature count, extent, trust metadata), which makes it unmistakable what this tool does versus search_datasets, get_features, or query.

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

Usage Guidelines4/5

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

Explicitly says "Call this before writing spatial questions so you know both the available columns and whether the source may be stale," giving a clear triggering condition. It stops short of naming a specific alternative tool or a when-not-to-use case, so it does not reach the 5 bar.

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

get_featuresA

Get GeoJSON features for a dataset (bounded).

Returns an OGC-API FeatureCollection. Raster datasets have no features and will error. Results are capped by limit; page with offset. Only the arguments listed below are supported; anything else is rejected.

Args: dataset_id: Dataset id. limit: Max features (1-200, default 10). offset: Feature offset for paging. bbox: Optional bounding box filter "minx,miny,maxx,maxy" (WGS84).

NameRequiredDescriptionDefault
bboxNo
limitNo
offsetNo
dataset_idYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does so well: it discloses the response shape (OGC-API FeatureCollection), a failure mode (raster datasets will error), pagination behavior (capped by limit, page with offset), and strict argument validation. It omits auth/permission requirements and whether results are ordered, which are the remaining behavioral gaps.

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

Conciseness4/5

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

Purpose and return type are front-loaded, followed by caveats and then the argument list, which is the right ordering. The "Only the arguments listed below are supported; anything else is rejected" line partially duplicates additionalProperties=false, a minor redundancy in an otherwise tight description.

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?

With no output schema, the description correctly explains the return type (OGC-API FeatureCollection) and error conditions, and it documents all four parameters despite zero schema coverage. It is complete enough to call correctly; the main residual gap is that dataset_id's expected form (id vs. slug) is not clarified.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate, and it does: it gives the units/format for bbox ("minx,miny,maxx,maxy", WGS84), the range and default for limit (1-200, default 10), and the paging role of offset. Only dataset_id ("Dataset id") stays a bare restatement, which is the one weak spot.

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

Purpose4/5

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

Specific verb+resource ("Get GeoJSON features for a dataset") with an explicit scope qualifier ("bounded") and a stated return format (OGC-API FeatureCollection). It clearly separates itself from a generic query tool, but it never names or contrasts a sibling (e.g. query) so the differentiation is implicit rather than explicit.

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

Usage Guidelines3/5

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

It supplies real usage conditions: raster datasets have no features and will error, results are capped and must be paged with offset, and unsupported arguments are rejected. However, it never names an alternative tool or says when to prefer query/search_datasets over this one, so an agent is left to infer routing on its own.

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

get_mapA

Get one saved map's full metadata, including its layers, view state, basemap, and terrain configuration.

Args: map_id: Map id (e.g. from list_maps).

NameRequiredDescriptionDefault
map_idYes

TDQS

A3.8/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it does disclose that this is a read returning full metadata plus the specific configuration surface returned. It omits not-found behavior, permission requirements, and size limits, so it is useful but not complete.

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?

Front-loaded single sentence that names the resource and its returned content, followed by a compact Args block. No filler sentences; every line earns its place.

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?

For a single-parameter read with no output schema, the description covers purpose, payload contents, and id provenance, which is most of what an agent needs. Error and empty-result behavior remain undocumented.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must compensate. It explains what map_id is and where to obtain it (from list_maps), but gives no format, expected shape, or example value, leaving part of the gap unfilled.

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

Purpose4/5

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

States a specific verb and resource ('Get one saved map's full metadata') and enumerates the payload (layers, view state, basemap, terrain). The contrast with list_maps is only implicit via the word 'one', so it is clear but not fully differentiated.

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

Usage Guidelines3/5

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

Usage is implied by 'one saved map' versus the list-oriented sibling, and it helpfully notes the id can come from list_maps. However, there is no explicit when-to-use/when-not statement or guidance on what to do when map_id is unknown or invalid.

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

list_mapsA

List saved maps (read-only metadata: id, name, visibility, layer count).

Args: search: Optional text filter on map name/description. limit: Max results (1-200, default 50). offset: Result offset for paging.

NameRequiredDescriptionDefault
limitNo
offsetNo
searchNo

TDQS

A3.9/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose the key trait: this is a read-only metadata listing and it enumerates exactly what is returned (id, name, visibility, layer count). It omits auth/permission requirements and whether search is case-insensitive or substring-based, which keeps it out of the top band.

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?

One front-loaded summary sentence plus a compact, clearly labelled arg list. Every line carries information and nothing is padded.

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?

For a simple, zero-required-param read tool with no output schema and no annotations, the description covers purpose, all three params, and the returned fields, so an agent can call it correctly. The only real gap is the absence of routing guidance relative to get_map and search_datasets.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate and largely does: it explains that search filters on name/description (the schema only says string), states limit is 1-200 with default 50, and identifies offset as paging. Limit/offset are conventional enough that no further explanation is needed.

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

Purpose4/5

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

States a specific verb and resource ('List saved maps') and scopes the return to metadata (id, name, visibility, layer count), which clearly separates it from the single-map sibling get_map. It does not name any sibling explicitly, so it stops just short of full differentiation.

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

Usage Guidelines3/5

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

Usage is only implied: listing 'saved maps' suggests browsing rather than fetching a specific map, but there is no explicit when-to-use, when-not-to-use, or pointer to get_map/search_datasets. An agent must infer the routing from the resource name alone.

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

queryA

Run one read-only SQL SELECT against accessible datasets.

Executes through the server's hardened SQL sandbox: a single SELECT over data.* tables, an allowlisted function set (aggregates, math, string, date, JSON, common PostGIS like ST_Area/ST_DWithin/ST_Intersects), and a strict server-side budget (a few seconds of runtime, a repetition cap on self-joins, and row_limit rows). Returns {columns, rows, row_count, truncated} with rows as lists in column order.

Requires credentials with AI-chat permission — anonymous configurations cannot use this tool. Workflow: search_datasets to find a dataset, then get_dataset_schema for its table_name and columns, then reference it as data.<table_name> in the SQL and list the same table_name in restrict_tables. Every table the query touches must be listed there; the scope can only narrow what your credentials already see. Writes, other schemas, and unlisted functions are rejected with a short reason.

Args: sql: A single SELECT statement over data.* tables. restrict_tables: Table names (no data. prefix) the query may touch. Required and non-empty. row_limit: Max rows to return (1-1000, default 100).

NameRequiredDescriptionDefault
sqlYes
row_limitNo
restrict_tablesYes

TDQS

A4.9/5.0
Behavior5/5

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

No annotations are provided, so the description carries the full burden and does so thoroughly: hardened sandbox, allowlisted function set, server-side time budget, self-join repetition cap, row_limit truncation, the exact return shape {columns, rows, row_count, truncated}, and the AI-chat permission requirement with anonymous configs excluded.

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

Conciseness4/5

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

Front-loads the core purpose and constraints effectively, but the trailing Args block restates details already conveyed in prose (row_limit's range, restrict_tables' requiredness), producing mild redundancy rather than wasted space.

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

Completeness5/5

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

Despite no output schema, the description specifies the return payload, the credential prerequisite, the sandbox limits, and the required call sequence, leaving nothing an agent needs in order to invoke it correctly.

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?

Schema description coverage is 0%, but the description fully compensates: sql is defined as a single SELECT over data.* tables, restrict_tables is declared required, non-empty, and prefix-free, and row_limit is given its 1-1000 range and default of 100.

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?

States a specific verb and resource ('Run one read-only SQL SELECT against accessible datasets') and implicitly distinguishes itself from siblings like search_datasets and get_dataset_schema, which are named as earlier steps in the workflow rather than substitutes.

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

Usage Guidelines5/5

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

Gives an explicit multi-step workflow (search_datasets -> get_dataset_schema -> query) and states the constraint that every touched table must appear in restrict_tables and that scope can only narrow existing credential visibility. Writes, other schemas, and unlisted functions are explicitly excluded.

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

search_datasetsA

Search the GeoLens catalog for datasets by free text.

Matches title, description, and keywords (semantic ranking is used automatically when the instance has it enabled). Returns a GeoJSON FeatureCollection where each feature is a dataset record; use the feature id as the dataset_id for the other tools. Each feature's properties include source_origin (upload, postgis, service, stac, created, or null) and source_freshness (fresh, due, overdue, or unknown). Freshness is advisory: due means one declared update interval has elapsed, while overdue means two have elapsed; neither proves that the content is wrong.

Search does not make a detail request per result. When the catalog summary has no health/check/refresh value, source_health, source_health_detail, last_checked_at, and last_refreshed_at are null. Call get_dataset_schema for populated trust metadata. Raw provider URLs and credentials are never included in these source-state fields.

Args: query: Search text. limit: Max results (1-200, default 10). offset: Result offset for paging.

NameRequiredDescriptionDefault
limitNo
queryYes
offsetNo

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses the return type (GeoJSON FeatureCollection), that no per-result detail request is made, when trust fields are null, that freshness is advisory rather than proof of bad content, and that credentials/provider URLs are never exposed. It omits auth requirements, rate limits, and whether paging returns totals, which keeps it from a 5.

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

Conciseness4/5

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

Front-loaded with the core action and return shape, followed by supporting detail about source fields, nulls, and freshness. The freshness and null paragraphs are long but each carries information an agent needs; a small amount of the enumeration could be tightened.

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?

No output schema exists, and the description compensates well by naming the return container, the feature id's role as dataset_id, and the meanings of source_origin, source_freshness, and the null trust fields. Remaining gaps are paging behavior beyond the offset argument and permission/auth requirements.

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

Parameters3/5

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

Schema description coverage is 0%, so the description must compensate, and it does document all three parameters (query, limit, offset) in the Args block. However, the entries largely restate what the schema's own bounds and defaults already show ('limit: Max results (1-200, default 10)') and add little semantic meaning beyond 'free text' and 'for paging'.

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?

States a specific verb and resource ('Search the GeoLens catalog for datasets by free text') and names the exact fields matched (title, description, keywords). It also routes onward ('use the feature `id` as the dataset_id for the other tools'), which makes the boundary with siblings like get_dataset_schema and list_maps unambiguous.

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

Usage Guidelines4/5

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

Gives clear usage context: free-text discovery, with semantic ranking applied when enabled, and explicitly routes the agent to get_dataset_schema when it needs populated trust metadata. It does not state explicit when-not-to-use conditions or contrast against `query`/list_maps, so it stops short of a 5.

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.

  1. 6 tool updatesv1.25.1
    • Changedget_dataset_schema1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedget_features4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +200
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / offset / minimum
        Added value: +0
    • Changedget_map1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedlist_maps4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +200
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / offset / minimum
        Added value: +0
    • Changedquery3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / row_limit / maximum
        Added value: +1000
      • addedInput schema / properties / row_limit / minimum
        Added value: +1
    • Changedsearch_datasets4 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / limit / maximum
        Added value: +200
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / offset / minimum
        Added value: +0
  2. 6 tool updatesv0.1.0
    • First observedget_dataset_schema
    • First observedget_features
    • First observedget_map
    • First observedlist_maps
    • First observedquery
    • First observedsearch_datasets

TDQS

A4/5.0

Scored across 6 tools

Disambiguation4/5

Each tool has a clearly distinct target: search_datasets (catalog lookup), get_dataset_schema (schema/trust metadata), get_features (bounded GeoJSON rows), list_maps/get_map (saved map read), and query (SQL sandbox). The only mild overlap is conceptual between search_datasets/get_features/query, which all touch dataset data, but the descriptions make the boundaries explicit (metadata vs features vs ad-hoc SQL).

Naming Consistency4/5

Five tools follow a clean verb_noun or list/get pattern (search_datasets, list_maps, get_map, get_features, get_dataset_schema). The lone bare verb 'query' breaks the pattern and get_dataset_schema is a bit longer, but overall the convention is predictable.

Tool Count4/5

Six tools is well-scoped for a read-only geospatial catalog: discovery, schema inspection, feature retrieval, two map-read tools, and one analyst query tool. Nothing feels redundant, though a couple of operations could plausibly be added without bloating.

Completeness4/5

The read-only surface covers the core lifecycle: find datasets, inspect schema/trust, pull features, browse maps, and run SQL. Gaps are minor and consistent with the read-only design (no dataset/map creation or saved-map writes, and no list_datasets without a free-text query), which agents can work around.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides read-only access to PostgreSQL databases with schema inspection, query execution in multiple formats (JSON, CSV, Markdown), and query history tracking with built-in security features.
    -
  • F
    license
    Not graded
    quality
    F
    maintenance
    Provides read-only SQL query access to Postgres and DuckDB databases via MCP tools, with extensive security hardening for public endpoints.
    1
    -
  • F
    license
    B
    quality
    C
    maintenance
    Provides read-only query tools over OpenStreetMap data in PostGIS, enabling natural language queries for features, categories, and spatial analysis.
    7
    -
  • A
    license
    A
    quality
    B
    maintenance
    Enables read-only PostgreSQL interaction with enforced SQL security policies, including query validation, row limits, and timeouts.
    4
    MIT