MCP server for LegiScan API - Access legislative data from all 50 US states
Strong definition quality overall. All 10 tools have clear names starting with action verbs (get_, find_, search_), solid descriptions (150-300 chars typical), and explicit input schemas with type definitions. Parameters are well-described and include helpful context. However, output schemas are not explicitly documented in the visible code, and some parameters lack formal constraints (enums). Error handling guidance exists but is implicit. The server includes good instructional context and chains common workflows, which helps LLMs understand tool composition.
Find a bill by its number within a state's current session or specific session. Handles format variations (AB 858, AB858, AB-858). Returns bill summary if found, null if not.
Find a legislator by name (case-insensitive partial match). Returns all matching legislators with people_id, party, role, and district. Use the people_id with other tools.
Get detailed bill information including sponsors, full history, votes, texts, amendments, and supplements. This is the primary tool for bill research.
Get how a legislator voted on specific bills. Use find_legislator first to get people_id from a name. Returns vote positions (Yea/Nay/NV/Absent) for each bill with roll call details. Duplicate bill_ids are deduplicated. Each bill fetches at most max_roll_calls_per_bill roll calls (default 5, most recent first) to limit API quota usage.
Get legislator information including party, role, district, and third-party IDs (VoteSmart, OpenSecrets, Ballotpedia, FollowTheMoney).
Output schemas not explicitly documented in source code. While parameter input schemas are visible, return types and response field structures are not formally declared in the tool registration. LLMs cannot reliably plan downstream tool calls without knowing what fields a response contains.
Numeric parameters lack explicit range constraints. 'max_roll_calls_per_bill' (default 5) has no min/max bounds in schema. 'page' parameter in legiscan_search has no documented range. LLMs may pass absurd values (page=999999, max_roll_calls=10000) that waste API quota or fail.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 66 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 59 | - | v1 |
Get bills where a legislator is the primary author/sponsor only. Use find_legislator first to get people_id from a name. Returns bills with full metadata and session info. Handles both state and session_id parameters.
Get roll call vote details including individual legislator votes. Get roll_call_id by calling get_bill first.
Get list of available legislative sessions. Returns sessions with session_id, years, and state info. Use session_id for subsequent bill lookups.
Get all legislators active in a legislative session. Returns list of people with their roles, parties, and districts.
Full-text search across bill texts. Returns 50 results per page with relevance scores, bill summaries, and URLs. Use for interactive searches.
Enum constraints not enforced for chamber parameter in legiscan_get_legislator_votes. Schema shows enum=['H','S','A'] but description could be clearer on what each means. No error guidance for invalid chamber values.
No pagination metadata returned. legiscan_search accepts 'page' parameter but tool description doesn't state whether response includes total_results or next_page_available. Large result sets (50 items per page) risk context window exhaustion without explicit guidance on result limits.
Error recovery guidance is implicit, not explicit. Tool descriptions do not state what to do if a bill is not found, a legislator lookup fails, or an API limit is hit. Error messages are not documented with recovery paths.