Skip to main content
Glama
shadowinlife

NanoSearchMCP

by shadowinlife

NanoSearchMCP

NanoSearchMCP 是一个通用网页搜索与结构化文本检索 MCP 服务。

核心能力包括:通用网页搜索(百炼 WebSearch)、任意页面正文抓取(Playwright)、以及中国 A 股数据源接入(新浪财经定期报告、临时公告、行业研报、监管处罚、投资者关系活动记录)。

在当前仓库中的定位

  • 子模块目录:nano-search-mcp/

  • 主要用途:为仓库内其他技能模块提供通用搜索与结构化数据抓取能力

  • 注意:这是 MCP 服务包,不是单个 SKILL.md 技能目录

  • 上游/下游关系:

    • 上游数据底座:tushare-duckdb-sync(提供结构化指标,不直接依赖本模块)

    • 下游消费者:2min-company-analysis 等需要外部数据接入的技能模块

在当前 mono-repo 中推荐安装方式:

conda activate legonanobot
cd nano-search-mcp
pip install -e ".[dev]"
playwright install chromium

项目现在只保留 MCP 交付面,假设所有工具调用都可以在一次 HTTP 请求超时内完成;不再提供异步任务提交、轮询、归档和任务持久化恢复这套额外 API。

Related MCP server: AgentSkills MCP

工具一览

服务按能力域提供 12 个 MCP 工具(详细参数 / 返回结构见各工具 docstring):

能力域

工具

说明

通用检索

search

百炼 WebSearch 网页搜索,返回 [{title, url, snippet}]

通用检索

fetch_page

抓取任意 URL 正文(Markdown),带 SSRF 防护 + Playwright 渲染

通用检索

search_with_template

基于预置主题模板或自由查询的 WebSearch 检索,支持 context 变量填充

标的解析

resolve_instrument

解析股票/指数/ETF/港股/美股代码或名称,返回标准化代码信息

定期报告

get_company_report

指定年份年报 / 半年报 / 一季报 / 三季报全文(新浪财经)

临时公告

list_announcements

A 股临时公告列表,支持按 ann_type 过滤

临时公告

get_announcement_text

单条公告正文

行业研报

list_industry_reports

券商行业研报列表,支持 ts_code 自动路由至申万二级行业

行业研报

get_report_text

单条研报正文

监管处罚

list_regulatory_penalties

公司违规处理 / 监管处罚记录

投资者关系

list_ir_meetings

机构调研 / 业绩说明会等 IR 活动列表

投资者关系

get_ir_meeting_text

单条 IR 纪要正文 + 参会机构名单

金融标的解析

resolve_instrument 工具支持多种输入格式,自动识别并返回标准化代码信息:

  • A 股代码: "300750", "300750.SZ", "sz300750"

  • A 股名称: "宁德时代"

  • 拼音缩写: "NDSD"

  • 历史名称: "藏格控股" → 解析为当前代码

  • 指数: "000001.SH", "沪深300", "上证指数"

  • ETF: "510300.SH"

  • 港股: "00700.HK"

  • 美股: "AAPL", "TSLA"

A 股和指数通过本地 DuckDB 离线解析(快速、无需网络);港股/美股通过格式识别返回标准化代码。

所有 A 股工具(list_announcements, get_company_report 等)均支持 code 参数,可直接传入名称或任意格式代码,自动解析为标准 ts_code

错误契约:除 search / get_company_report 会在参数非法或网络彻底失败时抛异常外, 其余工具在失败时统一返回 {source: "unavailable", error, fetch_time} 字典。

安全基线

  • 所有域名构造均采用白名单校验(新浪财经),防止 URL 注入

  • fetch_page 拒绝 file://、loopback、RFC1918 私网、云元数据端点等 SSRF 向量

  • HTTP 层均有指数退避重试 + 请求限频

环境要求

  • Python 3.10+

  • conda 环境:legonanobot

  • Playwright Chromium 浏览器

安装

conda activate legonanobot
pip install -e ".[dev]"
playwright install chromium

如果只需要作为普通依赖安装,也可以使用:

conda activate legonanobot
pip install .
playwright install chromium

安装完成后,既可以把它当作命令行 MCP 服务启动,也可以在 Python 代码中直接导入包内对象。

启动方式

启动 MCP Server

conda activate legonanobot
nano-search-mcp

默认通过 streamable HTTP 方式监听 http://127.0.0.1:8000/mcp

如果需要本地直连或被支持 stdio 的 MCP Client 直接拉起,可以切换到 stdio transport:

conda activate legonanobot
nano-search-mcp --transport stdio

等价写法:

conda activate legonanobot
python -m nano_search_mcp --transport stdio

如果你的 MCP Client、网关或反向代理有请求超时限制,需要把超时时间设到足够覆盖最慢的一次 fetch_pageget_company_report 调用。

配置

服务支持四层配置源,优先级从高到低:

优先级

来源

说明

1

CLI 参数

--transport, --host, --port, --config

2

YAML 配置文件

通过 --config 指定或按默认路径自动发现

3

环境变量

NANO_SEARCH_MCP_{SECTION}_{FIELD}(大写下划线)

4

内置默认值

代码中的 dataclass 默认值,零配置即可启动

配置文件

生成示例配置文件:

nano-search-mcp --generate-config > config.yaml

配置文件自动查找顺序(未指定 --config 时):

  1. ./config.yaml

  2. ./nano-search-mcp.yaml

  3. ~/.config/nano-search-mcp/config.yaml

完整配置结构见 config.example.yaml。主要配置段:

api:
  dashscope_api_key: "sk-xxx"       # 百炼 API 密钥(推荐用环境变量)
  bailian_websearch_endpoint: "..."  # 百炼 WebSearch MCP 端点
  bailian_mcp_timeout: 30.0          # HTTP 请求超时(秒)

server:
  transport: "streamable-http"       # streamable-http 或 stdio
  host: "0.0.0.0"
  port: 8000

http:
  max_retries: 3                     # 网络请求最大重试次数
  backoff_base: 2.0                  # 指数退避基数(秒)
  request_interval: 1.0              # 相邻请求最小间隔(秒)

cache:
  cache_dir: "~/.cache/nano_search_mcp"  # 缓存根目录(支持 ~)
  list_cache_ttl: 3600                   # 列表页缓存 TTL(秒)
  detail_cache_ttl: 604800               # 详情页缓存 TTL(秒)

fetch:
  playwright_wait_ms: 2000           # 渲染后额外等待(毫秒)
  max_content_length: 500000         # 正文最大字符数

announcements:
  max_pages: 10                      # 公告列表最多翻页数

industry_reports:
  max_pages: 5

ir_meetings:
  max_pages: 20

环境变量

两种命名格式均受支持:

新格式(推荐):NANO_SEARCH_MCP_{SECTION}_{FIELD}

export NANO_SEARCH_MCP_API_DASHSCOPE_API_KEY="sk-xxx"
export NANO_SEARCH_MCP_HTTP_MAX_RETRIES=5
export NANO_SEARCH_MCP_CACHE_CACHE_DIR="/tmp/mcp_cache"

旧格式(向后兼容):

export DASHSCOPE_API_KEY="sk-xxx"
export BAILIAN_WEBSEARCH_ENDPOINT="https://..."
export BAILIAN_MCP_TIMEOUT=60

CLI 参数

nano-search-mcp --help

# 指定配置文件
nano-search-mcp --config /path/to/config.yaml

# 覆盖服务参数
nano-search-mcp --transport stdio
nano-search-mcp --host 127.0.0.1 --port 9000

作为 Python 包导入

项目本身是标准 Python 包,可以直接安装并导入:

import nano_search_mcp
from nano_search_mcp.server import mcp
from nano_search_mcp.api import app

print(nano_search_mcp.__version__)

当前更适合将其作为“可安装的 MCP 服务包”复用:

  • nano_search_mcp.server:mcp:标准 MCP 服务对象

  • nano_search_mcp.api:app:streamable HTTP ASGI app

  • nano_search_mcp.__main__:main:命令行入口

如果你的目标是把它当作稳定 SDK 直接调用内部抓取函数,建议优先通过 MCP 工具接口或 mcp / app 进行集成;tools/ 下模块目前主要按服务注册组织,而不是按独立 SDK API 设计。

MCP 调用示例

获取指定年份定期报告

调用 get_company_report 时,调用方必须显式提供 yearreport_type 默认为 annual(年报),semi 表示半年报/中报,q1 表示一季报,q3 表示三季报,也支持这些中文别名。不支持“最近一期”“最新报告”这类含糊输入。

示例参数:

get_company_report(
  stockid="300750",
  year=2023,
)

get_company_report(
  stockid="300750",
  year=2023,
  report_type="q1",
)

返回内容为 3007502023 年的中文完整版年报、半年报、一季报或三季报正文;如果该年份不存在对应报告,工具会明确报错。

典型调用流程

对定期报告场景,上层 Agent 一般会按下面的 MCP 调用顺序工作:

  1. 在调用侧先明确目标年份,例如 202320242025

  2. 如果还没有报告列表页 URL,先调用 search 搜索,例如:新浪财经 宁德时代 年报 site:sina.com.cn

  3. fetch_page 抓取报告列表页正文,提取每个条目的详情页或 PDF 链接。

  4. 如果目标是“直接获取某家公司某一年的定期报告正文”,优先调用 get_company_report(stockid=..., year=..., report_type=...)

  5. 针对后续详情页或 PDF 链接继续调用 fetch_page,或进入 PDF 下载与解析流程。

  6. 将解析结果与本地链接仓库、缓存仓库关联保存。

测试

当前覆盖 MCP 工具层和关键抓取路径的单测,覆盖范围:

  • MCP 服务启动与工具注册(契约断言)

  • 各工具的参数校验、URL 构造、解析、缓存、错误路径

  • fetch_page 的 SSRF 防护专项测试

  • 新浪定期报告 / 公告 / 行业研报 / IR 纪要 / 监管处罚等数据源接入

运行测试:

conda activate legonanobot
pytest

测试文件位于 tests/ 目录。

目录结构

config.example.yaml          示例配置文件(可复制为 config.yaml 直接使用)
src/nano_search_mcp/
  config.py       集中式配置管理(四层优先级合并)
  api.py          标准 MCP HTTP app 兼容入口
  server.py       MCP Server 入口(注册 12 个工具 + CLI 解析)
  tools/
    search.py                百炼 WebSearch 搜索
    fetch.py                 页面抓取(含 SSRF 防护)
    deferred_search.py       模板化检索
    instrument_resolver.py   金融标的解析器(多市场代码/名称标准化)
    sina_reports.py          定期报告
    announcements.py         临时公告
    industry_reports.py      行业研报
    ir_meetings.py           投资者关系活动
    regulatory_penalties.py  监管处罚
tests/
  test_server.py           MCP 服务入口与工具注册契约
  test_fetch.py            SSRF 防护专项
  test_*.py                各数据源单测
F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/shadowinlife/vibetrading-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server