oravan
Oravan's server provides read-only, keyless access to U.S. federal legislative and representative data, with bilingual (EN/ES) support and citation envelopes on every response.
lookup_representatives: Find a constituent's U.S. House member and two Senators by 5-digit ZIP code — returns names, party, phone numbers, official websites, portrait URLs, and district office contact info. Handles split-ZIP situations and explicitly surfaces vacant seats.get_bill: Retrieve a full plain-language decode of any federal bill by slug (e.g.hr-2701-119) or citation (e.g.H.R. 2701). Includes summary, what/who/why/cost breakdown, official status, urgency band, sponsor, key dates, and links to Congress.gov.search_bills: Search the bilingual federal bill corpus using free-text queries, issue topic filters (e.g. health, immigration, housing), status filters, and an active-only flag. Results are returned most urgent first.whats_moving: Discover recently active bills that have cleared Oravan's "act now" urgency threshold within a configurable lookback window (default 7 days, up to 90), optionally filtered by topic. Honestly returns an empty list with aquiet_weekflag when nothing qualifies — never pads results.get_representative: Get comprehensive details on a specific member of Congress by Bioguide ID, including their 5 most recently active sponsored bills. Strictly factual — no scorecards or vote grades.
All tools require no API key and include a citation envelope detailing source, data freshness, AI-content label, and license.
Oravan
Your line to Congress · Tu línea con el Congreso
Oravan is free, nonpartisan civic infrastructure: find your federal representatives, understand active bills in plain language (English and Spanish), get a 30-second call script, and make the call — in under 5 minutes, with no account.
The name is the Oravan: the platform in the Roman Forum where citizens stood to address the public and the powerful — the original place a voice met power. Latin roots are the shared ancestry of English and Spanish alike.
MCP server
This repository also implements a remote MCP (Model Context Protocol) server — the same decoded corpus and lookups, exposed for AI assistants and agents:
Endpoint (Streamable HTTP):
https://oravan.org/api/mcp/mcp— keyless, read-only, rate-limited; no account or credentials requiredLocal/stdio:
npm cithennpx tsx scripts/mcp-stdio.mjs— the same 5 tools over stdio, zero env vars/secrets requiredImplementation:
app/api/mcp/[transport]/route.ts(built onmcp-handler+@modelcontextprotocol/sdk), tool definitions shared with the stdio entry vialib/core/mcp-tools.ts, pure data layer inlib/core/Five tools:
lookup_representatives,get_bill,search_bills,whats_moving,get_representative— every response carries a citation envelope (source, as-of freshness, AI-content label, license) in English or SpanishOfficial MCP Registry: published as
org.oravan/mcp(server.jsonat the repo root, schema-validated in CI byscripts/check-server-json.mjs)Docs: oravan.org/mcp (tool reference, client config, privacy posture) · docs/mcp-server-readme.md
Related MCP server: CongressMCP-full
Design principles
Zero accounts. ZIP code, interests, and call history live in
localStorageon the visitor's device. No server-side user data exists — nothing to breach, leak, or subpoena. This is the core privacy posture for at-risk users, not a missing feature.Static-first. Bills, legislators, district offices, and ZIP→district mappings are static JSON in
data/, baked into ~1,000 statically generated pages. Fast, nearly free to host, resilient under load. The only dynamic endpoints are/api/script(AI script generation, cached per bill+stance+language, IP rate-limited),/api/reps(pure lookup),/api/district(stateless split-ZIP address refinement: proxies the Census geocoder so the visitor's IP never reaches census.gov; the address is never stored or logged), and/api/feedback(beta feedback relayed to a private GitHub issue — only what the visitor volunteered, no identifiers).Bilingual as a first-class feature. Full EN/ES UI via
next-intl; scripts are generated in the user's language.Truth first; the call is the natural next step. Oravan leads as an unbiased, plain-words account of what Congress is actually doing — understanding is the front door, never an assignment. The call apparatus stays the differentiator (voicemail legitimized, offices tally it identically; after-hours calling encouraged; district offices listed alongside DC; outcomes — spoke / voicemail / couldn't reach — logged locally on the device), and every decoded answer keeps a completed call script within two interactions. Demoted, never buried. (Amended 2026-07-26; previously "The call moment is the product." Enforced by the three named invariants in
tests/funnel.spec.ts— see DESIGN.md structural constraint 2.)Honest about AI. Every generated summary and script is labeled at first contact, and nothing publishes unless the automated gates pass: both languages present, the official record attached, and a schema check on every decode — a decode that comes back missing a required field is discarded rather than stored half-written, and
scripts/verify-sync.mjsre-checks the whole corpus and fails the nightly run before it is allowed to commit anything. (Amended 2026-08-12: one check left that file and now runs AFTER the commit — the cursor-age ceiling inscripts/check-cursor-age.mjs. It is a progress signal, not a corpus one: a stalled cursor means we are behind, and failing it before the commit made a stalled night throw away a night of already-paid decodes. Every corpus check named here is unchanged and still runs before anything is committed. See CLAUDE.md's amendment of the same date.) Nonpartisan wording is a drafting instruction to the model on bill decodes and an enforced vocabulary lint on Big Questions (lib/moments-gate.mjs) — the two are not the same guarantee, and the copy never blurs them. The nightly decode path has no human step and the product never claims one; the one review it does claim is real: a caller reads, and can edit, the call script before dialing. (Amended 2026-08-06; previously "labeled, editable, and reviewed by the human before any call." See CLAUDE.md's 2026-07-25 amendment, which this line should have followed and did not.)Accessible by default. Semantic landmarks, skip link, visible focus,
prefers-reduced-motion, 44px+ touch targets, AA contrast.
Data sources
File | Source | Refresh |
| Decoded bill corpus (Congress.gov bills + AI plain-language summaries, English and Spanish) | Nightly sync ( |
| unitedstates/congress-legislators (public domain) + district offices |
|
| same | |
| Derived, not fetched: |
|
| Human-authored ( |
|
| Civilian Senate nominations (PNs) of the 119th Congress — Congress.gov's own citation, description sentence, and latest action, plus a status derived from that action text by |
|
| Real news articles about top-band bills via TheNewsAPI, AI-relevance-filtered (Haiku) |
|
| Outlet political-lean ratings by AllSides, used under CC BY-NC with attribution | Vendored snapshot |
Portraits are served from the public-domain unitedstates/images project.
Solved pipeline incidents (root cause + the CI gates that prevent recurrence) are documented in docs/solutions/.
The "Read" section (outlet-bias coverage)
Each top bill's page shows real third-party articles about it, labeled by the outlet's political lean (Left / Center / Right) — reusing AllSides' publication-level ratings, never a Oravan-invented one. Oravan takes no stance and authors no partisan text: AI is used only behind the scenes — generating each bill's news-search terms (press-style names and a subject query) and a cheap relevance gate (is this article about this bill?) — and authors nothing displayed. The ingestion runs nightly in CI and bakes results to JSON, so the site still makes zero runtime third-party calls. Without NEWS_API_KEY the sync is a no-op and the section renders nothing; a small hand-built real sample (data/coverage.json) keeps it demoable. Lean is shown by text label + position only — never party colors (a hard rule; see DESIGN.md).
Develop
npm install
echo "ANTHROPIC_API_KEY=sk-ant-..." > .env.local # script generation + decode/relevance
echo "NEWS_API_KEY=..." >> .env.local # optional; enables the "Read" coverage sync
npm run devnpm run build statically generates every bill page in both locales.
Known v1 caveats
ZIP→district mapping is ZCTA-based; a split ZIP shows all candidate districts by default (senators are unaffected). Entering a street address — optional, sent once by POST, never stored or logged — narrows it to the actual district via a server-proxied Census-geocoder lookup; the all-candidates view remains the graceful fallback whenever the geocoder can't help. The geocoder request pins the "119th Congressional Districts" layer, which needs a bump when the Census rolls the vintage to the 120th.
Script cache and rate limits are in-memory per serverless instance — fine at demo scale, should move to a shared store before heavy traffic.
New bills can lag behind Congress.gov: the nightly sync decodes at most
MAX_NEW_DECODESnew bills per run (cost ceiling), so after a missed window the corpus catches up over several nights (decode-before-publish; the backlog drains oldest-first)."Read" coverage exists only for top-band bills (the long tail shows nothing); the ES locale shows the same English articles with localized chrome; outlets absent from
data/media-bias.jsonappear without a lean chip.
License
Code: GNU AGPL-3.0. You may use, modify, and run this code — including as a network service — provided modified versions you operate or distribute remain open under the same license. Embedding Oravan's hosted widgets on your site via the loader/script tag does not subject your site to the AGPL; that's use of our service, not distribution of this code.
Not licensed: the Oravan name, logo, and brand assets (
assets/brand/, app icons). All rights reserved — forks must use their own identity.Content: underlying legislative data is U.S. government work (public domain). AI-generated decodes and summaries are licensed CC BY 4.0, exactly as declared in the MCP citation envelope and on the citations page.
Available Tools
5 toolsget_billGet a bill decodeARead-onlyInspect
Get the full plain-language decode of a federal bill by slug (e.g. "hr-2701-119") or citation (e.g. "H.R. 2701" - resolves to the most recent Congress on a match). Returns the AI-generated summary (headline, tl;dr, what/who/why/cost - automatically checked before publish and clearly labeled when present), the official status in plain language, an urgency band, sponsor, key dates, the official Congress.gov page, and an act_url to Oravan's on-site call flow. This tool never drafts a phone script - script generation happens only on-site, where the caller reads and can edit the script before dialing; that is not available over this API.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | No | Bill slug, e.g. "hr-2701-119". Takes priority over citation when both are given. | |
| locale | No | Response language: "en" (default) or "es". | |
| citation | No | Bill citation, e.g. "H.R. 2701" or "S.J.Res. 99". Used only when slug is omitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint: true and openWorldHint: false, and the description adds valuable context: AI summaries are auto-checked before publishing, citation resolution defaults to the most recent Congress, and script generation is not available through the API. This goes beyond the base annotations, though it could mention error behavior or data freshness.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, dense sentence but is structured logically, starting with the core action and then detailing the return payload and a key limitation. It is verbose yet every phrase contributes meaningful detail, with no fluff. Breaking it into two sentences could improve readability without adding bulk.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main aspects: purpose, input methods, output fields (summary, status, urgency, sponsor, dates, URLs), and a critical limitation. Given the tool's moderate complexity and absence of an output schema, this is largely complete. Minor gaps include no mention of error conditions, rate limits, or handling of invalid slugs/citations, which could be inferred from typical API behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While the schema provides basic parameter descriptions, the tool description enriches understanding by explaining that slug takes priority over citation, how citations are resolved, and gives realistic examples. The explicit mention of the precedence rule and the 'most recent Congress' behavior adds semantic value that the schema alone does not convey. This helps the agent use parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: getting a full plain-language decode of a federal bill using either a slug or citation. It distinguishes itself from sibling tools by focusing on bill-specific data and explicitly noting it never drafts a phone script, setting it apart from the on-site call flow and other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains how to invoke the tool (by slug or citation) and the priority of slug over citation, which helps in usage. It also clarifies a limitation (no script drafting). However, it does not explicitly compare this tool to siblings like search_bills or what to do when a bill ID is unknown. A direct 'when to use this instead of search_bills' would be an improvement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_representativeGet a representativeARead-onlyInspect
Get full details for one member of Congress by bioguide ID (e.g. "W000797"), plus their 5 most recently active sponsored bills. Facts only: no scorecards, ratings, or vote grades.
| Name | Required | Description | Default |
|---|---|---|---|
| locale | No | Response language: "en" (default) or "es". | |
| bioguide | Yes | Bioguide ID, e.g. "W000797". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses read-only nature (consistent with annotations) and adds scope: single member, specific output including '5 most recently active sponsored bills'. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with core purpose, no superfluous words. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, description fully conveys what the tool returns: member details + 5 bills. Input params fully described. Sufficient for agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters with descriptions (100% coverage). Description adds real-world example 'W000797' and enriches understanding by noting output includes sponsored bills.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb 'Get' and specific resource 'full details for one member of Congress by bioguide ID' plus bills. Differentiates from siblings like 'lookup_representatives' and 'get_bill'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly states input (bioguide ID) and output (details + 5 bills). Includes constraint 'Facts only: no scorecards...', guiding usage. No explicit when-not or alternatives, but implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_representativesLook up representatives by ZIPARead-onlyInspect
Look up a person's U.S. House member and two Senators by 5-digit ZIP code. Returns each member's name, party, phone, official website, portrait URL, and district office phone numbers - the number a constituent should actually call. Some ZIP codes span more than one congressional district (needs_address: true, all candidate districts returned); this tool does not perform address-level refinement itself in this release - point the person to the response's reps_url, where a stateless, unlogged Census-geocoder proxy narrows it to a single district from a street address that Oravan never stores. When a House seat currently has no member, vacancies lists the empty seat(s) (state + district) explicitly - the departed member is never returned as if still serving, and no election timeline is implied.
| Name | Required | Description | Default |
|---|---|---|---|
| zip | Yes | 5-digit U.S. ZIP code. | |
| locale | No | Response language: "en" (default) or "es". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Exceeds annotations by explaining return fields, multi-district handling, vacancy behavior, and the stateless proxy. No contradiction with readOnlyHint and openWorldHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured: first sentence states main purpose, then details returns, then edge cases. Slightly verbose but each sentence adds necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all relevant aspects: return data fields, edge cases (multi-district, vacancies), and behavior (no address storage). No output schema, but description compensates adequately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description adds context: ZIP pattern, language enum, multi-district edge case. Adds value beyond the schema with practical usage details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it looks up U.S. House member and two Senators by 5-digit ZIP code. Differentiates from siblings like get_representative by specifying the lookup method and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides guidance on when to use (by ZIP), explains limitations for multi-district ZIPs, and directs users to reps_url for address refinement. Could explicitly contrast with alternatives but is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_billsSearch billsARead-onlyInspect
Search Oravan's bilingual federal bill corpus by free-text query, issue topic, status, or active-only. Returns short teasers (headline, status, urgency) for matching bills, most urgent first.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results (default 20, max 50). | |
| query | No | Free-text search over the bill title and plain-language summary. | |
| topic | No | One of the 12 issue categories. | |
| locale | No | Response language: "en" (default) or "es". | |
| status | No | Bill status to filter to. | |
| active_only | No | Exclude signed/vetoed (terminal) bills when true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, and the description aligns by describing a search operation returning teasers. It adds behavioral detail about sorting by urgency and the bilingual nature, which is helpful beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no fluff. Front-loaded with action and criteria, then output format. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, but the description explains return value format (headline, status, urgency). It covers all parameters implicitly and provides sufficient context for a search tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with all parameters described. The description adds minor context (e.g., 'bilingual' hints at locale) but mostly restates schema info. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it searches a bilingual federal bill corpus by multiple criteria (query, topic, status, active-only) and returns teasers ordered by urgency. It distinguishes itself from siblings like get_bill which retrieves a single bill.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly indicates when to search bills by specifying the searchable fields. It does not explicitly exclude cases or mention alternatives, but the context is sufficient to understand its use relative to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whats_movingWhat's moving in CongressARead-onlyInspect
What's moving in Congress recently: active, plain-language-decoded bills that cleared Oravan's 'act now' urgency bar within the last N days (default 7), optionally filtered by topic. Returns an honest empty list with quiet_week: true when nothing has cleared the bar - this tool never pads the list to look busier than Congress actually is this week. If the list is empty because Oravan's own data sync looks stale rather than Congress being quiet, data_stale is set instead so that distinction is never lost.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Lookback window in days (default 7). | |
| limit | No | Max results (default 10, max 50). | |
| topic | No | One of the 12 issue categories. | |
| locale | No | Response language: "en" (default) or "es". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description discloses honest empty list behavior with quiet_week/data_stale flags, never pads results, and mentions Oravan's urgency bar and plain-language decoding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is one paragraph, front-loaded with purpose, and each sentence adds value. Slightly lengthy but efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description explains return value shape (honest empty list with flags) and key behavior. Could clarify bill fields, but adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 100% parameter description coverage. The description adds default values (days=7) and mentions topic filtering but does not provide additional syntax or meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns active bills that cleared an urgency bar, optionally filtered by topic. It distinguishes from siblings like get_bill (single bill) and search_bills (general search) by focusing on recent urgent bills.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use for recent urgent bills and explains empty result behavior. It does not explicitly name alternatives or state when not to use, but context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
get_bill - First observed
get_representative - First observed
lookup_representatives - First observed
search_bills - First observed
whats_moving
TDQS
Scored across 5 tools
The tools are mostly distinct: representative lookup is split by ID vs ZIP, and bill discovery is split into search teasers vs full-detail retrieval. whats_moving and search_bills can overlap when filtering by active status and topic, but their intent is clearly differentiated by recency/urgency vs free-text query.
Four tools follow a clear verb_noun pattern: get_representative, lookup_representatives, get_bill, search_bills. whats_moving breaks the pattern stylistically but is still readable and memorable, so the set is mostly consistent with one minor deviation.
Five tools is well-scoped for a focused congressional-information server. Each tool covers a distinct core action: look up a representative, get representative details, get a bill, search bills, and see recent urgent activity.
Core read-only workflows are covered: search bills, retrieve bill details, find representatives by ZIP, and see recent activity. However, get_representative requires a bioguide ID that lookup_representatives does not appear to return, and address-level district refinement is explicitly left to an external URL, creating possible dead-ends for agents.
Maintenance
Related MCP Connectors
Access U.S. congressional data - bills, votes, members, committees - via MCP.
GovTrack MCP — federal US Congress data (free, no auth)
Congress MCP — US Congress data via GovTrack API (free, no auth required)
An MCP server that provides congressional transcripts
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceAn MCP server for the Congress.gov API that consolidates 91 operations into 6 comprehensive legislative tools that can be used by any MCP client (i.e. Claude Desktop), or MCP-compatible AI agent, to query and reason about congressional data.4 npm1JavaScriptMIT
- AlicenseAqualityAmaintenanceThe open Congress.gov MCP server. Provides comprehensive access to the Congress.gov API through 6 organized toolsets, enabling AI systems to retrieve and interact with legislative data from the United States Congress with a clean, unified interface.2488 PyPI32Sustainable Use v1.0
- AlicenseNot gradedqualityCmaintenanceEnables querying legislative data from the LegiScan API, including bills and votes, via natural language through an MCP gateway.6 npmMIT
- FlicenseAqualityCmaintenanceExposes a Congress.gov-style legislative GraphQL API to MCP clients, enabling querying bills, actions, committee activities, and cosponsors via natural language.7-