Skip to main content

Congress Explorer MCP

Explore congressional hearings, witnesses, bills, members, recordings, and related documents from your AI assistant. Free and open source. No data API key required. Start with the setup guide.

A local FastMCP server for the current Congressional Document Archive and its phase 2 entities. It reads one immutable release: every Parquet table, every published column, and native nested lists/structs. DuckDB 2.0.0 and FastMCP 4.1.4 are pinned in this app's own uv.lock.

This is a replacement implementation. It has no pre-v6/v6 readers, separate committee catalog, legacy parser imports, review overlays, copied DuckDB database, or custom SQL language. The producer owns data assembly and SpicyRegs imports; the MCP queries the published result. It stays a separate Congress server.

Install a release (macOS or Linux)

Install uv, then:

uv tool install --python 3.12 \
  'https://github.com/civictechdc/congressional-tech/releases/download/congress-mcp-v0.3.0/congressional_explorer_mcp-0.3.0-py3-none-any.whl'
congress-explorer-mcp prepare
congress-explorer-mcp check

If the command is not on your shell's PATH, run uv tool update-shell and open a new terminal. check should report "status": "ok" and six tools. It launches the installed server, connects over MCP and reads one document row. Python 3.12 is managed by uv. Windows is not supported yet.

Print configuration for your client:

congress-explorer-mcp config --client claude-desktop
congress-explorer-mcp config --client codex
congress-explorer-mcp config --client cursor
congress-explorer-mcp config --client claude-code

Choose one. These commands print settings with absolute paths and never edit the client's configuration. Merge the output into the appropriate settings, preserving other servers, then restart the client connection:

Client Configuration
Claude Desktop Settings → Developer → Edit Config; merge into mcpServers
Codex Add or replace [mcp_servers.congress] in ~/.codex/config.toml
Cursor Merge into mcpServers in ~/.cursor/mcp.json
Claude Code Save JSON to a file and pass --mcp-config /absolute/path/to/file.json when starting Claude Code

The client starts serve for you. There is no port to open or terminal to keep running. Ask: “Use Congress Explorer to find documents related to H.R. 1 in the 119th Congress.” Your assistant needs its own tools to fetch and read linked files.

Run prepare again and restart the client connection to refresh data. Software updates are separate: install the wheel for the desired release and restart the client. Preparation currently downloads about 65 MiB (October 30, 2026 snapshot); the Python runtime and dependencies require additional disk space.

Queries run locally, but your AI client may send prompts and tool results to its model provider. Coverage varies by source and Congress. This is a bounded published collection, not a complete record of every congressional activity.

Run from source

From the repository root, on macOS or Linux:

uv sync --locked --project apps/explorer_mcp
uv run --locked --project apps/explorer_mcp congress-explorer-mcp prepare
uv run --locked --project apps/explorer_mcp congress-explorer-mcp serve

prepare defaults to the public archive pointer and stores metadata under ~/.cache/congress-explorer-mcp. serve uses stdio and makes no network requests. Use --data-dir /absolute/path on each command to select another directory. inspect prints the selected release and published table counts.

For a retained or test release:

uv run --locked --project apps/explorer_mcp congress-explorer-mcp prepare \
  --publication /absolute/path/to/manifest.json \
  --archive-origin https://congressional-data.spicygov.ai \
  --data-dir /absolute/path/to/mcp-data

--publication accepts the current pointer or a direct release manifest, as a URL or local path. Remote publications supply the body archive origin automatically. For local inputs, omit --archive-origin if body URLs are unknown; the server returns null saved URLs instead of guessing.

Configure an MCP client with absolute paths:

{
  "mcpServers": {
    "congress": {
      "command": "/absolute/path/to/repo/apps/explorer_mcp/.venv/bin/congress-explorer-mcp",
      "args": ["serve", "--data-dir", "/absolute/path/to/mcp-data"]
    }
  }
}

The independent environment is deliberate: producer packages still pin DuckDB below 2. The MCP imports none of those packages. Do not install it into the producer's environment.

Six tools

Tool Purpose
get_dataset_info Available tables, coverage and published relationship/recipe IDs. Pass table for columns, identity and incoming/outgoing IDs; relationship for join meaning; recipe for bounded SQL examples. Also accepts table: "schema", "capture_scope", and "capture_profile".
search_documents Title/filename search and exact Congress, kind, format, committee, meeting, bill/nomination, member or witness filters.
get_document A document's summary, paged source links, or paged recoveries.
search_entities Search the eight phase 2 entity tables with text and exact scalar filters.
get_entity One entity by its published key, or its directly associated documents.
query_sql One read-only DuckDB SELECT, including WITH and FROM-first SQL, with optional ? parameters. All published tables are available.

Except for get_dataset_info, arguments are inside a query object. For example:

{"query":{"measure_key":"119-hr-1","limit":10}}

Document results include a reference containing release_id and link_key. Pass those fields to get_document, adding section: "sources" or section: "recoveries" when needed. Page cursors belong to the same release, filters and page size. A running server stays on its selected release; run prepare and restart it to adopt a newer one.

Entity keys:

Table Key
meetings event_id
witnesses witness_key (an appearance, not a deduplicated person)
recordings video_key
committees system_code
members bioguide_id
bills bill_id, e.g. 119-hr-1
nominations nomination_id, e.g. 119-pn-730-2
rosters Compound fields; use search_entities or SQL

File URLs follow the recorded body hash and exact suffix. Summaries include alternate formats; recordings include saved caption/transcript track URLs. Recovery records retain kind and identity_note: a substitute or related file is not necessarily the requested original. Fetch and read the files with the agent's own tools. The MCP searches metadata and does not download, extract, OCR, or search document bodies.

Hidden documents are excluded from ordinary searches and entity document pages. An exact document reference still resolves and exposes its review explanation. SQL exposes all rows, including hidden rows; add a filter when needed.

Query relationships directly

Start with get_dataset_info. For releases publishing native relationship metadata, call it with {"table":"witnesses"}, then {"relationship":"witness_submitted_documents"} or {"recipe":"witness_transcripts"}. Use one selector at a time. The response explains keys, result grain, parameters and missing required tables. Recipes do not run until the caller submits their SQL to query_sql.

The producer owns this metadata in schema.json; the MCP has no separate join registry. New definitions within the supported metadata version appear without MCP changes. Older releases report that relationships were not published, and unknown versions report unsupported metadata while table and SQL access remain available. The complete producer reference is generated at docs/release-relationships.md.

These examples use the defined phase 2 fields and require those tables in the selected release.

Documents about a bill, including their saved file identifiers:

SELECT filename, title, hex(link_key) AS link_key,
       hex(saved_body) AS body, saved_suffix
FROM documents
WHERE list_contains(measure_keys, ?) AND NOT coalesce(hidden, false)
ORDER BY list_row

Hearings about a measure and their witnesses:

SELECT m.event_id, m.title, m.meeting_date, w.witness_key,
       w.name, w.position, w.organization
FROM meetings m
LEFT JOIN witnesses w ON w.event_id = m.event_id
WHERE list_contains(m.subject_keys, ?)
ORDER BY m.event_id, w.panel_order, w.display_order, w.witness_key

Transcript documents and recordings for a meeting:

SELECT m.event_id, t.package_id, d.filename, hex(d.link_key) AS link_key
FROM meetings m, UNNEST(m.transcripts) AS u(t)
LEFT JOIN documents d ON d.list_row = t.list_row
WHERE m.event_id = ?
SELECT video_key, tracks
FROM recordings
WHERE list_contains(event_ids, ?)

Member terms, votes, amendments, CBO estimates, committee history and cross-system IDs remain native nested fields. SQL can unnest, filter, join or aggregate them. New Parquet tables appear automatically without an MCP release. Entity convenience tools cover the named phase 2 tables; use SQL for any additional tables.

list and detail gain a virtual, zero-based list_row. Detail shards use their declared row offsets; sources and recoveries retain their physical list_row and ordinal. documents joins list and detail without copying them. The raw links, urls, URL state/variants and every other published table remain queryable.

SQL returns actual column types, bounded rows, and a truncated flag. BLOB values use DuckDB's JSON escaping; use hex()/unhex() for portable keys. Fractional numbers return as strings to preserve precision; integers, booleans, nulls, lists and objects retain their JSON types. Alias duplicate columns explicitly.

Cost and lifetime

Preparation streams each changed file once, checking SHA-256 during the transfer. It verifies Parquet footer counts without scanning all rows, then atomically selects the completed release. An unchanged preparation reads the pointer/manifest and checks local file metadata; it does not recopy, rehash or decode retained data. A failed attempt keeps the prior selection and reuses completed downloads on retry. The cache is app-owned; do not edit its immutable objects or selection.json.

Serving creates views over those exact files. There is no persistent DuckDB copy or Python table cache. One query worker uses two DuckDB threads, a 512 MB engine memory limit, 512 MB spill limit, and a default 10-second execution deadline. serve --query-timeout can change the deadline up to 120 seconds. Up to four queries can wait behind the active one. Cancellation or timeout stops and reaps the worker and removes its spill directory; the next request starts a new worker. The engine memory limit is not a process RSS limit.

Responses are capped at 128 KiB, browse pages at 100 rows, SQL results at 200 rows and 128 columns. A single oversized row produces an actionable error; select fewer fields or slice nested lists. Reads are limited to selected metadata files. Network access, writes, extension autoloading, persistent secrets and configuration changes are disabled in the query runtime.

Completed objects remain reusable and may still be in use by an older running server. Preparation therefore does not delete old objects. To retire a cache, stop every server using that data directory, remove that directory, then prepare again. The next preparation removes its interrupted download and selection files after acquiring the exclusive prepare lock. It keeps completed objects for live readers and rollback. If the server is killed, its worker detects parent death, interrupts DuckDB, closes the connection and removes its own spill directory. An unexpectedly killed worker produces a retryable error; the next call starts a new worker.

To roll back, prepare the previous immutable release manifest and restart the server. Existing servers remain on their selected release. If a cached object is corrupt, preparation refuses it and preserves the current selection; prepare into a fresh data directory to recover, then retire the old cache after its readers stop.

Check it

apps/explorer_mcp/.venv/bin/python scripts/dev.py test explorer-mcp -- -q

The root runner dispatches to the app's locked environment. Tests cover the canonical archive fixture, phase 2 entity shapes, raw SQL and relationships, shards, duplicates, missing versus empty data, failure/reuse, SQL restrictions, byte limits, subprocess cancellation and real stdio MCP calls. The dedicated CI workflow also builds the native phase 2 fixture and consumes its actual output over stdio in the independent MCP environment. See verification and production measurements.

Published data availability is separate from reader support. Absent tables are reported as unavailable; an empty table means zero published rows; nulls remain unknown. The server cannot supply phase 2 fields before producers publish them. The current model is defined by the data model and the phase 2 annex.

Metadata

Release files for congressional-explorer-mcp 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for congressional-explorer-mcp 0.3.0
File Size Uploaded Provenance Actions
congressional_explorer_mcp-0.3.0.tar.gz 42.3 kB With provenance Details for congressional_explorer_mcp-0.3.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for congressional-explorer-mcp 0.3.0
File Interpreter ABI Platform Actions
congressional_explorer_mcp-0.3.0-py3-none-any.whl Python 3 none any Details for congressional_explorer_mcp-0.3.0-py3-none-any.whl

Total release size: 70.8 kB

Release files / congressional_explorer_mcp-0.3.0.tar.gz

Download URL congressional_explorer_mcp-0.3.0.tar.gz
Size 42.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0fa3d6edd789915e34740c69a644f49b36f884dddbb329fa6068b4efbe659072
BLAKE2b-256 checksum
How to use checksums
a57060408815f15847fcf67ba209f7d94b872f52bbbca3e13a72343ffa5b8482
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Release files / congressional_explorer_mcp-0.3.0-py3-none-any.whl

Download URL congressional_explorer_mcp-0.3.0-py3-none-any.whl
Size 28.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
784e272488be27b3fd9c45e74a44192c2894153917809bb9e6990a110b7ccbea
BLAKE2b-256 checksum
How to use checksums
f35d6a6cd70719d494330f67f61f704148e66d88a36de3f91423fbe605f98a3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

Security for congressional-explorer-mcp 0.3.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for congressional_explorer_mcp-0.3.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page