Bill Commons

org.billcommonsPublished by billcommons.orgOfficial publisherv1.0.0Updated Oct 24, 2026

Search 209k+ US state bills, all 50 states + DC: full text, sponsors, votes, status. Free.

VerifiedStreamable HTTPWeb executableWeb Search & ScrapingKnowledge & Memory

Overview

AI-generated overview

Remote MCP server for searching and analyzing 209k+ US state bills across all 50 states plus DC, with full text, sponsors, votes and history.

What you can do
  • Search full bill text, titles and descriptions across jurisdictions, with quoted phrases, OR and exclusion syntax
  • Fetch a bill's full record by ID or by jurisdiction plus bill number, including sponsors, subjects, actions and versions
  • Compare two versions of a bill's text and find bills with similar titles across jurisdictions
  • Retrieve vote events with member-level records and trace a bill's chronological legislative history
  • Compile citation-ready evidence packets and check jurisdiction coverage and active sessions
  • List curated cross-state topic trackers such as AI, data privacy or cybersecurity
When to use it
Useful when you need to research US state legislation: tracking bills on a topic across states, checking sponsors and votes, comparing bill versions, or assembling citable legislative evidence without scraping state sites yourself.
Requirements
A remote Streamable HTTP endpoint; no API key or local install is needed for ordinary use. Anonymous callers are capped at 2,000 requests per day per IP and 5,000 per day per /24 subnet; a free API key raises the limit.
Before you install
Read-only research tools, but some outputs are computed by the service and labeled derived rather than official, so verify against official sources before citing. High-volume or bulk use is paid, and anonymous use is rate-limited per IP and subnet.

Installation

In SourceWeft

  1. Open Bill Commons in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/org.billcommons%2Fbill-commons/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "bill-commons": {
      "type": "http",
      "url": "https://mcp.billcommons.org/mcp"
    }
  }
}

README

Bill Commons

Bill Commons is a public, open-source legislative search platform covering the current session/biennium for all 50 U.S. states plus DC. It provides a web search UI, a REST API, an MCP (Model Context Protocol) server, and a public status/coverage page. Public infrastructure first: no paywall on ordinary search or reasonable API use — anonymous callers get a generous daily cap (2,000 requests/day per IP, 5,000/day per /24 subnet); a free API key raises that further, and only high-volume/bulk use is paid. See /docs/bulk for API keys and full-corpus snapshots.

See docs/architecture/ARCHITECTURE.md for the locked architecture and data model.

Production

Hosted on Railway (project billcommons: api, mcp, worker services + managed Postgres) and Vercel (project billcommons-web). See docs/operations/deployment-runbook.md for the full deploy/rollback procedure.

Use with Claude (or any MCP client)

The hosted MCP server gives AI assistants direct access to all 209k+ bills — no API key, no setup beyond one command:

bash
claude mcp add bill-commons --transport http https://mcp.billcommons.org/mcp

Claude Desktop: Settings → Connectors → Add custom connector with URL https://mcp.billcommons.org/mcp. Cursor and other clients: add the same URL as a Streamable HTTP server in mcp.json.

Ten tools including search_legislation, get_bill_record, compare_bill_versions, and trace_legislative_history. Full walkthrough (including REST recipes for agents without MCP): https://billcommons.org/docs/agents

Architecture at a glance

                    ┌─────────────┐   users ─────────▶ │  apps/web   │  Next.js, billcommons.org                    │ (Vercel)    │  status.billcommons.org (rewrite → /coverage)                    └──────┬──────┘                           │ HTTPS (NEXT_PUBLIC_API_BASE)                           ▼                    ┌─────────────┐        ┌──────────────┐                    │  apps/api   │◀──────▶│  apps/mcp    │  Streamable HTTP                    │  FastAPI    │        │  10 MCP tools│  mcp.billcommons.org                    │ /api/v1     │        └──────────────┘                    │ api.billcommons.org                    └──────┬──────┘                           │ reads (SQLAlchemy)                           ▼                    ┌─────────────────────────────┐                    │   Postgres 16 (Railway)      │                    │  jurisdictions, sessions,     │                    │  bills, actions, sponsorships,│                    │  votes, ingest_jobs, coverage  │                    └──────────────▲──────────────┘                                   │ writes (idempotent upserts)                    ┌──────────────┴──────────────┐                    │  workers/ingest (worker svc)  │                    │  autoboot: seed → bootstrap →│                    │  schedule-refresh → job loop  │                    │  sources: Open States bulk CSV│                    │  (T2 bootstrap) + v3 API (T2  │                    │  incremental, OPENSTATES_API_ │                    │  KEY) + full-text fetcher     │                    └──────────────┬──────────────┘                                   ▼                    RawStore (filesystem, RAWSTORE_ROOT                    volume in prod) — sha256-addressed                    raw payload archive

packages/schema (SQLAlchemy models + Alembic) is the single source of truth every other package/app imports from — no service owns its own copy of the data model.

Monorepo layout

apps/web        Next.js 15 (App Router, TS) — search UI + status pageapps/api        FastAPI — REST API (/api/v1)apps/mcp        MCP server (Streamable HTTP, mounted at /mcp)workers/ingest  Ingestion workers, job queue, per-source adapterspackages/schema SQLAlchemy models + Alembic migrations (single source of truth)packages/shared Shared Python utils: bill-number normalization, rawstore, http clientpackages/source-registry  Per-jurisdiction source registry (data + loader)packages/search Search SQL builders / query parsinginfra/docker    Dockerfiles + docker-compose.yml (local stack)infra/deployment Railway/Vercel configs, DNS runbookdocs/           Architecture, API, sources, operations, state-coverage docsdata/registry   Machine-readable registry (sessions, sources)

Local development setup

Prerequisites

  • Python 3.12
  • PostgreSQL 16 (with pg_trgm, unaccent, pgcrypto extensions available)
  • Node.js 20+ (for apps/web)

Python environment

bash
python3 -m venv .venv.venv/bin/pip install -r requirements.txt

This installs packages/schema and packages/shared as editable installs (single source of truth for the data model + shared utils), plus the worker package: .venv/bin/pip install -e workers/ingest. Install the API package too if you're working on it: .venv/bin/pip install -e apps/api.

Database

Set DATABASE_URL in your environment (or in ~/.config/billcommons/.env, which is read as a fallback and is never committed):

DATABASE_URL=postgresql://user:password@host:port/dbname

Requires Postgres 16 with the pg_trgm and unaccent extensions available (created by migration 0001). Run migrations:

bash
cd packages/schema../../.venv/bin/alembic upgrade head

Seeding data locally

bash
# Seed all 51 jurisdictions/sessions/coverage rows from the registry:.venv/bin/python -m billcommons_ingest seed-registry
# Download a state's Open States bulk-CSV zip and ingest it (see# docs/operations/ingestion-runbook.md for the full command reference):python3 workers/ingest/download_bulk.py --only NC.venv/bin/python -m billcommons_ingest bootstrap --state NC --zip data/bulkzips/NC_2025.zip.venv/bin/python -m billcommons_ingest recompute-coverage

Running the apps locally

bash
# API (FastAPI, http://localhost:8000, docs at /docs).venv/bin/uvicorn main:app --app-dir apps/api --reload --port 8000
# MCP server (Streamable HTTP, http://localhost:8400/mcp by default).venv/bin/python apps/mcp/server.py
# Ingestion worker (long-running queue loop; runs schedule-refresh# periodically inside the same process).venv/bin/python -m billcommons_ingest worker
# Web app (Next.js — separate from the Python stack)cd apps/webnpm installNEXT_PUBLIC_API_BASE=http://localhost:8000 npm run dev

Tests

bash
.venv/bin/pytest packages/shared/tests.venv/bin/pytest workers/ingest/tests.venv/bin/pytest apps/api/tests

Running the stack locally with Docker

bash
cd infra/dockerdocker compose up --build

This brings up Postgres, the API, the ingestion worker, and the MCP server. The web app (apps/web) is run separately via npm run dev during local development (see infra/docker/docker-compose.yml for the placeholder service definition).

Documentation

License

Apache-2.0. See LICENSE and NOTICE for data attribution (Open States / Plural Policy, public-domain legislative data).

Contributing

See CONTRIBUTING.md. This project follows the Contributor Covenant.

Security

See SECURITY.md for responsible disclosure.

Source: README.md at commit 43b1cf3

Tools

10

search_legislation

Search FULL BILL TEXT -- not just known-bill-number lookup. `q` is matched against titles, descriptions, AND ingested document text via Postgres websearch_to_tsquery (supports "quoted phrases", OR, and -exclusion, same syntax as a search engine), with a fuzzy pg_trgm title-similarity fallback when the exact query has no hits. `q` can ALSO be a bill number ("HB 123", "H.B. 123", "hb123" all match) and that fast path is tried first. Optionally filter by jurisdiction (two-letter state code or name), chamber, and status. For a curated cross-state slice of a subject (e.g. "every AI bill in the country") rather than an ad-hoc keyword search, call list_topics first -- its membership rules also match on structured subject tags this full-text search does not see.

Parametersqrequiredlimitstatuschamberjurisdiction

get_bill_record

Fetch the full record for one bill: metadata, sponsors, subjects, actions, versions, and vote-event summaries. Look up by canonical bill_id (UUID), or by jurisdiction + identifier (+ optional session to disambiguate). For a human bill number like HB 123, use jurisdiction="NC", identifier="HB 123"; bill_id is for UUIDs.

Parametersbill_idsessionidentifierjurisdictioninclude_full_text

compare_bill_versions

Deterministic diff (unified + structured) between two versions of a bill's extracted text. Defaults to earliest vs. latest texted version if version ids are omitted. Errors if fewer than 2 versions have extracted text. Result is labeled 'derived' (computed by Bill Commons, not an official document).

Parametersbill_idrequiredversion_id_aversion_id_b

find_similar_bills

Find bills with similar titles via deterministic trigram similarity, across jurisdictions. Labeled 'derived' -- not an official cross-reference or companion-bill designation.

Parameterslimitbill_idrequired

get_vote_details

Fetch vote event(s) with member-level (yes/no/other/absent) vote records. Provide vote_event_id for one vote, or bill_id for all recorded votes on that bill.

Parametersbill_idvote_event_id

trace_legislative_history

Full chronological legislative history for a bill: merged timeline of actions, version publications, and votes, plus related-bill links.

Parametersbill_idrequired

build_legislative_evidence_packet

Compile a citation-ready evidence packet for a bill: full official record, legislative history timeline, votes with member-level detail, and hearings -- each explicitly labeled official vs. derived with source URLs. Returns a `how_to_cite` block with a one-line `cite_as` sentence, a human `permalink`, a JSON `download_url`, and a `snapshot_id` that changes if and only if a cited fact about the bill changes -- so a reader can check later whether the citation still holds. Snapshots are NOT archived; the id is a change detector, not a way to retrieve an older packet. Pass `question` to record what the packet was assembled to answer; it is echoed into the artifact so a filed packet carries its own scope.

Parametersbill_idrequiredquestioninclude_full_text

get_jurisdiction_coverage

Return the jurisdiction_coverage state-machine status for one state (abbreviation or name), or the full stored coverage matrix if state is omitted. Public-registry and unlisted row counts are explicit. Includes bounded retained official-source observation health and evidence links. Coverage status measures stored bill/text availability; local coverage timestamps can advance on count recomputation. Statewide semantic freshness remains unverified, including for GREEN coverage.

Parametersstate

get_active_sessions

List legislative sessions currently flagged active, optionally filtered by jurisdiction (two-letter state code or name).

Parametersjurisdiction

list_topics

List Bill Commons' curated cross-state topic trackers (e.g. artificial intelligence, youth online safety, platform accountability, cybersecurity, cryptocurrency, data privacy, local government & preemption) -- the entry point for "what subjects does Bill Commons track across all 50 states + DC" and "how do I get every bill in one". Each topic is a title/subject membership rule tuned for precision over recall, with a live bill_count and how_to_fetch_bills. This tool does not itself return bill rows -- pair it with search_legislation or the REST API's /topics/{slug} for the bills.

Takes no parameters.

Version history

1
  1. v1.0.0LatestSep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts