Skip to main content
Glama
Mars-0310

morning-brief-mcp

by Mars-0310
README.md
# Morning Brief MCP

独立、确定性的 A 股晨报服务。它不依赖 AlphaAgent、XQ、内部数据库或 LLM Key,
通过标准 MCP stdio transport 暴露现有 `MorningBriefService`,同时保留普通 Python
调用方式。

## 功能

服务暴露 4 个 MCP tools:

- `generate_morning_brief(target_date=None, output_format="json"|"markdown")`:生成完整晨报。
- `get_morning_news(target_date=None, categories=None, limit_per_category=5)`:返回完成窗口过滤、去重、聚类、分类和相关性排序后的事件。
- `get_previous_close_context(target_date=None)`:返回该晨报对应的上一交易日 A 股市场背景。
- `get_news_coverage(target_date=None)`:返回新闻 provider 状态、角色、指标和覆盖情况,不包含原始 payload 或认证信息。

所有 tool 都面向确认的 A 股目标交易日,结果是确定性的来源证据整理,不构成投资建议。

## 环境与安装

- Python 3.11+
- MCP Python SDK `>=2.0.0,<3`(当前验收稳定版:2.0.0)
- `HITHINK_FINANCE_API_KEY`(用于交易日历和上一交易日市场背景)

晨报新闻直接来自国内公开财经 Web provider,不需要 Brave Key。不要提交真实 `.env`:

```powershell
$env:HITHINK_FINANCE_API_KEY="your-key"
```

```bash
python -m venv .venv
# Windows
.venv\Scripts\python -m pip install -e ".[test]"
# macOS/Linux
.venv/bin/python -m pip install -e ".[test]"
```

## 普通 Python 调用

```python
from morning_brief_mcp.renderers.markdown import render_markdown
from morning_brief_mcp.services.morning_brief import MorningBriefService

service = MorningBriefService()
try:
    report = service.generate("2026-08-17")
    markdown = render_markdown(report)
finally:
    service.close()
```

## MCP stdio 启动

安装后直接启动:

```bash
morning-brief-mcp
```

也可使用通用的 `command + args + env` 客户端配置:

```json
{
  "mcpServers": {
    "morning-brief-mcp": {
      "command": "python",
      "args": ["-m", "morning_brief_mcp.server"],
      "env": {
        "HITHINK_FINANCE_API_KEY": "${HITHINK_FINANCE_API_KEY}"
      }
    }
  }
}
```

`target_date` 必须严格使用 `YYYY-MM-DD`。省略时使用 `Asia/Shanghai` 当前日期,
随后仍由 HiThink 交易日历验证;非交易日返回 `target_not_trading_day`,不会静默改日。

日期、参数、配置和上游错误分别返回稳定的 `invalid_request`、
`target_not_trading_day`、`provider_unavailable` 或 `upstream_error` 结构。业务报告的
`status="partial"` 仍是成功的 tool result,例如单个新闻源失败但其他数据足以生成晨报。
stdio server 不向 stdout 打印调试信息;stdout 仅承载 MCP protocol。

## 数据架构

新闻发现默认直接访问国内财经站点的公开 Web 接口:

| Provider | 角色 | 历史能力 | Tier |
| --- | --- | --- | --- |
| 财联社 CLS | primary | `primary_full_window`(`last_time`) | 2 |
| 东方财富 7×24 | primary | `primary_full_window`(`sortEnd`) | 2 |
| 华尔街见闻 | primary | `primary_full_window`(响应 `next_cursor`) | 2 |
| 金十 | supplemental | `supplemental_latest` | 2 |
| MKTNews | supplemental | `supplemental_latest` | 3 |
| 东方财富个股新闻 | supplemental | `supplemental_security`,严格限制标的数 | 2 |
| 巨潮公告 | supplemental | `supplemental_security`,严格限制标的数 | 1 |

只要至少两个不同 upstream domain 的 primary provider 实际翻页到
`news_window.start`,本轮就不会调用 GDELT。只有完整窗口覆盖不足时才使用 GDELT
作为最后 fallback;latest-only 成功不会被计为完整窗口覆盖。

HiThink 只负责交易日历、上一交易日和 previous-close 市场背景,不参与新闻发现。

## 新闻窗口与流水线

晨报窗口固定为上一交易日 `15:00` 到目标交易日 `08:30`,时区为
`Asia/Shanghai`,两个边界均包含。所有 provider 先映射到统一字段:

`id`、`title`、`url`、`canonical_url`、`source`、`domain`、
`published_at`、`description`、`language`、`category`、`tags`、
`source_tier`、`provider`、`raw_source_id`。

之后继续走已有 deterministic pipeline:

`exact time filter → canonicalize → dedup/event cluster → classify → relevance → today_watch`

同一事件的多源报道只展示一个 cluster,并保留 `related_sources` 与
`related_count`。代表项按 Tier、时间和信息完整度确定。description 只保存上游
真实 brief/summary/content snippet/hover,不做程序扩写。

## 限流、失败隔离与安全

每个 domain 共享一个 HTTP session 和 rate limiter。请求具有 timeout、有界重试、
`Retry-After`、指数退避和抖动。东方财富默认串行且最小间隔 1 秒。单一 provider
失败只记录其 status、warning 和 metrics,不会阻断其他 provider。

分页均受 `DOMESTIC_MAX_PAGES` 与 `DOMESTIC_MAX_ITEMS` 限制。每个 provider
记录页数、原始条数、最老时间、停止原因以及 HTTP request/429/403/retry 计数。

API Key 只从环境变量读取;它不会成为 tool 参数,也不会出现在 tool description、
日志、schema 或 MCP result 中。诊断 tool 不返回请求 Header、完整 upstream payload、
预签名 URL 或内部 secret。

## 测试与真实 smoke

默认测试完全离线,所有 HTTP 行为均使用 fixtures/MockTransport:

```bash
PYTHONPATH=src python -m pytest
```

配置 HiThink Key 后,可用官方 MCP Python client 运行真实子进程 smoke,并对比
Service 与 MCP 关键字段:

```bash
python scripts/stdio_smoke.py
```

## 内容与许可说明

这些 provider 使用公开 Web 接口,仅用于数据发现和链接聚合。开源实现许可证不
等于上游新闻内容许可证;生产或商业部署前,使用者必须自行确认各上游服务条款、
抓取政策和内容使用许可。参考实现与许可证记录见
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md)。

> 本服务用于市场信息整理和研究,不构成投资建议。

## License

本项目采用 Apache License 2.0,详见 [LICENSE](LICENSE)。

第三方代码参考与归属说明见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a distinct role: generating the brief, fetching news events, retrieving previous-close context, and diagnosing news coverage. No two tools appear to target the same resource or action.

Naming Consistency4/5

Three tools follow a clear get_<noun> pattern, while generate_morning_brief uses a different verb. The deviation is minor and the names remain predictable and readable.

Tool Count5/5

Four tools is well-scoped for a focused morning-brief server. Each tool serves a clear purpose in the brief-generation workflow without unnecessary overlap.

Completeness5/5

The server covers the full workflow: generating the brief, retrieving source news, retrieving market context, and diagnosing coverage issues. There are no obvious dead ends or missing operations for its stated purpose.

Maintenance

ActivitySlowing
ResponsivenessNo issues