- Brand
- USLege
- Category
- Operations
- Primary Subcategory
- Regulated-Industry Compliance & Regulatory Research
Integration details
Description
USLege connects ChatGPT to your USLege account so you can research and monitor state government without leaving the conversation. Search bills, votes, committees, hearing videos and transcripts, statutes, executive orders, agency rules, lobbyist and campaign-finance filings, and press releases across all 50 states. Pull up your organization's tracks, dashboards, positions and review notes, add bills to a track, subscribe to updates, and leave comments for your team. Access is scoped to the states and data your USLege subscription already includes. Requires an active USLege account.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Regulated-Industry Compliance & Regulatory Research
- Secondary Subcategories
- None listed
- Brand
- USLege
- Access
- Account required
- First tracked
- 2026-09-29
- Tool count
- 191
- Market
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for USLege
Get updates when USLege’s Discoverability Score or category rank changes.
Competing in ChatGPT Regulated-Industry Compliance & Regulatory Research
View Category191 tools agents can invoke
Add a bill to a track by providing the track ID and bill ID. Call list-tracks first to find the track ID. The bill ID comes from bill search tools or get-track-bills output. If the bill is already tracked, it returns the existing tracked bill (idempotent). Only tracks you have access to can be modified — you cannot access another user's private tracks, even if they are in your organization. Before adding, confirm with the user which track and bill to add.
add-bill-to-track
Add an organization tag to a tracked bill for categorization. Requires the tracked bill ID from get-track-bills output and the organization tag ID (from list-organization-tags or create-organization-tag). Before adding, confirm the tag with the user.
add-bill-tag
Add a new widget to a dashboard the caller can edit. Mirrors the "Add widget" UI flow. The widget is placed automatically: directly to the right of the last widget if the row has room, otherwise on a new row at the bottom. Before adding, always confirm the dashboard, widget type, and filter intent with the user. Bills / Calendar / Videos / Tasks filter payloads are validated against the matching widget filter schema before write — invalid filter JSON is rejected with a clear error. Caller must be Owner or Editor on the dashboard. Viewers are rejected. CRITICAL: "my X" intent → use sentinel flags, NEVER bake a userId. When the user asks for "my tasks", "tasks assigned to me", "my bills", "my calendar", "my videos", or any variant scoped to the caller, set the matching sentinel flag in `filters` instead of looking up and pasting the caller's userId. The server resolves these against `auth.userId` at query time so the widget travels with whoever views the dashboard: - Tasks widgets: set `filters.assigneeIsCurrentUser = true` (takes precedence over assigneeId / noAssignee). - Bills widgets: set `filters.assignedToCurrentUser = true` (instead of leadUserIds / memberUserIds). - Calendar widgets: set `filters.assignedToCurrentUser = true`. - Videos widgets: set `filters.assignedToCurrentUser = true`. Without the sentinel, the widget defaults to the whole org and "my X" returns everyone's data — the canonical bug (ENG-6549). If the user explicitly asks for a different user's data, baking that userId is fine; only "my X" / "assigned to me" / "tasks I own" map to the sentinels.
add-widget-to-dashboard
Post many bill comments in a single call, one comment per bill. All comments are created with Organization visibility (shared with your whole organization) and owned by you. Rows referencing a bill ID that doesn't exist are skipped rather than failing the whole batch — check the "skipped" list in the response for any rows that didn't import and why. Before running, confirm the number of comments and a sample of their content with the user. This creates real, org-visible comments and cannot be bulk-undone (each would need to be deleted individually via delete-bill-comment).
bulk-import-bill-comments
Change the PRIMARY email address on an EXISTING Clerk user, in place. Super-admin tool. Use this for a member email rotation (e.g. moving off a work address to a personal one) — it keeps the same account, its organization membership(s), and its history intact instead of the destructive delete-and-recreate path. Resolve the target `userId` with `search-users` (by the current email) first. The change is admin-initiated, so the new address is attached already-verified and set primary in one step; our database's stored email updates automatically via Clerk's webhook. Before executing, always confirm with the requester: the target user (current email) and the exact new email, whether to keep or remove the old address, and whether to notify the user. Collision: if the new email is already in use by a DIFFERENT Clerk user, the call fails and returns a message explaining the conflict must be untangled by an engineer in the Clerk dashboard (it cannot be forced here) — surface that message and the remediation steps to the user.
update-user-email
Clear the authenticated user's notification delivery-hour preference. Idempotent — calling when no preference is saved returns `deleted: false` rather than erroring. After removal, the radar producer leaves daily/weekly digests on immediate delivery. Before mutating, confirm with the user that they want to clear their delivery hour.
remove-notification-delivery-preference
Show what changed between two stored versions of one agency rule, as a server-side line diff of their text. Pass the id of the rule you are working with, then name each side as one entry of get-agency-rule's "documents" list (newest publication first, current flagged): by its documentId, or — for an entry whose documentId is null — by its "id" as fromRuleId / toRuleId. Give exactly one selector per side. Put the OLDER version on the "from" side and the NEWER on "to"; omit both "to" selectors to compare against the rule's current text. Versions contributed by linked source records are resolved for you: unlike get-agency-rule-full-text, you do NOT need to pick the reading rule id. Use this instead of reading both versions yourself: it is exact, and long rule texts will not fit side by side. HTML, plain-text, and PDF versions are all compared as text (PDF text is extracted, first 150 pages; layout may be flattened, so ignore line-wrapping noise). The diff is sentence-level, so an HTML version and a PDF version of the same wording compare as identical. Hunks come back in document order with a couple of unchanged lines of context; markup is stripped first so formatting noise does not register as a change. "diff" is null only when a version is genuinely unreadable (a scanned-image PDF, or storage briefly unavailable) — say so rather than guessing at the change. When "truncated" is true the hunks stop at a character budget; report how many of "totalHunks" you covered. A missing rule, a document not linked to the rule, and a rule outside your organization's jurisdictions all fail identically — treat the failure as "no such version".
compare-agency-rule-versions
Create a new bill radar rule (saved bill search) owned by the calling user. The returned shape excludes shared-user emails. After creating, call `list-bill-radar-rules` with `ids: [<newRuleId>]` if you need to surface resolved shared users to the user. Before creating, confirm the rule name, states, filters, and sharing settings with the user.
create-bill-radar-rule
Create a calendar alert rule that notifies recipients when calendar events match the configured locations. Calendar alert rules filter by location (state legislatures + institutions) ONLY — there is NO keyword / text filter. Do not invent a `keywords` input. Recipient resolution: `Owner` notifies only the caller, `SharedUsers` notifies the emails listed in `selectedEmails` (must already belong to the caller's organization — others are dropped), `Organization` notifies every member of the caller's org. Confirm the rule details with the user before calling.
create-calendar-alert-rule
Create a new dashboard owned by the calling user, scoped to their organization. The caller becomes the sole owner; for shared dashboards they must invite members in a follow-up step via share-dashboard. Before creating, always confirm the dashboard name and access type with the user. The caller cannot set `ownerId` or `organizationId` — those are derived from `auth`. `accessType` defaults to 'Owner' (private) if not provided.
create-dashboard
Create a track: either a client the user represents (trackType 'Client') or a subject they watch (trackType 'Policy' or 'Other'). A track is a named collection of bills that the user wants to follow. Call list-tracks first and check for a track of the same name, so running a setup conversation twice does not create every client again. Status, size and the deal fields describe a client and should be left out for a policy area. Set them here rather than calling update-track afterwards, so a client is never left half-created. When trackAccessType is 'Group', provide groupMemberEmails with the email addresses of users to share with. Emails will be resolved to user IDs automatically. Before creating, confirm the track name and settings with the user.
create-track
Create a new portal owned by the calling user. Caller must have access to every track id provided; the call is rejected if any track is inaccessible. New portals are created with `accessType: 'Owner'` (only the creator can see them) — call `share-portal` afterward to expand access to a Group or to the whole organization. Asset uploads (logos, banners, attachments) are NOT supported via MCP — direct users to the UI for that step. Before creating, always confirm the portal name, track list, and visibility flags with the user.
create-portal
Create a new video radar rule owned by the calling user. Video radar rules are saved natural-language queries that monitor legislative video transcripts for matches. They are persisted as `AiMonitorQueries` rows (with `AiMonitorQueriesByInstitution` for targeting and `AiMonitorSharedUsers` for the recipient list) — there is no separate "RadarVideoRule" table. Targeting accepts either individual institution ids (`organizationIds`), state-level "all institutions of type X" selections (`allSelections`), or both — at least one must be provided. State / institution access is enforced by the existing tRPC guard; unauthorized targets are rejected. `alertRecipients` is required: `Owner` (only the creator), `CustomList` (resolves `selectedEmails` against the caller's org), or `OwnerOrganization` (every user in the caller's org). Before creating, always confirm the rule definition, targeted institutions / "all" selections, alert recipients, and notification cadence with the user.
create-video-radar-rule
Create a new organization-wide tag, visible to everyone in the user's organization. Call list-organization-tags first. If an Organization-access tag with the same name already exists, use it instead of creating a new one. If the same-named tag is Owner or Group access, it is not visible to the whole organization: tell the user, and ask whether to use it as is or create an org-wide tag under a different name (names are unique per organization). If creation fails because the name is taken but the tag is not in list-organization-tags, it is a colleague's private tag: ask the user for a different name. The returned tag ID can be passed straight to add-bill-tag as organizationTagId. Before creating, confirm the tag name, color and description with the user.
create-organization-tag
Create or update a video clip from a legislative video recording. **Create** (omit clipId): Creates a new clip from the specified video. Requires videoId, title, startTimeSeconds, and endTimeSeconds. By default, the clip is saved but NOT processed for download — set processClip to true to trigger processing. **Update** (provide clipId): Updates an existing clip you own. Only provided fields are changed. If start/end times change and processClip is true, clip processing is re-triggered. Do NOT process the clip for download unless the user explicitly asks. Processing creates a downloadable video file from the source video — it takes a few minutes and costs resources. Leave processClip unset (defaults to false) unless the user says they want it processed. Logos default to none. Before creating a clip, ask the user if they want a logo watermark applied. If yes, call list-logos first to show available options and let them choose. Pass the chosen logoId and optional logoPlacement. Before creating or updating, confirm the clip details with the user — especially the video, timestamps, and title. Requires the video ID. Call search-videos first to find the video. Use get-video-transcript or search-transcript to identify the right start/end timestamps; capture all the relevant discussion the user asked for and err on the side of slightly too long over too short. After creating a clip, you can provide the user a shareable link: https://app.uslege.ai/share/{clipId}?from=clips
manage-clip
Delete a comment you previously posted on a bill, along with any of its attachments. Only the comment's own author can delete it — call list-bill-comments first to find the comment ID and confirm isMine is true. This action cannot be undone. Before deleting, always confirm with the user by showing the comment's content.
delete-bill-comment
Permanently delete a bill radar rule. Deletion cascades to the rule's stored bill matches and notification records via the underlying foreign-key constraints — there is no undo. Before deleting, always confirm with the user by showing the rule name and any pending shared users.
delete-bill-radar-rule
Delete a calendar alert rule. Only the rule owner may delete. Removes the rule, its location associations, and every shared-user row. Confirm with the user before calling — this is irreversible.
delete-calendar-alert-rule
Delete a dashboard. Owner-only. Cascades to every widget on the dashboard, every member entry, and every per-user view order — all permanently lost. Before deleting, ALWAYS confirm with the user. Call get-dashboard first and show them the dashboard name, widget count, and access type so they can identify what's about to disappear. The operation cannot be undone.
delete-dashboard
Delete a single widget from a dashboard. Permanent and cannot be undone. Before deleting, ALWAYS confirm with the user. Show the widget name and type (call get-dashboard to retrieve them if you don't already have them). Caller must be Owner or Editor on the dashboard; Viewers are rejected. After deleting, consider calling reorder-widgets to backfill the gap if the user wants a tidy grid — let the user choose; some prefer the gap as a placeholder.
delete-widget
Delete a bill track and remove all associated data. This permanently removes the track along with its tracked bills, digests, video clips, and access records. The user must have access to the track to delete it. This action cannot be undone. Requires the track ID. Call listTracks first to find the ID of the track to delete. Before deleting, always confirm with the user by showing the track name and bill count.
delete-track
Permanently delete a portal. Owner-only — non-owner callers receive a permission error. Cascades cleanup of: portal-track associations, portal access entries, free email-access entries, portal-level updates, and uploaded assets (logos / banners / attachments in Supabase storage). This is irreversible. Underlying tracked bills and source tracks are NOT deleted — only the portal wrapper. Before deleting, always confirm with the user by showing the portal name and (if possible) the track count + recent update count obtained via `get-portal`.
delete-portal
Permanently delete a portal-level update. Cleans up any file attachments stored in Supabase, then deletes the update row. Irreversible. Requires paid access to the parent portal. Before deleting, confirm with the user — show the update title (or first line of content) and `updateDate` from `list-portal-updates`.
delete-portal-update
Permanently delete a video radar rule. Video radar rules are persisted as `AiMonitorQueries` rows — there is no separate "RadarVideoRule" table. Deletion is restricted to the rule's owner; sharing with the caller is not enough. Associated `AiMonitorQueriesByInstitution` rows are removed, while historical `AiMonitorMatches` rows are kept for audit. This action cannot be undone. Always confirm the rule id and intent with the user before calling.
delete-video-radar-rule
Delete a client from the calling user's organization. This cannot be undone. Requires the client id — call list-clients first to find it. Before deleting, always confirm with the user by showing the client's name.
delete-client
Deprovision a Clerk organization: remove EVERY member while keeping the org and all of its data (tracks, dashboards, settings, Salesforce/JustPaid links, states) so a returning client can be reactivated later. Super-admin tool. This is the MANUAL path for churned or overdue paying customers — trials deprovision automatically when they expire, so this tool is normally not needed for them. Two-step flow, and the first step is mandatory: 1. Call with just the org id (no confirmationToken). NO changes are made — the tool returns status "confirmation_required" with the org name, every member who will lose access (names/emails/roles), trial + billing status, the org's Salesforce/JustPaid links, and a confirmationToken. Show ALL of this to the operator and get their explicit approval. 2. Only after the operator approves, call again with the same org id plus the returned confirmationToken to execute. If they decline, make no further calls. The token is bound to everything the preview showed — the org's membership set plus its trial/billing status and Salesforce/JustPaid links. If any of that changes between the two calls the token stops matching and the tool errors — re-run step 1 and re-review. Never invent or guess a token. Requires the Clerk org id (org_...). Call search-orgs first to find it. Already-deprovisioned orgs error clearly instead of no-opping. Removal is resumable: if a member removal fails partway, the error reports progress and re-running step 1 then step 2 removes the rest (the deprovision stamp is only written once every member is removed). The removed roster is captured first, so this is reversible: reactivate-organization re-seats everyone and clears the stamp in one call.
deprovision-organization
Duplicate a track into a new track the user owns, with the same type, description, sharing, bills, laws and (when the user can track them) interim topics. Call list-tracks first to find the source track ID. Before duplicating, ask the user about each optional part to copy rather than guessing, then confirm the new track's name and those choices with the user before calling. Bills from states the user is not entitled to are left out. Copied comments are new comments that keep their original authors; mentions are not copied and nobody is notified. Portal, client, radar rules, priorities, tasks and notification settings are never copied.
duplicate-track
Modify an existing portal-level update (announcement). Partial-field semantics — at least one changeable field must be provided; omitted fields are unchanged. Attachments are managed in the UI — this tool does not add or remove file attachments. Before updating, confirm the changes with the user.
update-portal-update
Exports a video's full transcript as a downloadable file. Defaults to a DOCX file. Pass format: "json" or "md" only when the user explicitly asks for that file format — otherwise leave it unset so the user receives a DOCX. When format is "json", the downloaded file is UTF-8 JSON with this shape: { "videoId": number, "title": string | null, "institutionName": string, "recordedOn": "YYYY-MM-DD", "paragraphs": [{ "startSeconds": number, "endSeconds": number, "text": string }] } When format is "md", the downloaded file is a UTF-8 Markdown document with an institution-name heading, a title heading, a recorded-on line, and one paragraph of transcript text per line — no timestamps or speaker labels. Returns a presigned download URL (valid for 1 hour) along with video metadata and a suggested filename. The AI client should surface the downloadUrl to the user as a link or download action — there is no inline file content to decode. Requires a video ID. Use the search-videos tool first to find the video ID. To read the transcript text directly (e.g., to summarize or quote it), use get-video-transcript instead — that tool returns the paragraphs inline.
export-transcript
Fetch the full file body (HTML or text) for state register sections — the same content the in-app RegisterViewer shows when you click a section in the tree. Get sectionIds from get-state-register-issue-inventory (whole issue) or search-state-register-sections (keyword). Two modes: - sectionId (optionally fileId): one section, full body, top-level fields populated. - sectionIds (up to 10): several sections in one call, returned in `items` in the order requested, each with its default (first) file. Use this when summarizing an agency's or an edition's rules — ten rules is one call, not ten. Bodies are capped at 15000 characters each by default (truncated=true when cut); raise maxCharsPerSection if you need more of a specific rule, or re-fetch it alone. Any per-section failure (missing section, no files, state not authorized, or a transient storage/database fault reported as error="fetch_failed") is reported inline on that item and does not fail the others; retry just the failed sectionIds. A section may have one or more attached files. Every item includes a `files` array listing every file's id/name/type, so a single call gives you full visibility into what's attached. For TEXT-LIKE files (HTML/HTM/TXT/MD/JSON), the item includes the decoded body as `content`. For BINARY files (PDF/DOC/DOCX), `content` is null and the item instead includes `downloadUrl` — a presigned S3 URL (valid 1 hour, with `expiresAt` ISO timestamp) you can surface to the user as a download link or fetch yourself to parse the file contents. By default `selectedFile` is the first attached file. To read a different file, call again in single mode with that file's id from the `files` array as the `fileId` input. Errors (top-level in single mode, per item in batch mode): - error="section_not_found" if a sectionId doesn't exist - error="no_files_found" if the section has no attached files - error="file_not_attached" if fileId is provided but isn't attached to this section - error="state_access_denied" if your org isn't authorized for the section's state - error="fetch_failed" (batch mode only) if that one section could not be read right now
get-state-register-section-content
The mandatory duplicate check for a failed video: returns other videos sharing the SAME institution + committee + recordedOn as the target. Use this before recommending deletion — a target may only be marked for deletion when a fully-processed duplicate exists AND the target itself has no usable content. Get the videoId from dev-videos-triage-failed. `isFullyProcessed` flags a candidate whose latest jobs include a Completed PostprocessTranscription (a real, processed duplicate). Different durations/rooms usually mean separate recordings, not duplicates — verify before concluding. A same-day sibling from a different `sourceViewUrl` may be a true duplicate (a livestream archive superseded by a full re-upload), one segment of a meeting the extractor split across uploads (a livestream that dropped and resumed, an executive-session return), or a different meeting the same body held that day. Only call it a duplicate with positive evidence of the same recording: the same meeting per the titles, the same start time per the two source pages, and `seconds` covering the target's source-reported duration. A `part` on either side, or a candidate far shorter than the target's source duration, marks a split meeting whose failed segment is the only copy of that part of the meeting — retry or defer it, never delete it. When the evidence is incomplete, defer rather than delete. Errors if the video does not exist.
dev-videos-triage-duplicate-candidates
Get per-year lobbyist <-> client compensation rows for Texas. Filterable by lobbyistId, clientId, year, and compensationMethod (Earned / Paid / Prospect). Sorted by year desc, then lobbyist name asc. Each row returns the lobbyist + client refs (with names), reporting interval, compensation method, minAmount/maxAmount in USD, the original compensationCode, and compensatedFrom/compensatedTo windows (ISO 8601). Lobbyist data is currently TX-only — non-TX-authorized callers receive a structured access-denied error.
get-lobbyist-compensation
Get a Texas lobbyist's full profile by id. Returns: - contact info (full name, firm, address, phone) - subject matters lobbied on, with the year each was reported - per-client compensation history (minAmount/maxAmount in USD, compensationCode original code, method, reporting interval, compensated-from/to dates) - political fund reimbursements (fund name + address + reporting interval per year) Lobbyist data is currently TX-only — non-TX-authorized callers receive a structured access-denied error. Returns { found: false } when no lobbyist exists for the supplied id.
get-lobbyist-details
Fetch the organization-level notification settings for a single bill and (when applicable) its current subscriber list. Call `list-bill-subscriptions` or `search-bills` first to discover the bill id. Returns `settings: null` when the caller's organization has no notification settings configured for the bill. The `subscribers` array is only populated when the bill's access type is `Group` — for `Owner` / `Track` / `Organization` access types it is empty by design, since per-user subscriptions are not tracked on those rows.
get-bill-notification-settings
Fetch a single calendar alert rule by id. Call `list-calendar-alert-rules` first to discover the rule id. Returns `rule: null` when the rule does not exist or the caller has no access — the two cases are intentionally indistinguishable.
get-calendar-alert-rule
Consolidated profile for a single campaign-finance donor (entity), assembled in one call: identity header, lifetime giving stats, the top recipients they've funded, and per-section row counts. This is the donor detail view. First call search-campaign-finance to resolve a name to an entity id (results where kind='entity'); pass that id here. If the donor is itself a registered filer, the header's resolvedFilerId points to the filer-side record — use the filer tools for that view. Money amounts are integer cents. `topRecipients.rollup` buckets ALL of the donor's giving by recipient type (candidates / committees / party / other), while `topRecipients.recipients` is only the five largest recipients by dollars. `sectionCounts` reports how many rows exist per detail section so you can tell what's worth drilling into. Campaign finance is only available for states where the "elections" product is enabled. A state your org isn't authorized for returns `state_access_denied`; an authorized state without campaign-finance data returns `state_not_supported` along with the currently-supported states. An unknown entity id (or one from another state) returns `not_found`.
get-entity
One page of a single donor's (entity's) transaction history for one section, the drill-down behind get-entity's `sectionCounts`. Resolve a donor id with search-campaign-finance (results where kind='entity'), call get-entity to see which sections have rows, then page the section you want here. Each row's `counterparty` is the filer on the other side; pass its `filerId` to the filer tools. Rows are newest-first by transaction date (id-tiebroken). Paginate with `pagination.offset`: add `limit` to `offset` for the next page and stop once `offset + rows.length >= totalCount`. An unknown or wrong-state donor id simply returns zero rows (never an error). Campaign finance is only available for states where the "elections" product is enabled. A state your org isn't authorized for returns `state_access_denied`; an authorized state without campaign-finance data returns `state_not_supported` with the currently-supported states.
get-entity-activity
One paginated activity section for a single campaign-finance filer, selected by `type`. Use it after get-filer once you have a filerId and its `sectionCounts` tell you which sections have rows — this is the drill-down that returns the actual transaction rows behind those counts. Discover the filerId first with search-campaign-finance (a result where kind='filer', or the resolvedFilerId on a donor). Call once per section you want; the response populates only the field named by `type` (e.g. type='contributions' fills `contributions`), and echoes `type` back. Pagination: `contributions`, `expenditures`, `reports`, `pledges`, `loans`, `spacPositions`, and `travel` are server-paginated — use `limit`/`offset` and page against `totalCount`. `topContributors` and `spendByCategory` are aggregates that ignore `limit`/`offset`: `topContributors` returns only the top 5 donors by total (a fixed cap — `totalCount` is at most 5 and does NOT reflect the true number of distinct contributors), while `spendByCategory` returns every category and its `totalCount` is the full category count. Period bounds: `dateFrom`/`dateTo` scope only the money sections `contributions`, `expenditures`, `topContributors`, and `spendByCategory` (on transaction date). The all-time sections `reports`, `pledges`, `loans`, `spacPositions`, and `travel` ignore them. Campaign finance is only available for states where the "elections" product is enabled. A state your org isn't authorized for returns `state_access_denied`; an authorized state without campaign-finance data returns `state_not_supported` along with the currently-supported states.
get-filer-activity
Get a committee's calendar of past and upcoming meetings/hearings, including agenda bills, participants, hearing notice links, and attached files. Fields not present in the underlying data (room, structured participants, isHost) are returned as null/empty. If a state does not have the "calendars" product enabled, returns an empty events list with an explanatory message rather than an error. If the committee does not exist OR the user is not authorized for the committee's state, returns { events: [], totalCount: 0, error: "not_found" } with the same shape — these cases are intentionally indistinguishable to prevent committee-ID enumeration.
get-committee-calendar
Get a committee's full detail plus its seated members, staff roster, parent committee, and direct subcommittees (one level deep only). Returns ONLY this committee's own membership (chair, vice chair, ranking minority chair, members of this committee). It does NOT return the full chamber/legislature roster — for that, use list-legislators. For per-meeting attendance, use a calendar event tool instead. Legislators are sorted Chair → ViceChair → RankingMinorityChair → Member, then alphabetical. Staff is sorted alphabetical by name; a staffer with multiple roles surfaces once with all StafferPositionType values aggregated into positions[]. staff[] is the committee's own professional staff. For the members' personal-office staff (e.g. each member's Legislative Director or Chief of Staff), call list-staff with this committeeId and a title filter instead of calling list-staff per member.
get-committee
Consolidated profile for a single campaign-finance filer (candidate, officeholder, or PAC/committee) in one call: identity header, summary-card aggregates, headline money-in/money-out totals, officers, legislator links, and per-section row counts. Use this as the follow-up to search-campaign-finance once you have a filer id — it replaces six separate lookups. Discover the filer id first with search-campaign-finance (a result where kind='filer', or the resolvedFilerId on a donor). `sectionCounts` tells you which detail sections have rows so you can decide which paginated follow-up tools to call next. `moneyTotals` is the only period-aware section: pass `dateFrom` / `dateTo` to scope it, or omit both for all-time; the other sections are always all-time. `header` is null when no filer matches the id in the given state. Campaign finance is only available for states where the "elections" product is enabled. A state your org isn't authorized for returns `state_access_denied`; an authorized state without campaign-finance data returns `state_not_supported` along with the currently-supported states.
get-filer
Get one dashboard's full layout: metadata, the calling user's role on it, the member list (user id + role), and every widget on the grid with its name, type, display type, stored filters JSON, and grid position. Useful for understanding what a user is currently tracking before suggesting changes or fetching rendered data. Requires the dashboard id, which the user must provide directly. Member user ids returned here are internal Clerk user ids scoped to the caller's organization.
get-dashboard
Get a downloadable link for one document stored against a legislative calendar event — handouts, witness lists, minutes, presentations and the like. Call get-calendar-event-details first and take a fileId from its "materials" array; this tool takes no other way of naming a document. Returns a presigned download URL (valid for 1 hour, with an `expiresAt` ISO timestamp) alongside the document's type and label. Surface it to the user as a download link, or fetch it yourself to parse the contents — there is no inline file content to decode. A document in a state you cannot see reports the same error as one that does not exist.
get-calendar-event-document
Fetch a single portal by id with its tracks, paid-access users, and (if the caller is owner / paid) the email-access list. Call `list-portals` first to discover the portal id. Returns `portal: null` when the caller has no access. The `paidAccessUsers` array is empty for read-only viewers. The `emailAccess` array is populated only for callers with paid/owner access (it is owner-managed data) — for everyone else it is `null`.
get-portal
Fetch a single executive order by database ID, including the full body, scraper- supplied summary, source URL, and PDF link. Federal EOs carry state='US' with the president in the 'governor' field. Use after identifying an EO via search-executive-orders.
get-executive-order
Fetch a single press release by database ID, including the full body (HTML) and source URL. Releases with no state (federal / unknown jurisdiction) carry state=null. Use after identifying a release via search-press-releases.
get-press-release
Fetch a single social media post by its internal id, including its full text, the account that surfaced it, and the bills it references. On a Repost the text is the original author's words, not the account holder's — read `originalAuthor` to attribute the argument correctly rather than crediting the reposter. Find the id via search-social-posts. Returns "not found" for an id that doesn't exist or belongs to a state the caller cannot access; the two are indistinguishable on purpose.
get-social-post
Fetch the notification settings for a single track and the current recipients list. Call `list-tracks` or `list-track-subscriptions` first to discover the track id. Errors with "Track has no notifications configured yet" when the track exists but has no `TrackNotificationSettings` row yet. The `recipients.subscriberUserIds` array reflects the users who currently receive notifications; `recipients.accessUsers` lists every user who has access to the track (the candidate pool for `update-track-notification-settings.recipientUserIds`).
get-track-notification-settings
The spine of a single-video failure investigation: returns one video with its institution, committee, and FULL job-queue history (every attempt, error category, and error metadata), newest job first. Get the videoId from dev-videos-triage-failed. Use the latest failing job's errorCategory + errorMetadata to identify the failure, then dev-videos-triage-source-urls to fetch the URLs for a live source check. Errors if the video does not exist.
dev-videos-triage-jobs
Returns the source URLs and identity for one video — the argument feed for the sandbox source-check scripts (check-source.ts / check-source-listing.ts). Fetch sourceViewUrl (the immutable page URL) and sourceFileUrl (the resolved media URL) to verify whether the source is still live, has moved, or is a placeholder. Get the videoId from dev-videos-triage-failed or dev-videos-triage-jobs. Storage keys are intentionally not exposed — hasStoredVideo/hasStoredAudio are DB flags telling you only whether a key is recorded (not whether the S3 object is actually present); verify that with dev-videos-triage-s3-artifacts. Errors if the video does not exist.
dev-videos-triage-source-urls
USLege ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve USLege's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are USLege alternatives on ChatGPT?
As of 2026-11-02, USLege competes with 1102tools for Federal Register, 1102tools for Regulations.gov, Acquisition.gov by 1102tools, Ansvar Gateway, BoardWise, Brokly, CMS Coverage, COLA Cloud and 19 more in ChatGPT Regulated-Industry Compliance & Regulatory Research, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.