turnout.apppublic · no accounts · no tracking
For developers & AI assistants

A public MCP server,
so AI can answer civic questions correctly.

Connect Claude Desktop, ChatGPT, Cursor, or any other Model Context Protocol client to mcp.turnout.app and ask questions like “What’s on the ballot for 11211?” The model gets real, citation-bearing answers from US Census TIGER/Line, FEC, FVAP, Google Civic, Clarity Elections, and NCSL — 26 tools, no auth, no API key.

Connect Claude Desktop in 30 seconds

Drop this into your config file.

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows). Restart Claude Desktop. Look for the “Search and tools” icon — turnout will appear with all 26 tools listed.

{
  "mcpServers": {
    "turnout": {
      "url": "https://mcp.turnout.app/mcp"
    }
  }
}
Live tool surface · 26 tools

What the AI can call.

Server-rendered from a build-time tools/list POST to https://mcp.turnout.app/mcp. Argument shapes are mirrored from the zod input schemas in mcp-public/src/tools.ts. Refreshed every 10 minutes — new tools appear without a redeploy.

elections.list_upcoming1T1 · official source of record

List upcoming US elections. Optionally filter by state (two-letter code) or OCD-ID, and a date floor.

Input
state?string(2)two-letter code
ocdId?string
afterDate?ISO date
limit?int 1-100default 20
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"elections.list_upcoming","arguments":{"state":"GA"}}}' \
  | jq .result.structuredContent
geo.lookup_divisions1T1 · official source of record

Given a longitude and latitude, return all political divisions (OCD-IDs) the point falls within: state, congressional district, state senate, state house, county, city, school district.

Input
lngnumber
latnumber
vintage?'2024' | '2025'default 2024
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"geo.lookup_divisions","arguments":{"lng":-73.9619,"lat":40.7128}}}' \
  | jq .result.structuredContent
geo.geocode1T1 · official source of record

Resolve a free-text address, ZIP code, or 'City, ST' string to a latitude/longitude. Uses ZIP Code Tabulation Area centroids and TIGER place-name centroids; no external API key needed.

Input
querystring(3-200)ZIP, 'City, ST', or address
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"geo.geocode","arguments":{"query":"94110"}}}' \
  | jq .result.structuredContent
civic.voting_info3T3 · curated

Return voter ID requirements, vote-by-mail rules, online registration URL, and polling-place lookup URL for a US state. Covers all 50 states + DC.

Input
statestring(2)
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.voting_info","arguments":{"state":"TX"}}}' \
  | jq .result.structuredContent
civic.get_district_issues1T1 · official source of record

Return upcoming ballot items / contests for a given OCD-ID. Useful for Claude Desktop or ChatGPT to answer 'what's on the ballot for X?'.

Input
ocdIdstring
limit?int 1-20default 5
lang.translate5T5 · turnout.app interpretation

Translate text between en/es/zh/ht/vi/ar/tl. The public MCP server returns a client-side resolution instruction; canvass clients run the model on-device.

Input
textstring(1-5000)
targetLanguageen|es|zh|ht|vi|ar|tl
Resolution is intentionally client-side — canvass clients run NLLB-200 on-device.
civic.list_states1T1 · official source of record

Return all 50 US states + DC + territories with their two-letter codes and OCD division IDs. Useful for clients enumerating coverage.

No arguments.
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.list_states","arguments":{}}}' \
  | jq .result.structuredContent
civic.find_polling_place1T1 · official source of record

Return the authoritative state polling-place lookup URL for a state. Optionally supplies a ZIP centroid for context. The MCP server does NOT host a polling place database — the URL is the only source of truth.

Input
statestring(2)
zip?string(/^\d{5}$/)
Returns the SOS lookup URL — never a polling-place database.
civic.about_state3T3 · curated

Return state-level civic facts: capital, time zone(s), sitting governor (name + party), both U.S. senators with class numbers, U.S. House seat count, 2020 census population, and whether the state holds a 2025 statewide general election. Hand-verified data; refreshed periodically until the real-time feed lands.

Input
statestring(2)
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.about_state","arguments":{"state":"OH"}}}' \
  | jq .result.structuredContent
civic.house_districts1T1 · official source of record

List all U.S. House congressional districts in a state, with OCD-IDs and FIPS district codes. Sourced from US Census TIGER/Line 119th Congress shapefiles.

Input
statestring(2)
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.house_districts","arguments":{"state":"NY"}}}' \
  | jq .result.structuredContent
civic.my_reps1T1 · official source of record

Composite 'who represents me' lookup. Takes a ZIP, 'City, ST', or address; geocodes, resolves all 7 political divisions, and returns: governor + state senators (federal Class 1+2+3) + U.S. House district + state legislative districts + county + city. Single round-trip.

Input
querystring(3-200)ZIP, 'City, ST', or address
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.my_reps","arguments":{"query":"94110"}}}' \
  | jq .result.structuredContent
civic.about_division5T5 · turnout.app interpretation

Return a Wikipedia summary for a political division (state, congressional district, county, city, etc.) given its OCD-ID. Server-side cached up to 24h. Wikipedia content is CC BY-SA 4.0; preserve attribution.

Input
ocdIdstring
vintage?'2024' | '2025'default 2024
Wikipedia content is CC BY-SA 4.0 — preserve attribution.
civic.uocava_info1T1 · official source of record

Return UOCAVA / military / overseas voter information for a US state or territory: deadlines (registration, FPCA, FWAB, ballot return), local election office contacts, FPCA/FWAB/VBR ballot rules, and Q&A. Sourced from FVAP eVAG XML feeds; federal authority tier; cached server-side via the fvap_* tables.

Input
statestring(2)
civic.uocava_deadlines1T1 · official source of record

Slim variant of civic.uocava_info: just the upcoming UOCAVA deadlines for a state. Most-asked question for military / overseas voters checking 'have I missed the cutoff?'.

Input
statestring(2)
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.uocava_deadlines","arguments":{"state":"WV"}}}' \
  | jq .result.structuredContent
civic.live_results2T2 · official-republished

Live election returns from Clarity Elections (Civix), the vendor that powers GA, CO, PA, AZ, OH, MO, MN, NV, IN, WV and ~25 other states' results portals. Pass state (and optional county) to get the most recent election's contest-level summary with reporting progress and candidate vote totals. Pass electionId to query a specific past election. The data is republished from the state / county SOS — always cite back to that authority of record for certified results.

Input
statestring(2)
county?string
electionId?string
Clarity / Civix vendor — covers ~30 states.
civic.fl_results2T2 · official-republished

Live Florida county election results from the Florida ENR (voterfocus) network. Pass a 3-letter FL county code (e.g. DAD = Miami-Dade, BRO = Broward, ORA = Orange, DUV = Duval) and a known election ID. Returns contest-level summary with candidate vote totals, party labels, and precincts-reporting progress. Includes a cite-able 'data as of' Unix timestamp. NOTE: voterfocus removed automatic election-ID discovery in 2026 — callers must know the EID, typically from the county Supervisor of Elections site.

Input
countystring(2-8)FL 3-letter code
electionIdstring
Florida voterfocus dropped auto-discovery in 2026 — caller must know the EID.
civic.gis_layer1T1 · official source of record

Generic GIS adapter — fetches county-published ArcGIS FeatureServer layers for drop-boxes, polling places, or sample-ballot zones. Pass a 5-digit county FIPS (e.g. 53033 = King County, WA; 42101 = Philadelphia, PA) and a task ('drop-box' default, 'polling-place', 'sample-ballot'). Returns GeoJSON-style features with point/polygon geometry + free-form attributes (name, address, hours, accessibility, ward/division). Wired for King County drop-boxes (84 features) and Philadelphia polling places (1,703 features). Fulton 13121 + Maricopa 04013 endpoints are TODO.

Input
countyFipsstring(2-8)
task?drop-box | polling-place | sample-ballotdefault drop-box
resultRecordCount?int 1-2000
Wired for King County (53033) drop-boxes and Philadelphia (42101) polling places.
civic.ballot_measures1T1 · official source of record

Statewide 2026 ballot measures (constitutional amendments, citizen initiatives, bond questions, etc) for a US state. Pass the 2-letter state code (e.g. 'GA', 'VA', 'LA'). Returns each measure's official ballot designation, official title (verbatim where the SOS has published it), turnout.app plain-language paraphrase clearly labeled as interpretation, measure type, source URL on the state SOS site, and verifiedAt date. Hand-curated from per-state SOS pages; primary states with measures: GA (3), VA (3+1 special), LA (6), SD (2), MI (1), AR (4), HI (1), NV (2), TN (3), ND (3), OK (1 special), VT (1), NC (1).

Input
statestring(2)
onOrAfter?ISO datedefault today
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.ballot_measures","arguments":{"state":"VA"}}}' \
  | jq .result.structuredContent
civic.voter_info2T2 · official-republished

LIVE voter information for a residential address via the Google Civic Information API. Returns the upcoming election, full contest list (federal/state/local/referendum) with candidates including party, websites, phone, email and social channels; polling places; early-vote sites; drop-off locations; and election-administration URLs (registration, mail-ballot info, polling lookup). The most comprehensive per-voter ballot resource. Returns null when Google has no current election for the address (common off-cycle).

Input
addressstring(5-300)
officialOnly?boolean
electionId?string
Returns null when Google has no current election for the address (common off-cycle).
civic.officeholders1T1 · official source of record

Current incumbents for federal offices in a US state. House members keyed by ocd-division/country:us/state:{st}/cd:{N}; senators by virtual ocd-division/country:us/state:{st}/senate:{bioguideId} (Civic doesn't district-key Senate). Governor + statewide officials from hand-curated state-data.ts. State legislators (upper + lower) returned grouped by district as `{districtOcdId, districtNumber, members[]}` so multi-member districts (WV, NH, MD, VT, NJ, MA) preserve all sitting members. Optional ocdIds[] filter to limit to a specific ballot. Source: api.congress.gov + OpenStates v3, refreshed every 7 days.

Input
statestring(2)
ocdIds?string[]filter to specific divisions
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.officeholders","arguments":{"state":"WV"}}}' \
  | jq .result.structuredContent
civic.admin_authority3T3 · curated

Returns the local election-administration authority for a US state — `tier` is one of county/municipal/township/town/parish/borough/none. Used by UI copy to route to 'your town clerk' vs 'your county clerk' vs 'your parish Registrar of Voters' depending on jurisdiction. Town-only states: ME, NH, VT, RI. Municipal: MA, WI, CT. Township: MI. Parish: LA. Borough: AK. ND has no voter registration at all.

Input
statestring(2)
Tells UI copy whether to route to county clerk vs town clerk vs parish Registrar.
civic.candidate_finance1T1 · official source of record

Federal-candidate campaign finance summary for the 2026 cycle (default). Source-of-record: the FEC OpenFEC API. Returns each candidate's name, party, office (H/S/P), state + district, OCD-ID, status (Challenger/Incumbent/Open), and summary financials — total receipts, total disbursements, cash on hand, debts owed, and the coverage end date of the most recent filing. Filter by any of: 2-letter state, OCD division ID (e.g. 'ocd-division/country:us/state:wv/cd:1'), office ('H' / 'S' / 'P'), or cycle. Refreshed daily server-side. Tier-1 confidence; FEC filings are mandatory under FECA.

Input
state?string(2)
ocdId?string
office?'H' | 'S' | 'P'
cycle?int 1980-2100default 2026
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.candidate_finance","arguments":{"state":"WV","office":"H"}}}' \
  | jq .result.structuredContent
civic.census_profile1T1 · official source of record

US Census ACS 5-year demographic profile for a political division, keyed by OCD-ID. Supports state, congressional district, and county geographies (e.g. 'ocd-division/country:us/state:wv', '.../state:wv/cd:2', '.../state:wv/county:kanawha_county'). Returns total population, median age, median household income, race breakdown (white/black/asian/hispanic/other percentages), and percent with bachelor's degree or higher. Optional `vintage` argument (2018-2024) selects a historical ACS 5-year release; defaults to the latest (2023). Tier-1 confidence — Census Bureau is the federal source-of-record for demographic statistics (13 USC § 141, § 193). Cached server-side keyed by (ocdId, vintage); the underlying ACS data only refreshes once per year.

Input
ocdIdstring
vintage?int 2018-2024default 2023 (latest)
civic.health1T1 · official source of record

Aggregate operational health snapshot for the public turnout.app data infrastructure. Returns row counts and last-refresh timestamps for every backing dataset: source registry (505 URLs), federal + state-leg officeholders, federal committee assignments, FEC candidate finance (cycle 2026), TIGER/Line divisions (vintage 2024 + 2025), FVAP UOCAVA jurisdictions, NCSL voter rules, Google Civic Information probe coverage, hand-curated ballot measures, Census ACS cache, and the full public tool list. Powers the /status page on turnout.app and any external uptime checker that wants a single GET to assert freshness across the whole stack.

No arguments.
Aggregate operational snapshot. Powers the /status page.
TRY IT WITH CURL
curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"civic.health","arguments":{}}}' \
  | jq .result.structuredContent
civic.registry_status

Per-URL freshness for every catalogued source in the turnout.app registry. Returns the most recent verifier sweep result for each URL: status code (200 = ok, 0 = manual or SPA-shell skip, 4xx/5xx = fail), last-ok timestamp, last-checked timestamp, last error sentinel, derived verify mode (http/spa-shell/manual), and the state + task labels stamped by the verifier. Pass `urls[]` for an exact-match lookup of specific URLs, or `stateCode` (2-letter) to filter to one jurisdiction. With no arguments returns the full set (~505 rows). Capped at 1000 rows. Backs the /sources page status pills and any external freshness audit.

civic.bill_detail

Single-bill detail for a federal bill identified by (congress, billType, billNumber). Returns title, plain-text summary (when Congress.gov has published one), sponsor, full cosponsor list (capped at 50 most-recent), latest action, policy area, and the canonical congress.gov URL. Tier-1 confidence — Congress.gov is the federal source-of-record for bill metadata under 2 USC 285b. Cache TTL 24h. Use this to surface 'which of my reps signed onto this bill' by joining cosponsor bioguide IDs to a delegation roster from civic.officeholders. Returns null when the bill doesn't exist on Congress.gov.

Try these in Claude

Example questions.

What's on the ballot for ZIP 11211?
civic.my_repscivic.voter_infoelections.list_upcoming
Who represents San Francisco in Congress?
civic.my_repscivic.officeholders
Tell me about California's congressional district 12.
civic.about_divisioncivic.census_profile
What are the voter ID rules in Texas?
civic.voting_infocivic.admin_authority
List all 26 NY congressional districts.
civic.house_districts
Who is the governor of Ohio and what are its US senators' names?
civic.about_statecivic.officeholders
Show me the live results for the Georgia 2026 primary.
civic.live_results
Which 2026 ballot measures are on Virginia's November ballot?
civic.ballot_measures
Find drop-boxes in King County, Washington.
civic.gis_layer
How much money has WV-01 raised this cycle?
civic.candidate_finance
What's the UOCAVA registration deadline for an Ohio voter overseas?
civic.uocava_deadlinescivic.uocava_info
Demographic profile of Ohio's 12th congressional district?
civic.census_profile
Or call it directly

JSON-RPC 2.0 · Streamable HTTP.

No auth. No API key. Spec-compliant MCP — works with any client that speaks JSON-RPC over POST. Or hit https://mcp.turnout.app/civic-health for a single GET that aggregates every dataset row count.

curl -sS https://mcp.turnout.app/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc":"2.0",
    "id":1,
    "method":"tools/call",
    "params":{
      "name":"civic.my_reps",
      "arguments":{"query":"94110"}
    }
  }' | jq .result.structuredContent
On the wire

Every tool here is read-only and sourced from public reference data. No PII flows through this server. No request bodies are logged. The Postgres database behind it has zero voter records by design — that’s a separate, end-to-end-encrypted system at canvass.turnout.app. See About for the two-sided architecture, or Sources for every dataset traced.