Back to Directory/Developer Tools

io.github.cyanheads/congressgov-mcp-server

Access U.S. congressional data - bills, votes, members, committees - via MCP.

Developer ToolsTypeScriptv0.7.3

@cyanheads/congressgov-mcp-server

Access U.S. congressional data - bills, votes, members, committees - through MCP. STDIO & Streamable HTTP.

11 Tools • 5 Resources • 2 Prompts

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


Overview

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.

Tools

ToolDescription
congressgov_bill_lookupBrowse and retrieve U.S. legislative bill data — actions, sponsors, summaries, text, related bills
congressgov_enacted_lawsBrowse enacted public and private laws by congress
congressgov_member_lookupDiscover congressional members by state/district/congress, retrieve legislative portfolios
congressgov_committee_lookupBrowse congressional committees and their legislation, reports, and nominations
congressgov_roll_votesRetrieve House and Senate roll call votes and individual member voting positions
congressgov_senate_nominationsBrowse presidential nominations to federal positions and track the Senate confirmation process
congressgov_bill_summariesBrowse recent CRS bill summaries — the "what's happening" feed
congressgov_crs_reportsBrowse and retrieve nonpartisan CRS policy analysis reports
congressgov_committee_reportsBrowse and retrieve committee reports accompanying legislation
congressgov_daily_recordBrowse the daily Congressional Record — floor speeches, debates, and proceedings
congressgov_search_billsKeyword-search bill titles and CRS summaries via a local full-text mirror (opt-in, off by default)

Resources

ResourceDescription
congress://currentCurrent congress number, session dates, chamber info
congress://bill-typesReference 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.

Prompts

PromptDescription
congressgov_bill_analysisStructured framework for analyzing a bill
congressgov_legislative_researchResearch framework for a policy area across Congress

Capability reference

congressgov_bill_lookup tool

  • Operations: list (browse by congress/billType/date range — no keyword search), get (full detail), or drill into actions, amendments, cosponsors, committees, subjects, summaries, text, titles, related
  • list defaults to order='recent' (newest update-date first); limit 1–250, offset pagination
  • content 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 bill
  • summaries 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 exactly
  • Typed failures on content: 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 row

congressgov_enacted_laws tool

  • list filters by congress and lawType (pub public laws, priv private) — the enactment-status filter congressgov_bill_lookup doesn't offer
  • get 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 resolved
  • limit 1–250, offset pagination for list

congressgov_member_lookup tool

  • No name search — list filters by stateCode (+ optional district, which requires stateCode), congress, and currentMember
  • get returns the full profile by bioguideId (e.g. P000197); sponsored/cosponsored return that member's legislative portfolio
  • limit 1–250, offset pagination

congressgov_committee_lookup tool

  • Committee codes are chamber-prefix (h/s/j) + abbreviation + 2-digit number (e.g. hsju00); get and sub-resources infer chamber from the prefix, or accept an explicit override
  • committeeCode also accepts a committee name, resolved automatically (all-token match, then a bigram-similarity fallback labeled approximate: true) against the full cross-chamber roster
  • list with filter name-matches the same way, paging past the 250-row upstream cap to search the complete roster before filtering
  • bills 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 row
  • nominations sub-resource is Senate-only

congressgov_roll_votes tool

  • chamber 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 position
  • Senate list 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 31
  • Roll call numbers reset each session and are specific to one chamber
  • limit 1–250, offset pagination for list and members

congressgov_senate_nominations tool

  • Nominations use PN numbering; list browses by congress, get returns detail, actions/committees/hearings cover the confirmation pipeline, nominees returns individuals in a batch (requires ordinal)
  • Multi-part parents (e.g. 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 form
  • ordinal is discovered from the nomination's nominees array via get first

congressgov_bill_summaries tool

  • Filters by congress and billType (requires congress); date filters apply to the CRS summary's update time, not the bill's action date
  • Defaults to summaries updated in the last 7 days when neither date bound is supplied
  • A page stops adding rows once they reach a fixed response-character budget: at least one row always returns, pagination.nextOffset resumes at the first row not returned, and a notice discloses the stop
  • A summary past the per-row window arrives as an exact character window carrying textTotalCharacters, textTruncated, and textNextOffset; the notice names the congressgov_bill_lookup call that reads on from there
  • For summaries of one specific bill — and to read a windowed summary to the end — use congressgov_bill_lookup with operation='summaries' instead

congressgov_crs_reports tool

  • Report IDs use letter-number codes (e.g. R40097, RL33612, IF12345)
  • list browses the catalog; get returns full detail (authors, topics, summary, download formats) by reportNumber
  • limit 1–250, offset pagination for list

congressgov_committee_reports tool

  • Report types: hrpt (House), srpt (Senate), erpt (Executive); list browses by congress + optional reportType, get returns citation/title/committees/associated bill
  • text 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)
  • Typed failures on content: document_unavailable, format_unavailable, document_fetch_failed, document_too_large, offset_past_end

congressgov_daily_record tool

  • Hierarchical navigation: list (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)
  • Typed failures on content: document_unavailable, format_unavailable, document_fetch_failed, document_too_large, offset_past_end

congressgov_search_bills tool

  • Opt-in: off by default and absent from tools/list entirely until CONGRESS_MIRROR_ENABLED=true
  • Keyword-searches a local SQLite FTS5 mirror of bill titles + CRS summaries — the discovery path the Congress.gov API itself lacks; policy area and full bill text are not indexed
  • Narrows with congress, billType, and originChamber; returns BM25-ranked matches with each bill's derived id, ready for a follow-up congressgov_bill_lookup call
  • With the flag set but the index not yet built (bun run mirror:init), the tool answers with an empty result and a build-the-index notice instead of an error
  • limit 1–100 (a narrower cap than the other tools' 1–250), offset pagination

congress://current resource

  • Current congress number, session dates, and chamber info — baseline context for other queries
  • Cached publicly for 1 hour

congress://bill-types resource

  • Static reference table of the 8 valid bill type codes (hr, s, hjres, sjres, hconres, sconres, hres, sres) with chamber and an example citation
  • Cached publicly for 24 hours — fixed by chamber rules, not fetched upstream

congress://member/{bioguideId} resource

  • bioguideId must match one uppercase letter followed by 6 digits (e.g. P000197)
  • Returns the member profile — name, state, party, terms, leadership, office, legislation counts

congress://bill/{congress}/{billType}/{billNumber} resource

  • congress and billNumber must be positive integers; billType must be a valid bill type code
  • Returns bill detail — sponsor, status, policy area, committees, latest action

congress://committee/{committeeCode} resource

  • committeeCode must match h/s/j followed by 3–8 lowercase alphanumeric characters (e.g. hsju00); chamber is inferred from the first letter
  • Returns committee detail — name, chamber, subcommittees, history, legislation counts

congressgov_bill_analysis prompt

  • Arguments: congress, billType, billNumber — all required strings
  • Returns one user message framing a structured analysis (summary, sponsors, committee referrals, action timeline, related legislation, policy implications, outlook) and naming which tools to call for each section

congressgov_legislative_research prompt

  • Arguments: topic required; congress optional (defaults to the current congress)
  • The discovery plan is configuration-aware: with 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 string
  • Synthesizes findings into landscape, key players, substance, recent activity, and outlook

Features

Built 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:

  • Type-safe client for the Congress.gov REST API v3, plus a second client for the Senate's official LIS XML feed (fast-xml-parser) backing Senate roll votes
  • Optional API key from api.data.gov — defaults to DEMO_KEY (30 req/hr); own key gets 5,000 req/hr
  • Bounded document-text retrieval for bill text, committee reports, and Congressional Record articles — a 25 MB fetch ceiling, 30s deadline, and a www.congress.gov host allowlist
  • Opt-in local SQLite FTS5 mirror (CONGRESS_MIRROR_ENABLED) adds keyword search over bill titles and CRS summaries, the one discovery path the API itself lacks
  • All tools are read-only and idempotent

Agent-friendly output:

  • Effective-query echo and total-count enrichment on every browse/list operation, plus a notice when a query resolves to zero matches or an offset runs past the end
  • Character-exact document windows — content operations return offset/nextOffset so walking a multi-megabyte bill or report never skips or repeats a character
  • Typed failure reasons on document reads (document_unavailable, format_unavailable, document_too_large, offset_past_end, …) alongside the shared upstream-error set, each resolved to a recovery hint

Getting started

Public Hosted Instance

A 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"
    }
  }
}

Self-Hosted / Local

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

Prerequisites

Installation

  1. Clone the repository:
git clone https://github.com/cyanheads/congressgov-mcp-server.git
  1. Navigate into the directory:
cd congressgov-mcp-server
  1. Install dependencies:
bun install
  1. Configure environment:
cp .env.example .env
# edit .env and set required vars

Configuration

VariableDescriptionDefault
CONGRESS_API_KEYAPI key from api.data.gov. Omit to use DEMO_KEY (30 req/hr); own key: 5,000 req/hr.DEMO_KEY
CONGRESS_API_BASE_URLCongress.gov API base URL.https://api.congress.gov/v3
CONGRESS_MIRROR_ENABLEDEnable the local bill search mirror and the congressgov_search_bills tool.false
CONGRESS_MIRROR_PATHFilesystem path to the SQLite mirror index..mirror/bills.sqlite3
CONGRESS_MIRROR_REFRESH_CRONCron schedule for the in-process mirror refresh (HTTP transport only). Unset runs mirror:refresh manually.—
CONGRESS_MIRROR_CONGRESSESComma-separated congress numbers to mirror (e.g. 118,119).current congress + 1 prior
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_SESSION_MODEHTTP session mode: auto, stateful, or stateless; auto resolves to stateful.stateless
MCP_LOG_LEVELLog level (debug, info, notice, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
STORAGE_PROVIDER_TYPEStorage backend.in-memory
OTEL_ENABLEDEnable OpenTelemetry instrumentation (spans, metrics, completion logs).false

See .env.example for the full list of optional overrides.

Running the server

Local development

  • 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

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.

Project structure

DirectoryPurpose
src/index.tscreateApp() 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.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • All tools are read-only, with readOnlyHint: true and idempotentHint: true annotations
  • Wrap external API calls: validate raw → normalize to a domain type → return the output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

Installation

Source-derived launch command. Check the maintainer’s required arguments and credentials before running:

bash
npx -y @cyanheads/congressgov-mcp-server

Set up in your AI client

Merge 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.

json
{
  "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 reference

Package

@cyanheads/congressgov-mcp-servernpm

Compatible MCP Clients

io.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.

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.
  • Cursor~/.cursor/mcp.jsonRestart Cursor for changes to take effect.
  • VS Code.vscode/mcp.jsonReload VS Code window for changes to take effect.
  • Windsurf~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect.
  • Claude Code.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.

Learn More