Ugrc
FreeNot checkedMCP server wrapping UGRC's ArcGIS Feature Services. Query Utah's SGID layers (land use, parcels, hydrography) from an LLM.
About
MCP server wrapping UGRC's ArcGIS Feature Services. Query Utah's SGID layers (land use, parcels, hydrography) from an LLM.
README
An MCP server for Utah's State Geographic Information Database (SGID) and the UGRC Web API. Wraps ArcGIS Feature Services + mapserv so an LLM can discover layers, query features, and aggregate without writing Python or curl.
Runs on Cloudflare Workers. Built with @modelcontextprotocol/sdk and the Cloudflare Agents SDK (agents/mcp). MCP session state lives in a Durable Object; business logic is stateless.
See docs/plan.md for the authoritative design (discovery model, registry pipeline, acceptance criteria). docs/epic-v0.2.md tracks epic scope; docs/stories/ has per-story rollout notes.
Tools (33)
Three coverage tiers: cataloged SGID core via list_<category> (Tier 1), uncategorized UGRC via find_layer (Tier 2), outside-UGRC via arcgis_raw (Tier 3).
Generic discovery (2)
| Tool | Purpose |
|---|---|
list_capabilities |
Overview of all three tiers — categories with blurbs/layer counts, mapserv tools, query primitives, registered orgs. Call first if uncertain. |
describe_layer |
Full schema for a cataloged ({ org, layer }) or arbitrary ({ url }) layer. Fields with coded-value domains, current last_edit_date (re-fetched live), plus curated gaps / caveats. Per-isolate cached. |
SGID category discovery (20)
One list_<category> per SGID category. Returns the catalog (per-layer freshness, useful fields, known gaps). Pair with arcgis_query / arcgis_aggregate.
list_cadastre, list_society, list_indices, list_boundaries, list_demographic, list_energy, list_environment, list_geoscience, list_political, list_recreation, list_location, list_water, list_economy, list_health, list_transportation, list_planning, list_utilities, list_elevation, list_farming, list_climate.
Long-tail search (1)
| Tool | Purpose |
|---|---|
find_layer |
Live ArcGIS Hub Search across UGRC's full catalog (~763 Feature Services). Use when no list_<category> surfaces the layer. Returns URLs ready for arcgis_query({ url, ... }). Capped at 50. |
Action: query primitives (3)
| Tool | Purpose |
|---|---|
arcgis_query |
Feature read — where, spatial filter, pagination. Takes EITHER { org, layer } (Tier 1) OR { url } (Tier 2/3). GeoJSON in/out, WGS84. |
arcgis_aggregate |
Server-side groupBy + outStatistics. Same dual-shape input. Reach for this before paging features for headline numbers. |
arcgis_raw |
Escape hatch — direct ArcGIS REST passthrough. For non-UGRC services or endpoints the primitives can't model (queryAttachments, image export, multipoint geometries). |
mapserv (7)
All seven require UGRC_API_KEY and default to spatialReference=4326. See Configuration.
| Tool | Endpoint | Purpose |
|---|---|---|
geocode_address |
/api/v1/geocode/{street}/{zone} |
Address → coordinates |
reverse_geocode |
/api/v1/geocode/reverse/{x}/{y} |
Coordinates → address |
geocode_milepost |
/api/v1/geocode/milepost/{route}/{milepost} |
UDOT route + milepost → coordinates |
reverse_milepost |
/api/v1/geocode/reversemilepost/{x}/{y} |
Coordinates → UDOT route + milepost |
search_sgid_via_mapserv |
/api/v1/search/{table}/{fields} |
SQL-like search over mapserv-known SGID tables |
list_sgid_tables |
/api/v1/info/featureClassNames |
Enumerate mapserv-known table names |
list_sgid_fields |
/api/v1/info/fieldnames/{table} |
Enumerate columns of a mapserv table |
Geometry I/O is always GeoJSON in WGS84 (EPSG:4326). ArcGIS handles reprojection to the layer's stored SR (EPSG:26912 for most UGRC layers).
Endpoints
POST /mcp— streamable HTTP transport (preferred).GET/POST /sse— legacy SSE transport.
Live deployment
Hosted instance on Cloudflare Workers: https://ugrc-mcp.ompwwcx2yz.workers.dev — point an MCP client at /mcp. Unauthenticated and runs on my personal account, so please be nice: light, exploratory use is fine, but if you're hammering it or building something real on top, deploy your own (npx wrangler deploy — it's free-tier friendly).
Configuration
Set the mapserv API key once per environment:
- Local dev: copy
.dev.vars.exampleto.dev.varsand fill in your key (.dev.varsis gitignored). - Deployed:
wrangler secret put UGRC_API_KEY
Request a key at https://developer.mapserv.utah.gov. Tools that need it short-circuit with a clear message if the secret is unset.
Mapserv keys are issued with a Referer allow-list. The Worker sends a configurable Referer header on every mapserv request; the default (UGRC_API_REFERER in wrangler.jsonc) targets this repo's prod URL. If you self-deploy on a different workers.dev subdomain, override UGRC_API_REFERER so its value matches whatever pattern your key allows.
Setup
npm install
npm run cf-typegen # regenerate worker-configuration.d.ts after wrangler.jsonc binding changes
Develop
npm run dev # wrangler dev — server at http://localhost:8787
npm run typecheck # tsc --noEmit
npm run sync-sgid-registry # refresh src/registry/sgid.ts from agrc/sgid-index
Poke the tools with the MCP Inspector pointed at http://localhost:8787/mcp:
npx @modelcontextprotocol/inspector@latest
Deploy
npx wrangler deploy # Cloudflare account from `wrangler login`
npx wrangler tail # stream production logs
License
MIT — see LICENSE.
Acceptance test
The five canonical conversations from docs/plan.md §"Acceptance criteria" (A1–A5) — irrigated-alfalfa aggregation, reverse-geocode, parcel polygon overlay, Stratos honest-gaps cadastre query, and the springs long-tail (find_layer → NHD Springs). A fresh MCP Inspector agent must walk all five without writing Python or curl.
Installing Ugrc
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/cwoodcox/ugrc-mcpFAQ
Is Ugrc MCP free?
Yes, Ugrc MCP is free — one-click install via Unyly at no cost.
Does Ugrc need an API key?
No, Ugrc runs without API keys or environment variables.
Is Ugrc hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Ugrc in Claude Desktop, Claude Code or Cursor?
Open Ugrc on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
by modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
by xuzexin-hzCompare Ugrc with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All ai MCPs
