# io.github.cyanheads/openfec-mcp-server (remote · openfec.caseyjhand.com)

Access FEC campaign finance data. Query data about candidates, money trails, and election filings.

- Trust score: 70/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `openfec.caseyjhand.com`: 70/100 (this document), [markdown](https://verifymcp.io/servers/cyanheads-openfec-mcp-server/openfec.md), [page](https://verifymcp.io/servers/cyanheads-openfec-mcp-server/openfec)
- npm · `@cyanheads/openfec-mcp-server`: 35/100, [markdown](https://verifymcp.io/servers/cyanheads-openfec-mcp-server/cyanheads-openfec-mcp-server.md), [page](https://verifymcp.io/servers/cyanheads-openfec-mcp-server/cyanheads-openfec-mcp-server)

## Channel facts

- Endpoint: `https://openfec.caseyjhand.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `0.7.1`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 66/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 12 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC is configured correctly; the domain's records validate against the full chain to the root.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 74/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 5701 tokens (~475/item across 12 items; 12 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http cyanheads-openfec-mcp-server https://openfec.caseyjhand.com/mcp
```

### Codex

```toml
[mcp_servers.cyanheads-openfec-mcp-server]
url = "https://openfec.caseyjhand.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cyanheads-openfec-mcp-server": {
      "type": "remote",
      "url": "https://openfec.caseyjhand.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add cyanheads-openfec-mcp-server --url https://openfec.caseyjhand.com/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  cyanheads-openfec-mcp-server:
    url: "https://openfec.caseyjhand.com/mcp"
```

### Other

```json
{
  "mcpServers": {
    "cyanheads-openfec-mcp-server": {
      "type": "http",
      "url": "https://openfec.caseyjhand.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-02 (score 70, +1)

No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-31 (score 69, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 68, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 67, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 66, +1)

- [functional improvement] Stability: unverified → 0.03

### 2026-07-26 (score 65)

First indexed and scored.

## MCP tools (12)

### `openfec_search_candidates` (~359 tokens)

Openfec Search Candidates

Find federal candidates by name, state, office, party, or cycle. Retrieve a specific candidate by FEC ID with financial totals. Candidate IDs start with H (House), S (Senate), or P (President) followed by digits.

Input parameters:

- `candidate_id` (string): FEC candidate ID (e.g., P00003392, H2CO07170). Get IDs from openfec_search_candidates results. When provided, returns a single candidate with full detail.
- `candidate_status` (string): Candidate status: C=present, F=future, N=not yet, P=prior.
- `cycle` (number): Two-year election cycle (even year, e.g., 2024).
- `district` (string): Two-digit district number for House candidates.
- `election_year` (number): Specific election year the candidate ran in.
- `has_raised_funds` (boolean): Only candidates whose committee has received receipts.
- `include_totals` (boolean): Include financial totals (receipts, disbursements, cash on hand). Defaults to true when fetching by candidate_id.
- `incumbent_challenge` (string): Incumbent status: I=incumbent, C=challenger, O=open seat.
- `office` (string): Filter by office: H=House, S=Senate, P=President.
- `page` (integer): Page number (1-indexed).
- `party` (string): Three-letter party code (e.g., DEM, REP, LIB).
- `per_page` (integer): Results per page.
- `query` (string): Full-text candidate name search.
- `state` (string): Two-letter US state code (e.g., AZ, CA).

Output parameters:

- `candidates` (array): Candidate result set; one record per match.
- `missing_totals` (array): Candidates whose financial totals were not retrieved because the totals fetch hit its page cap. Re-query each one on its own with candidate_id to get its totals.
- `notice` (string): Guidance when no candidates matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching candidates before pagination.
- `totals` (array): Financial totals (receipts, disbursements, cash_on_hand) when include_totals is true. One row per candidate per cycle.

### `openfec_search_committees` (~329 tokens)

Openfec Search Committees

Find political committees (campaign, PAC, Super PAC, party) by name, type, candidate affiliation, or state. Retrieve a specific committee by FEC ID. Committee IDs start with C followed by digits (e.g., C00358796).

Input parameters:

- `candidate_id` (string): Find committees linked to this candidate (authorized, leadership, joint fundraising). Get IDs from openfec_search_candidates results.
- `committee_id` (string): FEC committee ID (e.g., C00358796). Get IDs from openfec_search_committees results. Starts with 'C' followed by digits. Returns a single committee with full detail.
- `committee_type` (string): Committee type code. Common: H (House), S (Senate), P (Presidential), O (Super PAC), N (PAC nonqualified), Q (PAC qualified), X (Party nonqualified), Y (Party qualified).
- `cycle` (number): Two-year election cycle (even year).
- `designation` (string): Committee designation. A (authorized), B (lobbyist PAC), D (leadership PAC), J (joint fundraiser), P (principal campaign), U (unauthorized).
- `page` (integer): Page number (1-indexed).
- `party` (string): Three-letter party code (e.g., DEM, REP).
- `per_page` (integer): Results per page.
- `query` (string): Full-text committee name search.
- `state` (string): Two-letter state code.
- `treasurer_name` (string): Full-text treasurer name search.

Output parameters:

- `committees` (array): Committee result set; one record per match.
- `notice` (string): Guidance when no committees matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching committees before pagination.

### `openfec_get_committee_totals` (~652 tokens)

Openfec Get Committee Totals

Get pre-aggregated committee financial totals — receipts, disbursements, cash on hand, debts, and the itemized/unitemized breakdown — without paginating Schedule A. Use mode "single" (the default) with a committee_id for one committee's totals, one row per two-year cycle it has filed. Use mode "by_entity_type" to rank or screen every committee of one type (presidential, pac, party, pac-party, house-senate, ie-only) by state, designation, or a receipts/disbursements threshold.

Input parameters:

- `committee_designation` (string): Committee designation — A (authorized), B (lobbyist PAC), D (leadership PAC), J (joint fundraiser), P (principal campaign), U (unauthorized). by_entity_type mode only.
- `committee_id` (string): Committee ID (e.g., C00703975). Get IDs from openfec_search_committees results. Required in single mode; in by_entity_type mode it narrows the grouped search to that one committee.
- `committee_state` (string): Two-letter state code of the committee. by_entity_type mode only.
- `committee_type` (string): Committee type code — H (House), S (Senate), P (Presidential), O (Super PAC), N/Q (PAC), X/Y (party). by_entity_type mode only.
- `cycle` (number): Two-year election cycle (e.g., 2024). Even years only. Omit in single mode to get every cycle the committee has filed.
- `entity_type` (string): Committee entity type for the grouped search. Required in by_entity_type mode. house-senate covers both chambers as one group; ie-only is committees that report only independent expenditures.
- `max_disbursements` (number): Maximum total disbursements in dollars. by_entity_type mode only.
- `max_receipts` (number): Maximum total receipts in dollars. by_entity_type mode only.
- `min_disbursements` (number): Minimum total disbursements in dollars. by_entity_type mode only.
- `min_receipts` (number): Minimum total receipts in dollars. by_entity_type mode only.
- `mode` (string): Query mode. "single" returns one committee's totals, one row per cycle. "by_entity_type" returns a page of committees of one entity type, filterable and sortable across committees.
- `organization_type` (string): Sponsoring organization type — C (corporation), L (labor), M (membership), T (trade), V (cooperative), W (corporation without capital stock). by_entity_type mode only.
- `page` (integer): Page number (1-indexed). Read pagination.pages in the response to see how many pages exist — a long-running committee can have more cycles than one page holds.
- `per_page` (integer): Results per page.
- `sort` (string): Sort field. A "-" prefix sorts descending: "-receipts" ranks the biggest fundraisers first in by_entity_type mode, "-cycle" puts a committee's most recent cycle first in single mode.

Output parameters:

- `mode` (string): Query mode as the server resolved it. Rows mean different things by mode — single rows are cycles of one committee, by_entity_type rows are different committees — so read this rather than inferring f…
- `notice` (string): Guidance when no totals matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `results` (array): Committee totals result set; one row per cycle in single mode, one row per committee in by_entity_type mode.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching totals rows before pagination.

### `openfec_search_contributions` (~604 tokens)

Openfec Search Contributions

Search itemized individual contributions (Schedule A) or get aggregate breakdowns by size, state, employer, or occupation. Use to answer "who is funding this committee?" Itemized mode requires a committee_id. Aggregate by_size/by_state can use candidate_id instead.

Input parameters:

- `candidate_id` (string): Candidate ID (e.g., P00003392). Get IDs from openfec_search_candidates results. Enables by_size and by_state aggregates without a committee_id.
- `committee_id` (string): Receiving committee ID (e.g., C00703975). Get IDs from openfec_search_committees results.
- `contributor_city` (string): Contributor city. Itemized only.
- `contributor_employer` (string): Full-text employer search. Itemized only.
- `contributor_name` (string): Full-text donor name search. Itemized only.
- `contributor_occupation` (string): Full-text occupation search. Itemized only.
- `contributor_state` (string): Two-letter state code (e.g., CA). Itemized only.
- `contributor_zip` (string): ZIP code prefix (starts-with match). Itemized only.
- `cursor` (string): Opaque 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, rejec…
- `cycle` (number): Two-year election cycle (e.g., 2024). Even years only. Defaults to current cycle for itemized mode.
- `is_individual` (boolean): Only individual contributions (excludes committee-to-committee transfers). Itemized only.
- `max_amount` (number): Maximum contribution amount in dollars. Itemized only.
- `max_date` (string): Latest contribution date (YYYY-MM-DD). Itemized only.
- `min_amount` (number): Minimum contribution amount in dollars. Itemized only.
- `min_date` (string): Earliest contribution date (YYYY-MM-DD). Itemized only.
- `mode` (string): Query mode. "itemized" returns individual contribution records (keyset pagination). "by_size" aggregates by contribution size bucket. "by_state" aggregates by contributor state. "by_employer" aggrega…
- `page` (integer): Page number (1-indexed) for the aggregate modes. Ignored in itemized mode, which paginates with cursor. Read pagination.pages in the response to see how many pages exist.
- `per_page` (integer): Results per page.
- `sort` (string): Sort field. A "-" prefix sorts descending: use "-contribution_receipt_amount" for the largest receipts first, since the ascending form leads with the most negative rows (refunds, reattributions, rede…

Output parameters:

- `committee` (object): The 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 co…
- `count` (number): Total result count (may be approximate for itemized).
- `mode` (string): Query mode as the server resolved it. "by_size" and "by_state" resolve to "by_size_candidate" / "by_state_candidate" when scoped by candidate_id — a different endpoint with different row shapes — so…
- `next_cursor`: Pagination cursor for the next page of itemized results. Null when no more pages.
- `notice` (string): Guidance when no contributions matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination info (aggregate modes only).
- `results` (array): Contribution result set; itemized records or aggregate buckets depending on mode.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching contributions or aggregate rows.

### `openfec_search_disbursements` (~587 tokens)

Openfec Search Disbursements

Search itemized committee spending (Schedule B) or get aggregate breakdowns by purpose or recipient. All modes require a committee_id. Use to answer "what is this committee spending money on?" or "who is receiving payments from this committee?"

Input parameters:

- `committee_id` (string, required): Spending committee ID (e.g., C00703975). Get IDs from openfec_search_committees results. Required for all modes.
- `cursor` (string): Opaque 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, rejec…
- `cycle` (number): Two-year election cycle (e.g., 2024). Even years only. Itemized mode defaults to the current cycle when omitted — Schedule B spans all history, and an all-history scan of an active committee times ou…
- `disbursement_description` (string): Full-text description search (e.g., "media buy", "consulting"). Itemized only.
- `disbursement_purpose_category` (string): Purpose category code. Itemized only.
- `max_amount` (number): Maximum amount in dollars. Itemized only.
- `max_date` (string): Latest disbursement date (YYYY-MM-DD). Itemized only.
- `min_amount` (number): Minimum amount in dollars. Itemized only.
- `min_date` (string): Earliest disbursement date (YYYY-MM-DD). Itemized only.
- `mode` (string): Query mode. "itemized" returns individual disbursement records (keyset pagination). "by_purpose" aggregates by purpose category. "by_recipient" aggregates by recipient name. "by_recipient_id" aggrega…
- `page` (integer): Page number (1-indexed) for the aggregate modes. Ignored in itemized mode, which paginates with cursor. Read pagination.pages in the response to see how many pages exist.
- `per_page` (integer): Results per page.
- `recipient_city` (string): Recipient city. Itemized only.
- `recipient_committee_id` (string): Recipient committee ID (for committee-to-committee transfers). Itemized only.
- `recipient_name` (string): Full-text payee name search. Itemized only.
- `recipient_state` (string): Recipient state. Itemized only.
- `sort` (string): Sort field. A "-" prefix sorts descending: use "-disbursement_amount" for the biggest payments first, since the ascending form leads with the most negative rows (refunds and voided payments). Itemize…

Output parameters:

- `committee` (object): The 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 co…
- `count` (number): Total result count (may be approximate for itemized).
- `mode` (string): Query mode as the server resolved it. Row shapes differ by mode — itemized rows are individual payments, aggregate rows are buckets with a total — so read this rather than inferring the shape from th…
- `next_cursor`: Pagination cursor for the next page of itemized results. Null when no more pages.
- `notice` (string): Guidance when no disbursements matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination info (aggregate modes only).
- `results` (array): Disbursement result set; itemized records or aggregate buckets depending on mode.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching disbursements or aggregate rows.

### `openfec_search_expenditures` (~835 tokens)

Openfec Search Expenditures

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 parameters:

- `candidate_id` (string): Targeted candidate ID (e.g., P00003392). Get IDs from openfec_search_candidates results.
- `candidate_office` (string): Office 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_sta…
- `candidate_office_district` (string): Two-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 m…
- `candidate_office_state` (string): Two-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…
- `candidate_party` (string): Three-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.
- `committee_id` (string): Spending committee ID (e.g., C00703975). Get IDs from openfec_search_committees results.
- `cursor` (string): Opaque 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, rejec…
- `cycle` (number): Two-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 explici…
- `is_notice` (boolean): Only 24/48-hour notice filings (near-election spending). Itemized only.
- `max_amount` (number): Maximum expenditure amount in dollars. Itemized only.
- `max_date` (string): Latest expenditure date (YYYY-MM-DD). Itemized only.
- `min_amount` (number): Minimum expenditure amount in dollars. Itemized only.
- `min_date` (string): Earliest expenditure date (YYYY-MM-DD). Itemized only.
- `mode` (string): Query mode. "itemized" returns individual expenditure records (keyset pagination). "by_candidate" returns aggregated totals per candidate by committee (page-based).
- `most_recent` (boolean): Only 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.
- `page` (integer): Page number (1-indexed) for by_candidate mode. Ignored in itemized mode, which paginates with cursor. Read pagination.pages in the response to see how many pages exist.
- `payee_name` (string): Full-text payee name search. Itemized only.
- `per_page` (integer): Results per page.
- `sort` (string): Sort 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…
- `support_oppose` (string): S = support, O = oppose. Filter by whether the expenditure supports or opposes the candidate.

Output parameters:

- `committee` (object): The 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 co…
- `count` (number): Total result count (may be approximate for itemized).
- `mode` (string): Query 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…
- `next_cursor`: Pagination cursor for the next page of itemized results. Null when no more pages.
- `notice` (string): Guidance when no expenditures matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination info (by_candidate mode only).
- `results` (array): Expenditure result set; itemized records or per-candidate aggregates depending on mode.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching expenditures or per-candidate aggregates.

### `openfec_search_coordinated_expenditures` (~389 tokens)

Openfec Search Coordinated Expenditures

Search coordinated party expenditures (Schedule F) — spending a party committee makes on behalf of a candidate it supports, in coordination with that campaign. Distinct from independent expenditures (openfec_search_expenditures), which cannot be coordinated with the candidate, and from direct contributions: coordinated expenditures carry their own statutory limits and can run into tens of millions per party in a presidential cycle. Scope with a spending committee_id, a benefiting candidate_id, or a cycle; unscoped queries span all years.

Input parameters:

- `candidate_id` (string): Benefiting candidate ID (e.g., P00003392). Get IDs from openfec_search_candidates results.
- `committee_id` (string): Spending party committee ID (e.g., C00003418). Get IDs from openfec_search_committees results — party committees carry committee_type X or Y.
- `cycle` (number): Two-year election cycle (e.g., 2024). Even years only. Omitting it searches every cycle on record.
- `max_amount` (number): Maximum expenditure amount in dollars.
- `max_date` (string): Latest expenditure date (YYYY-MM-DD).
- `min_amount` (number): Minimum expenditure amount in dollars.
- `min_date` (string): Earliest expenditure date (YYYY-MM-DD).
- `page` (integer): Page number (1-indexed). Read pagination.pages in the response to see how many pages exist.
- `payee_name` (string): Full-text payee name search (the vendor the party paid).
- `per_page` (integer): Results per page.
- `sort` (string): Sort field. A "-" prefix sorts descending: use "-expenditure_amount" for the largest coordinated spending first, since the ascending form leads with the most negative rows (corrections and voided ent…

Output parameters:

- `committee` (object): The 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 co…
- `notice` (string): Guidance when no coordinated expenditures matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `results` (array): Coordinated expenditure result set; one record per itemized transaction.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching coordinated expenditures before pagination.

### `openfec_search_filings` (~380 tokens)

Openfec Search Filings

Search FEC filings and reports by committee, candidate, form type, or date range. Covers financial reports (F3/F3P/F3X), statements of candidacy (F2), organizational filings (F1), 24-hour IE notices (F24), and amendments.

Input parameters:

- `candidate_id` (string): Associated candidate ID (e.g., P00003392). Get IDs from openfec_search_candidates results.
- `committee_id` (string): Filing committee ID (e.g., C00358796). Get IDs from openfec_search_committees results.
- `cycle` (number): Two-year election cycle (even year).
- `filer_name` (string): Full-text filer name search.
- `form_type` (string): FEC form type. Common: F3 (House/Senate quarterly), F3P (Presidential), F3X (PAC/party), F24 (24-hour IE notice), F1 (statement of organization), F2 (statement of candidacy), F5 (IE by persons).
- `is_amended` (boolean): Filter to original or amended filings only.
- `max_receipt_date` (string): Latest FEC receipt date (YYYY-MM-DD).
- `min_receipt_date` (string): Earliest date FEC received the filing (YYYY-MM-DD).
- `most_recent` (boolean): Only the most recent version (filters out superseded amendments).
- `page` (integer): Page number (1-indexed).
- `per_page` (integer): Results per page.
- `report_type` (string): Report type code. Common: Q1/Q2/Q3 (quarterly), YE (year-end), M3-M12 (monthly), 12G/12P/30G (pre/post election).
- `report_year` (number): Filing year.

Output parameters:

- `notice` (string): Guidance when no filings matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `results` (array): Filing result set; one record per match.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching filings before pagination.

### `openfec_lookup_elections` (~296 tokens)

Openfec Lookup Elections

Look up federal election races and candidate financial summaries. Find who's running in a race with fundraising totals, or get an aggregate race summary.

Input parameters:

- `cycle` (integer, required): Election cycle year (even years only, e.g. 2024).
- `district` (string): Two-digit district number (e.g. "07"). Required for house unless zip is provided.
- `election_full` (boolean): Expand to full election period (4yr president, 6yr senate, 2yr house). Defaults to true when omitted; a ZIP-scoped search rejects it, since that endpoint has no such parameter. Carries no schema defa…
- `mode` (string): search = candidates in a race with financial totals. summary = aggregate race financial summary.
- `office` (string, required): Office sought: H=House, S=Senate, P=President.
- `page` (integer): Page number (1-indexed). Search mode only — summary mode returns a single aggregate row. Read pagination.pages in the response to see how many pages exist.
- `per_page` (integer): Results per page. Search mode only.
- `state` (string): Two-letter US state code (e.g., AZ, CA). Required for senate/house unless zip is provided.
- `zip` (string): ZIP code — finds races covering this ZIP. Search mode only.

Output parameters:

- `mode` (string): Query mode as the server resolved it. Row shapes differ by mode — search rows are per-candidate financial records, summary is one aggregate race row — so read this rather than inferring the shape fro…
- `notice` (string): Guidance when no election results matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `results` (array): Election race result set; candidate financial rows in search mode, a single aggregate summary row in summary mode.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching candidates or race summaries.

### `openfec_search_legal` (~468 tokens)

Openfec Search Legal

Search FEC legal documents: advisory opinions, enforcement cases (MURs), alternative dispute resolutions, and administrative fines.

Input parameters:

- `ao_number` (string): Specific advisory opinion number (e.g. "2024-01").
- `case_number` (string): Specific MUR or ADR case number.
- `date_kind` (string): Which date min_date/max_date bound. Each document type records its own dates, so this must be one the chosen type has: type=advisory_opinions → issue_date (opinion issued), request_date (request rece…
- `from_hit` (integer): Offset for pagination (0-indexed). Default 0.
- `hits_returned` (integer): Results per page. Default 20, max 200.
- `max_date` (string): Latest date (YYYY-MM-DD) for the date_kind selected. Requires type and date_kind.
- `max_penalty_amount` (number): Maximum penalty amount in dollars. Filters enforcement cases (murs, adrs) only — other document types are returned unfiltered by it.
- `min_date` (string): Earliest date (YYYY-MM-DD) for the date_kind selected. Requires type and date_kind.
- `min_penalty_amount` (number): Minimum penalty amount in dollars. Filters enforcement cases (murs, adrs) only — other document types are returned unfiltered by it.
- `query` (string): Full-text search across legal documents.
- `regulatory_citation` (string): CFR citation (e.g. "11 CFR 112.4").
- `respondent` (string): Respondent name (enforcement cases).
- `statutory_citation` (string): U.S.C. citation (e.g. "52 U.S.C. 30106").
- `type` (string): Document type filter. Omit to search all types. admin_fines is slow without a query or respondent filter.

Output parameters:

- `notice` (string): Guidance when no legal documents matched — echoes filters and suggests how to broaden.
- `results` (array): Legal document result set spanning advisory opinions, MURs, ADRs, admin fines, and statutes.
- `retrievalHint` (string): How to recover the material trimmed out of these results. Present whenever any result was returned, because every result is trimmed.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching legal documents across all types.
- `total_count` (number): Total matching documents across all types.

### `openfec_get_legal_document` (~291 tokens)

Openfec Get Legal Document

Fetch one FEC legal document in full — advisory opinion, MUR, ADR, administrative fine, or statute — by its type and number. openfec_search_legal replaces each result's documents array with a count and category summary and cuts every commission vote down to a date and a 200-character action; this returns the record untouched. doc_type is the plural form of the document_type discriminator on a search result (advisory_opinion becomes advisory_opinions, mur becomes murs, adr becomes adrs, admin_fine becomes admin_fines, statute becomes statutes), and no is that result's no field — every document type carries it, and advisory opinions repeat it as ao_no.

Input parameters:

- `doc_type` (string, required): Legal document type, always plural. openfec_search_legal reports the singular form in each result document_type — advisory_opinion, mur, adr, admin_fine, statute — so add an "s" to get the value this…
- `no` (string, required): Document number, copied from the no field of the matching openfec_search_legal result. Advisory opinions are year-serial (e.g. "2024-01", also repeated as ao_no); murs, adrs, and admin_fines are digi…

Output parameters:

- `attachedDocumentCount` (number): Number of related filings in the record documents array. Compare against the document_count openfec_search_legal reported for the same record.
- `document` (object): The complete legal document record. Carries the full documents array that openfec_search_legal replaces with a count and category summary, and the complete commission_votes entries it reduces to a vo…
- `search_criteria` (object): Echo 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.

### `openfec_lookup_calendar` (~399 tokens)

Openfec Lookup Calendar

Look up FEC calendar events, filing deadlines, and election dates. Use to find upcoming filing windows for a committee, locate when a federal election occurred, or scope FEC events by date range and category.

Input parameters:

- `category` (string): Calendar category ID. 20=Commission Meetings, 21=Reporting Deadlines, 22=Conferences and Outreach, 23=AOs and Rules, 24=Other, 25=Quarterly, 26=Monthly, 27=Pre and Post-Elections, 28=EC Periods, 29=I…
- `description` (string): Full-text event description search. Events mode.
- `election_year` (integer): Election year. Election dates mode.
- `max_date` (string): Latest date (YYYY-MM-DD).
- `min_date` (string): Earliest date (YYYY-MM-DD).
- `mode` (string): events = FEC calendar events. filing_deadlines = report due dates. election_dates = upcoming/past elections.
- `office` (string): Office sought (H=House, S=Senate, P=President). Election dates mode.
- `page` (integer): Page number (1-indexed). Default 1.
- `per_page` (integer): Results per page. Default 20, max 100.
- `report_type` (string): Report type code (e.g. "Q1", "Q2"). Filing deadlines mode only.
- `report_year` (integer): Report year. Filing deadlines mode.
- `state` (string): Two-letter state code (e.g., AZ, CA). Primarily for election_dates mode.

Output parameters:

- `mode` (string): Query mode as the server resolved it. Each mode reads a different FEC dataset with its own row shape — calendar events, report due dates, or election dates — so read this rather than inferring the da…
- `notice` (string): Guidance when no calendar entries matched — echoes filters and suggests how to broaden.
- `pagination` (object): Page-based pagination metadata.
- `results` (array): Calendar result set; events, filing deadlines, or election dates depending on mode.
- `search_criteria` (object): Echo 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.
- `totalCount` (number): Total matching calendar entries before pagination.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/cyanheads-openfec-mcp-server/openfec#diagnostics

## Score history

- 2026-08-03: 70
- 2026-08-02: 70
- 2026-08-01: 69
- 2026-07-31: 69
- 2026-07-30: 68
- 2026-07-29: 67
- 2026-07-28: 66
- 2026-07-27: 66
- 2026-07-26: 65

## Links

- Remote endpoint: https://openfec.caseyjhand.com/mcp
- Repository: https://github.com/cyanheads/openfec-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/cyanheads-openfec-mcp-server/openfec/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/cyanheads-openfec-mcp-server/openfec/changelog.json
- HTML version of this page: https://verifymcp.io/servers/cyanheads-openfec-mcp-server/openfec
