Geospatial questions → reproducible, validated GIS analysis project (with very nice interactive map).
Install:
npx skills add jaakla/openmapstack -gOpenMapStack gives your favorite AI agent: Claude Code, Codex, Cursor, OpenCode, and 50+ other agents a production workflow from authoritative data discovery through analysis to interactive web and GIS deliverables. Material workflows become inspectable and repeatable well-defined projects in a yaml file with pinned sources, explicit assumptions and CRS choices, deterministic processing, isolated overrides, machine-readable validation, and surfaced provenance.
It is open-first and cloud-native by default, built on shoulders of the awesome Open GIS stack: STAC for discovery; GeoParquet, COG, and PMTiles for storage and delivery; DuckDB and PostGIS for compute; and QGIS, MapLibre, and Martin for presentation. It also uses GDAL/OGR, GeoPandas, xarray/rioxarray, PDAL, routing engines, spatial SQL, and pragmatic hosted services when scale or reliability requires them.
- SKILL.md — the skill entry point: triggers, global defaults, format and compute decision matrices, anti-patterns, and a quick triage guide.
- references/data-sources.md - lists OSM, Overture, Sentinel/Landsat, regional portals, STAC catalogs and others.
- references/services-and-scale.md - depending on case use local installs or hosted/SaaS services for global-scale basemaps, elevation, routing, geocoding, place search, and postcodes.
- references/user-data-sources.md - the user's own warehouse data: credentials by reference, read-only discovery, approval-gated snapshots, and the pin classes that make a warehouse table reproducible.
- references/formats-and-crs.md - how to choose formats, conversions, projections, EPSG codes.
- references/processing.md - when and how to use GDAL/OGR, GeoPandas, xarray, DuckDB, PostGIS, PDAL and other open geo processing tools.
- references/analytics.md — do vector/raster analytics, terrain, hydrology, network, point clouds, geocoding etc.
- references/web-delivery.md — renderer selection for maps, PMTiles, MVT, Martin, TiTiler, MapLibre, deck.gl, kepler.gl, and lonboard formats and engines.
- references/qgis.md — QGIS desktop, plugins, PyQGIS, Processing, QGIS MCP.
- references/validation-and-ops.md — validation, manifests, attribution, and deployment checks, including the machine-readable reproducible-project contract.
- references/project-spec.md — the specific
openmapstack-project/v1schema: compiling any material analysis into a reproducible GIS project (project.yaml, pipeline, source provenance, overrides, validation, semantic presentation, QGIS output). - templates/ — ready scaffolds (
project.yaml,pipeline.py,presentation.yaml,validation.yaml) for new projects. - examples/tartu-development/ — a fully-worked reproducible project matching the acceptance scenario: source provenance + timestamps, explicit assumptions, two verified project overrides (a scenario attribute change with prior-value verification, and hypothetical scenario geometry), deterministic pipeline, machine-readable validation, and semantic presentation.
- evals/ — the eval suite grading whether an agent reaches the right analytical answer, respects the GIS-method guardrails, and reruns reproducibly, with the
openmapstack-project/v1contract as the substrate that makes those independently checkable:python evals/run.py --mode fixtureruns deterministic, no-LLM checks against real generated artifacts (analytical correctness against known geospatial truth, metric CRS, source immutability, schema, overrides, validation integrity, presentation contract, and clean reruns), plus adversarial cases and a pluggable live-agent benchmark (Claude Code, Codex, and any OpenAI-compatible API such as OpenRouter — URL and model viaOPENAI_COMPATIBLE_*env, API key as a secret). openmapstack/— the installableopenmapstack validate/run/inspectCLI for auditing and executingopenmapstack-project/v1projects, plusopenmapstack/checks/: the reusable, semantic check library. All but five of its checks are oracle-free, so the same functions that grade the eval suite also grade a user's own project on data this repository has never seen.- docs/openmapbench-interop.md — the narrow, versioned contract a benchmark harness such as OpenMapBench consumes:
openmapstack checks/check/api-info(openmapstack-check-api/v1), the packaged result schemas, skill snapshots, arm provenance, and exported task bundles. .claude-plugin/— Claude Code plugin and marketplace manifests, so the repository can also be installed with/plugin install. Validated in CI by.github/workflows/plugin.yml.
My local Estonia-specific guidance (Maa- ja Ruumiamet, ETAK, EPSG:3301 / L-EST97) is included for convenience. But all the global sources are incuded for world-wide coverage.
The recommended way is the skills CLI, which works for Claude Code, Cursor, OpenCode, Codex, and 50+ other agents.
Install globally (available in every project):
npx skills add jaakla/openmapstack -gUpdate later with npx skills update open-map-stack. Remove with npx skills remove open-map-stack.
Claude Code users can install the same repository as a plugin instead. This adds
versioned installs, /plugin update, and project-scoped installs that a team
picks up from a repository's .claude/settings.json:
/plugin marketplace add jaakla/openmapstack
/plugin install open-map-stack@open-map-stackThe repository is its own marketplace, so no separate marketplace repo is
needed. The plugin wraps the same root SKILL.md — nothing is duplicated, and
the skills-CLI install path above keeps working unchanged.
The skills installer loads the agent instructions; the Python package provides the project commands. From a clone of this repository:
python3 -m pip install .
openmapstack --versionFor development, the commands can also run directly without installation:
python3 -m openmapstack --helpIf you'd rather not use the CLI, clone directly into your agent's skills directory. For Claude Code:
# User-level (every project)
git clone https://github.com/jaakla/openmapstack.git ~/.claude/skills/open-map-stack
# Project-level (one repo)
git clone https://github.com/jaakla/openmapstack.git .claude/skills/open-map-stackStart Claude Code and run /skills open-map-stack should appear in the list. The expected layout is:
<skills-dir>/open-map-stack/
├── SKILL.md
├── references/
│ ├── analytics.md
│ ├── data-sources.md
│ ├── formats-and-crs.md
│ ├── processing.md
│ ├── project-spec.md
│ ├── qgis.md
│ ├── services-and-scale.md
│ ├── spatial-sql.md
│ ├── validation-and-ops.md
│ └── web-delivery.md
├── templates/
│ ├── project.yaml
│ ├── pipeline.py
│ ├── presentation.yaml
│ └── validation.yaml
├── examples/
│ └── tartu-development/
└── .claude-plugin/ # Claude Code plugin + marketplace manifests
├── plugin.json
└── marketplace.json
The skill auto-activates when you ask Claude about geospatial work — terms like GIS, OpenStreetMap, Overture, Sentinel, Landsat, LiDAR, GeoTIFF, shapefile, GeoPackage, raster/vector tiles, isochrones, spatial joins, EPSG codes, and projections will all trigger it. You don't need to invoke it manually, but sometimes hinting "use open-map-stack skills" helps.
Example prompts that engage the skill:
- "Pull all buildings in Tartu from Overture and publish them as a PMTiles layer."
- "Compute average NDVI for these polygons from Sentinel-2 over the last 12 months."
- "Reproject this GeoTIFF from EPSG:3301 to EPSG:3857 as a COG."
- "Set up an OSRM routing server from a Estonia OSM extract."
- "Build an isochrone API around these points."
If you want to force the skill to load, you can reference it explicitly:
Use the open-map-stack skill to convert this shapefile to GeoParquet.
The CLI operates on an openmapstack-project/v1 manifest. A project directory may
be supplied in place of its project.yaml file.
# Audit the complete artifact, including outputs, report, and run record.
openmapstack validate path/to/project.yaml
# Check the produced artifacts without requiring a golden answer.
openmapstack verify path/to/project.yaml
# Run the one canonical pipeline, then validate what it produced.
openmapstack run path/to/project.yaml
# Review sources, versions, overrides, ordered steps, outputs, and latest run.
openmapstack inspect path/to/project.yaml
# Copy SKILL.md, references/, and templates/ into a hashed, inspectable snapshot.
openmapstack skill-snapshot --out /tmp/oms-skill --json
openmapstack skill-snapshot --inspect /tmp/oms-skill
# Read-only discovery of a warehouse source, then an approval-gated snapshot.
openmapstack source discover path/to/project.yaml --source parcels
openmapstack source snapshot path/to/project.yaml --source parcels \
--query "SELECT id, geom FROM cadastre.parcels" --destination data/source/parcels.parquet --approveUseful automation options:
openmapstack validate project.yaml --json --output validation/cli-report.json
openmapstack validate project.yaml --strict # warnings also return non-zero
openmapstack validate project.yaml --preflight # skip not-yet-generated artifacts
openmapstack run project.yaml --dry-run
openmapstack run project.yaml --json
openmapstack inspect project.yaml --jsonvalidate audits the manifest and its bookkeeping. verify runs the check
library in openmapstack/checks/ against what the pipeline actually produced:
geometry read back through DuckDB Spatial, dataset CRS read from the artifact
rather than the manifest's claim, validation evidence recomputed from the
geodata it summarises, and QGIS project structure and runtime loading where
PyQGIS is available.
openmapstack verify path/to/project.yaml
openmapstack verify path/to/project.yaml --rerun # + rebuild from source and compare
openmapstack verify path/to/project.yaml --metamorphic # + run declared no-oracle relations
openmapstack verify path/to/project.yaml --json --output validation/verify-report.json
openmapstack verify path/to/project.yaml --strict # warnings and not-testable also return 1These checks require no repository-owned golden answer, so they work on data neither this repository nor the model has seen. They establish bounded structural, provenance, artifact, and reproducibility predicates; they do not prove every project-specific analytical answer.
--rerun is the strongest signal available without a known answer. It rebuilds
the project in an empty workspace from only the manifest, the declared
immutable inputs, and the declared dependencies, runs the one canonical
entrypoint, re-hashes the sources, and compares the outputs semantically. A
pipeline that cannot reproduce itself, or that mutates its own declared
immutable inputs, is not trustworthy whatever its numbers say.
The check plan is derived from the manifest rather than configured, so a
project cannot opt out of a check by omitting it: a declared output is a
checked output. A check whose dependency is missing reports not_testable and
is counted separately — never a silent pass. A mixture of executed and
not_testable checks has aggregate status warning, and every report includes
applicable, executed, and execution_rate coverage. Install
openmapstack[geo] for the DuckDB-backed geodata checks; PyQGIS comes from a
system QGIS install.
See the applicability reference for the exact
plan conditions, dependencies, current regression evidence, and deliberate
exclusions. In particular, browser/dashboard checks are not yet part of the
automatic verify plan.
Project-specific known answers can be declared under
validation.expectations[]. The five allowlisted checks cover row count,
feature presence/absence, one feature-field value, and field range. New
expectations start as attestation.status: unverified; they produce a warning
and are not executed. The JSON report supplies the exact
expected_expectation_sha256 an independent reviewer must bind, together with
the current runs.latest.inputs_hash. Changing the expected check, arguments,
inputs, or a retained local evidence file invalidates the attestation and
returns it to warning status. See
the project contract.
Where no golden answer exists at all, validation.metamorphic[] declares
relations that must hold under a controlled perturbation: shuffle a source and
the result must not change, duplicate every feature and a keyed set must not
change, widen an inclusion buffer and no candidate may disappear. Each relation
states the precondition that makes it valid, is executed by
verify --metamorphic in an isolated copy against the project's own pipeline,
and reports not_testable with the reason when the precondition does not hold
on the actual data. See the project contract.
openmapstack source is the connector pilot for the user's own data
(DuckDB local files and PostGIS). Credentials are referenced, never stored;
discovery is read-only with a statement timeout; a snapshot is a dry run
until --approve, is limited by rows and bytes, lands only under
data/source/, and hands back the pin block that makes the source
reproducible. A warehouse table with only a timestamp is not pinned; an
expired backend snapshot is reported as not_reproducible. See
user data sources.
validate checks manifest structure, source retrieval/version/licensing data,
CRS declarations, processing graph resolution, override provenance and files,
output existence, validation-report parity/status propagation, override
application results, and run-record identity/hashes. GIS-specific checks such as
geometry validity remain the pipeline's responsibility; the CLI verifies that
each declared check appears exactly once with an explicit result.
Normal validation warnings return exit code 0 so known limitations remain
representable. Failures return 1; malformed invocation or an unstartable runtime
returns 2. --strict makes warnings return 1.
Will:
- Recommend modern, cloud-native formats (GeoParquet, COG, PMTiles) and flag legacy patterns (Shapefile output, MBTiles for new deployments).
- Push spatial joins to DuckDB / PostGIS instead of Python loops.
- Discover data via STAC before downloading.
- Preserve license metadata (OSM ODbL, Overture per-source, Sentinel attribution).
- Pin dataset versions for reproducibility (Overture releases, STAC item IDs, OSM extract dates).
- Compile material multi-stage analysis into a reproducible GIS project (
project.yaml+ pipeline + overrides + validation), deriving the final map/dashboard from it.
Won't:
- Trigger on simple location lookups ("what city is this?") or casual map references with no analytical work.
- Default to proprietary services when an open/self-hosted option fits the scale, quality, privacy, and budget.
Licensed under the MIT License.
Issues and PRs welcome at github.com/jaakla/openmapstack. When adding a new tool or workflow, place it in the matching reference file and add a one-row entry to the relevant decision matrix in SKILL.md.