Skip to main content
Glama
JonnyWaffles

va-lis-mcp

by JonnyWaffles

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
LIS_API_KEYYesYour LIS API key (a GUID). Required for all requests.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_current_sessionA

The General Assembly's current working session.

During the interim this is the upcoming session, not the one that just ended; continued bills and new prefiles accumulate there. For retrospective work on a finished session, pass that session's code to the other tools instead of relying on this default.

list_sessionsA

Legislative sessions for a calendar year.

Returns each session's code, e.g. 20261 = 2026 Regular Session and 20262 = 2026 Special Session I. The reference list reaches back to 1994.

get_sessionC

One session with its milestone dates: prefiling, convening, adjournment.

events are the dates LIS records for the session, oldest first: "Prefile Date", "Session Start", "Adjournment" (the regular session's sine die), and "Reconvene" (the one day session that takes up the Governor's vetoes and recommendations). projected_date is the planned date LIS holds for an event.

list_billsA

List bills in a session, optionally filtered by a search term.

query is a case-insensitive substring match against the bill number, description, and title. limit is capped at 200; page through larger result sets with offset. total_matching counts all matches, not just the returned page.

search_billsA

Search a session's bills by keyword, stage, patron, or chapter number.

This is the full text search; list_bills only matches the number and the short description. keyword searches the summaries, or the bill text when search_in is "Bill Text", and takes AND, OR, and parentheses ("firearm AND ammunition"). LIS drops common words, so "the" finds nothing. category is a stage a bill reached, by name: "In Committee", "Passed House", "Continued", "Vetoed", "Acts of Assembly chapters"; an unknown name answers with the full list. member_id narrows to one patron in any role. chapter finds the bill behind an Acts of Assembly chapter (350 finds CHAP0350). At least one of the four is required.

One row per bill, in LIS order, with status, chapter, chief patron, and the committee that holds the bill. include_summaries adds the plain text of each bill's furthest-along summary. A keyword search on its own includes failed bills; with category or member_id LIS leaves out failed and incorporated bills. limit is capped at 200; page with offset.

list_most_viewed_billsA

The bills of a session that readers of the LIS website open most often.

LIS sends at most 100, in its own order, with the same fields as search_bills. The list measures public attention, not legislative weight.

list_amended_billsA

Every bill in a session that carries an amendment, with its amendments.

amended_by picks the chamber that offered the amendments, not the chamber of the bills: "H" returns the bills with a House amendment, Senate bills among them, and only their House amendments. Each amendment has its document_code (HB1005AH1 is the first House amendment to HB1005), a description that names the committee or the floor, and a disposition (Adopted, Not Adopted, Engrossed, Removed, Posted). query is a case-insensitive substring match against the bill number and description. limit is capped at 200; page with offset.

list_conference_billsA

The bills of a session that went to a conference committee.

A conference committee settles the differences when the two chambers pass different versions of a bill. chamber is the bill's chamber of origin, and member_id narrows the list to the conferences one member sat on. The rows name no conferees: get_bill_history lists them on the bill's events ("House Conferees: ..."). limit is capped at 200; page with offset.

get_billA

Full detail for one bill: title, status, dates, patrons, session lineage.

patrons groups member names by role (Chief Patron, Co-Patron, ...); get_bill_patrons returns the same list with member ids. sessions lists every session the bill appears in; two entries mean it was carried over from the even-year session into the odd-year session.

get_bill_patronsA

Every patron of a bill with their member ids, in LIS display order.

role is Chief Patron, Chief Co-Patron, or Co-Patron. member_id chains into get_member, get_member_bills, get_member_votes, and get_member_committees. get_bill lists the same names grouped by role, without ids.

get_bill_summariesB

Plain-text summaries of a bill (as introduced, as passed, ...).

The entry with is_active true is the current summary. An empty list means LIS has published no summary for that bill and session.

get_bill_textA

Full text of one bill version, HTML stripped to plain text.

document_code selects a version (e.g. "HB1" = introduced, "HB1ER" = enrolled); the default is the most recent version. available_versions lists every version that can be requested. Long texts are cut at 15,000 characters with truncated set true. Amendment markup (additions and strikethrough deletions) is flattened to plain text.

get_bill_versionsA

Every published version of a bill, oldest first, with links to its files.

Introduced, each substitute and amendment, engrossed, enrolled, and chaptered. Each version carries the address of its pdf and html file and of any fiscal impact_statements. chamber is the chamber that made the version, not the bill's: a Senate substitute for a House bill says S. sponsor is who offered it (House, Senate, Committee, Conference, Governor, Member) and disposition what became of it (Offered, Adopted, Rejected, Posted). Pass a document_code to get_bill_text to read that version. A chaptered version's code is its chapter number (CHAP0350).

get_bill_historyA

Chronological action history for a bill, from prefiling to governor action.

Passage dates live here (the bill detail's passage date fields are always null in LIS): look for events with is_passage true and read date and vote_tally. is_passage marks the events whose resulting status is a passage status (Passed House, Passed Senate, ...). status is the bill's status after each event. committee names the committee that acted; this is the only place LIS records which committee holds a bill. vote_id links an event to its vote: pass it to get_roll_call.

get_bill_votesA

Every recorded vote on a bill, in both chambers, in chronological order.

Floor, committee, and subcommittee votes all appear. is_roll_call is true when the recorded members voted on this bill alone; it is false for a voice vote (no members recorded) and for a block vote (one motion that disposed of bills_in_vote bills at once, which is not a position on any one of them). Pass a vote_id to get_roll_call for the member by member record. Costs one request per vote; get_bill_vote_tallies lists the tallies in two requests when the flags are not needed.

get_bill_vote_talliesA

A bill's votes with their tallies and no members, in two requests.

The fast route to how a bill fared at each stage: committee, subcommittee, and floor votes from both chambers, oldest first. It is lighter than get_bill_votes and it knows less. Most voice votes are missing, there is no pass or fail flag (read description and tally), and a block vote does not say how many bills it covered. An empty list can mean the bill was decided by voice votes alone. referred_to names the committee a vote sent the bill on to. Pass a vote_id to get_roll_call for the members.

list_votesA

Every vote a chamber took in a date range: floor, committee, and subcommittee.

Dates are YYYY-MM-DD and inclusive; end_date defaults to start_date, which gives one day. Keep the range short, since a chamber takes about 50 votes on a session day. chamber is the chamber that voted, so a row can name a bill from the other chamber. Rows carry the tally and no members: pass a row's bill_number and vote_id to get_roll_call for those. A block vote names no bill, most voice votes are missing, and classification "Attendance" marks a quorum call. limit is capped at 200; page with offset.

get_roll_callA

Who voted which way on a bill, with party and district, one entry per vote.

Members are grouped under yea, nay, abstain, and not_voting. statements are corrections members filed ("recorded as yea. Intended to vote nay."); the recorded response still stands. Only votes that record members on this bill alone are included: voice votes and block votes are left out (get_bill_votes lists those too). vote_id narrows the result to one vote.

get_member_votesA

Every vote one member cast in a session, or their votes on one bill.

Floor, committee, and subcommittee votes all appear, in LIS order. A row is one (vote, bill) pair: a block vote that disposed of 105 bills appears 105 times, each with is_block true and bills_in_vote set. A block vote is a real vote, but not a considered position on any one bill; exclude_block_votes drops them. total_matching counts rows and distinct_votes counts votes cast. Attendance roll calls are omitted. limit is capped at 200; page with offset.

list_membersA

The session's member roster, searchable by name, chamber, and party.

query matches any part of a name, ignoring case ("schmidt", "Charlie Schmidt", "Schmidt, C"); omit it for the whole roster. The roster deliberately includes members who left or arrived mid-session (service_end_date and service_end_reason mark a departure): they cast the votes recorded before they left. member_id is the key for the member tools.

get_memberA

One member's roster record: name, chamber, party, district, status, contact.

Reads the session roster, which is the authoritative source (LIS's by-id endpoint answers nothing for some sitting members). Use get_member_committees for seats, get_member_bills for patronage, get_member_votes for the voting record, and get_member_office for the district office.

get_member_officeA

A member's district office: postal address, phone, and email.

The district office is the contact detail LIS publishes nowhere else; get_member has the Capitol room, phone, and email. The record is not session scoped, so there is no session code. Many members have no record, and found is false for them.

get_member_billsA

Every bill a member patrons in a session, in any role.

The session bill list names only chief patrons, so this is the route to a member's co-patronage. is_chief_patron marks the bills the member sponsors; role restricts the list to one role. query is a case-insensitive substring match against the bill number, description, and title. limit is capped at 200; page with offset.

get_member_committeesA

Every committee seat one member holds in a session, with the role.

LIS has no member-first committee endpoint, so this reads every seat list in the member's chamber: 14 requests cold for a House member, 67 with subcommittees, all cached afterwards.

list_committeesA

The standing committees of one or both chambers, optionally with subcommittees.

The list is not session scoped: it describes the committees that exist now. Who sits on them is session scoped; see get_committee. Use a committee's number ("H08") or name with get_committee, list_meetings, and list_dockets.

get_committeeA

A committee's roster for a session: each member's role, party, and district.

committee is a number ("H08", "S13") or any part of a name ("Courts of Justice", "courts"). Both chambers have some names, so pass chamber or the number when a name is ambiguous. Seats come back in LIS order, chair first. meeting_note is the committee's regular meeting time when LIS records one, and subcommittees lists the subcommittees, which this tool accepts by number too.

get_committee_staffA

The clerks and staff who serve a committee.

committee is a number ("H08", "S13") or any part of a name; pass chamber or the number when both chambers use the name. role is Committee Clerk or Committee Staff, the Division of Legislative Services staff assigned to the committee. The list is not session scoped: it names who serves now, and since is when each assignment began. LIS sends no phone number or email for staff.

list_meetingsA

Meetings on the master schedule in a date range: committees, floor, caucuses.

Dates are YYYY-MM-DD and inclusive; keep the range short, since a week in session is about 150 meetings. committee narrows the list to one committee by number or name (chamber disambiguates a name found in both chambers). time is free text as the clerk entered it ("15 minutes after adjournment") and may be blank. Cancelled meetings stay listed with cancelled true. limit is capped at 200; page with offset.

list_docketsA

A Senate committee's dockets for a session: each meeting and the bills on it.

Dockets are the Senate's committee agendas, newest first as LIS lists them. The House keeps none in the API: read a House bill's committee from get_bill_history and the committee's meetings from list_meetings. committee is a Senate committee number ("S13") or name. A docket and its linked schedule can disagree on the hour, so both times are reported. Costs one request per docket cold, cached afterwards.

list_floor_calendarsA

A chamber's floor calendars for a session, one per sitting.

A floor calendar is the day's order of business: the bills up for a reading or a vote. Pass a calendar_id to get_floor_calendar for the bills on it. Several calendars can share a date.

get_floor_calendarA

One floor calendar: the bills up for action, by section, with the votes taken.

calendar_id comes from list_floor_calendars. Each bill carries its calendar section (e.g. "Senate Bills on Third Reading") and the actions recorded against it, with a vote_id where a vote was taken; pass that with the bill number and session code to get_roll_call.

list_minutes_booksA

The published minutes books of a session, newest first.

A minutes book is the clerk's record of what one body did on one day. Both chambers publish committee books. Only the Senate publishes floor books (is_floor true), so read House floor action from list_floor_calendars and get_bill_history. committee is a number or name, and it excludes every floor book; kind picks the floor books or the committee books. Dates are YYYY-MM-DD and inclusive. A book with status "In Progress" can still change. Pass a minutes_book_id to get_minutes_book for the bills and votes. limit is capped at 200; page with offset.

get_minutes_bookA

One minutes book: each action a chamber or committee took that day, in order.

One record per action, with the bill, the section of business it fell under, the action taken, and the tally. A vote_id here belongs to the bill beside it, which a vote_id in get_bill_history does not always do: pass it with the bill number and the session code to get_roll_call. The tally keeps a presiding officer's tiebreak ("18-Y 18-N 0-A, Chair votes Yea"), which the vote record drops. is_block marks one motion that disposed of many bills, and is_voice a vote that names no members. include_procedural adds the entries that name no bill: the call to order, recesses, communications received. A floor day runs to about 200 records; limit is capped at 200, page with offset.

list_communicationsA

The messages the two chambers sent each other in a session, newest first.

A communication is the formal notice a clerk sends the other chamber: "The House of Delegates has passed the following Senate bills". chamber is the chamber that sent it. The rows name no bills; pass a communication_id to get_communication for those. reference is unique within one session only. limit is capped at 200; page with offset.

get_communicationA

One communication between the chambers: each statement and the bills it names.

statements are the clerk's sentences in order ("THE SENATE HAS PASSED THE FOLLOWING HOUSE BILLS:"), each with its bills, their chief patrons, and the document_code of the text version acted on. A communication records what a chamber did, not how it voted: it carries no vote ids. LIS holds structured content from May 2024 on. An older communication comes back with no statements and an html link to the original.

get_session_statisticsA

LIS's own bill counts for a session, by chamber of origin and legislation type.

One row per chamber and type (B bill, J joint resolution, R resolution); a type with no bills has no row. total is introduced plus continued_from_last_session, and passed counts chaptered plus vetoed bills. LIS computes these counts itself and they do not always agree with the bill list: a total can miss by a bill, the outcome columns add up differently in each session, passed_house and passed_senate are not a funnel, and continued_to_next_session overcounts (pending matches the next session). Count from list_bills when a number has to be exact.

get_committee_statisticsA

LIS's own referral counts for each standing committee of one chamber.

house_bills and senate_bills split each count by the bill's chamber of origin, so senate_bills on a House committee counts the Senate bills sent to it after crossover. The counts are referrals, not bills, and the columns do not add up: failed counts only what the committee itself killed, and in_subcommittee is a part of in_committee. Subcommittees have no rows. LIS names no bill behind a count; get_bill_history is the record of where one bill went.

check_api_keyA

Validate the configured LIS API key.

LIS heartbeat endpoints accept any key, so this is the only real check: it asks the PartnerAuthentication service whether the key is registered and active.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.8/5.0

Scored across 38 tools

Disambiguation4/5

The set has several potentially overlapping clusters (list_bills vs search_bills; get_bill_votes vs get_bill_vote_tallies vs list_votes vs get_member_votes vs get_roll_call), but descriptions explicitly draw the boundaries (e.g. tallies is 'lighter and knows less', list_bills only matches number/description while search_bills is full text). A careful agent can select correctly, though the five-tool vote surface requires reading closely. No tool appears to do the same thing as another.

Naming Consistency5/5

Everything is snake_case with a predictable verb_noun pattern (get_bill, list_sessions, search_bills, check_api_key), and the get_/list_ split maps cleanly to single-record vs collection. Minor variants like list_most_viewed_bills or get_bill_vote_tallies are still readable and on-pattern. No mixed casing or vague verbs.

Tool Count3/5

38 tools is heavy and well above the comfortable 3-15 band, so discovery cost is real, but the domain (sessions, bills, members, committees, meetings, dockets, calendars, minutes, communications, votes) is genuinely broad and most tools map to a distinct resource or operation. It sits at the borderline of justified breadth rather than bloat.

Completeness5/5

Coverage spans the full legislative lifecycle: sessions, bills, versions, text, history, votes and roll calls, patrons, members, offices, committees and staff, meetings, dockets, floor calendars, minutes books, and inter-chamber communications, plus aggregate statistics. The read-only surface has no obvious dead ends for the domain, and cross-tool chaining (e.g. vote_id, member_id, committee number) is consistently documented.

Maintenance

ActivityMaintained
ResponsivenessNo issues