Perch Civic MCP — civic data for AI agents
One canonical, agent-queryable interface over the fragmented open-data portals of US cities. Ask an agent about 311, crime, crashes, or permits in any covered metro without learning each city's schema.
Perch is a living civic map (perchmap.com). This connector exposes the same per-city data contracts as MCP tools — street-level and real-time, the machine-readable complement to county-level sources like USAFacts. See it in action: a live cross-city comparison dashboard.
Connect
Hosted endpoint — add it to any MCP client by URL:
https://perch-civic-mcp.summer-sky-2a4d.workers.dev/mcp
In claude.ai → Settings → Connectors → Add custom connector, paste that URL — no install, no auth.
There's also a plain REST interface for non-MCP clients (/api/cities, /api/query, /api/weather, …) — AI-agnostic JSON, same data, same edge endpoint.
No authentication. It returns only already-public open-government data and never writes anything — read-only by construction.
Tools
Eight read-only tools — five for the canonical per-city datasets, three city-agnostic external feeds. Bad inputs return a JSON error rather than throwing, so exploration is safe.
list_cities()
Covered metros, each city's timezone, and the set of dataset keys it publishes (the coverage map).
list_datasets(city)
Datasets available for one city, with source type and attribution.
describe_dataset(city, dataset)
Which canonical fields this city exposes (category / date / status / area / location) and the raw field each maps to. A missing field = this city doesn't publish it.
query(city, dataset, filters, …)
Canonical query — category, status, area, date_from/to, bbox, plus select/group/order/limit. Works across cities despite different raw schemas.
query_raw(city, dataset, where, …)
Escape hatch — raw backend query (SoQL / SQL-92) for fields not yet canonicalized.
weather_history(city, …)
Daily historical weather for any city (precip, temp, rain-only) — cross-reference crashes on rainy days.
wildlife(city, …)
Recent iNaturalist species observations near a city.
wildfires(city, …)
Active wildfires & prescribed burns near a US city (NIFC/WFIGS).
Trying it out
list_cities→list_datasets(city)→describe_dataset(city, dataset)→query(…)
Derive city/dataset keys from live calls rather than hardcoding — coverage varies by city. A few things the canonical layer makes easy:
query(city:"austin", dataset:"crashes", filters:{ date_from:"2026-01-01" }, select:"count(*) as n")
query(city:"nyc", dataset:"311", filters:{ area:"BROOKLYN", category:"Noise - Residential" })
The real payoff is cross-feed and cross-city questions — "most dangerous intersections on rainy days" (crashes + weather), or "which metros publish crash severity at all" (the coverage map itself).
Coverage
23 US metros today, across 311, crime, crashes, and building permits (coverage varies by city), served through four open-data backends behind one canonical interface: Socrata (Austin, New York City, Chicago, Los Angeles, San Francisco, Seattle, Dallas, Cincinnati, New Orleans, Oakland, Kansas City, Honolulu, Montgomery County MD), ArcGIS (Washington DC, Detroit, Nashville, Baltimore, Louisville, Denver, Atlanta), CKAN (Boston, San Antonio), and Carto (Philadelphia). The same query works across all of them.
Each city is a declarative contract, so new metros are added as data, not code. Layer availability differs per city — that heterogeneity is queryable (the coverage map), not hidden.
Data & terms
All data is open government data served under each source's license (e.g. Socrata open-data portals, public-domain federal data). Every response carries source attribution — please cite it. Perch is an independent project and is not an official endpoint of any city.
Read-only · public data only · no personal data held · the connector never places a request on your behalf beyond the public API it cites.