Access U.S. congressional data - bills, votes, members, committees - via MCP.
Access U.S. congressional data - bills, votes, members, committees - through MCP. STDIO & Streamable HTTP.
Public Hosted Server: https://congressgov.caseyjhand.com/mcp
U.S. congressional data from the Congress.gov API v3 and the Senate's official vote feed — bills, enacted laws, members, committees, roll call votes, and presidential nominations. Browse legislative activity, read bill and report text, and track the Senate confirmation pipeline from any MCP client. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
| Tool | Description |
|---|---|
congressgov_bill_lookup | Browse and retrieve U.S. legislative bill data — actions, sponsors, summaries, text, related bills |
congressgov_enacted_laws | Browse enacted public and private laws by congress |
congressgov_member_lookup | Discover congressional members by state/district/congress, retrieve legislative portfolios |
congressgov_committee_lookup | Browse congressional committees and their legislation, reports, and nominations |
congressgov_roll_votes | Retrieve House and Senate roll call votes and individual member voting positions |
congressgov_senate_nominations | Browse presidential nominations to federal positions and track the Senate confirmation process |
congressgov_bill_summaries | Browse recent CRS bill summaries — the "what's happening" feed |
congressgov_crs_reports | Browse and retrieve nonpartisan CRS policy analysis reports |
congressgov_committee_reports | Browse and retrieve committee reports accompanying legislation |
congressgov_daily_record | Browse the daily Congressional Record — floor speeches, debates, and proceedings |
congressgov_search_bills | Keyword-search bill titles and CRS summaries via a local full-text mirror (opt-in, off by default) |
| Resource | Description |
|---|---|
congress://current | Current congress number, session dates, chamber info |
congress://bill-types | Reference table of valid bill type codes |
congress://member/{bioguideId} | Member profile by bioguide ID |
congress://bill/{congress}/{billType}/{billNumber} | Bill detail by congress, type, and number |
congress://committee/{committeeCode} | Committee detail by committee code |
Bill, member, and committee data is also reachable through congressgov_bill_lookup, congressgov_member_lookup, and congressgov_committee_lookup (operation get) — many MCP clients are tool-only and never surface resources.
| Prompt | Description |
|---|---|
congressgov_bill_analysis | Structured framework for analyzing a bill |
congressgov_legislative_research | Research framework for a policy area across Congress |
congressgov_bill_lookup toollist (browse by congress/billType/date range — no keyword search), get (full detail), or drill into actions, amendments, cosponsors, committees, subjects, summaries, text, titles, relatedlist defaults to order='recent' (newest update-date first); limit 1–250, offset paginationcontent reads a text version's actual document text: select the version with textVersionIndex (0-based, against text's order), the window with characterOffset/characterLimit (1–100,000 chars, default 25,000), and follow nextOffset to walk a full billsummaries selects one version with versionCode (the code a summary row carries — 00 introduced, 49 public law) and reads each row's text through the same characterOffset/characterLimit window; a row past the window carries textTotalCharacters, textTruncated, and textNextOffset, and a window end never splits an HTML tag or character reference, so following textNextOffset reassembles the upstream text exactlycontent: document_unavailable, format_unavailable, document_fetch_failed, document_too_large, offset_past_end, alongside the shared not_found / rate_limited / invalid_request / upstream_error set — offset_past_end also covers a summaries call whose characterOffset is past the end of every returned rowcongressgov_enacted_laws toollist filters by congress and lawType (pub public laws, priv private) — the enactment-status filter congressgov_bill_lookup doesn't offerget returns the origin bill record; the law citation lives on the bill's laws[] array (e.g. {"number":"118-2","type":"Public Law"})lawNumber accepts either the bare number (90) or the full {congress}-{number} citation a list row carries; a citation naming a different congress than the congress param is rejected rather than silently resolvedlimit 1–250, offset pagination for listcongressgov_member_lookup toollist filters by stateCode (+ optional district, which requires stateCode), congress, and currentMemberget returns the full profile by bioguideId (e.g. P000197); sponsored/cosponsored return that member's legislative portfoliolimit 1–250, offset paginationcongressgov_committee_lookup toolh/s/j) + abbreviation + 2-digit number (e.g. hsju00); get and sub-resources infer chamber from the prefix, or accept an explicit overridecommitteeCode also accepts a committee name, resolved automatically (all-token match, then a bigram-similarity fallback labeled approximate: true) against the full cross-chamber rosterlist with filter name-matches the same way, paging past the 250-row upstream cap to search the complete roster before filteringbills sub-resource defaults to order='recent' (newest update-date first, computed client-side since upstream ignores sort); rows carry no titles — chain congressgov_bill_lookup get per rownominations sub-resource is Senate-onlycongressgov_roll_votes toolchamber is house (default, Congress.gov API) or senate (the Senate's official LIS XML feed — the API exposes no Senate votes)list browses by congress + session (1 or 2), newest-first by default (computed client-side for strict ordering); get returns tallies and party breakdown, members returns each member's recorded positionlist rows carry the feed's year-less voteDate ("19-Dec") alongside a derived voteDateIso (2023-12-19), resolved across the whole session — including the January votes of a session that sat past December 31limit 1–250, offset pagination for list and memberscongressgov_senate_nominations toolPN numbering; list browses by congress, get returns detail, actions/committees/hearings cover the confirmation pipeline, nominees returns individuals in a batch (requires ordinal)PN851) carry no activity of their own — sub-resources live on partitioned children (851-1, 851-2, …); a bare-parent sub-resource call on such a nomination returns an enrichment notice pointing at the partitioned formordinal is discovered from the nomination's nominees array via get firstcongressgov_bill_summaries toolcongress and billType (requires congress); date filters apply to the CRS summary's update time, not the bill's action datepagination.nextOffset resumes at the first row not returned, and a notice discloses the stoptextTotalCharacters, textTruncated, and textNextOffset; the notice names the congressgov_bill_lookup call that reads on from therecongressgov_bill_lookup with operation='summaries' insteadcongressgov_crs_reports toolR40097, RL33612, IF12345)list browses the catalog; get returns full detail (authors, topics, summary, download formats) by reportNumberlimit 1–250, offset pagination for listcongressgov_committee_reports toolhrpt (House), srpt (Senate), erpt (Executive); list browses by congress + optional reportType, get returns citation/title/committees/associated billtext lists each format's {type, url} link (report formats arrive one per entry, unlike bill text versions); content then reads the actual text, a bounded character window at a time via characterOffset/characterLimit (1–100,000 chars, default 25,000)content: document_unavailable, format_unavailable, document_fetch_failed, document_too_large, offset_past_endcongressgov_daily_record toollist (volumes) → issues (within a volume) → articles (within an issue)content reads one article's text, selected by articleIndex (0-based) and bounded by characterOffset/characterLimit; the Congressional Record publishes Formatted Text and PDF only (no XML)content: document_unavailable, format_unavailable, document_fetch_failed, document_too_large, offset_past_endcongressgov_search_bills tooltools/list entirely until CONGRESS_MIRROR_ENABLED=truecongress, billType, and originChamber; returns BM25-ranked matches with each bill's derived id, ready for a follow-up congressgov_bill_lookup callbun run mirror:init), the tool answers with an empty result and a build-the-index notice instead of an errorlimit 1–100 (a narrower cap than the other tools' 1–250), offset paginationcongress://current resourcecongress://bill-types resourcehr, s, hjres, sjres, hconres, sconres, hres, sres) with chamber and an example citationcongress://member/{bioguideId} resourcebioguideId must match one uppercase letter followed by 6 digits (e.g. P000197)congress://bill/{congress}/{billType}/{billNumber} resourcecongress and billNumber must be positive integers; billType must be a valid bill type codecongress://committee/{committeeCode} resourcecommitteeCode must match h/s/j followed by 3–8 lowercase alphanumeric characters (e.g. hsju00); chamber is inferred from the first lettercongressgov_bill_analysis promptcongress, billType, billNumber — all required stringscongressgov_legislative_research prompttopic required; congress optional (defaults to the current congress)CONGRESS_MIRROR_ENABLED it opens with congressgov_search_bills; without it, it asks for a seed (a bill, member, committee, or CRS report id) since no registered tool accepts a topic stringBuilt on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
Congress.gov-specific:
fast-xml-parser) backing Senate roll votesDEMO_KEY (30 req/hr); own key gets 5,000 req/hrwww.congress.gov host allowlistCONGRESS_MIRROR_ENABLED) adds keyword search over bill titles and CRS summaries, the one discovery path the API itself lacksAgent-friendly output:
content operations return offset/nextOffset so walking a multi-megabyte bill or report never skips or repeats a characterdocument_unavailable, format_unavailable, document_too_large, offset_past_end, …) alongside the shared upstream-error set, each resolved to a recovery hintA public instance is available at https://congressgov.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"congressgov-mcp-server": {
"type": "streamable-http",
"url": "https://congressgov.caseyjhand.com/mcp"
}
}
}
Add the following to your MCP client configuration file.
{
"mcpServers": {
"congressgov-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/congressgov-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"CONGRESS_API_KEY": "your-api-key"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"congressgov-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/congressgov-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"CONGRESS_API_KEY": "your-api-key"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"congressgov-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "CONGRESS_API_KEY=your-api-key",
"ghcr.io/cyanheads/congressgov-mcp-server:latest"
]
}
}
}
Get a free API key at api.data.gov/signup for 5,000 req/hr. Without a key the server falls back to DEMO_KEY (30 req/hr).
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 CONGRESS_API_KEY=your-api-key bun run start:http
# Server listens at http://localhost:3010/mcp
git clone https://github.com/cyanheads/congressgov-mcp-server.git
cd congressgov-mcp-server
bun install
cp .env.example .env
# edit .env and set required vars
| Variable | Description | Default |
|---|---|---|
CONGRESS_API_KEY | API key from api.data.gov. Omit to use DEMO_KEY (30 req/hr); own key: 5,000 req/hr. | DEMO_KEY |
CONGRESS_API_BASE_URL | Congress.gov API base URL. | https://api.congress.gov/v3 |
CONGRESS_MIRROR_ENABLED | Enable the local bill search mirror and the congressgov_search_bills tool. | false |
CONGRESS_MIRROR_PATH | Filesystem path to the SQLite mirror index. | .mirror/bills.sqlite3 |
CONGRESS_MIRROR_REFRESH_CRON | Cron schedule for the in-process mirror refresh (HTTP transport only). Unset runs mirror:refresh manually. | — |
CONGRESS_MIRROR_CONGRESSES | Comma-separated congress numbers to mirror (e.g. 118,119). | current congress + 1 prior |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_AUTH_MODE | Authentication: none, jwt, or oauth. | none |
MCP_SESSION_MODE | HTTP session mode: auto, stateful, or stateless; auto resolves to stateful. | stateless |
MCP_LOG_LEVEL | Log level (debug, info, notice, warning, error, etc.). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation (spans, metrics, completion logs). | false |
See .env.example for the full list of optional overrides.
Build and run the production version:
bun run rebuild
bun run start:http # or start:stdio
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
docker build -t congressgov-mcp-server .
docker run --rm -e CONGRESS_API_KEY=your-api-key -p 3010:3010 congressgov-mcp-server
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/congressgov-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools/resources/prompts and inits services. |
src/config/ | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools/definitions/ | Tool definitions (*.tool.ts) — eleven Congress.gov tools. |
src/mcp-server/resources/definitions/ | Resource definitions (*.resource.ts) — congress, bill, member, and committee resources. |
src/mcp-server/prompts/definitions/ | Prompt definitions (*.prompt.ts) — bill analysis and legislative research. |
src/services/congress-api/ | Congress.gov API client — auth, pagination, rate limiting. |
src/services/congress-documents/ | Bounded document-text fetch — host allowlist, byte ceiling, character window. |
src/services/congress-mirror/ | Local SQLite FTS5 bill-search mirror — ingest, normalize, schema. |
src/services/senate-lis/ | Senate LIS XML client for Senate roll call votes. |
src/utils/ | Shared pure helpers — single-pass HTML/XML character-reference decoding. |
scripts/ | Mirror lifecycle CLI scripts (mirror:init / mirror:refresh / mirror:verify). |
tests/ | Unit and integration tests, mirroring the src/ structure. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagereadOnlyHint: true and idempotentHint: true annotationsIssues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y @cyanheads/congressgov-mcp-serverMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-cyanheads-congressgov-mcp-server": {
"command": "npx",
"args": [
"-y",
"@cyanheads/congressgov-mcp-server"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceio.github.cyanheads/congressgov-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.