Skip to main content
Glama

Openfec Search Expenditures

openfec_search_expenditures
Read-onlyIdempotent

Search independent expenditures (Schedule E) — outside spending supporting or opposing federal candidates. Covers Super PACs, party committees, and other groups. Use itemized mode for individual expenditure records, or by_candidate for aggregated totals per candidate; by_candidate needs either a candidate_id or a full race scope (candidate_office alone for President, plus candidate_office_state for Senate, plus candidate_office_district as well for House).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeNoQuery mode. "itemized" returns individual expenditure records (keyset pagination). "by_candidate" returns aggregated totals per candidate by committee (page-based).itemized
pageNoPage number (1-indexed) for by_candidate mode. Explicit page is rejected in itemized mode, which paginates with cursor. Defaults to 1 for by_candidate.
sortNoSort field. A "-" prefix sorts descending: use "-expenditure_amount" for the largest outside spending first, since the ascending form leads with the most negative rows (corrections and voided entries). Itemized only; OpenFEC sorts by "-expenditure_date" when omitted.
cycleNoTwo-year election cycle (e.g., 2024). Even years only. Itemized mode defaults to the current cycle when omitted — Schedule E spans all history and an unscoped scan times out upstream. Pass an explicit cycle to search an earlier period.
cursorNoOpaque pagination cursor from a previous response of this tool. Itemized mode only (keyset pagination). Valid only for an otherwise-identical call — changing any other argument, including sort, rejects the cursor; omit it to start over.
max_dateNoLatest expenditure date (YYYY-MM-DD). Itemized only.
min_dateNoEarliest expenditure date (YYYY-MM-DD). Itemized only.
per_pageNoResults per page.
is_noticeNoOnly 24/48-hour notice filings (near-election spending). Itemized only.
max_amountNoMaximum expenditure amount in dollars. Itemized only.
min_amountNoMinimum expenditure amount in dollars. Itemized only.
payee_nameNoFull-text payee name search. Itemized only.
most_recentNoOnly the most recent version of amended filings. Itemized only — by_candidate rejects it. Defaults to true in itemized mode when omitted; pass false to see superseded versions of amended filings.
candidate_idNoTargeted candidate ID (e.g., P00003392). Get IDs from openfec_search_candidates results.
committee_idNoSpending committee ID (e.g., C00703975). Get IDs from openfec_search_committees results.
support_opposeNoS = support, O = oppose. Filter by whether the expenditure supports or opposes the candidate.
candidate_partyNoThree-letter party code of the targeted candidate (e.g., DEM, REP). Itemized only — by_candidate rejects it, since the aggregate endpoint has no party filter.
candidate_officeNoOffice of the targeted candidate: H=House, S=Senate, P=President. In by_candidate mode this scopes a whole race: P stands alone, S also needs candidate_office_state, H also needs candidate_office_state and candidate_office_district.
candidate_office_stateNoTwo-letter state code of the targeted race. Required alongside candidate_office=H or candidate_office=S in by_candidate mode; leave it off for candidate_office=P, whose aggregate rows carry no state and match nothing when one is supplied.
candidate_office_districtNoTwo-digit House district of the targeted race (e.g., "09"). Required alongside candidate_office=H and candidate_office_state in by_candidate mode; Senate and presidential rows carry no district and match nothing when one is supplied.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeNoQuery mode as the server resolved it. Row shapes differ by mode — itemized rows are individual expenditures, by_candidate rows are per-candidate totals — so read this rather than inferring the shape from the fields present.
countNoTotal result count (may be approximate for itemized).
errorNoPresent when the call failed. Absent on success.
noticeNoGuidance when no expenditures matched — echoes filters and suggests how to broaden.
resultsNoExpenditure result set; itemized records or per-candidate aggregates depending on mode.
committeeNoThe committee every row in this response belongs to, carried once instead of repeated in each row. Present only when the query was scoped to a single committee_id; otherwise each row keeps its own committee object.
paginationNoPage-based pagination info (by_candidate mode only).
totalCountNoTotal matching expenditures or per-candidate aggregates.
next_cursorNoPagination cursor for the next page of itemized results. Null when no more pages.
search_criteriaNoEcho of the search filters this call applied, as the server parsed them, minus paging arguments. Always present — compare it against what you sent to confirm every filter was honoured.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations already declaring readOnlyHint and idempotentHint, the description's job is lighter, yet it adds substantial behavioral context: pagination differences (keyset vs page-based), rejection of certain parameters in by_candidate mode, the sorting quirk with negative amounts, the default-cycle behavior, and the explicit timeout risk for unscoped scans. This goes well beyond the structured fields and contains 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with a concise purpose statement, then delivers all critical usage details in a dense but organized paragraph. Every sentence earns its place—mode requirements, pagination, sorting, cycle defaults, and timeout warnings are all included without redundancy. It is long but information-dense, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 20-parameter tool with two modes and many constraints, this description is remarkably complete. It covers mode selection, required vs optional parameters, pagination behavior, sorting, cycle handling, and even failure modes (timeouts, rejections). With an output schema present, no return-value explanation is needed. An agent has everything required to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema description coverage is 100%, the tool description adds significant meaning: it explains that by_candidate requires candidate_id or full race scope, that cursor is only valid for identical calls, that most_recent only applies to itemized, and that certain parameters are rejected in by_candidate. It also clarifies sorting semantics with a concrete example (ascending leads with negative rows). This is far more than the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Search independent expenditures (Schedule E) — outside spending supporting or opposing federal candidates.' It clearly distinguishes from siblings like coordinated expenditures by naming the filing type, and explains the two modes (itemized vs by_candidate) and their use cases. The purpose is unambiguous and does not rely on the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use each mode, including the parameter requirements for by_candidate (candidate_id or full race scope) and the default-cycle behavior to avoid upstream timeouts. It does not explicitly name alternatives among sibling tools, but the resource (Schedule E) is specific enough that an agent can infer when this tool is appropriate. A clear 'use this for independent expenditures, not coordinated' would push it to 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.1/5.0
Disambiguation5/5

Each tool targets a clearly distinct FEC resource or action, and even closely related tools are explicitly differentiated. Independent versus coordinated expenditures and legal search versus legal document retrieval are described in enough detail that an agent should not misselect.

Naming Consistency5/5

All tools share the openfec_ prefix and follow a predictable verb_noun snake_case pattern: get for direct retrieval, lookup for calendar/election lookups, and search for queryable datasets. The naming is highly consistent across the full tool set.

Tool Count5/5

Twelve tools is well-scoped for a campaign-finance data server covering candidates, committees, money flows, filings, legal documents, calendar, and elections. Each tool represents a meaningful slice of the domain without unnecessary overlap or bloat.

Completeness4/5

The tool surface covers core FEC workflows thoroughly: candidates, committees, contributions, disbursements, independent and coordinated expenditures, filings, legal documents, calendar, and elections. The only notable gaps are specialized FEC categories such as electioneering communications and communication costs, which are not exposed.