Agent access
MCP server setup
Bill Commons runs a Model Context Protocol (MCP) server over Streamable HTTP, so Claude and other MCP-compatible clients can search and cite legislation directly. Tools return structured JSON; bill results include canonical IDs, source URLs, and local retrieval timestamps. Coverage warnings identify thin local data rather than treating an empty result as proof that no legislation exists.
Endpoint
https://mcp.billcommons.org/mcpStreamable HTTP, stateless, no authentication required for public read access.
Using ChatGPT? Follow the developer-mode setup and plugin availability notes. The public endpoint is available now; the packaged Bill Commons plugin is still in preparation.
Claude Desktop / Claude.ai
Open Customize → Connectors, choose + → Add custom connector, name it Bill Commons, and paste this remote server URL. Then enable the connector for your conversation:
https://mcp.billcommons.org/mcpOn a Team or Enterprise account, an organization owner first adds the custom web connector in Organization settings → Connectors. See Claude's remote MCP setup guide.
Claude Code
Add the same remote server from your terminal:
claude mcp add bill-commons --transport http https://mcp.billcommons.org/mcpOther MCP clients
Clients that support remote Streamable HTTP can be configured with the endpoint above. Exact setup and tool routing depend on the client.
With Python 3.10 or newer installed, save the code below as billcommons_example.py. Use a virtual environment to install the tested SDK version without changing your system Python.
python3 -m venv .venv
.venv/bin/python -m pip install "mcp==1.28.1"
.venv/bin/python billcommons_example.pypy -3 -m venv .venv
.venv\Scripts\python.exe -m pip install "mcp==1.28.1"
.venv\Scripts\python.exe billcommons_example.pyimport asyncio
from mcp.client.streamable_http import streamablehttp_client
from mcp import ClientSession
async def main():
async with streamablehttp_client("https://mcp.billcommons.org/mcp") as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
result = await session.call_tool(
"search_legislation", {"q": "paid family leave"}
)
if result.isError:
raise RuntimeError(result.content)
for item in result.content:
if item.type == "text":
print(item.text)
if __name__ == "__main__":
asyncio.run(main())A successful call prints the search result, including any coverage limitations. For a known number, call get_bill_recordwith jurisdiction="NC" and identifier="HB 920", or pass the canonical UUID returned by search as bill_id. A number alone can match more than one session, so the tool asks you to disambiguate rather than choosing a bill silently. An empty search result does not prove that no matching legislation exists; checkget_jurisdiction_coverage with state="NC" for the state you are researching. Its argument is state, while get_bill_record uses jurisdiction.
Tools
All 10 advertised tools declare readOnlyHint: true, destructiveHint: false, idempotentHint: true, and openWorldHint: false. They retrieve stored records; they do not enroll alerts, modify data, or schedule work.
| Tool | Description |
|---|---|
| list_topics | Discover curated cross-state topic trackers and live bill counts; follow each topic's API link for its complete bill list. |
| search_legislation | Search bills across jurisdictions by keyword, number, sponsor, subject, or status. |
| get_bill_record | Fetch a full bill record: sponsors, actions, versions, votes, official sources. |
| compare_bill_versions | Deterministic diff between two versions of a bill's text. |
| find_similar_bills | Find related bills by title similarity and shared text (labeled as derived, not official). |
| get_vote_details | Get a recorded vote, including member-level votes where available. |
| trace_legislative_history | Trace a bill's full action timeline from introduction to current status. |
| build_legislative_evidence_packet | Assemble a citation-backed packet of bill facts for research use. |
| get_jurisdiction_coverage | Check local coverage before trusting results. Use state="NC" for one jurisdiction; omitted state returns the full matrix. |
| get_active_sessions | List sessions stored with active=true. This local flag does not verify official adjournment or eligibility. |
Hearing and committee-calendar data is not collected for any jurisdiction. The legacy get_upcoming_hearings call remains compatible for existing clients but is omitted from tool discovery. Its data_status: "not_collected" result means the data is unavailable, never that no hearings are scheduled. Consult the legislature's official calendar for a schedule.
MCP tool results reflect the same underlying data as the REST API, including attribution and known-limitations metadata. See methodology for sourcing details.