Metadata-Version: 2.5
Name: geolens-mcp
Version: 1.17.0
Summary: Apache-2.0 read-only Model Context Protocol (MCP) server for GeoLens. Lets coding agents discover datasets, inspect schemas, and ask spatial questions against any GeoLens instance.
Project-URL: Homepage, https://github.com/geolens-io/geolens
Project-URL: Repository, https://github.com/geolens-io/geolens
Project-URL: Documentation, https://docs.getgeolens.com/
Author-email: "Carto Concepts, LLC" <noreply@getgeolens.com>
License: Apache-2.0
License-File: LICENSE
Keywords: agents,geolens,geospatial,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.11
Requires-Dist: cryptography>=50.0.0
Requires-Dist: geolens<2.0.0,>=1.2.0
Requires-Dist: idna>=3.18
Requires-Dist: mcp<2.0.0,>=1.28.1
Provides-Extra: dev
Requires-Dist: pytest<10.0.0,>=9.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# geolens-mcp

Apache-2.0 read-only [Model Context Protocol](https://modelcontextprotocol.io) server for [GeoLens](https://github.com/geolens-io/geolens).

Point a coding agent (Claude Code, Cursor, Codex, …) at a GeoLens instance so it can discover datasets, inspect schemas, read features and maps, and run read-only SQL from inside a dev session.

**Read-only by design.** No writes, ingest, or admin. The discovery tools are `GET`s against existing API endpoints; `query` is a `POST` mechanically but executes inside the server's READ ONLY SQL sandbox, so it cannot modify anything. Calls are scoped to the caller's access: with an API key, the agent sees the datasets that key's user can see; with no credential it sees only public/published data (`query` additionally requires a credential whose user holds the AI-chat permission — `read_only` API keys work, via a route-specific server-side carve-out).

## Install

```bash
pip install geolens-mcp        # or: uvx geolens-mcp
```

## Configure

The server reads its target instance and credentials from the environment (same names as the `geolens` CLI):

| Variable | Required | Meaning |
|---|---|---|
| `GEOLENS_INSTANCE` | yes | Instance URL, e.g. `https://geolens.example.com`. The `/api` suffix is appended automatically if you omit it. |
| `GEOLENS_API_KEY` | recommended | API key, sent as `X-Api-Key`. Create one in **Settings → API keys**. Omit for public-only access. |
| `GEOLENS_TOKEN` | — | JWT bearer token, used only if `GEOLENS_API_KEY` is unset. |

## Register with an MCP client

Claude Code:

```bash
claude mcp add geolens -e GEOLENS_INSTANCE=https://geolens.example.com -e GEOLENS_API_KEY=... -- uvx geolens-mcp
```

Cursor / Codex / any client that reads an `mcpServers` block:

```json
{
  "mcpServers": {
    "geolens": {
      "command": "uvx",
      "args": ["geolens-mcp"],
      "env": {
        "GEOLENS_INSTANCE": "https://geolens.example.com",
        "GEOLENS_API_KEY": "your-api-key"
      }
    }
  }
}
```

## Tools

| Tool | What it does |
|---|---|
| `search_datasets` | Catalog search by free text (semantic ranking where the instance enables it). Returns dataset records as GeoJSON features with safe origin and freshness state; health/check/refresh keys are null when unavailable in the search summary. |
| `get_dataset_schema` | A dataset's columns, geometry type, CRS/SRID, feature count, extent, and source trust metadata. |
| `get_features` | Bounded GeoJSON features for a dataset (OGC API — Features), with optional bbox. |
| `list_maps` | Saved maps (id, name, visibility, layer count). |
| `get_map` | One saved map's full metadata, including layers and view state. |
| `query` | One read-only SQL `SELECT` through the server's hardened sandbox ([#565](https://github.com/geolens-io/geolens/issues/565)): single statement over `data.*` tables, allowlisted functions, a mandatory `restrict_tables` scope, and a strict server-side budget (statement timeout, self-join cap, row limit, rate limits). Needs a credential whose user has the AI-chat permission; requires GeoLens ≥ the release that ships `POST /api/query/`. |

## Develop

```bash
cd mcp
uv run --extra dev python -m pytest -v
```

<!-- mcp-name: io.github.geolens-io/geolens -->
<!-- The marker above is how the MCP Registry proves ownership of the PyPI package: it
     looks for `mcp-name: <server name>` in the published package description, which is
     this file. Keep it byte-identical to `name` in server.json, and keep it alone on its
     line — the token has to be followed by whitespace or the comment close to match. -->
