Openfec Mcp Server

io.github.cyanheads由 GitHub 帳號 cyanheads 發布v0.10.0更新於 Oct 29, 2026

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

已驗證Streamable HTTP可網頁執行金融資料與分析

概覽

AI 產生的概覽

透過 FEC 的 OpenFEC API 查詢美國聯邦競選財務資料:候選人、委員會、資金流向、申報文件、選舉、法律文件與截止日期。

可以做什麼
  • 依姓名、州、職位、政黨或週期搜尋候選人與政治委員會,或以 FEC ID 取得單筆紀錄及財務總額
  • 取得委員會各週期的財務總額,或依實體類型對委員會排名
  • 追蹤資金:逐筆與彙總的捐款、支出、獨立支出及政黨協調支出
  • 搜尋 FEC 申報文件與報告,查詢選區候選人的募款,並查看行事曆事件、申報截止日期與選舉日期
  • 搜尋 FEC 法律文件(諮詢意見、執法案件、罰款、法規)並取得單份完整文件
  • 讀取候選人、委員會與選區資源,以及資金追蹤與競選分析提示詞
適用情境
適合研究美國聯邦政治獻金:追蹤某候選人或委員會的募款與支出、比較選區、核對申報截止日期,或查閱 FEC 執法與諮詢意見。不涵蓋州或地方層級的競選財務資料。
執行需求
可使用公開託管的 HTTP 端點,或透過 npx 在本機執行(需 Node.js;從原始碼建置需 Bun 1.4+ 或 Node.js 24+)。FEC_API_KEY 中的 OpenFEC API 金鑰為選用:預設 DEMO_KEY 每小時 30 次請求,自有金鑰為 1,000 次。需要能連線至 OpenFEC API。
安裝前請注意
未設定 FEC_API_KEY 時會使用共用的 DEMO_KEY,速率限制很嚴,容易遭到限流。查詢內容與識別碼會傳送給 FEC 的 OpenFEC API,託管端點也會看到你的請求。對 FEC 資料本身為唯讀,但 HTTP 模式可透過 MCP_AUTH_MODE 設定 jwt 或 oauth 驗證,對外開放前需正確設定。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Openfec Mcp Server,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.cyanheads%2Fopenfec-mcp-server/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "openfec": {
      "type": "http",
      "url": "https://openfec.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/openfec-mcp-server

Access FEC campaign finance data on candidates, money trails, and election filings via MCP. STDIO or Streamable HTTP.

12 Tools • 5 FEC Resource Templates • 2 Prompts • 1 Skill

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.

Tools

ToolDescription
openfec_search_candidatesFind federal candidates by name, state, office, party, or cycle; fetch one by FEC ID with financial totals
openfec_search_committeesFind political committees by name, type, candidate affiliation, or state; fetch one by FEC ID
openfec_get_committee_totalsPre-aggregated financial totals for one committee by cycle, or ranked across committees of one entity type
openfec_search_contributionsItemized contributions (Schedule A), or aggregates by size, state, employer, or occupation
openfec_search_disbursementsItemized committee spending (Schedule B), or aggregates by purpose or recipient
openfec_search_expendituresIndependent expenditures (Schedule E) supporting or opposing candidates, itemized or totaled per candidate
openfec_search_coordinated_expendituresCoordinated party expenditures (Schedule F) made on behalf of a candidate
openfec_search_filingsFEC filings and reports by committee, candidate, form type, or date range
openfec_lookup_electionsCandidates in a federal race with their fundraising totals, or an aggregate race summary
openfec_search_legalAdvisory opinions, enforcement cases, alternative dispute resolutions, administrative fines, and statutes
openfec_get_legal_documentOne legal document in full, including the arrays search trims away, paged by entry when too large for one response
openfec_lookup_calendarFEC calendar events, filing deadlines, and election dates

Resources

ResourceDescription
openfec://candidate/{candidate_id}Candidate profile with financial totals and principal committees
openfec://committee/{committee_id}Committee profile with type, designation, and financial summary
openfec://election/{cycle}/{office}Presidential race with candidate financial totals
openfec://election/{cycle}/{office}/{state}Senate or at-large House race with candidate financial totals
openfec://election/{cycle}/{office}/{state}/{district}House district race with candidate financial totals

The same data is reachable through openfec_search_candidates, openfec_search_committees, and openfec_lookup_elections for tool-only clients.

The openfec-guide skill covers campaign-finance investigations, historical committee attribution, and coverage checks. MCP clients can read it at skill://openfec-guide/SKILL.md.

Prompts

PromptDescription
openfec_money_trailTrace the money around a candidate: direct fundraising, PAC support, independent expenditures, and party spending
openfec_campaign_analysisStructured analysis of a candidate's financial position

Capability reference

openfec_search_candidates tool

  • query name search filtered by state, district, office, party, cycle, election_year, incumbent_challenge, candidate_status, and has_raised_funds, up to 100 per page; or a candidate_id lookup (H/S/P + eight letters or digits) returning one full record
  • include_totals (default on for an ID lookup) adds per-cycle totals rows and caps a search page at 35 candidates when cycle or election_year scopes the totals, 5 when they span every cycle; candidates the totals fetch didn't reach are listed in missing_totals
  • Typed errors: candidate_not_found, inputs_not_applicable_to_id_lookup

openfec_search_committees tool

  • query name search filtered by candidate_id, state, party, committee_type, designation, cycle, and treasurer_name, up to 100 per page; or a committee_id lookup (C + eight digits)
  • Typed errors: committee_not_found, inputs_not_applicable_to_id_lookup

openfec_get_committee_totals tool

  • mode: "single" (default) takes a committee_id and returns one row per two-year cycle; mode: "by_entity_type" ranks every committee of one entity_type (presidential, pac, party, pac-party, house-senate, ie-only), filterable by state, type, designation, organization type, and receipts/disbursements bounds; up to 100 per page
  • Rows carry receipts, disbursements, cash on hand, debts, and the itemized/unitemized split; the output mode says whether rows are cycles or committees
  • Typed errors: committee_id_required_for_single_mode, entity_type_required_for_group_mode, committee_totals_not_found

openfec_search_contributions tool

  • itemized (default) needs a committee_id and filters by contributor name, employer, occupation, city, state, ZIP, date and amount ranges, and is_individual, 30 rows per page; by_size / by_state take a committee_id or candidate_id, by_employer / by_occupation a committee_id
  • The output mode becomes by_size_candidate or by_state_candidate when scoped by candidate, a different row shape; itemized responses carry next_cursor, count, and count_is_approximate
  • Typed errors: itemized_requires_committee_id, aggregate_requires_committee_id

openfec_search_disbursements tool

  • committee_id required in every mode: itemized (default; recipient name, state, city, and committee ID, description, purpose category, date and amount ranges, 30 rows per page), by_purpose, by_recipient, by_recipient_id
  • Itemized responses carry next_cursor, count, and count_is_approximate; aggregate modes page by number

openfec_search_expenditures tool

  • itemized (default) filters by committee, candidate, support_oppose, payee, targeted office/state/district, party, is_notice (24/48-hour notices), dates, and amounts; most_recent defaults to true; 60 rows per page when scoped by committee_id, 30 otherwise
  • by_candidate totals need a candidate_id or a full race scope (candidate_office=P alone, S plus candidate_office_state, H plus state and candidate_office_district), or fail as by_candidate_requires_scope

openfec_search_coordinated_expenditures tool

  • Scope by spending party committee_id, benefiting candidate_id, cycle, payee, dates, and amounts; unscoped queries span all years
  • Page-based, 80 rows per page when scoped by committee_id and 25 otherwise; rows carry subordinate_committee_id, the committee the spending is attributed to

openfec_search_filings tool

  • Filters: committee_id, candidate_id, filer_name, form_type (F3, F3P, F3X, F24, F1, F2, F5), report_type, report_year, cycle, is_amended, and receipt date range; 65 rows per page
  • most_recent defaults to true, hiding superseded amendments; rows carry form and report type, financial totals, and pdf_url

openfec_lookup_elections tool

  • office and an even cycle are required; Senate also needs state and House state plus district, unless a zip scopes a search
  • mode: "search" (default) returns the race's candidates with totals and candidate_pcc_id / candidate_pcc_name, that cycle's principal campaign committee; mode: "summary" returns one aggregate race row
  • Typed errors: cycle_must_be_even, missing_state_for_office, missing_district_for_house, summary_does_not_support_zip

openfec_search_legal tool

  • type (advisory_opinions, murs, adrs, admin_fines, statutes), query, ao_number, case_number, respondent, citations, penalty bounds, or dates; at least one is required (missing_filter), and a date bound needs type plus a date_kind that type records
  • Citations, penalty bounds, respondent, ao_number, and case_number each filter only some types; one sent with a type it doesn't filter fails as filter_not_valid_for_type, and with type omitted the search returns only the types they all apply to, with a total over those types. On MURs and ADRs a citation can't be combined with case_number, respondent, a penalty bound, or an open/close date bound, which upstream would ignore; the two citation fields together match either one
  • Citations take the form upstream parses — 52 U.S.C. 30104 or 11 CFR 110.1 (USC, C.F.R., §, and suffixes like 30104(g) are fine); a bare 30106 or 110.1 fails as invalid_citation instead of silently returning unfiltered results. One citation per field: upstream applies only the first citation in a value, so 52 U.S.C. 30104, 52 U.S.C. 30118 fails the same way
  • Offset paging via from_hit / hits_returned, up to 200 per type within a 10,000-result window
  • Results are trimmed: documents becomes document_count and document_categories, dispositions becomes disposition_count and disposition_categories, highlights stop at 3 with their <em> match markup removed and render one per line, and commission_votes shrink to a date and a 200-character action; openfec_get_legal_document returns the full record
  • Each response stays under 100,000 bytes: whole results are admitted one type at a time until the next would not fit, and a page that held some back reports truncated, shown, and nextFromHit — the from_hit that continues each type, passed back with that type

openfec_get_legal_document tool

  • doc_type is the plural of a search result's document_type (mur → murs); no is that result's no field
  • Returns the untrimmed record, including documents, commission_votes, and dispositions; fails as legal_document_not_found
  • A record over 100,000 bytes returns its scalar fields, the arrays that fit (smallest first), and withheld — each held-back array with its entry count and size; re-call with array and offset for that array's entries while they fit, plus next_offset. An array the record lacks fails as array_not_in_record

openfec_lookup_calendar tool

  • events (default; category, one of 18 codes, and description), filing_deadlines (report_type, report_year), or election_dates (state, office, district, election_year); min_date / max_date apply in every mode, up to 100 per page
  • A district filter never matches an at-large race; pair it with state

openfec://candidate/{candidate_id} resource

  • Candidate record merged with its financial totals and principal_committees (current designation P, not scoped to a cycle)
  • candidate_id comes from openfec_search_candidates; fails as candidate_not_found

openfec://committee/{committee_id} resource

  • Committee record merged with its financial totals, which are absent for a committee that files no Form 3/3X/3P
  • committee_id comes from openfec_search_committees; fails as committee_not_found

openfec://election/{cycle}/{office} resource

  • Presidential races (office P), with totals for the full election period
  • First page only: a longer race carries truncation_notice pointing to openfec_lookup_elections, and an empty one empty_result_notice

openfec://election/{cycle}/{office}/{state} resource

  • Senate races, or an at-large House race in a single-district state (office S or H)
  • Same first-page limit and notices as the presidential template

openfec://election/{cycle}/{office}/{state}/{district} resource

  • House district races (office H)
  • Same first-page limit and notices as the presidential template

openfec_money_trail prompt

  • Arguments: candidate_name or candidate_id (one required), optional cycle
  • Seven steps: identify the candidate, resolve the cycle's principal committee via candidate_pcc_id, then direct fundraising, independent expenditures, coordinated party spending, disbursements, and a synthesis

openfec_campaign_analysis prompt

  • Arguments: candidate_name or candidate_id (one required), optional cycle
  • Seven steps: candidate overview, principal committee and per-cycle trajectory, fundraising mix, burn rate, competitive position, outside money, and an 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 retry and a configurable timeout; error messages have the API key stripped and HTTP failures carry recovery hints
  • Cycles are even years covering two calendar years (2024 = Jan 2023 – Dec 2024); itemized Schedule A/B/E default to the current cycle when cycle is omitted, and election_full (default true) widens a race total to the full election period (4yr president, 6yr senate, 2yr house)
  • Itemized contributions and disbursements scope to a committee_id, not a candidate_id. Committee designation and principal_committees reflect current designation only, so for a cycle's principal committee read candidate_pcc_id from openfec_lookup_elections
  • Itemized Schedule A/B/E page with an opaque next_cursor, valid only for an otherwise-identical call; other tools page by number, and legal search by offset

Agent-friendly output:

  • Effective-query echo: every tool response carries search_criteria with the post-default filters, and an empty result carries a notice on how to broaden it
  • Response budget of 100,000 bytes per surface: high-volume tools cap rows per page and report truncated, shown, and cap when a page falls below the requested per_page (page-based tools also echo the applied size in pagination.per_page); legal search holds back whole results and reports nextFromHit, and a large legal document pages its arrays by offset; a single-committee query lifts that committee into one top-level committee field instead of repeating it per row
  • Typed contracts: multi-mode tools echo the resolved mode and reject a filter the mode can't apply (itemized_only_filters_in_aggregate_mode, inputs_not_applicable_to_mode) instead of dropping it; every failure carries a typed reason and recovery text, and estimated totals are flagged count_is_approximate

Getting started

Connect to the hosted instance, no install:

sh
claude mcp add --transport http openfec-mcp-server https://openfec.caseyjhand.com/mcp

Or run it locally:

sh
claude mcp add openfec-mcp-server -- npx -y @cyanheads/openfec-mcp-server

For other clients, add this to the MCP config file:

json
{  "mcpServers": {    "openfec-mcp-server": {      "command": "npx",      "args": ["-y", "@cyanheads/openfec-mcp-server"]    }  }}

An optional OpenFEC API key in FEC_API_KEY raises the limit from 30 to 1,000 requests per hour (-e FEC_API_KEY=your-key, or an env entry). For Docker or a source build, see Running the server.

Configuration

VariableDescriptionDefault
FEC_API_KEYOpenFEC API key from api.data.gov. DEMO_KEY allows 30 req/hr; your own key allows 1,000.DEMO_KEY
FEC_BASE_URLOpenFEC API base URL.https://api.open.fec.gov/v1
FEC_MAX_RETRIESRetry attempts for failed API requests.3
FEC_REQUEST_TIMEOUTPer-request timeout, in ms.30000
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto. Overrides the stateless mode the server declares.stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
STORAGE_PROVIDER_TYPEStorage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1.in-memory
OTEL_ENABLEDEnable OpenTelemetry.false

See .env.example for the full list of optional overrides.

Running the server

Local development

Requires Bun v1.4.0 or higher (or Node.js v24+).

  • Clone and install:

    sh
    git clone https://github.com/cyanheads/openfec-mcp-server.gitcd openfec-mcp-server && bun installcp .env.example .env   # set FEC_API_KEY as needed
  • Build and run:

    sh
    bun run rebuildbun run start:stdio   # or start:http
  • Run checks and tests:

    sh
    bun run devcheck      # Lint, format, typecheck, security auditbun run test          # Vitest test suitebun run lint:mcp      # Validate MCP definitions against spec

Docker

sh
docker build -t openfec-mcp-server .docker run --rm -e FEC_API_KEY=your-key -p 3010:3010 openfec-mcp-server

The 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

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools/resources/prompts and inits the OpenFEC service.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts), with shared validators and formatters in definitions/utils/.
src/mcp-server/resourcesResource definitions (*.resource.ts). Candidate, committee, and three election-race templates.
src/mcp-server/promptsPrompt definitions (*.prompt.ts). Money trail and campaign analysis.
src/services/openfecOpenFEC API client and domain types.
tests/Unit and integration tests, mirroring the src/ structure.
scripts/Build, clean, devcheck, tree, changelog, and lint scripts.
skills/Agent guide to campaign-finance workflows, identifiers, and coverage limits; also served over MCP.
docs/Design notes and the OpenFEC OpenAPI spec.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for logging, ctx.state for storage
  • Register new tools and resources in the barrels at src/mcp-server/*/definitions/index.ts
  • Wrap 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 and tests before submitting:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

來源:README.md,提交 88c4fa9

工具

12

openfec_search_candidates

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 exactly eight letters or digits.

輸入參數pagecyclepartyquerystateofficedistrictper_pagecandidate_idelection_yearinclude_totalscandidate_status另有 2 個

openfec_search_committees

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 exactly eight digits (e.g., C00358796).

輸入參數pagecyclepartyquerystateper_pagedesignationcandidate_idcommittee_idcommittee_typetreasurer_name

openfec_get_committee_totals

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.

輸入參數modepagesortcycleper_pageentity_typecommittee_idmax_receiptsmin_receiptscommittee_typecommittee_statemax_disbursements另有 3 個

openfec_search_contributions

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.

輸入參數modepagesortcyclecursormax_datemin_dateper_pagemax_amountmin_amountcandidate_idcommittee_id另有 7 個

openfec_search_disbursements

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?"

輸入參數modepagesortcyclecursormax_datemin_dateper_pagemax_amountmin_amountcommittee_id必填recipient_city另有 5 個

openfec_search_expenditures

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).

輸入參數modepagesortcyclecursormax_datemin_dateper_pageis_noticemax_amountmin_amountpayee_name另有 9 個

openfec_search_coordinated_expenditures

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.

輸入參數pagesortcyclemax_datemin_dateper_pagemax_amountmin_amountpayee_namecandidate_idcommittee_id

openfec_search_filings

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.

輸入參數pagecycleper_pageform_typefiler_nameis_amendedmost_recentreport_typereport_yearcandidate_idcommittee_idmax_receipt_date另有 1 個

openfec_lookup_elections

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.

輸入參數zipmodepagecycle必填stateoffice必填districtper_pageelection_full

openfec_lookup_calendar

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.

輸入參數modepagestateofficecategorydistrictmax_datemin_dateper_pagedescriptionreport_typereport_year另有 1 個

版本歷史

8
  1. v0.10.0最新Oct 29, 2026
  2. v0.9.2Oct 25, 2026
  3. v0.9.1Oct 9, 2026
  4. v0.9.0Sep 25, 2026
  5. v0.8.4Sep 24, 2026
  6. v0.8.2Sep 22, 2026
  7. v0.8.1Sep 20, 2026
  8. v0.8.0Sep 16, 2026

評分

已滿足適用檢查項的 100%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分