@cyanheads/openfec-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@cyanheads/openfec-mcp-serverfind candidates for president in 2024"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://openfec.caseyjhand.com/mcp
Overview
US federal campaign finance data from the FEC's OpenFEC API. Search candidates, committees, and filings, trace contributions (Schedule A), disbursements (Schedule B), and independent and coordinated party expenditures (Schedules E/F), and look up election races, legal documents, and filing deadlines. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Find federal candidates by name, state, office, party, or cycle; fetch one by FEC ID with financial totals. |
| Find political committees by name, type, candidate affiliation, or state; fetch one by FEC ID. |
| Pre-aggregated committee financial totals — one committee's per-cycle summary, or a ranked search across committees of one entity type. |
| Search itemized individual contributions (Schedule A) or aggregate breakdowns by size, state, employer, or occupation. |
| Search itemized committee spending (Schedule B) or aggregate breakdowns by purpose or recipient. |
| Search independent expenditures (Schedule E) supporting or opposing federal candidates, itemized or aggregated by candidate. |
| Search coordinated party expenditures (Schedule F) made on behalf of a candidate. |
| Search FEC filings and reports by committee, candidate, form type, or date range. |
| Look up federal election races and candidate financial summaries. |
| Search FEC legal documents: advisory opinions, enforcement cases, administrative fines, and statutes. |
| Fetch one legal document in full, including the arrays search trims away. |
| Look up FEC calendar events, filing deadlines, and election dates. |
Resources
Resource | Description |
| Federal candidate profile with current financial totals and principal committees. |
| Political committee profile with type, designation, and financial summary. |
| Presidential election race with candidate financial totals. |
| Senate or at-large House election race with candidate financial totals. |
| House district election race with candidate financial totals. |
Prompts
Prompt | Description |
| Framework for tracing the flow of money around a candidate or race. |
| Structured analysis of a candidate's financial position. |
Related MCP server: mcp-open-fec
Capability reference
openfec_search_candidates tool
Full-text name search, or a direct lookup by FEC candidate ID (H/S/P + eight letters or digits) that returns full detail
Filters: state, district, office, party, cycle, election_year, incumbent_challenge, candidate_status, has_raised_funds
include_totalsmerges receipts/disbursements/cash-on-hand per cycle — defaults to true on an ID lookup, false on search; capped at 5 pages of 100 rows, with uncovered IDs listed inmissing_totalsfor re-queryPagination up to 100 results per page
Typed errors:
candidate_not_found;inputs_not_applicable_to_id_lookupwhen search-only filters accompany a direct ID lookup
openfec_search_committees tool
Full-text name search, or a direct lookup by FEC committee ID (
C+ eight digits)Filters: candidate_id, state, party, committee_type, designation, cycle, treasurer_name
Pagination up to 100 results per page
Typed errors:
committee_not_found;inputs_not_applicable_to_id_lookupwhen search-only filters accompany a direct ID lookup
openfec_get_committee_totals tool
mode: "single"(default): one committee's totals, one row per two-year cycle filed.mode: "by_entity_type": ranks or screens every committee of one entity type (presidential, pac, party, pac-party, house-senate, ie-only)by_entity_type-only filters: committee_state, committee_type, committee_designation, organization_type, and receipts/disbursements min/max boundsReturns receipts, disbursements, cash on hand, debts, and the itemized/unitemized contribution split
Typed errors:
committee_id_required_for_single_mode,entity_type_required_for_group_mode,inputs_not_applicable_to_mode,committee_totals_not_found
openfec_search_contributions tool
Modes:
itemized(Schedule A records, requires committee_id, keyset cursor pagination),by_size/by_state(committee_id or candidate_id),by_employer/by_occupation(committee_id only)Itemized filters: contributor name, employer, occupation, city, state, ZIP, date range, amount range, is_individual; defaults to the current cycle when omitted
Sort defaults to
-contribution_receipt_date; a cursor is valid only for an otherwise-identical callTyped errors:
itemized_requires_committee_id,aggregate_requires_committee_id,itemized_only_filters_in_aggregate_mode,inputs_not_applicable_to_mode
openfec_search_disbursements tool
Modes:
itemized(Schedule B records, keyset cursor pagination),by_purpose,by_recipient,by_recipient_id— committee_id required for every modeItemized filters: recipient name/state/city/committee ID, description, purpose category, date range, amount range; defaults to the current cycle when omitted
Sort defaults to
-disbursement_dateTyped errors:
itemized_only_filters_in_aggregate_mode;inputs_not_applicable_to_modefor an explicit page in itemized mode
openfec_search_expenditures tool
Modes:
itemized(Schedule E, keyset cursor pagination, defaults to the current cycle andmost_recent: true) andby_candidate(aggregated per targeted candidate — needs candidate_id or a full race scope: office alone for President, plus state for Senate, plus district for House)Itemized filters: payee_name, candidate_party, is_notice (24/48-hour notices), date range, amount range, support_oppose (S/O)
Typed errors:
by_candidate_requires_scope,itemized_only_filters_in_aggregate_mode,inputs_not_applicable_to_mode
openfec_search_coordinated_expenditures tool
Schedule F — party committee spending coordinated with a candidate's campaign, a separate legal category from independent expenditures and direct contributions
Filters: committee_id (spending party committee), candidate_id (benefiting candidate), cycle, payee_name, date range, amount range; unscoped queries span all years
Page-based pagination; the spending committee is hoisted out of rows when committee_id is supplied
openfec_search_filings tool
Form types: 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)
Filters: committee_id, candidate_id, filer_name, report_type, report_year, cycle, is_amended, receipt date range
most_recentdefaults to true, filtering out superseded amendmentsPage-based pagination, up to 100 results per page
openfec_lookup_elections tool
mode: "search"(default): candidates in a race with financial totals.mode: "summary": aggregate race financial totalsRequires office and cycle; Senate/House also need state (House also needs district) unless a ZIP is given — ZIP resolves geography for search mode only
election_fulldefaults to true (expands to the full election period: 4yr president, 6yr senate, 2yr house); rejected on ZIP-scoped searchesTyped errors:
cycle_must_be_even,missing_state_for_office,missing_district_for_house,summary_does_not_support_zip,inputs_not_applicable_to_mode
openfec_search_legal tool
Types: advisory_opinions, murs (enforcement cases), adrs, admin_fines, statutes; requires at least one scoping filter (query, type, ao_number, case_number, respondent, citation, penalty bound, or a date bound)
Date filters are type-scoped — pick a
date_kindthe type records (advisory opinions: issue/request/document date; murs/adrs: open/close/document date; admin_fines: rtb/fd date; statutes have none)Every result is trimmed: highlights capped at 3, the
documentsarray replaced by a count and category summary,commission_votescut to a date and a 200-character action — retrieve the untrimmed record withopenfec_get_legal_documentOffset-based pagination (
from_hit/hits_returned), up to 200 results per page
openfec_get_legal_document tool
Fetches one legal document untouched — the full
documentsarray and completecommission_votesthatopenfec_search_legaltrimsdoc_typeis the plural of a search result'sdocument_type(mur→murs);nois that result'snofieldTyped error:
legal_document_not_found
openfec_lookup_calendar tool
Modes:
events(calendar_category_id, one of 18 category codes),filing_deadlines(report_type, report_year),election_dates(state, office, election_year)min_date/max_dateapply in every mode; other filters are mode-specific and rejected outside their modeTyped error:
inputs_not_applicable_to_mode
openfec://candidate/{candidate_id} resource
Candidate record merged with its current financial totals and principal campaign committees (designation
P)candidate_idcomes fromopenfec_search_candidatesTyped error:
candidate_not_found
openfec://committee/{committee_id} resource
Committee record merged with its financial totals; totals are simply omitted for a committee that files no Form 3/3X/3P
committee_idcomes fromopenfec_search_committeesTyped error:
committee_not_found
openfec://election/{cycle}/{office} resource
Presidential races only (
officeliteralP); candidates returned with financial totals for the full election periodTruncates to the first page when a race has more candidates than one page holds — use
openfec_lookup_electionsmodesearchto page further
openfec://election/{cycle}/{office}/{state} resource
Senate races, or an at-large House race in a single-district state (
officeSorH)Same first-page truncation as the presidential variant
openfec://election/{cycle}/{office}/{state}/{district} resource
House district races (
officeH)Same first-page truncation as the presidential variant
openfec_money_trail prompt
Args:
candidate_nameorcandidate_id(one required), optionalcycle(defaults to the current cycle)Seven-step framework: identify the candidate → map committees → direct fundraising → outside independent expenditures → coordinated party spending → disbursements → synthesis
openfec_campaign_analysis prompt
Args:
candidate_nameorcandidate_id(one required), optionalcycle(defaults to the current cycle)Seven-step framework: candidate overview → principal committee and per-cycle totals trajectory → fundraising breakdown → burn rate and spending → competitive position → outside money context → assessment
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
OpenFEC-specific:
Type-safe client for the OpenFEC REST API, with automatic retry and configurable timeout
Keyset cursor pagination for high-volume Schedule A/B/E queries; page-based pagination everywhere else
Multi-mode tools reject a filter that belongs to a different mode rather than silently dropping it
Error sanitization strips API keys from error messages; HTTP status errors are enriched with actionable recovery hints
Two guided prompts (
openfec_money_trail,openfec_campaign_analysis) chain multiple tools into a financial investigation
Agent-friendly output:
Provenance on every response — a
search_criteriaecho of the effective (post-default) filters, so an implicit cycle default is never hiddenEmpty results carry a
noticeenrichment suggesting how to broaden the query, instead of a bare empty arrayTyped per-tool error contracts (
reasonplus actionablerecoverytext) instead of generic validation failures
Getting started
Public Hosted Instance
A public instance is available at https://openfec.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"openfec-mcp-server": {
"type": "streamable-http",
"url": "https://openfec.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"openfec-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/openfec-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"FEC_API_KEY": "your-api-key"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"openfec-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/openfec-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"FEC_API_KEY": "your-api-key"
}
}
}
}Or with Docker:
{
"mcpServers": {
"openfec-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "-e", "FEC_API_KEY=your-api-key", "ghcr.io/cyanheads/openfec-mcp-server:latest"]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 FEC_API_KEY=your-key bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.3.0 or higher (or Node ≥24)
(Optional) A free OpenFEC API key for higher rate limits (1,000 req/hr vs 30 req/hr with the default
DEMO_KEY)
Installation
Clone the repository:
git clone https://github.com/cyanheads/openfec-mcp-server.gitNavigate into the directory:
cd openfec-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env and set FEC_API_KEY (optional)Configuration
Variable | Description | Default |
| OpenFEC API key. Optional — defaults to |
|
| OpenFEC API base URL. |
|
| Max retry attempts for failed API requests. |
|
| Request timeout in milliseconds. |
|
| Transport: |
|
| Port for HTTP server. |
|
| Hostname for HTTP server. |
|
| HTTP session mode: |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Directory for log files (Node.js only). |
|
| Storage backend. |
|
| Enable OpenTelemetry instrumentation (spans, metrics, completion logs). |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
bun run rebuild bun run start:stdio # or start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security audit bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t openfec-mcp-server .
docker run --rm -e FEC_API_KEY=your-key -p 3010:3010 openfec-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/openfec-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| Resource definitions ( |
| Prompt definitions ( |
| OpenFEC API client and domain types. |
| Unit and integration tests. |
| Build, clean, devcheck, tree, and lint scripts. |
| Design docs and OpenAPI spec. |
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor domain-specific logging,ctx.statefor storageRegister new tools and resources in the
index.tsbarrel filesWrap the OpenFEC API: validate raw → normalize to domain type → return the output schema; never fabricate fields the upstream response omitted
Contributing
Issues are welcome. Run checks before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Query SEC EDGAR filings, XBRL financials, and company data through MCP. STDIO & Streamable HTTP.
OpenFEC MCP — Federal Election Commission campaign finance data
Access U.S. congressional data - bills, votes, members, committees - via MCP.
FEC campaign finance data: candidate fundraising, donors, and spending
Related MCP Servers
- AlicenseAqualityBmaintenanceQuery FEC campaign finance data — search candidates, track donations, analyze spending, and monitor Super PAC activity via the OpenFEC API.82 npm4MIT
- AlicenseNot gradedqualityCmaintenanceAccess Federal Election Commission campaign finance data through MCP tools. Enables querying OpenFEC data using natural language via ask_pipeworx or direct tool calls.2 npmMIT
- FlicenseNot gradedqualityBmaintenanceAn MCP server that searches official FEC PDF rulebooks for compliance and contribution limits, and provides real-time lookups against the OpenFEC API for candidates, committees, filings, and financial data.-
- AlicenseNot gradedqualityAmaintenanceQuery US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP with STDIO or Streamable HTTP.74 npm2Apache 2.0