Charlotte Open City Data

io.github.ajwannPublished by GitHub account ajwannv1.0.1Updated Nov 2, 2026

Charlotte and Mecklenburg County open data: addresses, crime, 311, zoning, budget, and services

Overview

AI-generated overview

Read-only MCP server for Charlotte and Mecklenburg County open data, answering resident questions about addresses, crime, 311, zoning, transit and budget.

What you can do
  • Look up an address: council district, police and fire service, zoning, flood zone, parcel ID, trash and recycling schedule
  • Check safety: crime near a point, crime trends and summaries by division, traffic crashes near a location
  • Review city services and neighborhood change: nearby 311 requests, code enforcement cases, street closures, capital projects, pending rezonings
  • Find nearby places across 18 categories such as libraries, schools, parks, pharmacies, EV chargers and transit stops, and read bus route frequency
  • Inspect government data: city budget figures and aggregated salary statistics
  • Explore the whole portal: keyword search datasets, describe layer fields, run SQL-filtered queries…
When to use it
Useful when someone needs official answers about living in Charlotte or Mecklenburg County, such as what services cover an address, whether a street is closed, how crime has changed, or what the city budget allocates. Also handy for exploring the city's open data catalog without writing ArcGIS queries.
Requirements
Runs as a hosted HTTP endpoint with OAuth sign-in through Google and an email allow list, or locally over stdio via the queensestate PyPI package with uvx or a Python 3.14 virtual environment. No API key is needed for the open data portal; network access to the city and county GIS hosts is required.
Before you install
The hosted endpoint requires Google sign-in and only admits allow-listed addresses. Self-hosting the HTTP transport needs QUEENSESTATE_PUBLIC_URL, QUEENSESTATE_GOOGLE_CLIENT_ID, QUEENSESTATE_GOOGLE_CLIENT_SECRET and QUEENSESTATE_ALLOWED_EMAILS. Tools are read-only, but data is third-party and varies in freshness, geocoding only covers Mecklenburg County, and crime locations are generalized.

Installation

In SourceWeft

  1. Open Charlotte Open City Data in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.ajwann%2Fqueensestate/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "charlotte-open-city-data": {
      "type": "http",
      "url": "https://queensestate.adamwanninger.com/mcp"
    }
  }
}

README

QueensEstate ♔⛫

[CI]

An MCP server that lets an LLM answer Charlotte residents' everyday questions with official public data from the City of Charlotte Open Data Portal — https://data.charlottenc.gov.

The portal lives at data.charlottenc.gov. It is an ArcGIS Hub site; its ~380 datasets are ArcGIS REST layers run by the City of Charlotte and Mecklenburg County. No API key is required.

What's on the portal

A survey of the catalog (/api/feed/dcat-us/1.1.json) shows these main themes:

ThemeExamples
Public safetyCMPD incidents (870k+ since 2017, updated daily), homicides, traffic stops, fire incident reports, crashes
City services311 service requests (3.4M), solid-waste collection routes, code enforcement cases, street closures
Planning & zoningZoning, rezoning petitions, historic districts, 2040 policy map, floodplains, parcels
TransportationCATS bus routes and stops, LYNX light rail, park-and-ride, bike lanes, sidewalks, greenways
PlacesLibraries, schools, parks, fire/police stations, pharmacies, grocery stores, EV chargers, day care
GovernmentCapital projects, budget, employee salaries, council and commissioner districts
DemographicsCensus block groups/tracts, Quality of Life neighborhood profiles

Tools

The tools are chosen for the questions residents actually ask. Every tool is read-only, and every location parameter accepts either an address ("600 E 4th St, Charlotte") or "latitude,longitude".

My address

ToolAnswers questions like
get_address_profile"Who is my council member?" "What police division and fire station serve me?" "What's my zoning? Am I in a flood zone or historic district?"
get_trash_and_recycling_schedule"What day is trash pickup? Is this a recycling week (GREEN/ORANGE)?"
lookup_address"Is this a valid address? What's its parcel ID and municipality?"

Safety

ToolAnswers questions like
get_crime_near"Any car break-ins near my apartment this month?"
summarize_crime"How have robberies in Charlotte changed since 2019?" "Which division has the most burglaries?"
get_traffic_crashes_near"Is the intersection by my kid's school dangerous?"

City services and neighborhood change

ToolAnswers questions like
get_311_requests_near"Has anyone already reported this pothole or streetlight?"
get_code_enforcement_cases"Does the house I'm renting have open housing-code violations?"
get_street_closures"Are any roads closed on my commute?"
get_capital_projects_near"What's being built near me, when is it done, and who do I contact?"
get_pending_rezonings"Is anyone trying to rezone land near my neighborhood?"

Places and transit

ToolAnswers questions like
find_nearby_placesNearest library, school, park, greenway, pharmacy, grocery store, EV charger, light rail station, bus stop, public Wi-Fi… (18 categories)
get_bus_route"How often does the 9 run on Sunday evenings?"

Government transparency

ToolAnswers questions like
get_city_budget"How much does the city budget for Police?"
get_city_salary_stats"What do Charlotte firefighters earn on average?" (aggregates only, no names)

Anything else in the catalog

ToolPurpose
search_datasetsKeyword search over the whole portal
describe_datasetFields, types, and record count for a layer
query_datasetSQL-filtered records from any layer, optionally near a location
summarize_datasetServer-side counts/sums grouped by fields

Setup

Requires Python 3.14 (developed on 3.14.7).

bash
~/.pyenv/versions/3.14.7/bin/python -m venv .venv.venv/bin/python -m pip install -e . --group dev

Use with Claude Code

bash
claude mcp add queensestate -- /absolute/path/to/queensestate/.venv/bin/queensestate

Use with Claude Desktop

Add to claude_desktop_config.json:

json
{  "mcpServers": {    "queensestate": {      "command": "/absolute/path/to/queensestate/.venv/bin/queensestate"    }  }}

Other transports and debugging

bash
.venv/bin/queensestate --transport http --port 8000        # http://127.0.0.1:8000/mcpnpx @modelcontextprotocol/inspector .venv/bin/queensestate  # interactive inspector

The http transport authenticates its callers with Google OAuth and refuses to start without a public URL, a Google client, and an allow list — see Hosting. To try it locally:

bash
QUEENSESTATE_PUBLIC_URL=http://localhost:8000 \QUEENSESTATE_GOOGLE_CLIENT_ID=... QUEENSESTATE_GOOGLE_CLIENT_SECRET=... \[email protected] \  .venv/bin/queensestate --transport http --port 8000

Hosting

The hosted server runs on Google Cloud Run at https://queensestate.adamwanninger.com/mcp, and is its own OAuth 2.1 authorization server: it delegates the sign-in to Google purely to learn which account is calling, then checks that address against an allow list and mints its own tokens. Google's tokens are never passed through to the MCP client.

bash
claude mcp add --transport http queensestate https://queensestate.adamwanninger.com/mcp

scripts/deploy-gcp.sh provisions and deploys the whole thing, and re-running it is also how you update. See deploy/GCP.md.

Hosting is only for the HTTP transport. Running the server locally over stdio needs no Google account, no allow list, and none of the cloud dependencies.

Development

bash
.venv/bin/pytest                 # unit + in-memory MCP tests; no network access.venv/bin/ruff format --check . && .venv/bin/ruff check ..venv/bin/mypy

Layout:

  • src/queensestate/arcgis.py: async ArcGIS REST / Hub client (timeouts, bounded retries, host allowlist)
  • src/queensestate/address.py: address matching against the county Master Address layer
  • src/queensestate/catalog.py: the curated layers behind the purpose-built tools
  • src/queensestate/server.py: the MCP tools

Data notes and limitations

  • Geocoding uses Mecklenburg County's Master Address layer, so only addresses inside the county resolve. Coordinates outside the county are rejected.
  • Freshness varies by dataset: CMPD incidents, 311 requests, and code enforcement are current within days; the Budget Report dataset currently runs FY2018–FY2023. Tools report what the portal publishes.
  • CMPD locations are generalized by the department for privacy.
  • 311 data records when requests were received, not when they were resolved.
  • Timestamps are ISO 8601 in Charlotte local time with the UTC offset (e.g. 2026-09-06T00:00:00-04:00). The underlying services store UTC.
  • Budget amounts include large negative lines (e.g. "00 Non Department", Charlotte Water), so get_city_budget reports both the net total and the sum of positive lines.
  • Statistics limits: some city map services ignore resultRecordCount on aggregate queries, so the client enforces row limits itself.
  • Live bus arrivals are not on the portal; pair this server with a CATS real-time source. Bus stop IDs from find_nearby_places match CATS stop IDs.
  • The generic tools only reach hosts that serve portal datasets (gis.charlottenc.gov, meckgis.mecklenburgcountync.gov, services.arcgis.com, gis.ci.charlotte.nc.us).
  • Mecklenburg County's server rejects default Python user agents, so the client sends its own.

Ideas for more tools

  • Neighborhood Quality of Life indicators by NPA (income, age, housing, amenities)
  • Charlotte Fire incident reports by address block
  • CMPD officer traffic-stop statistics
  • Sidewalk and bike network gaps near an address
  • Tree canopy and land surface temperature by neighborhood

License

MIT - see LICENSE.

Source: README.md at commit ef76ed5

Tools

0
SourceWeft has not read this server's tools yet.

Version history

2
  1. v1.0.1LatestSep 20, 2026
  2. v1.0.0Sep 20, 2026

Score

85% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts