mcpField
F
Flexreport Finance

Flexreport Finance

远程服务
app.flexreportfinapi.com金融数据232 天前更新

关于 Flexreport Finance

Flexreport Finance 是面向投资者和研究团队的 MCP 服务,提供实时市场事件、公司数据和研究报告。其工具结合事件流、精选金融数据集与报告生成。

主要功能

  1. 01实时市场事件流
  2. 02公司概况与事件图谱
  3. 03覆盖 2,900 多家公司的金融数据
  4. 04最新及定制研究报告
  5. 05股票筛选与财报分析

适用场景

  1. 01跟踪新发布的财报和 SEC 文件
  2. 02查看公司的最新报告及季度变化
  3. 03按基本面和技术指标筛选股票
  4. 04利用电话会记录和引文研究市场主题

MCP 相关

它将 Flexreport Finance 的市场事件、研究报告资料和金融数据作为工具提供给 MCP 客户端,支持事件订阅与流式读取,以及公司研究和报告生成。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://mcp.flexreportfinapi.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

详细介绍

flexreport-mcp

smithery badge Listed on mcpservers.org

一个独立的 MCP 微服务,可按需为 Claude(以及任何 MCP 客户端)提供对 Flexreport Finance 的实时事件、 研究报告资料和包含超过 7.5 亿个数据点的数据库的访问。

它为 AI Agent 提供实时市场事件和经过整理的黄金来源数据,涵盖基本面、电话会议文字记录、申报文件、内部人士交易(Form 3、4 和 5)、 比率、宏观数据、直接从各公司投资者关系网站获取的 IR 演示文稿等。

快速安装

将连接器添加到 Claude Code

claude mcp add --transport http flexreport https://mcp.flexreportfinapi.com/mcp

或添加到 Codex

codex mcp add flexreport --url https://mcp.flexreportfinapi.com/mcp

然后启动 Claude 并直接提问(例如 “从 flexreport 获取涨幅最大的股票”)。 首次调用数据时,MCP 客户端会在浏览器中启动 OAuth 登录流程 — 按提示登录或注册;无需粘贴令牌。添加 --scope user,即可在所有目录中使用。详情请参阅身份验证。

演示

**在终端中流式接收实时事件。**让 Claude 监控市场,事件发生时即可接收: 涨跌幅较大的股票、财报发布、8-K、IR 演示文稿和最新报告计划。每当报告计划保存后,Claude 都会呈现更新后的报告。

“关注涨跌幅最大的股票、财报发布、文字记录更新、投资者演示文稿和收盘后的 8-K 发布,并通过 Flexreport 实时接收这些事件”

“每有新事件发生时,能否检查是否有最新的报告计划,并获取更新后的报告以提供更深入的背景信息?”

Claude Code 在收盘后流式接收 Flexreport Finance 事件,并在报告计划生成后呈现报告

**打开研究报告。**每个数据都链接回生成它的查询,每个标题都链接到其来源。以下是 AAPL 的报告:

“获取最新的 AAPL flexreport 报告”

Flexreport Finance AAPL 公司深度分析报告第 1 页

打开完整的 AAPL 报告(PDF,共 13 页)

使用场景

1. 实时

1a. 流式传输(事件和实时报告)。 订阅发布的事件,包括每当报告准备就绪时触发的 report_plan 主题,然后获取渲染后的报告:“订阅 NVDA、AVGO、AMD 和 MU 的业绩发布、8-K 文件、投资者关系(IR)出版物和新报告计划。每当有新内容发布,告诉我发生了什么,检查盘中行情是否出现异常波动,并在 Flexreport Finance 报告准备就绪后获取它。”

工具:register_event_subscription → stream_event_subscription,或按需调用 stream_events,然后调用 detect_intraday_outlier_jumps 和 get_latest_report。

默认情况下,对于实时流式传输请求,会生成仪表板(在 Claude 中为 Artifact),而不是聊天记录。页面会自行运行 stream_events 循环,在每次读取时传递游标,因此一个提示词就能让数据流持续打开。如果页面无法连接到服务,Agent 会运行该循环,并将每个事件写入仪表板。如果你更喜欢上方演示中显示的终端视图,请明确要求输出聊天内容。

1b. 过去十二小时内的事件。 分析实时 SEC 8-K 文件,同时获取投资者关系演示文稿和 5 分钟 K 线数据,以便快速识别出现显著波动的股票:“最新发布的 8-K 文件有哪些?重点介绍其中最重要的文件,通过 Flexreport Finance 获取配套的投资者关系发布内容,为出现显著波动的股票绘制 5 分钟 K 线图,并说明这些信息与各公司的当前状况有何关联。我希望以表格形式呈现:8-K 摘要、公司趋势、Flexreport Finance 8-K 分析 S3 链接、IR 演示文稿链接。”

工具:situate → list_realtime_events,然后调用 get_aftermarket_data / detect_intraday_outlier_jumps 和 get_latest_report。

2. 报告

2a. 特定公司的最新报告: “获取 Snowflake 最新的 Flexreport Finance 报告,并总结本季度的变化:业绩指引、利润率,以及管理层在电话会议上提到的事项。”

工具:get_latest_report(["SNOW"])。新计划约需 10–20 秒完成渲染;对于状态为 stale 或 missing 的标的,可以使用 generate_report_for_stock 重新生成。

2b. 特定时间段内的最新报告: “过去三天,能源行业发布了哪些报告?获取最新报告,并根据相关事件的重要程度进行排序。”

工具:list_available_reports(report_date=<3 days ago>),筛选能源行业标的(list_options("sectors")、get_company_snapshot),然后对状态为 fresh 的标的调用 get_latest_report。

2c. 根据你的标准定制报告: “为我生成一份美国大型市值半导体公司的报告,筛选条件为 ROIC 高于 20%、净债务/EBITDA 低于 1 倍、股价高于 200 日 SMA 且 RSI 低于 60。展示每家公司的基本面、技术指标和最新预期修正,并按我保存的模板排版。”

工具:screen_stocks、explore_data_catalogue(比率、基本面、预期)、get_technical_indicator_data 和 get_user_template。Agent 会按照你的模板整理 PDF;使用 draft_user_template → save_user_template 创建模板。

3. 预测分析

预测即将发布财报的波动性,获取简单移动平均线、指数移动平均线和布林带数据,并生成定制投资备忘录:“预测明天即将发布财报的股票可能出现的波动,重点指出预期波动最大的股票;绘制它们的简单移动平均线、指数移动平均线和布林带;并重点说明当前最重要的基本面驱动因素,将这些内容整理成一份供团队使用的投资备忘录。”

工具:list_earnings_announcements → predict_earnings_move、get_technical_indicator_data、get_company_snapshot。

4. 研究与探索

围绕一个市场叙事开展主题研究:“AI 交易近期有所降温,主要是由于对资本支出和投资回报的担忧。我认为这种情况在 2025 年秋季之前也出现过。你能确认吗?当时有哪些因素消除了这些担忧?是管理层评论、AI 服务需求持续增长、盈利能力强劲,还是上调了指引?请使用 Flexreport Finance 编写一份深入报告。”

工具:explore_data_catalogue(电话会议记录、基本面数据、预估数据)、trace_data_sources / get_document_section(获取引用原文),或 generate_research_report(生成完整报告)。

工具

共 50 个工具,按注册工具的模块分组。客户端按 tools/__init__.py 中的导入顺序看到这些工具(situate 优先)。

情境分析与实时事件(tools/realtime_events.py)
工具后端端点功能
situate(symbols, window_days, question)GET /get-company-event-web + GET /get-event-ontology + GET /is-market-open**首次调用。**将事件网络(这家公司发生了什么)、本体(这类事件意味着什么、后续会发生什么、12h 缓存过期后其数据存放在哪里、每张表何时会刷新)和市场状态整合为当前情况,并提供按顺序排列的精确工具调用 plan、会返回空结果的调用 skip 列表,以及针对当前情境的 guidance。计划从问题所指的实时事件类型开始(situate.py 中的 EVENT_VOCABULARY 涵盖 list_options("event_types") 中的所有类型);如果问题只提到某个类别,则遍历该类别下的事件;如果没有提到任何类别,则遍历所有事件——不会使用默认类别;对于面向整个市场的“今天”问题,绝不会安排 explore_data_catalogue。逻辑位于 situate.py(纯函数;python tests/test_situate_routing.py);无需新增后端路由。公开、同步
list_realtime_events(event_type, tickers, sector, industry, market_cap)POST /get-realtime-events从 12h 缓存中提取实时事件(EPS 更新、电话会议记录、评级等);每个事件的 report_inputs(约 27 KB 的报告配置)都会被丢弃,但会保留 report_inputs_key
get_company_snapshot(symbol)GET /get-company-snapshot结构化快照:投资论点、基本面、技术指标、目标价、所有权、评级
get_company_event_web(symbol, window_days, max_nodes)GET /get-company-event-web揭示快照背后的原因——公司近期事件的图谱:按时间排序的事件/data_update 节点,包含 fetch 提示和带类型的边(same_chain_run / lineage / co_occurrence)。请将其与 get_company_snapshot 配合使用;针对单个标的调用 list_realtime_events / explore_data_catalogue / 报告工具前,也应先调用此工具
get_event_ontology(event_type, family, relation, format)GET /get-event-ontology事件网络背后的类级本体,说明某种事件类型包含什么:事件触发时写入的表(按层分类)、通常会接续发生的事件(观察到的发生率/时滞)、12h 实时缓存过期后数据存放的位置(persisted_in)、负责刷新的工作流及各关系的 next_run_at(新鲜度检查),以及读取这些数据的工具。与标的无关、公开、可缓存——对于任何事件驱动的请求,请先调用此工具,再将其与网络节点的 type / relation / family 关联起来
事件流(tools/event_subscriptions.py)

对于实时流式传输的请求,默认交付方式是一个仪表板(在 Claude 中是一个 Artifact),其页面会循环调用 stream_events 并传入游标。服务端说明和流工具的文档字符串都对此进行了说明。

工具后端端点功能
stream_events(topics, symbols, cursor, max_events, max_wait_seconds)GET /events (SSE)推送交付,临时调用。 对实时事件流进行有界读取:达到 max_events 条匹配事件或等待 max_wait_seconds(上限为 55 秒)后返回 {events, cursor, closed} — 每个事件都是 list_realtime_events 返回的同一个对象,即事件发布时的内容。可通过 topics(来自 list_options("event_types") 的事件类型或类别,以及仅限流的 report_plan 主题 — 每次保存报告计划时都会生成一个帧)和 symbols 内联筛选。服务端不保存状态:务必将返回的 cursor 传回,否则下一次调用会从“现在”开始(已认证)
register_event_subscription(topics, symbols)POST /register-subscription在服务端保存筛选条件 → {subscription_id, filter, cursor, created_at}。只会交付注册后发布的事件;请保存 ID(目前还没有列表端点)。每小时 30 次(已认证)
stream_event_subscription(subscription_id, cursor, max_events, max_wait_seconds)GET /event-subscription/{id} (SSE)可恢复的推送交付。 有界读取的形式与 stream_events 相同,但 API 会在读取结束时保存游标,因此重复调用时,每条匹配事件都会恰好出现一次,无需管理 cursor;cursor 只会为单次连接覆盖已保存的位置。closed: "subscription deleted" 表示应停止重新连接;对于不存在的 ID 和其他用户的 ID,都会返回 404(已认证)
delete_event_subscription(subscription_id)DELETE /event-subscription/{id}删除已保存的订阅;任何正在运行的订阅流都会在一个读取周期内以 closed 帧结束(已认证)
报告与 PDF 模板(tools/pdf_reports.py)
工具后端端点功能
get_latest_report(symbols)POST /get-cached-reports快速路径,适用于一个或多个指定股票代码。具有新鲜已保存计划的股票代码会进入 rendering({task_id, status, symbol}):后端会获取计划 JSON,并在约 10-20 s 内将其渲染到用户的模板中——轮询 get_task_status 获取 {"pdf": ...}。其他股票代码则返回缓存的 PDF(预签名 URL + 内联 base64,并附带 generated_at、age_hours、latest_event_at、stale),或列在 missing 中。stale: true 表示计划本身已过期——只有重建 generate_report_for_stock(ticker)(约 10 min)才能刷新。每小时 500 次
list_available_reports(event_types, report_date)POST /list-available-reports查询 report_date(YYYY-MM-DD,默认为今天)或之后生成的已保存报告计划清单(计划在 7 天内都可渲染,因此查询当前清单时请传入更早的日期——空列表表示该时间范围内没有计划,而不是没有研究)——列出每个因重大事件(eps_update、eps_release、8k_release、financials_release、ir_publication、transcript_update;company_update 每晚执行)而保存计划的股票代码,按最新时间优先排列,每项包含 event_type、planned_at、queued_at、source,以及应用与 /get-cached-reports 相同规则的 fresh 标志:true → get_latest_report([ticker]) 在约 10-20 s 内渲染,false → 只有重建 generate_report_for_stock(约 10 min)才能刷新。可通过 event_types 筛选;通过 report_date 扩大范围(日期格式错误会返回 422)。可用于检查 list_realtime_events(刚刚发布的内容)与 get_latest_report(获取内容)之间的情况,也是查看当前可用实时研究的直接方式
generate_report_for_stock(ticker, user_override, financial_items, as_reported_financial_items, ratios, revenue_segment, technical_analysis_items, estimate_items, institutional_ownership, include_as_report_financials, as_reported_periods)POST /create-full-report仅用于完整重建(约 10 min)——请谨慎使用。 标准模式(仅 ticker):重建并保存该股票代码的报告计划;只有当 get_latest_report 返回该股票代码的 stale 或 missing,且用户愿意等待时才调用——绝不要对处于 rendering 状态的股票代码调用。自定义模式(user_override=true + 定制列表):围绕用户指定的行项目、比率、按报告口径列示的概念、细分项、指标、估算值或管理者 CIK,完整生成一次报告(约 10 min,不保存);只要某个定制字段非空,该工具就会自动设置开关。对于定制需求,通常应先探索 → 构思 → 再叠加到模板中。异步返回 → {ticker: {task_id, status}}
generate_research_report(query, delivery)POST /generate-research-report深度分析(约 10-12 min,异步)——分析师级别的报告,仅在用户明确要求完整报告时使用 → {task_id, status}
download_pdf_from_url(url, file_name)POST /download-pdf-from-url在服务端获取预签名的 S3 PDF URL(带 SSRF 防护),并以内联 base64 返回——例如,供无法打开链接的客户端使用 get_latest_report 的 url(需认证)
draft_user_template(template, template_type, anchor)POST /draft-user-template用户自有 PDF 格式的第 1 步,共 2 步:将 HTML 页面编译为蓝图,提供多种处理样式,并将每种样式渲染为平台示例文档的预签名 PNG 预览——每种内容类型各一份(标题、导语、章节、项目符号、KPI 卡片、表格、图表、插图、来源行、脚注);add_on 按其在报告中的栏宽呈现,bespoke 则呈现为整页——另附 draft_id。用户确认设计如何处理每种内容类型,而不是确认示例文本。不会存储任何内容——草稿有效期为 24h(需认证,每分钟 30 次)
save_user_template(draft_id, variant_id, template, template_type, anchor)POST /save-user-template第 2 步,共 2 步:传入 draft_id + 选定的 variant_id,即可保存已审核的处理样式;或直接传入 template + template_type(+ anchor)以跳过预览(仅支持 HTML——markdown 会返回 422)。每位用户只能有一个模板——采用 upsert,保存时会替换之前的模板。返回 {status: "SAVED", template_type, anchor, bytes, patterns, tones, warnings}——包括设计所采用样式的内容类型及其语气类别(需认证,每分钟 100 次)
update_user_template(template, template_type, anchor, draft_id, variant_id)PUT /update-user-template更改已保存的模板——可更改任意字段(省略的字段保留已存储值),也可不传任何字段,以当前编译器按已存储内容重新编译。异步返回:{task_id, status: "PENDING", changed, next_step} → 轮询 get_task_status 获取 {status: "SAVED", patterns, tones, warnings}。404 = 尚未保存任何内容(请先保存);422 = 验证错误(需认证)
get_user_template()GET /get-user-template调用者已保存的模板(template_type、template_format、anchor、经清理的 template、时间戳)。404 = 未保存;503 表示后端表尚未创建,并非“未保存任何内容”。同时提供用于排版 Agent 组合生成的 PDF 的标记
delete_user_template()DELETE /delete-user-template删除已保存的模板——此操作不可撤销,PDF 将恢复为标准版式;在 WHERE 子句中强制执行所有权检查
Data exploration, citations & saved queries (tools/data_exploration.py)
工具后端端点功能
explore_data_catalogue(query)POST /data-catalogue-exploration默认路由——针对数据平台开展快速、交互式 EDA → 返回可渲染为图表/表格的结果集(仅限仪表板,每小时 20 次)→ {task_id, status}
explore_data_coverage(query)POST /data-coverage-exploration覆盖范围计数和细分——有多少标的包含某数据集(IR 演示文稿、文字记录、13F、内部人士、预估数据……),按行业板块/行业/国家/市值/年份细分,以及历史数据覆盖范围。公开访问:无需账号,因此潜在客户可以询问平台涵盖哪些内容
get_signed_sql_drilldown(encrypted_query_token, prompt, values, max_rows)GET /query-data根据 get_company_event_web 节点的 signed_query_url(或其裸 t 令牌),获取其背后的数据行——包含标记为 is_new_record: true 的新记录,以及上下文行;令牌仅由服务端生成,绝不自行构造。可选的 values(类型化槽位填充,不使用 LLM)和 prompt(自然语言,填充 values 未提供的内容)可将作为占位符孪生的令牌重新定向到其他实体;max_rows 限制返回数据量,截断的回复会附带 row_count 和 truncated: true(需认证)
trace_data_sources(relation, keys, column, encrypted_query_token, prompt, values, max_documents, resolve_passages)GET /trace-sources引用溯源——将 explore_data_catalogue / run_saved_query / get_signed_sql_drilldown 返回行中的数字追溯到其出处:文件、章节或经核实的引文。优先使用 relation + keys(所有标识列,包括期间),而非令牌
get_document_section(symbol, year, quarter, n, name)GET /query-section打开源文档中的一个编号章节——即 trace_data_sources 引用所指向的准确财报电话会议发言者轮次。从引用 URL 中读取这四个值;year / quarter 是电话会议的财年期间,而非日历季度
save_user_query(user_request, query_tokens)POST /save-user-query按用户自己的措辞保存 explore_data_catalogue 结果中不透明的 query_token,以便无需重新规划即可重放请求。返回 {msg, id, placeholder_status}——id 是删除时使用的键;PENDING 表示后端正在为每个查询编写占位符孪生,并为该行生成 metadata 槽位架构(约需 10 秒至 5 分钟),之后便可针对其他实体重新提问;NOT_DISPATCHED 表示只能精确重放(需认证,限定所有者;不执行 upsert——保存两次会创建两行,每分钟最多 100 次)
list_saved_queries(limit)GET /get-saved-queries调用者保存的请求,按时间从新到旧排列——包括 id(删除时使用)、queries(用于精确重放的令牌)、query_placeholder(与 queries 按索引对齐的孪生令牌)、user_request(用户自己的标签),以及 metadata:该行的 summary(一行说明,槽位用花括号括起)、parameters 槽位架构({name, type, description, example}——即 run_saved_query(values=…) 的键)、entities、datasets、topics、每个查询的 result_schema、stale、run_count、last_run_at。根据 metadata 匹配问题,而不是根据标签,并跳过 stale 行;占位符任务运行前,metadata 和 query_placeholder 均为 null。503 表示后端表尚未创建,而非“没有已保存内容”
run_saved_query(query_tokens, prompt, values, max_rows)GET /query-data重放已保存的请求:每个令牌都会按给定顺序针对实时数据同步运行(最多 25 个)——仅返回数据行,绝不返回 SQL;耗时为几秒,而非约 1–5 分钟的规划任务,且不占用每小时 20 次的探索额度。使用 query_placeholder 令牌时,values(以 metadata.parameters 为键确定性填充,不使用 LLM——实体集合槽位接受 [{id, name}] 行,若仅提供名称,则由服务端解析)会重新定向已保存的查询;prompt(“KSS 过去 8 个季度的销售额”)仅填充 values 未提供的内容,既未由 values 覆盖也未由 prompt 填充的槽位则保留已保存的示例。回复包含 parameters、defaulted_parameters 和 ignored_values;422 表示无法映射该请求——请改用 explore_data_catalogue。始终传入 max_rows(例如 500):不设上限时,一行的 _constituents 配套数据可能返回 7,000–35,000 行
delete_saved_query(query_id)DELETE /delete-saved-query根据 id 删除一条已保存的请求——此操作不可撤销,相关令牌也会一并删除;404 有意同时涵盖“该 id 不存在”和“该 id 不属于你”
市场数据(tools/market_data.py)
工具后端端点功能说明
get_technical_indicator_data(symbol, indicator, start_date, end_date)GET /technical-indicator-endpoint获取一个技术指标的每日历史数据(来自 list_options("technical_indicators")),日期范围为含首尾的 YYYY-MM-DD(需认证)
detect_intraday_outlier_jumps(symbol, frequency, zscore_threshold)GET /detect-intraday-outlier-jumps实时查看今日的 1 分钟行情;按 frequency(来自 list_options("intraday_frequency"))筛选;标记波动幅度属于日标准差异常值的 K 线(同步,需认证)
get_aftermarket_data(symbols, start_datetime, end_datetime)POST /get-aftermarket-data查询指定股票在 ET 日期时间范围内已存储的盘后 15 分钟 K 线(开盘价/最高价/最低价/收盘价/成交量,16:00-20:00 ET);按股票代码、K 线时间降序排列(默认为今日,需认证,每分钟 300 次)
predict_earnings_move(symbols)POST /predict-earnings-announcement-move预测各股票下一次财报发布后的预期涨跌幅(例如,NFLX 的 expected_move 为 0.10,即约 10%),并与其自身的历史平均值并列显示
list_earnings_announcements(start_date, end_date, symbols, industry, sector, market_cap)POST /list-upcoming-earnings-announcements查询指定日期范围内(起止日期默认为今日)已安排的财报发布;仅包含覆盖范围内的股票;sector / industry / market_cap 由服务端校验(无效值返回 422)
is_market_open(exchange)GET /is-market-open查询交易所当前是否开放——返回单个 is_open 布尔值(交易所代码,默认为 NYSE);根据市场状态路由至 detect_intraday_outlier_jumps(开放时)或 get_aftermarket_data(关闭时)。公开
数据源(tools/data_feeds.py)
工具后端端点功能
download_dataset(dataset, start_date, end_date, latest_file_version, bulk_download, event_types, symbols, include_page_text, document_urls, max_rows)GET /list-data-feed-options + POST /download-dataset按日期读取 Flexreport 的带版本的每日数据源文件。数据源并非硬编码:每次调用都会先读取公开目录(list_options("data_feeds")),并在开始下载前拒绝未知的 dataset 或 event_types;目录中的 returns 决定返回行还是预签名链接(有效期 12 小时);如果未请求页面文本,带有 document_url + page_number 的行会合并为每份文档一行。每位用户每周限 3 次调用,因此必须提供 start_date(明确的 ET 日期,绝不使用 API 的 UTC 默认值),工具会在单次响应中自行缩小结果范围:按 symbols / document_urls 过滤、合并页面、设置 max_rows 上限(默认 500),并返回 row_count / truncated,以及说明省略内容的 notes。获取一次并嵌入;绝不要从仪表盘轮询(需认证)
draft_custom_dataset(request, previous_draft_id, feedback, sample_rows, target_format)POST /draft-custom-dataset用户自定义定时数据集的第 1 步:根据通俗英文描述规划候选表并对每张表进行采样;target_format 为 rss/atom 时,每个数据源项目对应一行。异步执行(task_id = draft_id,通过 get_task_status 查询,约 45 秒至 4 分钟;sample_rows 为 1-5,默认 5)。对于事件/新闻数据源,Agent 会先进行调研(定位 + 本体、与用户确认定义、执行一次限定范围的探索性普查),并发送一个指出每个字段对应表和列的请求;普通数据源则直接生成草稿。默认情况下,每个数据源都会包含调研报告:构建过程会为带有 symbol / ticker 列的行添加 research_url,因此请求中无需填写报告链接;结果中的候选项带有不透明的 query_token,该令牌绝不显示,只会传递给保存步骤。使用相同的 request + previous_draft_id + feedback 进行修改。每位用户每小时限 20 次(需认证)
save_user_dataset(draft_id, query_token, dataset_name, date_mode, cron, format, build_now)POST /save-user-dataset第 2 步:保存所选候选项及其架构、格式(parquet、csv、tsv、json、jsonl、xlsx、xml、rss、atom)、日期模式(rolling 会将固定日期移至每次构建日期,snapshot 会按保存时的查询重新运行)以及任何有效的 5 字段 ET cron(每小时、每 30 分钟、范围)。发布前会由 LLM 审核新项目,每次构建最多 40 个(大型首次构建的其余项目会按查询结果发布,之后再审核;链接/GUID/股票代码/日期永不更改);rss 项目带有 <company:symbol> 和最多 10 个 <category>,每个 guid 对应一个项目。每个带有 symbol / ticker 的行都会获得 research_url,这是指向该股票代码最新调研报告 PDF 的固定签名链接(/user-dataset-research/<token>/<SYMBOL>,无需登录),在 rss/atom 项目中显示为“Research”链接。按名称执行 upsert;计划会以 ds:{email}:{name} 的形式显示在 list_scheduled_tasks 中。返回 latest_url(指向最新文件的固定免登录链接)以及 rss/atom 的 feed_fields。最多 5 个数据集;与工作流共用 10 个计划(需认证)
list_user_datasets(dataset_name, start_date, end_date, latest_only)GET /list-user-datasets用户的数据集,包含最近一次构建状态(written / unchanged / empty / too_large / schema_drift / failed)以及指向每次构建文件的 12 小时预签名链接——交给用户,不要获取文件(需认证)
get_user_dataset_file(dataset_name, version)GET /list-user-datasets + latest_url 中的文件(或某个日期版本的预签名链接)读取用户已发布的一个数据集并返回其行(json、jsonl、csv、tsv、xml,或带有类别、股票代码和 research_url 的 rss/atom 项目)。仪表盘应以此读取数据集,而不是重放其已保存的查询;文件会在响应大小上限内由服务器端获取,不使用 bearer(链接本身就是密钥)(需认证)
delete_user_data_feed(dataset_name)DELETE /delete-user-data-feed完全移除用户的一个数据集:计划、文件、固定链接和已保存的查询。此操作不可撤销,因此 Agent 会先确认;遇到 503 时可安全重试(需认证)
筛选、投资组合与策略(tools/strategies.py)
工具后端端点功能
screen_stocks(metrics, sectors, sub_sectors, market_cap, analyst_ratings, institutional_ownership, countries, price_performance)POST /screen-stocks按增长指标、行业/子行业、市值、分析师评级、机构持仓、国家和价格表现筛选股票范围。异步 → {task_id}(每小时 10 次)
optimize_portfolio_default(symbols, risk_tolerance)POST /optimize-symbols-non-llm默认优化器——为股票代码列表计算经过风险优化的权重;同步执行,不使用 LLM;不支持的股票代码列于 missing,历史数据较短的列于 dropped。公开
optimize_portfolio(symbols, risk_tolerance, delivery)POST /optimize-symbols速度较慢的 LLM 筛选版本:多信号评分 + LLM 筛选 + 风险优化。异步 → {task_id}(每小时 10 次)
get_stock_picks(strategy_name)GET /get-stock-picks获取当前再平衡周期中最新的 LLM 选股结果(可选指定一个策略)
get_strategy_performance_summary(amount)GET /get-strategy-performance-summary展示自成立以来每个策略组合与 S&P 500 的排行榜(回报、超额回报、夏普比率、回撤、年初至今表现、amount 的增长)——了解“这些选股表现如何?”的首选入口
get_strategy_track_record(strategy_name, book, amount)GET /get-strategy-track-record展示单个组合自成立以来的每日表现序列及与 S&P 500 的对比,以及关键统计数据;book = llm(默认)或 mechanical,strategy_name 可以是 pooled
get_strategy_swaps(strategy_name)GET /get-strategy-swaps按交易记录每周的加入/移除项,并分别与 S&P 500 对比(移除项按错失的回报计算)
调度(tools/scheduling.py)
工具后端端点功能
schedule_task(name, steps, regular_cron, delivery, description)POST /save-user-workflow保存一个包含 1–8 个步骤的工作流(fetch 允许列表中的端点 + transform 步骤),并附加定期 cron 投递;按小写连字符格式的 name 执行插入或更新
list_scheduled_tasks()GET /get-scheduled-tasks调用者的 cron 作业(name、schedule、enabled、last_run_at、total_run_count);工作流作业的名称格式为 wf:{email}:{workflow-name}
delete_scheduled_task(task_name)DELETE /delete-scheduled-task按 list_scheduled_tasks 返回的完整 name 删除 cron 作业;保留已保存的工作流定义
实用工具与计费(tools/utility.py)
工具后端端点功能说明
get_task_status(task_id)GET /task-status轮询异步任务,直至状态变为 SUCCESS,并读取其 result。超过 8 MB(MCP_MAX_TASK_RESULT_BYTES)的结果将被拒绝,并返回“请缩小查询范围”错误;在 _send 中,其他所有后端响应的大小上限均为 16 MB(MCP_MAX_RESPONSE_BYTES)
list_options(kind, ticker, q, cik)GET /list-realtime-event-options、/list-financial-items、/list-financial-ratios、/list-as-reported-items?ticker=、/list-revenue-segments?ticker=、/list-institutional-managers?q=&cik=、/get-sectors、/list-institutional-investor-types、/list-countries、/get-fiscal-quarter、/list-marketcap-options、/list-intraday-chart-options、/list-technical-indicators、/list-tickers、/list-symbols-with-names、/list-data-feed-options一个目录工具:列出某个参数的有效值(事件类型、明细项目、比率、申报方自己的 as-reported XBRL 概念和营收细分(ticker)、按名称片段 / CIK 查找机构管理人(q / cik)、行业板块、投资者类型、国家、财年季度、市值区间、日内频率、技术指标、带或不带公司名称的股票代码全集,以及 download_dataset 数据源)
list_sub_industries(sectors)GET /get-sub-industries给定行业板块中的不同细分行业
onboard_symbol(symbol)POST /onboard-symbol请求接入尚未覆盖的股票代码(异步、需认证,每小时 5 次)
upgrade_plan()GET /payment/upgrade-link用于升级或更改用户套餐的结账链接(例如,达到配额上限后);付款在浏览器中完成
manage_billing()GET /payment/portal-linkStripe 账单门户链接 — 发票、银行卡、取消订阅

对于单家指定公司,get_company_snapshot 和 get_company_event_web 是标准组合——它们是同一个问题的两个部分,通常会一起调用。快照说明是什么(公司当前的状况:投资论点、基本面、技术面、持仓、评级);事件关系网说明为什么(背后的事件经过:业绩公布 → 8-K → 电话会议记录更新 → 投资者关系部门发布内容 → 分析师反应,并通过边说明各事件之间的关系)。单独的快照只是没有证据支撑的结论;事件关系网则提供了证据。事件关系网也是成本低廉的依据调用,能让后续工作流更加精准——每个节点都附带确切的后续调用,因此接下来的 list_realtime_events、explore_data_catalogue 或报告请求都能使用真实的事件类型和日期,而不是猜测。

典型 Agent 工作流:对于开放式 / 探索性问题,默认使用 explore_data_catalogue(query)(快速交互式图表 / 表格)。仅在意图非常明确时才升级调用——对于指定股票代码的现有报告,使用 get_latest_report(symbols);要筛选整个股票全集,使用 screen_stocks(...);要进行明确的深度研究,使用 generate_research_report(query)(约需 10–12 分钟,异步——使用 get_task_status 进行轮询)。 重复问了同一个问题——还是问了关于另一家公司的同一个问题?explore_data_catalogue 每次都会重新规划 SQL,因此一次探索完成后,Agent 会提出保存结果:save_user_query 会存储其 query_token,后端则为每个查询创建一个占位符孪生查询——将股票代码、CIK 列表、日期、间隔和数量提取为类型化槽位——并保存该行的 metadata,其中会命名这些槽位并概述该行查询的内容。run_saved_query 随后会原样重放该行的 queries(使用实时数据运行相同查询,几秒内完成,无需规划步骤,也无需轮询),或者使用该行的 query_placeholder 令牌和类型化的 values,将请求重新指向其他实体——昨天保存的“TGT 最近 8 个季度的销售额”,今天便能确定性地回答“KSS 最近 8 个季度的销售额”,填充过程不使用大模型;替换后的 parameters(以及任何 defaulted_parameters / ignored_values)会与结果行一并返回;prompt 仍可用于处理 Agent 无法填入的内容。每次探索前都应先检查 list_saved_queries,它会将问题与每行的 metadata——summary、parameters、datasets——进行匹配,而不是与其 user_request 标签匹配,并跳过标记为 stale 的行;delete_saved_query 可清除其中一行。每次重放都要传入 max_rows,并根据 metadata.result_schema 选择要运行的查询,这样 _constituents 配套查询(7,000–35,000 行)就不会被纳入调用。令牌是后端生成的不透明密文:原样传递,绝不要自行构造或编辑,也绝不要向用户展示。

想要使用自己的格式生成报告?用户提供一个 HTML 页面——包括页眉、颜色、布局和品牌元素——并将其保存为蓝图:作者的样式表和页面框架,加上每种内容类型对应的一种标记模式;后端会自动将其应用于为该用户生成的每份 PDF(get_latest_report 对新计划的渲染、generate_report_for_stock 的重建版本、标准版和自定义版,以及定期报告)。模板是应用于文档自身内容的结构和样式:没有人会填充模板标记,也不会有其他调用来修改它。这是视觉选择,因此需要通过查看来批准:draft_user_template 会使用多种处理方式编译页面,并将每种处理方式渲染为平台样本文档的 PNG 预览(add_on 会按 anchor 指定的名称重新设置标准布局中某个部分的样式;bespoke 则控制整个文档);用户选定一种后,save_user_template(draft_id, variant_id) 会保存该样式——每位用户只有一个模板,采用 upsert 方式保存。update_user_template 可在之后修改任何字段,或者在不带参数调用时重新编译已保存的设计;get_user_template 会显示当前生效的模板;delete_user_template 会让用户恢复使用标准布局。

没有由 Agent 驱动的 PDF 构建器:build_pdf_full_width / build_pdf_sidebar 工具(后端 /create-pdf 和 /create-pdf-sidebar)以及 pdf_options 目录已弃用,改用模板。当用户想要一份由 Flexreport Finance 数据组成、且没有后端报告覆盖的文档时——包括定制的公司报告(例如“以产品收入和 RPO 为核心构建的 SNOW 报告”)——Agent 会探索用户指定的条目,与用户一起构思并完善结果集,再使用自己的文档工具构建 PDF;如果用户已保存模板,则将商定的结果叠加到该模板中(get_user_template);如果没有模板,则提议起草一个(起草 → 预览 → 保存,然后更新)。

报告按需生成:只有有人提出请求时才会重新生成。两个报告端点严格分开:

  • get_latest_report → /get-cached-reports 是快速路径。 已保存的报告计划是 JSON,包含摘要、查询、结果和格式映射;当某个标的发布重大事件时(或通过重建),系统会立即生成该计划,并在其输入持续变化期间每晚刷新。当某个标的的计划新鲜(有格式映射、生成时间不到 7 天、不早于该标的最新报告输入,且读取 EDGAR/FMP 数据分流的正确一侧)时,端点不会返回预先生成的 PDF:它会在约 10-20 秒内将该计划渲染到用户的模板中,并在 rendering 下列出该标的,同时提供用于轮询的 task_id。其他标的则会以缓存的 PDF 返回,并标记为 stale(true = 计划本身已过时,即之后出现了财报、文件提交或 13F 刷新),或者归入 missing。
  • generate_report_for_stock → /create-full-report 是完整重建(约 10 分钟),应谨慎使用。 只有当 get_latest_report 将该标的返回为 stale 或 missing,且用户愿意等待时,Agent 才会仅使用股票代码调用它;重建后的计划会被保存,因此之后调用 get_latest_report 时,只需几秒即可渲染。绝不用于处于 rendering 状态的标的,也绝不对列表中的多个标的批量调用。
  • 定制请求应通过探索完成,而非重建。 Agent 会探索用户指定的项目(先调用 list_saved_queries,再调用 explore_data_catalogue),与用户一起构思如何使用结果集,并通过自有的文档工具将双方确认的结果叠加到用户的模板(get_user_template)中。

list_available_reports(event_types, report_date) 用于盘点已保存的计划,范围限定为在 report_date 当天或之后生成的计划(默认值为今天)——显示哪些标的已准备好实时研究,以及每个计划是新鲜的(get_latest_report 可在几秒内完成渲染)还是需要重建(需几分钟)——这样 Agent 就能从 list_realtime_events(事件已发布)直接获取新鲜报告,而不必猜测;也可以跳过事件步骤,直接列出当前可用的报告。对于“提取今天最相关的报告”,应先用事件筛选,再检查计划是否可用:提取重大事件类型(transcript_update、8k_release、ir_publication、eps_release、financials_release)和市场行情(biggest_mover、biggest_loser),读取内容,通过 detect_intraday_outlier_jumps 根据日内价格走势确认重要性,将符合条件的事件与计划通过 list_available_reports(event_types=[...]) 匹配,然后仅通过 get_latest_report 提取匹配的报告。每当市场范围的计划出现此建议时,situate 都会显示该建议;如果 12 小时实时窗口在更早的 UTC 日期开启,还会附带 report_date。只有当用户明确要求围绕指定项目重建流水线自身的报告时,才会生成自定义报告——设置 user_override=true,并提供塑形列表(financial_items、ratios、as_reported_financial_items、revenue_segment、technical_analysis_items、estimate_items、机构持仓 institutional_ownership CIK,以及 include_as_report_financials / as_reported_periods)——这是一次完整构建(约 10 分钟),且绝不会保存。若未设置开关却提供了塑形列表,后端会拒绝请求(422),因此只要塑形字段非空,工具就会设置该开关。可用词汇表来自 list_options:financial_items、financial_ratios、technical_indicators,以及按股票代码限定的 as_reported_items / revenue_segments 和按 q 限定的 institutional_managers(返回 CIK)。事件上下文由服务端管理——请求中不包含论点、变更摘要、include_* 或价格日期字段。

代码布局

server.py            entrypoint: imports the tools package, adds /health, runs the transport
core.py              the FastMCP instance, server instructions and `_send` (backend forwarding)
client.py            shared httpx client + inbound-bearer forwarding
auth_verifier.py     OAuth resource-server token validation (RS256 via the backend JWKS)
situate.py           pure composition logic behind the `situate` tool
instructions.json    server instructions (non-code copy)
tools/
  realtime_events.py     situate, list_realtime_events, company snapshot / event web, event ontology
  event_subscriptions.py stream_events, register / stream / delete_event_subscription (SSE bounded reads)
  pdf_reports.py         get_latest_report, list_available_reports, generate_*, download_pdf_from_url, PDF templates
  data_exploration.py    explore_data_*, signed drilldowns, trace_data_sources, document sections, saved queries
  utility.py             get_task_status, list_options, list_sub_industries, onboard_symbol, billing
  market_data.py         technical indicators, intraday outliers, after-hours bars, earnings calendar + move prediction, market status
  data_feeds.py          download_dataset (versioned daily feed files), user datasets (draft / save / list / delete)
  strategies.py          screen_stocks, portfolio optimization, stock picks, strategy track records
  scheduling.py          schedule / list / delete scheduled tasks

每个模块都会执行 from core import mcp, _send,并通过 @mcp.tool(...) 注册;导入 tools 会注册所有工具。tools/__init__.py 固定了导入顺序,这也是向客户端展示工具的顺序(situate 排在最前)。

本地运行

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env          # set API_BASE_URL, MCP_HOST, MCP_PORT
set -a && source .env && set +a
python server.py              # serves streamable-http on http://MCP_HOST:MCP_PORT/mcp

身份验证

该服务器是一个OAuth 2.0 资源服务器,并且是无状态的(适合负载均衡),因此每次调用都会携带身份验证信息。它不保存凭据,也不保存签名密钥——它会验证传入的 Bearer 令牌,并将其转发给后端,由后端执行范围、套餐和配额检查。

工作原理

登录采用标准的浏览器授权码 + PKCE流程,由你的 MCP 客户端(例如 Claude)通过 Flexreport Finance 后端(即授权服务器)执行。你可以使用电子邮件和密码注册或登录,也可以使用 Google Sign-In——无需粘贴或输入令牌:

  1. 收到不含有效令牌的请求时,服务器会返回 401 和 WWW-Authenticate 挑战,并在 /.well-known/oauth-protected-resource 提供受保护资源元数据,指引客户端访问后端 AS。
  2. 客户端会打开浏览器;你登录并同意授权后,客户端会收到由后端签发的 RS256 访问令牌。
  3. 服务器会在每次调用时验证该令牌——通过后端的 JWKS(RS256 公钥)验证签名,并验证 aud、iss 和 exp——然后将令牌转发给后端。令牌无效或已过期时,服务器会返回明确的 401,客户端会重新执行此流程。

服务器永远不会看到你的密码,也不会持有签名密钥——它始终是一个不持有凭据的代理。只接受有效的 RS256 OAuth 令牌;不支持密码或静态 JWT 回退方式。

配置(环境变量)
变量默认值用途
OAUTH_ISSUERhttps://app.flexreportfinapi.com预期令牌的 iss,以及公布的授权服务器。必须与后端的 iss 一致——生产环境使用根域名 https://flexreportfinapi.com。
OAUTH_AUDIENCE= OAUTH_ISSUER预期令牌的 aud。将两端都设为规范 MCP URL,以实现真正的受众绑定。
OAUTH_JWKS_URL{issuer}/.well-known/jwks.json获取公钥的地址(与签发者解耦,以适应容器网络)。
MCP_RESOURCE_URLhttps://mcp.flexreportfinapi.com/mcp此服务器的规范资源标识符(PRM resource)。
静态请求头

在 MCP 客户端中配置 Authorization: Bearer <OAuth access token>,服务器会像处理其他调用一样验证并转发令牌——适用于使用其他位置签发的令牌进行测试。令牌不会持久化存储;每次调用时都会转发。

接入 MCP 客户端

.mcp.json(Claude Code):

{
  "mcpServers": {
    "flexreport": {
      "type": "http",
      "url": "http://localhost:8000/mcp",
      "headers": { "Authorization": "Bearer <YOUR_OAUTH_ACCESS_TOKEN>" }
    }
  }
}

使用 MCP Inspector 验证

npx @modelcontextprotocol/inspector
# Connect to http://localhost:8000/mcp with header Authorization: Bearer <OAuth access token>
# Confirm the tools list loads (46 tools), then exercise:
#   list_realtime_events("eps_update")        -> events (or [])
#   get_company_event_web("NVDA")             -> event graph (or an empty/degraded web)
#   get_latest_report(["AAPL"])               -> rendering task_id, cached PDF url, or missing  [named-ticker report; max 100 symbols]
#   list_available_reports(["eps_release"])   -> plans built today with `fresh` flags (or []); report_date="YYYY-MM-DD" widens
#   explore_data_catalogue("MU EPS growth last 8 quarters")  -> task_id  [default exploratory route]
#   get_task_status(task_id)                  -> eventually SUCCESS
# Negative: connect with no/invalid token     -> 401 + WWW-Authenticate challenge

部署

构建镜像并将其作为独立容器运行(例如,使用独立任务定义的单独 ECS 服务),与 API 和 Celery 工作进程分开。将 API_BASE_URL 设置为已部署的后端 URL。

docker build -t flexreport-mcp .
docker run -p 8000:8000 -e API_BASE_URL=https://flexreportfinapi.com flexreport-mcp

隐私

Flexreport Finance 的隐私政策——包括收集的信息、保留期限和涉及的第三方——已发布于 app.flexreportfinapi.com/privacy (来源:PRIVACY.md)。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。