关于 openfec-mcp-server
openfec-mcp-server 为研究人员等提供 FEC 联邦竞选财务数据,可查询候选人、委员会和选举,并结合财务记录、法律资料与日历信息追踪资金流向。
主要功能
- 01搜索候选人与委员会
- 02追踪捐款和支出
- 03查询申报文件与选举
- 04搜索法律记录和截止日期
- 05读取候选人与委员会档案
适用场景
- 01比较候选人各周期筹款情况
- 02追踪候选人相关的 PAC 与政党支出
- 03查找申报文件和 FEC 法律资料
- 04核对选举日期与申报截止日期
MCP 相关
通过 STDIO 或 Streamable HTTP 向 MCP 客户端提供 12 个工具、5 个资源和 2 个提示词,并提供公共托管服务。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://openfec.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-openfec https://openfec.caseyjhand.com/mcp{"mcpServers":{"cyanheads-openfec":{"type":"http","url":"https://openfec.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-openfec":{"type":"http","url":"https://openfec.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-openfec":{"type":"http","url":"https://openfec.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-openfec":{"serverUrl":"https://openfec.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
12| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | integer | 否 | 搜索结果页码(从 1 开始)。搜索路径中默认为 1。 |
| cycle | number | 否 | 两年一届的选举周期(偶数年份,例如 2024)。 |
| party | string | 否 | 三字母党派代码(例如 DEM、REP、LIB)。 |
| query | string | 否 | 候选人姓名全文搜索。 |
| state | string | 否 | 美国两字母州代码(例如 AZ、CA)。 |
| office | enum | 否 | 按 office 筛选:H=众议院,S=参议院,P=总统。H | S | P |
| district | string | 否 | 众议院候选人的两位数选区编号。 |
| per_page | integer | 否 | 每页搜索结果数。搜索路径上的默认值为 20。使用 include_totals 时,如果 cycle 或 election_year 限定了汇总范围,最多请求 35 位候选人;如果汇总涵盖所有周期,则请求 5 位,以使响应保持在 100,000 字节以内。若页面大小低于请求值,响应会报告 truncated 和 cap,且 pagination.per_page 会回显实际应用的页面大小;页码按该页面大小计算,因此请继续请求下一页。 |
| candidate_id | string | 否 | FEC 候选人 ID:H、S 或 P 后面恰好跟 8 个字母或数字(例如 P00003392、H2CO07170)。从 openfec_search_candidates 结果中获取 ID。提供此参数时,返回一位候选人的完整详细信息。 |
| election_year | number | 否 | 候选人参选的特定选举年份。 |
| include_totals | boolean | 否 | 包含财务汇总(收入、支出、现金余额)。按 candidate_id 获取时,默认值为 true。 |
| candidate_status | enum | 否 | 候选人状态:C=现任,F=未来,N=尚未,P=往届。C | F | N | P |
| has_raised_funds | boolean | 否 | 仅包括委员会收到过收入的候选人。 |
| incumbent_challenge | enum | 否 | 现任者状态:I=现任者,C=挑战者,O=空缺席位。I | C | O |
详细介绍
@cyanheads/openfec-mcp-server
通过 MCP 访问 FEC 候选人、资金流向和选举申报数据。支持 STDIO 或 Streamable HTTP。
概览
来自 FEC OpenFEC API 的美国联邦竞选财务数据。搜索候选人、委员会和申报文件,追踪捐款(Schedule A)、支出(Schedule B)、独立和协调政党支出(Schedules E/F),并查询选举竞选、法律文件和申报截止日期。
工具
| 工具 | 描述 |
|---|---|
openfec_search_candidates | 按姓名、州、职务、党派或选举周期查找联邦候选人;也可通过 FEC ID 获取单个候选人及其财务总额 |
openfec_search_committees | 按名称、类型、候选人关联情况或州查找政治委员会;也可通过 FEC ID 获取单个委员会 |
openfec_get_committee_totals | 获取单个委员会按选举周期预先汇总的财务总额,或按实体类型对多个委员会进行排名 |
openfec_search_contributions | 获取明细捐款(Schedule A),或按金额、州、雇主或职业汇总 |
openfec_search_disbursements | 获取委员会支出明细(Schedule B),或按用途或收款方汇总 |
openfec_search_expenditures | 获取支持或反对候选人的独立支出(Schedule E),包括明细或按候选人汇总的金额 |
openfec_search_coordinated_expenditures | 获取代表候选人进行的协调政党支出(Schedule F) |
openfec_search_filings | 按委员会、候选人、表格类型或日期范围查找 FEC 申报文件和报告 |
openfec_lookup_elections | 获取联邦选举中候选人及其筹款总额,或选举汇总 |
openfec_search_legal | 查找咨询意见、执法案件、替代性争议解决、行政罚款和法规 |
openfec_get_legal_document | 获取单份完整法律文件,包括搜索结果中会被删减的数组;文件过大无法在单次响应中返回时,可按条目分页获取 |
openfec_lookup_calendar | 获取 FEC 日历事件、申报截止日期和选举日期 |
资源
| 资源 | 描述 |
|---|---|
openfec://candidate/{candidate_id} | 候选人档案,包含财务总额和主要委员会 |
openfec://committee/{committee_id} | 委员会档案,包含类型、指定类别和财务摘要 |
openfec://election/{cycle}/{office} | 总统选举,包含候选人财务总额 |
openfec://election/{cycle}/{office}/{state} | 参议院或众议院非分区选举,包含候选人财务总额 |
openfec://election/{cycle}/{office}/{state}/{district} | 众议院选区选举,包含候选人财务总额 |
仅支持工具的客户端也可以通过 openfec_search_candidates、openfec_search_committees 和 openfec_lookup_elections 获取相同数据。
提示词
| 提示词 | 描述 |
|---|---|
openfec_money_trail | 追踪候选人相关资金流向:直接筹款、PAC 支持、独立支出和政党支出 |
openfec_campaign_analysis | 对候选人的财务状况进行结构化分析 |
能力参考
openfec_search_candidates tool
query按姓名搜索,并可按州、选区、职务、党派、选举周期、选举年份、现任者挑战情况、候选人状态和是否已筹集资金筛选;每页最多 100 条;也可通过candidate_id查询单条记录(H/S/P + 八个字母或数字),并返回完整记录include_totals(按 ID 查询时默认开启)会添加按选举周期划分的totals行;当选举周期或选举年份限定总额范围时,每页搜索结果最多包含 35 名候选人;当范围涵盖所有选举周期时,每页最多包含 5 名候选人;未能获取总额的候选人会列在missing_totals中- 类型化错误:
candidate_not_found、inputs_not_applicable_to_id_lookup
openfec_search_committees tool
query按名称搜索,并可按候选人 ID、州、党派、委员会类型、指定类别、选举周期和财务主管姓名筛选;每页最多 100 条;也可通过committee_id查询单条记录(C+ 八位数字)- 类型化错误:
committee_not_found、inputs_not_applicable_to_id_lookup
openfec_get_committee_totals 工具
mode: "single"(默认)接收一个committee_id,并按每个两年周期返回一行;mode: "by_entity_type"按entity_type(presidential、pac、party、pac-party、house-senate、ie-only)为所有委员会排名;可按州、类型、指定、组织类型以及收入/支出范围筛选;每页最多 100 条- 行数据包含收入、支出、现金余额、债务以及明细/非明细拆分;输出中的
mode表示行数据按周期还是委员会排列 - 类型化错误:
committee_id_required_for_single_mode、entity_type_required_for_group_mode、committee_totals_not_found
openfec_search_contributions 工具
itemized(默认)需要committee_id,并可按捐款人姓名、雇主、职业、城市、州、邮政编码、日期和金额范围以及is_individual筛选;每页 30 条;by_size/by_state接收committee_id或candidate_id,by_employer/by_occupation接收committee_id- 按候选人范围筛选时,输出中的
mode会变为by_size_candidate或by_state_candidate,且行结构不同;明细响应包含next_cursor、count和count_is_approximate - 类型化错误:
itemized_requires_committee_id、aggregate_requires_committee_id
openfec_search_disbursements 工具
- 所有模式均要求
committee_id:itemized(默认;接收方姓名、州、城市和委员会 ID、说明、用途类别、日期和金额范围;每页 30 条)、by_purpose、by_recipient、by_recipient_id - 明细响应包含
next_cursor、count和count_is_approximate;聚合模式按编号分页
openfec_search_expenditures 工具
itemized(默认)可按委员会、候选人、support_oppose、收款人、目标职位/州/选区、政党、is_notice(24/48 小时通知)、日期和金额筛选;most_recent默认值为 true;按committee_id筛选时每页 60 条,否则每页 30 条by_candidate汇总需要candidate_id或完整的选举范围(仅candidate_office=P、S加candidate_office_state、H加州和candidate_office_district),否则返回by_candidate_requires_scope
openfec_search_coordinated_expenditures 工具
- 可按支出方
committee_id、受益候选人candidate_id、cycle、收款人、日期和金额设定范围;未设定范围的查询会涵盖所有年份 - 按页分页;按
committee_id筛选时每页 80 条,否则每页 25 条;行数据包含subordinate_committee_id,即支出归属的委员会
openfec_search_filings 工具
- 筛选条件:committee_id、candidate_id、filer_name、form_type(F3、F3P、F3X、F24、F1、F2、F5)、report_type、report_year、cycle、is_amended 和收件日期范围;每页 65 条
most_recent默认值为 true,会隐藏已被替代的修正申报;行数据包含表格类型和报告类型、财务总额以及pdf_url
openfec_lookup_elections 工具
- 必须提供
office和偶数cycle;参议院还需要state,众议院需要state和district,除非使用zip限定搜索范围 mode: "search"(默认)返回该选举中候选人及其总额,以及candidate_pcc_id/candidate_pcc_name(该周期的主要竞选委员会);mode: "summary"返回一条选举汇总行- 类型化错误:
cycle_must_be_even、missing_state_for_office、missing_district_for_house、summary_does_not_support_zip
openfec_search_legal 工具
type(advisory_opinions、murs、adrs、admin_fines、statutes)、query、ao_number、case_number、respondent、citations、penalty bounds 或日期;至少需要提供一项(missing_filter),日期界限还需要提供type以及该类型记录的date_kind- citations、penalty bounds、respondent、ao_number 和 case_number 各自只适用于部分类型;若与不适用的
type一起发送,则会以filter_not_valid_for_type失败;若省略type,搜索只会返回这些筛选条件都适用的类型,并统计这些类型的总数。对于 MUR 和 ADR,citation 不能与 case_number、respondent、penalty bound 或开/结案日期界限同时使用,因为上游会忽略这些条件;两个 citation 字段同时提供时,将匹配其中任意一个 - citation 须采用上游可解析的形式——
52 U.S.C. 30104或11 CFR 110.1(USC、C.F.R.、§和30104(g)这类后缀均可);单独的30106或110.1会以invalid_citation失败,而不会静默返回未筛选的结果。每个字段只能提供一个 citation:上游只会应用值中的第一个 citation,因此52 U.S.C. 30104, 52 U.S.C. 30118也会以同样的方式失败 - 通过
from_hit/hits_returned进行偏移分页;每种类型最多 200 条,且位于 10,000 条结果的窗口内 - 结果会经过精简:
documents替换为document_count和document_categories,dispositions替换为disposition_count和disposition_categories,highlights 最多保留 3 条,移除其中的<em>匹配标记并逐行显示;commission_votes则缩减为日期和不超过 200 个字符的操作说明;openfec_get_legal_document会返回完整记录 - 每个响应都不超过 100,000 字节:结果按类型逐一完整纳入,直到下一个类型无法容纳;若页面未能容纳部分结果,则会报告
truncated、shown和nextFromHit——即每种类型的后续from_hit,与该type一起传回
openfec_get_legal_document 工具
doc_type是某条搜索结果的document_type的复数形式(mur→murs);no是该结果的no字段- 返回未经精简的记录,包括
documents、commission_votes和dispositions;找不到时会以legal_document_not_found失败 - 若记录超过 100,000 字节,则返回其标量字段、能容纳的数组(从最小的开始),以及
withheld——其中列出每个暂不返回的数组及其条目数和大小;对于仍能容纳的数组条目,可使用array和offset重新调用,并获取next_offset。若记录中不存在该数组,则会以array_not_in_record失败
openfec_lookup_calendar 工具
events(默认;category,18 个代码之一,以及description)、filing_deadlines(report_type、report_year)或election_dates(state、office、district、election_year);所有模式均可使用min_date/max_date,每页最多 100 条district筛选条件永远不会匹配无分区选区;请将其与state配合使用
openfec://candidate/{candidate_id} 资源
- 候选人记录与其财务总额及
principal_committees合并(当前 designation 为P,不限定选举周期) candidate_id来自openfec_search_candidates;找不到时会以candidate_not_found失败
openfec://committee/{committee_id} 资源
- 委员会记录与其财务总额合并;未提交 Form 3/3X/3P 的委员会没有财务总额
committee_id来自openfec_search_committees;找不到时会以committee_not_found失败
openfec://election/{cycle}/{office} 资源
- 总统选举(
office为P),包含整个选举期间的总额 - 仅提供第一页:持续较长的选举会显示指向
openfec_lookup_elections的truncation_notice,没有结果时则显示empty_result_notice
openfec://election/{cycle}/{office}/{state} 资源
- 参议院选举,或单一选区州的无分区众议院选举(
office为S或H) - 与总统选举模板一样,仅提供第一页,并显示相同的提示
openfec://election/{cycle}/{office}/{state}/{district} 资源
- 众议院选区选举(
officeH) - 首页面限制和提示与总统选举模板相同
openfec_money_trail 提示词
- 参数:
candidate_name或candidate_id(必填其一),cycle可选 - 七个步骤:识别候选人,通过
candidate_pcc_id确定该周期的主要委员会,然后依次查看直接筹款、独立支出、协调的政党支出、支出情况,最后进行综合分析
openfec_campaign_analysis 提示词
- 参数:
candidate_name或candidate_id(必填其一),cycle可选 - 七个步骤:候选人概览、主要委员会及各周期走势、筹款构成、资金消耗率、竞争态势、外部资金,以及评估
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔的身份验证(none / jwt / oauth)、可切换的存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。
OpenFEC 专属功能:
- 为 OpenFEC REST API 提供类型安全的客户端,支持重试和可配置的超时;错误消息会移除 API 密钥,HTTP 故障会附带恢复提示
- 周期为覆盖两个日历年的偶数年份(2024 = 2023 年 1 月 – 2024 年 12 月);未提供
cycle时,明细 Schedule A/B/E 默认使用当前周期;election_full(默认为 true)会将选举总额扩展至完整选举周期(总统 4 年、参议员 6 年、众议员 2 年) - 明细捐款和支出需按
committee_id查询,而非candidate_id。委员会的designation和principal_committees仅反映当前指定情况,因此要查询某个周期的主要委员会,请从openfec_lookup_elections读取candidate_pcc_id - 明细 Schedule A/B/E 使用不透明的
next_cursor翻页,该游标仅对其他参数完全相同的调用有效;其他工具按页码翻页,法律搜索按偏移量翻页
便于 Agent 使用的输出:
- 回显生效查询:每个工具响应都包含应用默认值后的筛选条件
search_criteria;没有结果时会附带说明如何放宽筛选条件的notice - 每种输出形式的响应上限为 100,000 字节:高流量工具会限制每页行数;当页面结果少于请求的
per_page时,会报告truncated、shown和cap(基于页码的工具还会在pagination.per_page中回显实际应用的页面大小);法律搜索会暂不返回完整结果,并报告nextFromHit;大型法律文档会按offset对数组分页;仅查询一个委员会时,会将该委员会提升至顶层的committee字段,而不是在每行重复显示 - 类型化契约:多模式工具会回显解析后的
mode,并拒绝该模式无法应用的筛选条件(itemized_only_filters_in_aggregate_mode、inputs_not_applicable_to_mode),而非直接忽略;每次失败都会附带类型化的reason和recovery文本;估算总数会标记为count_is_approximate
开始使用
公共托管实例
可使用公共实例 https://openfec.caseyjhand.com/mcp,无需安装。该实例提供 Streamable HTTP;每个客户端的配置格式各不相同。
Claude Code:
claude mcp add --transport http openfec-mcp-server https://openfec.caseyjhand.com/mcp
Cline(cline_mcp_settings.json):
{
"mcpServers": {
"openfec-mcp-server": {
"type": "streamableHttp",
"url": "https://openfec.caseyjhand.com/mcp"
}
}
}
Cursor(mcp.json):
{
"mcpServers": {
"openfec-mcp-server": {
"url": "https://openfec.caseyjhand.com/mcp"
}
}
}
Claude Desktop 可在“设置”→“连接器”中添加远程服务。
自托管 / 本地使用
将以下内容添加到 MCP 客户端配置文件中。
{
"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"
}
}
}
}
或使用 npx(无需 Bun):
{
"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"
}
}
}
}
或使用 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"]
}
}
}
使用 Streamable HTTP 时,设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 FEC_API_KEY=your-key bun run start:http
# Server listens at http://localhost:3010/mcp
先决条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
- 可选:免费的 OpenFEC API 密钥 可将速率限制从默认
DEMO_KEY的每小时 30 次请求提高到每小时 1,000 次。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/openfec-mcp-server.git
- 进入目录:
cd openfec-mcp-server
- 安装依赖:
bun install
- 配置环境:
cp .env.example .env
# edit .env and set FEC_API_KEY (optional)
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
FEC_API_KEY | 来自 api.data.gov 的 OpenFEC API 密钥。DEMO_KEY 每小时允许 30 次请求;自有密钥允许 1,000 次。 | DEMO_KEY |
FEC_BASE_URL | OpenFEC API 基础 URL。 | https://api.open.fec.gov/v1 |
FEC_MAX_RETRIES | API 请求失败时的重试次数。 | 3 |
FEC_REQUEST_TIMEOUT | 单次请求超时时间,单位为毫秒。 | 30000 |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式:stateless、stateful 或 auto。覆盖服务声明的 stateless 模式。 | stateless |
MCP_AUTH_MODE | 身份验证方式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(debug、info、warning、error 等)。 | info |
LOGS_DIR | 日志文件目录(仅限 Node.js)。 | <project-root>/logs |
STORAGE_PROVIDER_TYPE | 存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。 | in-memory |
OTEL_ENABLED | 启用 OpenTelemetry。 | false |
完整的可选覆盖项列表请参阅 .env.example。
运行服务
本地开发
-
构建并运行:
bun run rebuild bun run start:stdio # or start:http -
运行检查和测试:
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-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/openfec-mcp-server。默认会安装 OpenTelemetry 对等依赖;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口——注册工具、资源和提示词,并初始化 OpenFEC 服务。 |
src/config | 使用 Zod 解析并验证服务专属环境变量。 |
src/mcp-server/tools | 工具定义(*.tool.ts),共享验证器和格式化器位于 definitions/utils/。 |
src/mcp-server/resources | 资源定义(*.resource.ts)。包含候选人、委员会和三种选举竞选模板。 |
src/mcp-server/prompts | 提示词定义(*.prompt.ts)。用于资金流向和竞选分析。 |
src/services/openfec | OpenFEC API 客户端和领域类型。 |
tests/ | 单元测试和集成测试,结构与 src/ 对应。 |
scripts/ | 构建、清理、devcheck、tree、changelog 和 lint 脚本。 |
docs/ | 设计说明和 OpenFEC OpenAPI 规范。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md。简要说明如下:
- 处理程序抛出异常,由框架捕获——工具逻辑中不要使用
try/catch - 使用
ctx.log记录日志,使用ctx.state存储数据 - 在
src/mcp-server/*/definitions/index.ts的导出入口中注册新工具和资源 - 封装 OpenFEC API:验证原始数据 → 规范化为领域类型 → 返回输出模式;绝不伪造上游响应中未提供的字段
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0——详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。