# Boundary Atlas: full guide for agents

> Free MCP server of US and Canadian boundaries (cities, ZIP codes, counties, districts, precincts, ridings).
> MCP endpoint: https://boundarymcp.com/mcp (streamable HTTP, no key).
> Home: https://boundarymcp.com/ · Map demo: https://boundarymcp.com/demo

## Connect

- **Claude Code:** `claude mcp add --transport http boundary-atlas https://boundarymcp.com/mcp`
- **Cursor (~/.cursor/mcp.json):** `{"mcpServers": {"boundary-atlas": {"url": "https://boundarymcp.com/mcp"}}}`
- **Codex (~/.codex/config.toml):**
  ```
  [mcp_servers.boundary-atlas]
  url = "https://boundarymcp.com/mcp"
  ```
- **Claude app (claude.ai or desktop):** `Settings → Connectors → Add custom connector → https://boundarymcp.com/mcp`
- **ChatGPT (developer mode):** `Add a custom connector: URL https://boundarymcp.com/mcp, no authentication`

Limits per IP address: 60 requests a minute, 3,000 a day, 4 at once (429 with `Retry-After` past
them). Large boundary results come back as a signed `download_url` that works for an hour.

## Server instructions

Boundary Atlas: US and Canadian boundaries and lookups. Cities and towns (Census places), ZIP codes
(Census ZCTAs), counties, towns and townships, congressional and state legislative districts (the maps in force for the
Nov 3, 2026 election), voting precincts, and Canadian provinces, ridings and polling divisions.
IDs look like '<cc>:<level>:<code>': 'us:state:34', 'us:county:34013' (FIPS), 'us:place:1714000' (Chicago),
'us:zcta:07102', 'us:congressional_district:3410', 'us:precinct:...' (the current precinct where a state publishes
one, else the 2020 Census VTD; check `vintage`), 'us:vtd_2020:...' (2020 VTDs kept for historical joins),
'ca:province:35', 'ca:federal_electoral_district:35001'.
What contains an address or point: geocode it, then locate_point. Find IDs by name with search_geographies.
Cross between units with related_geographies (population shares: a ZIP's cities, counties and districts; a city's
districts; level='zcta' lists the ZIPs in a city, county or district). Walk the hierarchy with list_children.
Polygons: get_boundaries (GeoJSON; big sets come back as a download link, not inline). Every record carries its
source, vintage and updated_at; call data_freshness before relying on precincts, which change between elections.
lat/lon are internal points (inside the shape). Districts are not nested inside counties; their parent is the state.
ZCTAs approximate USPS ZIP Codes.

## How to use the tools well

1. Find IDs with `search_geographies` (filter by `country`, `level`, `region`). IDs are `<cc>:<level>:<code>`:
   `us:place:1714000` (Chicago), `us:county:34013`, `us:zcta:07102`, `us:congressional_district:3410`,
   `us:precinct:34013030504`, `ca:federal_electoral_district:35110`. Cities and towns are level `place`: incorporated
   places plus Census-designated places (named unincorporated communities; `extra.incorporated` is false).
2. Walk down with `list_children` (state → counties/districts, county → precincts/towns, riding → polling divisions),
   or across with `list_geographies` (all districts of one kind in a state/province).
3. Cross between units with `related_geographies`: a precinct's, town's, city's or county's congressional and
   legislative districts (a city also lists its counties); every precinct in a district (`level='precinct'`); the ZIP
   codes in a city, county or district (`level='zcta'`). `weight` is the population share; 'overlaps' means split.
4. Check a precinct's `vintage` and `source_id` before relying on it. Current official precincts (2022–2026) cover
   about 92% of the US population: statewide files in 34 states + DC, county/town files elsewhere. Counties without
   one keep 2020 Census VTDs (`data_freshness` lists every source and licence). Replaced 2020 VTDs remain as level
   `vtd_2020`. Oregon counties without a current file have no precinct rows. Canada has federal polling divisions
   (2025), provincial ridings and, for most provinces, provincial polling divisions.
5. To find what contains an address, geocode it, then call `locate_point` (true point-in-polygon; results flagged
   `approximate` were snapped to the nearest shape within ~1 km). `nearest_geographies` is only a nearest-centroid
   approximation. For a ZIP code, use `us:zcta:<zip>` (2020 Census ZIP Code Tabulation Areas): `related_geographies`
   gives its cities, counties, towns, precincts and districts with each one's share of the ZIP's population (use the
   shares to split ZIP-level data across counties or cities), and `get_boundaries`
   with `children_level='precinct'` draws its precincts. Tell users ZCTAs only approximate USPS ZIP Codes
   (PO-box-only ZIPs have none).
6. Who represents a place: `find_officials(id=...)` (a district, state, city, county or ZIP) or
   `find_officials(lat=..., lon=...)` for an exact point. Members of the U.S. House and Senate serving now, with party,
   phone, website and contact form; for areas split across districts each representative has a `share`. Representatives
   in states that redrew for 2026 carry a `note` (elected under the previous map). State legislators come from Open
   States (pass state_legislators=False to skip them). Mayors (local=True) come from Open States or Wikidata; a
   Wikidata mayor's `note` says to confirm on the city's website. For a city's or county's official website and,
   where known, its council's page, read the `links` in get_geography.
7. For maps, call `get_boundaries` with `children_level` (every `place` in a state, every `precinct` in a county) and
   `include_districts=true` if the dashboard joins results by district. Big sets come back as a `download_url`
   (hosted: `curl -o` it into the project within the hour) or a `file` (local: copy it in). Features carry `id`,
   `code`, `name`, `vintage` and `source_id`; join results on `code` within the county, and check `source_id` to tell
   current precincts from 2020 Census VTDs. Use detail `low` for a whole state, `medium` for a county.
8. Keep the `source` attribution from `get_geography` in anything you publish (Census: "Source: U.S. Census Bureau";
   Elections Canada: OGL-Canada notice; Statistics Canada: the "Adapted from Statistics Canada…" line).

When matching an election-night results feed (e.g. Clarity ENR precinct names) to precinct IDs, list the county's
precincts once and match names locally; precinct names in results feeds rarely match Census names exactly.

The hosted server is free and needs no key. It is rate-limited per IP address (60 requests a minute, 3,000 a day,
4 at once); on a 429, wait for the `Retry-After` seconds. Batch where you can: one `get_boundaries` call with
`children_level` beats hundreds of single-shape calls.

## Coverage

- cities and towns: 32,350
- ZIP codes (ZCTAs): 33,774
- counties: 3,222
- towns and townships: 36,297
- congressional districts: 437
- state senate districts: 1,958
- state house districts: 4,873
- voting precincts: 182,778
- Canadian federal ridings: 343
- federal polling divisions: 71,217
- provincial districts: 761

## Tools

### search_geographies(query: str, country: str | None = None, level: str | None = None, region: str | None = None, limit: int = 20)

Find geographies by name, e.g. 'Essex County', 'Newark ward 5', 'Toronto Centre'.

country: 'US' or 'CA'. level: one of the levels from coverage_summary (e.g. 'county', 'precinct',
'congressional_district', 'federal_electoral_district'). region: USPS state or province code ('NJ', 'ON').

### get_geography(id: str)

Full record for one geography: attributes, parent chain up to the country, child counts by level,
and the source it came from (licence, vintage, last fetched).

### list_children(id: str, level: str | None = None, limit: int = 200, offset: int = 0)

Geographies directly under `id` (state -> counties and districts, county -> precincts and towns,
province -> ridings). Filter with `level`; page with limit/offset (max 1000).

### list_geographies(country: str, level: str, region: str | None = None, limit: int = 500, offset: int = 0)

Every geography at one level, optionally within one state/province, e.g. all congressional districts
in 'NJ' or all federal ridings in 'ON'. Page with limit/offset (max 1000).

### related_geographies(id: str, level: str | None = None, min_weight: float = 0.0, limit: int = 500, offset: int = 0)

Links between geographies that overlap without nesting, with population shares.

Districts: for a precinct, county, town, city (place) or ZIP, the congressional, state senate and state house
districts it falls in; for a district, the precincts, counties, towns, cities or ZIPs inside it (filter with
`level`, e.g. 'precinct'). A city ('us:place:1714000') also lists its counties. A ZIP ('us:zcta:07102') lists the
cities, counties, towns, precincts and districts it overlaps. Ask for `level='zcta'` on a city, county, town or
district to list the ZIP codes in it.
`weight` is the share of the smaller unit's 2020 population inside the other (for a ZIP, the share of the ZIP's
residents in each unit; 0 for parts with land but no residents). relation 'within' means wholly inside (1.0),
'overlaps' means split, 'approximate' means the unit was too small to contain any 2020 block's internal point and
was placed by the nearest block. Use min_weight to drop slivers. ZCTAs approximate USPS ZIP Codes.

### find_officials(id: str | None = None, lat: float | None = None, lon: float | None = None, state_legislators: bool = True, local: bool = True)

Who represents a place: members of the U.S. House and Senate, state legislators and the mayor, with contacts.

Give a geography `id` (a congressional district, state, city 'us:place:...', county, town or ZIP 'us:zcta:...')
or a point (`lat`, `lon`; geocode an address first). For a city, county or ZIP that spans several districts, each
representative comes with `share` = share of that area's 2020 residents in the district; for an exact answer use a
point. Members listed are those serving now (119th Congress, until January 3, 2027); the districts are the 120th
Congress maps elected November 3, 2026. In states that redrew for 2026 (AL, CA, FL, LA, NC, OH, TN, TX, UT) a
representative's `note` says they were elected under the previous map. A district with no member is vacant.
State legislators (state_legislators=True, except for a whole state, where pass it explicitly) come from Open
States; members in states that redrew legislative maps for 2026 (MI, MN, MS) carry a similar note.
Mayors (local=True) come from Open States (larger cities, while their term runs) or, failing that, Wikidata
(one current head of government, in office since 2010; their `note` says to confirm on the city's website).
Sources: the @unitedstates congress-legislators dataset (CC0), Open States (public domain), Wikidata (CC0).
US only for now.

### locate_point(lat: float, lon: float, levels: list[str] | None = None)

Which geographies contain a point: precinct, county, town, congressional and state legislative districts in
the US; province, census division and subdivision, federal riding, polling divisions and provincial districts in
Canada. Point-in-polygon on stored boundaries (simplified to ~10 m, so a point within ~10 m of a line can land on
either side). Geocode an address to lat/lon first.

levels: restrict to some levels (default: all except 'vtd_2020'). If a point is just outside every shape of a
level that its state/province has (a pier, a beach, a gap between precinct files), it is matched to the nearest
shape of that level in the same state/province within ~1 km and flagged approximate=true with distance_m.
not_found lists levels the state/province has data for but no shape here; no_data lists levels with no
boundaries there at all (e.g. Nebraska has no state house; Ontario has no provincial polling divisions here).

### get_boundaries(id: str, children_level: str | None = None, detail: str = 'medium', include_districts: bool = False, clip_to_land: bool = True, offset: int = 0, limit: int = 2000, inline_max_kb: int = 100)

Polygon boundaries as a GeoJSON FeatureCollection (EPSG:4326, RFC 7946 winding), for drawing dashboard maps.

id: the geography to draw, e.g. 'us:county:34013'. children_level: draw everything at that level inside it
instead, e.g. every 'precinct' in a county or state, every 'county' in a state, every 'polling_division' in a
riding, or every 'precinct' overlapping a congressional district (any share; use related_geographies for shares).
detail: 'high' (~10 m), 'medium' (~50 m, default) or 'low' (~200 m). Neighbouring shapes from the same source
share identical edges at every detail level. clip_to_land: trim open water (ocean, bays, Great Lakes) using
the state/province shoreline outline (default true; inland lakes are not trimmed; shorelines are generalized
to ~1:500k, widened ~200 m so land isn't cut); false gives legal extents. include_districts: add each feature's
congressional / state senate / state house district holding the largest share of its population.
Feature properties: id, level, code, name, parent_id, region, population (2020 Census for precincts and towns,
latest estimate for counties and states), vintage and source_id (2020 Census VTDs have source_id
'us-census-vtd-2020'; current precincts don't), shape_source.

Small results come back inline as `geojson`. Larger ones are not returned inline (they'd flood the
conversation): the hosted service returns a short-lived `download_url` (fetch it with curl into your project);
a local server writes the file to its own export folder and returns `file` (copy it into your project). Page
big selections with offset/limit (max 5000 features).

### nearest_geographies(lat: float, lon: float, level: str, limit: int = 5)

Geographies at `level` whose internal point is closest to (lat, lon). This is a nearest-point
approximation, not point-in-polygon. To find the geography containing a point, use locate_point.

### data_freshness()

When each upstream dataset was last fetched and checked, what period it describes (vintage),
how often it is re-checked, and whether it is overdue. Includes the recent refresh history.

### coverage_summary()

What's in the atlas: row counts by country and level, with the vintage of each layer.

## Guides

### How to convert ZIP code data to counties (or cities, or districts)

ZIP codes don't nest inside counties, cities or districts, so a ZIP-level count can't simply be moved to one county. Split it by population instead: Boundary Atlas gives, for every ZIP, the share of its 2020 residents in each county, city, town and congressional or legislative district. Multiply your ZIP counts by those shares and add them up by county.

Ask your agent: Here's a CSV of counts by ZIP code. Use Boundary Atlas to split each ZIP across counties by population share and give me totals by county.

https://boundarymcp.com/guides/zip-to-county-crosswalk
### How to find the congressional and state legislative districts for an address

Geocode the address to latitude and longitude, then check which boundaries contain that point. Boundary Atlas does the second step for every level at once: city, county, ZIP, congressional district, state senate and state house districts and voting precinct, under the maps in force for November 3, 2026. For one address, use the free lookup page; for many, let an agent loop through them.

Ask your agent: For each address in this list, find its congressional district, state senate and state house districts and county using Boundary Atlas. Geocode with the free Census Geocoder first.

https://boundarymcp.com/guides/find-districts-by-address
### How to list the ZIP codes in a city, county or congressional district

Ask for the ZIP codes linked to the city, county or district, with each ZIP's share of residents inside it. That lets you keep ZIPs that are mostly inside and drop ones that only clip the edge, which a plain list can't tell you.

Ask your agent: List the ZIP codes that are at least half inside Houston, TX, with the share of each ZIP's residents in the city.

https://boundarymcp.com/guides/zip-codes-in-a-city
### How to assign leads and accounts to sales territories by city, county or district

Define territories as sets of counties, cities, ZIPs or districts, then place each lead's address in them: geocode the address, call locate_point, and look the result up in your territory table. Because every area has a stable ID, territories survive renames, and you can draw them as GeoJSON for the team.

Ask your agent: Here are our territories as lists of counties. For each new lead's address, find the county with Boundary Atlas and tell me which territory owns it.

https://boundarymcp.com/guides/route-leads-by-territory
### How to map election results by precinct

Get the precinct boundaries for the county or district, join your results on the precinct code, and colour the map. Boundary Atlas has current official precincts for about 92% of the US population (2020 Census voting districts elsewhere), each tagged with its congressional and legislative districts.

Ask your agent: Get the precincts for Essex County, NJ from Boundary Atlas as GeoJSON with their districts, join this results CSV on precinct name, and make a choropleth.

https://boundarymcp.com/guides/map-election-results-by-precinct
### How to match members or supporters to their legislative districts

Place each member's address in its congressional, state senate and state house districts, then count members per district. The 2026 maps include the mid-decade redraws, so a list matched before 2025 may be out of date.

Ask your agent: Match each member's address to their congressional and state legislative districts with Boundary Atlas and give me member counts per district.

https://boundarymcp.com/guides/match-members-to-districts
### How to make a map of your data by county, city or district

Get the boundaries as GeoJSON, join your numbers on the area code, and colour by value. One get_boundaries call returns every county, city, ZIP, district or precinct inside a state or county, at a detail level that fits a web map.

Ask your agent: Using Boundary Atlas, get Ohio's counties as GeoJSON at low detail and make a choropleth of this CSV by county FIPS.

https://boundarymcp.com/guides/map-data-by-county-or-district
### How to tell whether an address is inside city limits

Locate the address and see whether it falls in an incorporated city, town or village. If it lands in a Census-designated place, or no place at all, it's unincorporated and served by the county. That decides which taxes, permits, police and services apply.

Ask your agent: Is 7700 Wisconsin Ave, Bethesda, MD inside city limits? Use Boundary Atlas.

https://boundarymcp.com/guides/inside-city-limits
### How to find the federal riding and polling division for a place in Canada

Check the location against Elections Canada's boundaries: Boundary Atlas returns the federal riding (2023 Representation Order), the federal polling division from the 2025 general election, the provincial district and, for most provinces, the provincial polling division.

Ask your agent: Which federal riding and polling division is Toronto City Hall in? Use Boundary Atlas.

https://boundarymcp.com/guides/canada-riding-by-location
### How to find who represents an address in Congress and the state legislature

Place the address in its districts, then look up who holds each seat. Boundary Atlas does both: its find_officials tool returns the member of the U.S. House, both U.S. senators, and the state senator and state representative for any point, with party, phone and website. Use the free lookup page for one address.

Ask your agent: Who are the members of Congress and state legislators for 233 S Wacker Dr, Chicago? Use Boundary Atlas.

https://boundarymcp.com/guides/who-represents-an-address
### How to find a city's or county's official website and code of ordinances

Find the place, then read its links: Boundary Atlas has the official website for more than 15,000 US cities, towns and counties (from Wikidata and the federal .gov registry, each checked to load), and links to a search for the local code of ordinances, which most places publish through a code host such as Municode, American Legal or eCode360.

Ask your agent: Find the official websites for Chicago and Cook County, and where Chicago publishes its municipal code.

https://boundarymcp.com/guides/find-local-government-websites

## FAQ

**Is there an MCP server for US boundaries like cities, ZIP codes, counties and districts?**
Yes. Boundary Atlas is a free MCP server of US and Canadian boundaries: cities and towns, ZIP codes, counties, towns and townships, congressional and state legislative districts, and voting precincts, plus Canadian provinces, ridings and polling divisions. Add https://boundarymcp.com/mcp to Claude, ChatGPT, Cursor or Codex; no key or sign-up.

**What city, county and congressional district is an address in?**
Geocode the address to latitude and longitude, then call locate_point: a point-in-polygon lookup that returns the city, county, town, ZIP code, congressional and state legislative districts and voting precinct containing it. The map demo does this for any US address with the free Census Geocoder.

**What county or city is a ZIP code in?**
Often more than one: ZIP codes cross county lines and city limits (90210 is mostly Beverly Hills and partly Los Angeles). related_geographies on a ZIP (for example us:zcta:90210) returns every city, county and town it overlaps with each one's share of the ZIP's 2020 population, so you can split ZIP-level data correctly.

**How do I find which congressional district a ZIP code is in?**
Many ZIP codes span more than one district, so a single answer is often wrong. Ask Boundary Atlas for the ZIP: related_geographies returns every congressional, state senate and state house district it overlaps with each one's share of the ZIP's residents, and get_boundaries draws them.

**Which ZIP codes are in a city, county or district?**
Call related_geographies on the city, county or district with level='zcta'. Each ZIP comes with the share of its residents inside, so ZIPs that only clip the edge are easy to drop.

**Where can I get GeoJSON boundaries for cities, counties, districts or precincts?**
get_boundaries returns GeoJSON for any single area, or everything at one level inside another: every city in a state, every precinct in a county or district, every county in a state. Three detail levels; water can be trimmed. Large sets come back as a download link.

**How current are the precincts and district maps?**
Precincts are current official files for about 92% of the US population (statewide files in 34 states and DC, plus 437 county, town and municipio sources), with 2020 Census voting districts elsewhere. Districts are the maps in force for the November 3, 2026 election, including the 2025–26 mid-decade redraws.

**Are ZIP codes the same as ZCTAs?**
Not quite. ZIP Code Tabulation Areas are the Census Bureau's approximation of USPS ZIP Codes, built from 2020 blocks. PO-box-only and single-building ZIPs have none, and a mailing address's ZIP can differ from the ZCTA its location falls in. Boundary Atlas uses ZCTAs and says so.

**Does it cover Canada?**
Yes: provinces, census divisions and subdivisions, the 343 federal ridings (2023 Representation Order), federal polling divisions from the 2025 general election, provincial electoral districts, and provincial polling divisions for most provinces.

**Where does the data come from?**
Every record carries its source, licence, vintage and last update, and data_freshness lists each source with its refresh history. Sources include the U.S. Census Bureau (TIGER/Line and the 2020 Census; public domain), state and county election offices, Elections Canada and Statistics Canada. Keep their attribution in anything you publish.

**Is it free?**
Yes. The hosted server needs no key. It is rate-limited per IP address (60 requests a minute, 3,000 a day) so it stays fast for everyone.

## Attribution

Sources include the U.S. Census Bureau (TIGER/Line, 2020 Census; public domain), state and county election offices,
Elections Canada (Open Government Licence – Canada) and Statistics Canada ("Adapted from Statistics Canada…").
`data_freshness` lists every source with its licence and refresh history. Keep the attribution in anything you
publish.
