npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@legislation/mcp

v0.7.0

Published

Model Context Protocol server for the Delilah legislative data API — bills, legislators, votes, committees and coverage for 50 states, D.C. and Congress.

Readme

@legislation/mcp

An MCP server that gives AI assistants real U.S. legislative data from the Delilah API — all 50 states, D.C., and the federal Congress. Bills, sponsors, roll-call votes with individual member positions, action history, bill texts, committees, hearings, a change feed, and per-state coverage.

Read-only: it never writes anything. There are two ways to use it — a remote hosted server (recommended, nothing to install) and a local stdio package. Both expose the same 35 tools. The hosted server works without a key on a shared, rate-limited free tier; for your own cap use a Delilah API key (request one at https://delilahusa.com/developers/request).

Remote hosted server (recommended)

The server runs on Delilah's own infrastructure at https://mcp.delilahusa.com — you just point your client at the URL and pass your key. Nothing to install, and the implementation stays server-side.

Cursor~/.cursor/mcp.json:

{
  "mcpServers": {
    "legislation": {
      "url": "https://mcp.delilahusa.com/",
      "headers": { "Authorization": "Bearer dk_live_YOURKEY" }
    }
  }
}

Claude — Settings → Connectors → Add custom connector, URL:

https://mcp.delilahusa.com/?key=dk_live_YOURKEY

Any stdio-only client (bridge): npx mcp-remote https://mcp.delilahusa.com/ --header "Authorization: Bearer dk_live_YOURKEY"

See docs/ARCHITECTURE.md for how the hosted server works (a Cloudflare Worker fronting api.delilahusa.com), and where it deploys from.

Local install (stdio)

One command, nothing to configure:

claude mcp add legislation -- npx @legislation/mcp

With no key it runs on the shared free tier: the hosted server supplies a key of its own, so tools work immediately. That tier is read-only and rate-limited per client. Set DELILAH_API_KEY for your own monthly cap and for writes:

claude mcp add legislation -e DELILAH_API_KEY=dk_live_… -- npx @legislation/mcp

Claude Desktop

Add this to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json), then restart Claude Desktop:

{
  "mcpServers": {
    "legislation": {
      "command": "npx",
      "args": ["-y", "@legislation/mcp"],
      "env": {
        "DELILAH_API_KEY": "dk_live_..."
      }
    }
  }
}

Claude Code

Plugin (recommended) — adds the hosted MCP server and a /legislation skill that tells Claude how to answer legislative questions well (cite bill numbers, pick the right tool, never call a race). No API key needed to start: the hosted server has a shared, rate-limited free tier.

/plugin marketplace add https://mcp.delilahusa.com/marketplace.json
/plugin install legislation@legislation

Then, in any session: /legislation what passed in Florida this week — or just ask; Claude reaches for the tools on its own. For your own monthly cap, register the hosted server with your key:

claude mcp add --transport http legislation https://mcp.delilahusa.com/ -H "Authorization: Bearer dk_live_..."

MCP server only:

claude mcp add legislation --env DELILAH_API_KEY=dk_live_... -- npx -y @legislation/mcp

Tools

36 tools, all read-only except manage_webhooks (whose writes require confirm:true).

Bills

| Tool | Endpoint | What it does | | --- | --- | --- | | search_bills | /v1/bills | Search or list legislation with structured filters. Use this when you know the jurisdiction, sponsor, topic, or status you want. | | semantic_search_bills | /v1/search/semantic | Vector search over the full text of every bill: describe what you want in plain English — 'protecting kids from social media', 'limits on rent increases' — and get the closest bills with a match_score. Prefer this over search_bills for questions and topics; prefer search_bills for a known bill number, sponsor, or status filter, and keyword_search_bills for exact terms that must all appear. | | keyword_search_bills | /v1/search/bills | Keyword search where EVERY term must appear. Use when the user gives specific words that all have to be present, e.g. ['short-term rental', 'tax']. | | get_bill | /v1/bills/{bill_id} | Fetch a single bill by its numeric bill_id, optionally merging in sub-resources: votes (roll calls with tallies), sponsors, history (action timeline), texts (version metadata), amendments, subjects, analyses (staff analyses), calendar (scheduled events), citations (statutes the bill touches), referrals (committee referrals), sast (same-as / similar-to companion bills in the other chamber or other states), supplements (fiscal notes and summaries). analyses and citations are populated only for the deeper-coverage states. Each include is a separate API call, so ask only for what you need. | | get_bill_text | /v1/texts/{text_id} | The cleaned plain text of one bill-text version, entities decoded, ready to quote or summarize. Get text_id from get_bill with include:['texts'] (each version has a date and type). | | get_bill_text_history | /v1/bills/{bill_id}/changes | Timeline of all computed diffs between successive text versions of one bill: what changed, when, and how much. Use get_bill_diff for one specific pair of versions. | | get_bill_diff | /v1/bills/{bill_id}/diff | Compare two versions of a bill's text: a unified diff plus similarity, added/removed line and character counts, and changed-section highlights. Get the two version ids from get_bill with include:['texts'] — each text row's text_id. |

People and votes

| Tool | Endpoint | What it does | | --- | --- | --- | | list_legislators | /v1/legislators | Search or list legislators by jurisdiction, chamber, party, district, or name. This is how you turn a name into the people_id that get_legislator needs. | | get_legislator | /v1/legislators/{people_id} | Fetch a legislator's profile by people_id, optionally merging in votes (every roll call they are recorded on, newest first, with their individual position: 1=Yea, 2=Nay, 3=Not Voting, 4=Absent) and bills (legislation they sponsor, with sponsor_type_id 1=primary, 2=cosponsor). Find a people_id with list_legislators or from a bill's sponsors. | | get_legislator_scorecard | /v1/legislators/{people_id}/scorecard | One-call voting and sponsorship profile for a legislator: participation, party-line alignment, bills sponsored and passed, notable votes. This is the tool for 'how does X vote' or 'is X effective'. | | get_roll_call | /v1/votes/{roll_call_id} | Fetch a roll call by roll_call_id: the motion, chamber, date and yea/nay/absent tallies. Add include:['details'] to also pull how every individual member voted (vote_id 1=Yea, 2=Nay, 3=Not Voting, 4=Absent) — this is the tool for 'how did each legislator vote on this'. |

Committees and hearings

| Tool | Endpoint | What it does | | --- | --- | --- | | list_committees | /v1/committees | List legislative committees, filterable by jurisdiction, chamber, or name search. Returns the committee_id values that get_committee needs. | | get_committee | /v1/committees/{committee_id} | Fetch a committee by committee_id, optionally merging in members (its roster, with roles) and hearings (its scheduled meetings). Find a committee_id with list_committees. | | list_hearings | /v1/hearings | Scheduled committee hearings across committees, filterable by jurisdiction and start date. Use this to answer 'what is being heard this week' or to track when a committee next meets. |

Sessions and analytics

| Tool | Endpoint | What it does | | --- | --- | --- | | list_sessions | /v1/sessions | Legislative sessions: regular and special sessions with their years, start/sine-die dates and a session_id. Use this to resolve which session a bill belongs to, to find the current session for a state, or to pass session_id as a filter to search_bills. | | get_session_dashboard | /v1/sessions/{id}/dashboard | Headline counts for one legislative session: bills filed, passed, signed, vetoed, roll calls, active legislators. Start here for 'how is the 2026 Florida session going'. | | get_session_sponsor_stats | /v1/sessions/{id}/sponsor-stats | Legislators ranked by bills sponsored and passed in one session. Each row has bills_sponsored, bills_primary, bills_passed, bills_primary_passed and pass_rate (passed = status 4, 5 or 8). | | get_session_vote_participation | /v1/sessions/{id}/vote-participation | How many roll calls each legislator voted in versus missed during one session. Use for attendance questions. | | list_session_legislators | /v1/sessions/{id}/legislators | Every legislator who served in one session, with people_id. Use list_legislators for the current roster by state; use this for a specific past or special session. | | get_session_breakdown | /v1/sessions/{id}/status-counts | Bill count per status (by:'status', on the status_id ladder) or per subject (by:'subject') for one session. Get session_id from list_sessions. status_id values: 1=Introduced, 2=In Committee, 3=Passed One Chamber, 4=Passed Both Chambers, 5=Signed into Law, 6=Vetoed, 7=Failed/Dead, 8=Chaptered. | | get_trending_bills | /v1/trending | Bills with the most news coverage in the window, optionally for one state. Use for 'what's in the news' or 'hot bills right now'. | | list_bills_by_stage | /v1/bills-by-stage | Bills whose LATEST action in the window falls in a stage: introduced, committee, passed, executive (with the governor, signed, or vetoed), amendments, other. Fleet-wide across all jurisdictions — there is no state filter, so filter the rows by state_id or state_name yourself. | | get_weekly_stage_breakdown | /v1/bills-weekly-breakdown | One row per stage with the number of bills whose latest action landed there in the window. All jurisdictions combined. |

Elections and geography

| Tool | Endpoint | What it does | | --- | --- | --- | | list_candidates | /v1/candidates | Search the election-candidate directory: people running for office. Filters combine with AND. | | get_candidate | /v1/candidates/{id} | Fetch one election candidate by id: their party, office, district and cycle, plus an FEC filer id where the campaign has filed and a Bioguide id for sitting members of Congress. When people_id is set, the candidate has a legislative voting record — pass it to get_legislator or get_legislator_scorecard to go from candidate to voting history in one hop. | | get_midterms | /v1/midterms | The election slate for 2026-11-03: races, candidates and ballot measures per state, with official results where available. All data is official state election-office and FEC content collected by Delilah — no third-party attribution is required. live_results carries ONE ENTRY PER CONTEST, each with contest (e.g. primary:DEM, runoff:REP) and party: a closed primary returns each party separately and vote_pct is the share of THAT party's ballot, so never compare or rank candidates across two contests. | | get_ballot_measure | /v1/measures | Ballot measures: the list for a state, or one measure by its number (e.g. 'Amendment 1') with full text, summary and official source URL. Use for 'what's on the ballot in X' and 'what does Amendment N do'. | | get_candidate_photo | /v1/photos/{candidate_id} | The URL of a candidate's official portrait. Sources are official state-legislature and congressional portraits, public-domain and licensed images only — never a third party's photo library — and each carries a license and attribution string that MUST be shown when the license requires it (Wikimedia CC BY). | | list_districts | /v1/districts | District metadata by state and type: congressional, state senate, state house. Pass district_id with boundary:true to get the polygon as GeoJSON — it is large, so set simplify (degrees, e.g. 0.01) to shrink it. |

Monitoring and reference

| Tool | Endpoint | What it does | | --- | --- | --- | | get_changes | /v1/changes | Near-real-time feed of what changed. Poll with since= to get everything newer than your cursor; with no since it defaults to the last hour. | | list_topics | /v1/topics | The canonical topic taxonomy with per-topic bill counts. Call this first to find the right slug for the topic filter on search_bills, instead of guessing one. | | list_subjects | /v1/subjects | The raw subject taxonomy with per-subject bill counts. Subjects are the fine-grained categories the legislatures themselves assign to bills — narrower and more numerous than the curated topic slugs from list_topics. | | list_states | /v1/states | The jurisdiction directory: the 50 states, D.C. and the U.S. Congress with their state_id, 2-letter code and full name. Returns the full list (52 rows) so you can resolve a name to a code or enumerate everything the corpus covers. | | get_coverage | /v1/coverage | Per-state depth snapshot: how COMPLETE each jurisdiction's data is — bill counts, the share of bills holding at least one vote, text or sponsor, and whether the legislature is currently in session. Use it before drawing conclusions from a thin result set, to tell 'no such bills' apart from 'this state is thinly covered'. |

Account

| Tool | Endpoint | What it does | | --- | --- | --- | | get_usage | /v1/_meta/usage | The current key's tier, monthly cap, requests used and remaining, and when the period resets. Call this when a request is rate-limited (HTTP 429) or the user asks about their plan. | | manage_webhooks | /v1/webhooks | Manage the key's webhook subscriptions. action:'list' is read-only. 'create' REGISTERS a URL that Delilah will POST to on the chosen events — it changes the account, so it requires confirm:true and the user's explicit go-ahead. |

On semantic_search_bills

True vector search over the full text of every bill (GET /v1/search/semantic): ask a question in plain English and each result carries a match_score. Use search_bills for a known bill number, sponsor or status filter, and keyword_search_bills when specific terms must all appear.

Status IDs

| id | Meaning | | --- | --- | | 1 | Introduced | | 2 | In Committee | | 3 | Passed One Chamber | | 4 | Passed Both Chambers | | 5 | Signed into Law | | 6 | Vetoed | | 7 | Failed / Dead | | 8 | Chaptered (law) |

Aggregate buckets: passed = {4, 5, 8}, failed = {6, 7}, alive = {1, 2, 3}. The status_id filter on search_bills and the status field on every bill object use this scheme.

Notes

  • Coverage window: the corpus is 2026-forward only.
  • Response size: long arrays are capped and long strings clipped, each with an explicit truncation marker. Page with limit/offset for the rest.
  • Errors: API error bodies are passed through verbatim, including request_id and any X-RateLimit-* / Retry-After headers.
  • Includes: each entry in an include array is a separate API call against your rate limit, so request only what you need.

Configuration

| Variable | Required | Default | | --- | --- | --- | | DELILAH_API_KEY | yes, for tool calls | — | | DELILAH_API_BASE | no | https://api.delilahusa.com |

Requests time out after 30 seconds.

Development

npm install
npm run build          # tsc -> dist/
npm test               # vitest: catalog, client, errors, worker-catalog parity
npm run docs           # regenerate the README tool tables from the catalog
npm run emit-worker    # bundle the catalog into ../delilah-infrastructure/cloudflare-workers/mcp/tools.generated.js
DELILAH_API_KEY=… npm run contract   # call every tool once against the live API

Tools live in src/tools/*.ts — one defineTool({...}) per tool, written against the tiny Api interface in src/tools/types.ts. The stdio server (src/index.ts) registers that catalog directly; the hosted worker imports a bundle generated from the same files, so the two transports cannot drift. Add a tool by adding it to a module and to the ordered list in src/tools/index.ts, then run npm test, npm run docs and npm run emit-worker.

Requires Node 18 or newer.

License

MIT