Skip to main content
Glama
cstillick

who_reps-mcp

by cstillick

who_reps-mcp

Address → your elected officials, as an MCP server. A free, open replacement for the Google Civic Information Representatives API, which was shut down on April 30, 2025 and left a generation of civic apps broken.

Give it a U.S. street address and it returns the people who represent it — U.S. Senators, U.S. House member, Governor, and state legislators — by stitching together free public data: address → districts (Census) → officials (open congressional + state-legislator data).

Why this exists

When Google killed representativeInfoByAddress, the official guidance was: use our Divisions API for an OCD id, then go buy officeholder data from BallotReady, Cicero, or Ballotpedia. This rebuilds the free path so an agent can just answer "who represents this address?"

Related MCP server: civic-awareness-mcp

Quick start

The federal tier needs no API keys — the Census geocoder and the unitedstates/congress-legislators dataset are both free and key-less.

uv sync

# As an MCP server (stdio):
uv run whoreps-mcp

# Or try the data path from a terminal (no keys needed):
uv run whoreps-mcp lookup "1600 Pennsylvania Ave NW, Washington, DC 20500"
uv run whoreps-mcp lookup "2300 N Lincoln Blvd, Oklahoma City, OK 73105"
#  4 officials for 2300 N LINCOLN BLVD, ...: U.S. Senator James Lankford (R);
#  U.S. Senator Markwayne Mullin (R); U.S. Representative Stephanie I. Bice (R, 5);
#  Governor Kevin Stitt (R). State legislators omitted — set OPENSTATES_API_KEY ...

To add the state-legislator tier, get a free OpenStates key, cp .env.example .env, set OPENSTATES_API_KEY, and the same lookups will include state senators and representatives.

Use it as an MCP server

{
  "mcpServers": {
    "whoreps": {
      "command": "uv",
      "args": ["run", "whoreps-mcp"],
      "cwd": "/path/to/whoreps-mcp"
    }
  }
}

Tools

Tool

What it does

lookup_officials(address)

The headline tool. Address in, full slate out (federal + state where available), each official with party, contact, term, source, and as-of date, plus OCD divisions and coverage notes.

list_districts(address)

Just the districts/divisions for an address — congressional + state-legislative districts and OCD-IDs (the piece Google's Divisions API gave, free and self-hosted).

lookup_by_district(state, chamber, district)

Skip geocoding: senate/house (federal) or upper/lower (state).

get_official_details(official_id)

Enriched detail for one official — committees + full contact where available.

Each tool returns structured JSON plus a concise text summary.

Graceful degradation

This is a civic tool, so correctness and honesty matter:

  • Federal always works, with zero keys. Missing tiers never fail the whole request — you get what's available plus coverage_notes explaining any gap.

  • DC and territories return the non-voting delegate (no senators), and note that DC has a Mayor rather than a Governor and no state legislature.

  • Bad/PO-box/new-construction addresses that don't geocode return an empty result with a note, not an error.

  • Freshness is visible. Every official carries its source and as_of date. Governors are a vendored, dated snapshot (see docs/governors.md); everything else is fetched live and cached.

How it works

address ─▶ Census geocoder ─▶ {lat/lon, congressional district, state-leg districts, OCD divisions}
                                     │
              ┌──────────────────────┼───────────────────────┐
              ▼                      ▼                         ▼
     congress-legislators     OpenStates people.geo      governors.json
     (U.S. Senate + House)    (state legislators)        (vendored)
              └──────────────────────┼───────────────────────┘
                                     ▼
                     merge + normalize -> OfficialsResponse  (SQLite-cached)

Sources live behind sources/ so the whole flow is tested against recorded fixtures — CI is fully offline.

Development

uv run pytest        # offline suite (recorded fixtures)
uv run ruff check .  # lint

If uv run whoreps-mcp ever reports No module named 'whoreps_mcp' (a known editable-install quirk on some setups, e.g. paths with spaces), run with PYTHONPATH=src uv run whoreps-mcp ....

See SPEC.md and BUILD_PLAN.md for the design.

License

MIT.

Available Tools

5 tools
get_official_detailsA

Enriched detail for one official (committees + full contact where available), by the id returned from the other tools.

ParametersJSON Schema
NameRequiredDescriptionDefault
official_idYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses that the output includes committees and full contact (where available), which is helpful behavioral context. However, it does not mention error handling, rate limits, or what happens if the id is invalid, leaving gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that immediately conveys the tool's purpose and data sources with no wasted words. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema), the description is fairly complete: it explains what the tool returns (committees + full contact) and where the id comes from. It lacks details on error handling but is adequate for an AI agent to understand usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one parameter (official_id) with 0% description coverage. The description adds meaning by specifying the id comes from sibling tools, clarifying its provenance and purpose. This compensates well but could be more precise about expected format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool provides 'Enriched detail for one official (committees + full contact where available)', specifying the verb (get details) and resource (one official). It distinguishes from siblings like list_districts and lookup_officials by focusing on a single official's detailed info.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description hints at usage context by stating the id is 'returned from the other tools', implying a sequence (first use lookup_officials, then this tool). It does not explicitly exclude scenarios or provide alternative tools, but the sibling list helps differentiate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_districtsC

Just the districts/divisions for an address (the piece Google's Divisions API still gives) — congressional + state-legislative districts and OCD-IDs.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYes

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations provided; description only notes it gives data from Google's Divisions API but does not disclose auth needs, rate limits, or behavior quirks. Limited transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, no redundancy. Front-loaded with key information. Concise but could benefit from a slight structure improvement (e.g., bullet points for district types).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers primary purpose and types of districts. Lacks output schema details and error handling. For a simple tool, it suffices; but given siblings, more context on integration might help.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% (no param descriptions). The parameter 'address' is not elaborated on—no format, examples, or constraints. Despite the single parameter, description does not compensate for schema silence.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states it lists districts/divisions (congressional, state-legislative, OCD-IDs) for an address. Differentiates from siblings like get_official_details and lookup_by_district by focusing on raw district data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus siblings. The mention 'just the piece...' implies a specific use case but does not state conditions or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_by_districtB

Officials for a chamber + district, skipping geocoding. chamber is senate|house (federal) or upper|lower (state legislature).

ParametersJSON Schema
NameRequiredDescriptionDefault
stateYes
chamberYes
districtNo

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description mentions 'skipping geocoding' but does not disclose other behavioral traits like read-only status, required permissions, or potential errors. Since no annotations are provided, the description carries the full burden, and it is insufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise (two sentences) and front-loaded with the main purpose. Every sentence adds value; no wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 3 parameters, no output schema, and no annotations, the description provides key information but lacks details on return format, error cases, and clear usage context relative to siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema coverage, the description adds critical meaning by explaining the valid values for chamber and noting that district is optional. However, it does not explain the state parameter or district format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns officials for a chamber and district, and specifies valid chamber values (senate|house for federal, upper|lower for state). However, it does not differentiate from sibling tools like lookup_officials or get_official_details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives. The phrase 'skipping geocoding' hints at a use case but does not clearly explain when to choose this over lookup_officials or list_districts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

lookup_officialsA

Who represents this address? Returns U.S. Senators + House member (and, where available, Governor + state legislators), each with party, contact, term, source, and as-of date, plus the OCD divisions and coverage notes.

ParametersJSON Schema
NameRequiredDescriptionDefault
addressYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It clearly states the tool returns a set of officials with specific fields and additional info (OCD divisions, coverage notes). It does not mention error handling, data freshness, or potential delays, but the behavioral intent (read-only lookup) is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the core question and efficiently lists all returned elements. Every clause adds value with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (multiple officials, many fields), the description covers the key aspects. However, it does not specify the response format (e.g., list vs. object) or handle error cases, leaving some completeness gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The sole parameter 'address' has no schema description (0% coverage), but the description clarifies it is an address used to find representatives. It lacks format requirements (e.g., full address vs. zip), which could lead to ambiguity. The description adds moderate meaning but does not fully compensate for the missing schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear question format 'Who represents this address?' and specifies the exact officials returned (Senators, House, Governor, state legislators) along with the data fields (party, contact, term, etc.). It distinguishes itself from siblings like 'lookup_by_district' by focusing on address-based lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when you have an address and want representatives, but does not explicitly contrast with alternatives such as 'lookup_by_district' or provide conditions when not to use it. No guidance on prerequisites or edge cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pingA

Health check. Returns 'pong' if the server is alive.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It accurately describes the success response ('pong' if alive) but does not disclose behavior when the server is dead (e.g., timeout or error). This is a minor gap for a simple tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is minimal and front-loaded with the key information. Every word serves a purpose with no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity and the presence of an output schema, the description is complete. It covers the core behavior without needing to explain return values further.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are no parameters, so the baseline is 4 per the rule for 0-parameter tools. The description adds no additional parameter information, which is acceptable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states it is a health check that returns 'pong' if the server is alive. This is a specific verb-resource combination, and it clearly distinguishes from sibling tools which deal with official details and districts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

While no explicit usage guidance is given, the context is clear: it is a health check tool. The distinction from siblings is implicit but straightforward. No exclusions are needed due to its simple nature.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 5 tool updatesv0.1.0
    • First observedget_official_details
    • First observedlist_districts
    • First observedlookup_by_district
    • First observedlookup_officials
    • First observedping

TDQS

A3.6/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: lookup_officials and lookup_by_district differ in input (address vs. chamber+district), list_districts provides district IDs, get_official_details gives detailed info on a single official, and ping is a health check. No ambiguity.

Naming Consistency4/5

Tool names follow a pattern of verb_noun (list_districts, get_official_details, lookup_by_district, lookup_officials) with one exception (ping). The verbs 'list', 'get', and 'lookup' are thematically coherent, though using 'lookup' for two tools could cause slight confusion.

Tool Count4/5

Five tools is a reasonable count for a focused domain like legislative representation lookup. Each tool serves a distinct function, and the set feels neither sparse nor bloated.

Completeness4/5

The tool set covers core operations: address-based lookup, district-based lookup, district listing, and official details. Missing features like coordinate-based lookup or batch queries are minor gaps that don't significantly hinder typical use cases.

Maintenance

ActivityStale
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Provides US real estate data including housing stats, demographics, nearby amenities, area comparisons, cost-of-living analysis, and neighborhood search via free public APIs without any API keys.
    6
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Provides tools to search and retrieve US federal and state legislative data, including bills, votes, campaign contributions, and legislator information, with provenance tracking.
    8
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Access U.S. state legislative data including bills, legislators, and votes across all 50 states via the OpenStates API.
    14
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Remote MCP server for nonpartisan U.S. Congress data: plain-language bill decodes (bilingual EN/ES), representative lookup by ZIP with district-office phones, and what's-moving urgency ranking. Read-only, keyless.
    5
    1
    AGPL 3.0

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cstillick/who_reps-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server