Skip to content
Conduit

mcp server

georescue

Audit-first GIS data-quality checks and logged, reviewable repairs for parcel datasets, with deed/COGO verification and an MCP server for AI agents.

knightchrism/georescuecommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

Before you start

  • uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "georescue": {
      "command": "uvx",
      "args": [
        "georescue"
      ]
    }
  }
}

same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12

Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs

README

synced Oct 28, 2026

Status: early prototype, work in progress.

Test demo — not authoritative. Not a survey, title opinion, or legal determination; for testing and demonstration only. Results are automated, experimental data quality test results computed from public data. Verdicts are proposals, not findings; placements of deed descriptions are best-fit, not measured in the field. Consult a licensed surveyor and mapper or an attorney and the official records. GeoRescue is not affiliated with the City of Jacksonville, the Duval County Clerk of Courts or the Duval County Property Appraiser. See TERMS.md. Questions, corrections or removal requests: open an issue at https://github.com/knightchrism/georescue/issues

What it does

  • Inspects parcel layers (SHP / GPKG / GeoJSON) for invalid or empty geometry, duplicate IDs and geometries, CRS problems, out-of-bounds features, overlaps, slivers, gaps and attribute-rule violations (YAML rules, Pydantic-validated).
  • Proposes repairs on a copy — the source file is never modified; every proposed change is written to changelog.csv with before/after, reason and whether it was applied (an audit trail for review).
  • Checks overlaps against the record: appraiser legal descriptions, deed OCR, metes-and-bounds / COGO traverses and closure, compared back to the GIS fabric (verify/).
  • Publishes a static dashboard with per-case evidence pages, owner names redacted by default.
  • Talks to agents through an MCP server backed by a redacted DuckDB results store.

Architecture

flowchart LR
  A[Parcel layer<br/>SHP · GPKG · GeoJSON · ArcGIS REST] --> B[inspect<br/>checks.py + YAML rules]
  B --> C[repair on a copy<br/>repair.py]
  C --> D[(out/<br/>corrected.gpkg · changelog.csv<br/>issues.csv · diff.csv · report.html)]
  B --> V[verify/<br/>PAO legal desc · deed OCR · COGO · PLSS]
  D --> P[publish<br/>redact owners]
  V --> P
  P --> S[Static site<br/>GitHub Pages]
  D --> L[load-db<br/>redacted DuckDB]
  L --> M[georescue-mcp<br/>read-only tools · logs/mcp.log]
  M --> AG[AI agent<br/>Claude · Cursor · ...]

Quickstart

git clone https://github.com/knightchrism/georescue.git && cd georescue
uv sync --extra verify
PYTHONPATH=. uv run --extra verify pytest -q          # test suite
uv run georescue inspect data.gpkg -c configs/columbia_fl.yaml
uv run georescue repair  data.gpkg -c configs/columbia_fl.yaml -o out/

On Windows, clone to a local folder such as C:\dev\georescue (keep projects out of OneDrive-synced folders).

AI / agent angle

  • georescue-mcp exposes inspection, repair-to-a-new-folder, guarded read-only SQL, governed metrics and case lookups to any MCP client (details below).
  • scripts/mcp_demo.py records real agent sessions; agent_demo/ drives a visualization loop and saves before/after snapshots.
  • Agents get the redacted store only — never owner names, never write access to source data.

Tech stack

Python 3.13 · uv · GeoPandas · Shapely · pyogrio · PyProj · DuckDB · Pydantic · Typer · Jinja2 · Streamlit + Folium · MCP Python SDK · MapLibre GL JS · GitHub Actions + Pages

Core (V1)

GIS data-quality & repair for parcel datasets. Load (SHP/GPKG/GeoJSON) → inspect → classify issues → propose repairs on a copy (every change logged) → export corrected.gpkg, changelog.csv, issues.csv, diff.csv, summary.json, report.html.

Checks

missing/empty/invalid geometry · duplicate IDs · duplicate geometries · required attributes & types (YAML rules, Pydantic-validated) · CRS missing/unexpected · out-of-bounds · overlaps · slivers · small gaps · original-vs-corrected diff.

Repairs (all logged: feature_id, check, action, before, after, reason, post_valid, applied)

make_valid (polygonal parts kept) · numeric text→number coercion · assign CRS if missing · optional: drop empty geoms, drop exact duplicates, trim overlaps below an area. Everything else is flag_only. The source file is never modified.

Usage

uv sync
uv run georescue inspect data.gpkg -c configs/columbia_fl.yaml
uv run georescue repair  data.gpkg -c configs/columbia_fl.yaml -o out/
uv run georescue report  data.gpkg -c configs/columbia_fl.yaml -o out/
uv run streamlit run app.py          # demo UI (docs/demo.png)
uv run georescue-mcp                 # MCP stdio server: inspect_dataset, repair_dataset
PYTHONPATH=. uv run --extra verify pytest -q

Real data: uv run python scripts/fetch_columbia.py (Columbia County FL LCParcels FeatureServer).

Known gaps

Gap detection uses holes in the unioned fabric (misses gaps open to the outside edge); overlap trimming is greedy (higher row loses); DuckDB batch mode not implemented; no map of issue geometries in the UI (points only); type rules don't parse unit-suffixed text (e.g. "3 Ac").

Automated vs. manual steps

StepStatus
Inspect, classify, repair, change log, QA reportAutomated (georescue CLI / MCP)
RustGIS visualization loopAutomated (agent_demo/run_demo.py)
Appraiser legal descriptions, PLSS corner tie (BLM CadNSDI)Automated (verify/)
Fetching recorded deed images (myfloridacounty.com ORI)Manual today: portal sits behind a human-verification check
Deed OCR, metes-and-bounds + curve parsing, COGO traverse, closure and GIS comparisonAutomated (verify/run_deeds.py)
Final boundary position within ~3 ftNeeds a licensed surveyor

Deed PDFs, page images, and raw county data are excluded from the repo.

Credits

See THIRD_PARTY_NOTICES.md for open-source licenses and data sources, and Data sources below. Brand font: Exo 2 (SIL Open Font License, brand/fonts/OFL.txt).

Live demo

Static dashboard (GitHub Pages): https://knightchrism.github.io/georescue/

  • KPIs per check, filterable issues table, Leaflet map of flagged parcels only (small GeoJSON, not the 584 MB county layer), per-overlap case files (verdict, confidence, ORB refs, deed closure/acreage, overlay PNGs) and run history.
  • Basemap: OpenStreetMap tiles. The COJ Duval orthoimagery has no published licence, so imagery-backed figures are not published; case pages use the plain (no-imagery) overlay PNGs.
PYTHONPATH=. uv run --extra verify georescue run --config configs/duval_fl.yaml   # -> out/runs/<ts>/, out/latest/
PYTHONPATH=. uv run --extra verify georescue publish                               # -> site/
python -m http.server -d site 8765                                                  # preview locally

Automation: .github/workflows/pipeline.yml (weekly cron + manual dispatch) runs the pipeline on a bbox extract (configs/duval_fl_ci.yaml), fetching parcels at runtime, and deploys site/ to Pages. To enable: push the repo to GitHub, then Settings → Pages → Source: GitHub Actions, and allow Actions under Settings → Actions. Only invalid-geometry repair is ever auto-applied; every other fix is a proposal recorded in changelog.csv.

Data sources

GeoRescue does not own the data below and is not affiliated with, or endorsed by, any of these sources. Their records are maintained for their own purposes (for example, assessment) and, as the Property Appraiser states for its data, are not intended for legal use such as conveyances or boundary determinations.

Owner and person names are removed from the public site (georescue publish redacts by default; --no-redact-owners is for private local builds only).

Ask GeoRescue (MCP server)

georescue load-db loads the latest run into a redacted DuckDB results store, out/georescue.duckdb. It holds the tables issues, cases, verdicts, deed_traverses, runs and glossary, and it never contains owner names. georescue run refreshes it automatically. The MCP server (uv run --extra verify georescue-mcp, stdio) exposes these tools: inspect_dataset, repair_dataset (writes a repaired copy into a new folder only), list_tables, describe_table, run_query (single SELECT/WITH, guard + row cap + 10 s timeout), list_metrics/get_metric (governed metrics in semantic/metrics.yml), get_case, find_issues, explain_issue and compare_runs. All calls are logged to logs/mcp.log.

scripts/mcp_demo.py drives the server over stdio through realistic questions and records the real calls and outputs to examples/agent_sessions.{json,md}. The site's Ask GeoRescue page renders those sessions. Each answer is filled in by a fixed template from the tool outputs. The page also has Claude Desktop / Cursor config snippets for running it yourself. These are recorded sessions and test results, not authoritative.

The server structure, SQL guard, metrics layer, logging and demo are adapted from the author's own census-pipeline (MIT). GeoRescue keeps its existing MCP SDK (mcp>=2.3, MCPServer).

Glossary

The site's glossary (generated by georescue publish from src/georescue/glossary.py and the config thresholds) explains every issue type the checks emit — what it means, why it matters, how it is detected, what (if anything) is done automatically — plus terms like verdict, confidence, deed traverse/COGO, misclosure, POB, ORB, IoU and PAO. All results are proposed test results, not authoritative.

Terms

See TERMS.md. Questions, corrections or removal requests: open an issue at https://github.com/knightchrism/georescue/issues

License

Code: MIT, see LICENSE. Third-party software and data keep their own licenses and terms (THIRD_PARTY_NOTICES.md).

↑↓ navigate openesc close