mcpField
M
mcp-etf-holdings

mcp-etf-holdings

本地服务
github.com/vlearner金融数据13 天前更新

关于 mcp-etf-holdings

mcp-etf-holdings 是用于查询 ETF 数据的 MCP 服务,数据来自 Yahoo Finance,无需 API 密钥。它面向投资者,支持通过 MCP 客户端查看基金、股票敞口、费用和持仓。

主要功能

  1. 01查询持有指定股票的 ETF
  2. 02比较费用、规模、收益率和回报
  3. 03获取 ETF 信息和主要持仓
  4. 04按名称、主题或类别搜索基金
  5. 05解析公司和基金代码
  6. 06提供五种 ETF 研究提示词模板

适用场景

  1. 01查找持有某公司的基金
  2. 02比较多只 ETF 的费用和回报
  3. 03检查投资组合中的持仓重叠
  4. 04按投资主题探索 ETF

MCP 相关

向 MCP 客户端提供七种 ETF 研究工具和五种提示词模板。默认使用 stdio,也支持可选的 Streamable HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"vlearner-mcp-etf-holdings": {
"command": "uvx",
"args": [
"mcp-etf-holdings"
]
}
}
}
启动命令uvx mcp-etf-holdings

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimcp-etf-holdings0.6.0

工具

7

收录的工具列表 · 更新于 2 天前

参数类型必填说明
tickerstring是ETF 股票代码,例如 'SPY' 或 'QQQ'

详细介绍

mcp-etf-holdings

License

用于 ETF 数据的 MCP 服务。询问哪些基金持有某只股票、比较费用,或获取主要持仓。数据实时来自 Yahoo Finance。无需 API 密钥。


可以询问的问题

询问 Claude调用的工具
“哪些 ETF 持有 NVDA?”find_etfs_holding_stock
“哪只 ETF 的 Nvidia 投资成本最低?”stock_exposure_summary
“比较 SPY、VOO、QQQ 和 SCHD”compare_etfs
“SPY 的主要持仓有哪些?”etf_holdings
“QQQ 的费用比率和 AUM 是多少?”etf_info
“帮我找一些半导体 ETF”search_etfs
“Berkshire Hathaway 的股票代码是什么?”lookup_symbol

可以按公司名称或股票代码搜索。“哪些 ETF 持有 Nvidia?”和“哪些 ETF 持有 NVDA?”的效果相同。一次询问多只基金,即可获得一张对比表。


要求

  • Python 3.11+
  • MCP 客户端:Claude Code、Claude Desktop、VS Code、Cursor 或 Antigravity
  • uv,可在无需手动安装的情况下运行服务

安装 uv:

curl -LsSf https://astral.sh/uv/install.sh | sh

设置

无需先安装服务。以下所有配置都会通过 uvx 按需启动服务,并在独立的隔离环境中运行。

如需将其添加到 PATH,请运行 pip install mcp-etf-holdings,然后在以下任一配置中,将 uvx mcp-etf-holdings 替换为普通的 mcp-etf-holdings。

Claude Code
claude mcp add etf-holdings -- uvx mcp-etf-holdings
Claude Desktop
  1. 打开配置文件:

    • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows:%APPDATA%\Claude\claude_desktop_config.json
  2. 添加服务:

    {
      "mcpServers": {
        "etf-holdings": {
          "command": "uvx",
          "args": ["mcp-etf-holdings"]
        }
      }
    }
    
  3. 退出 Claude Desktop 并重新打开。仅关闭窗口是不够的。

VS Code
  1. 在工作区中创建 .vscode/mcp.json。如需使用全局配置,请改为运行 MCP: Open User Configuration。

  2. 添加服务。VS Code 使用 servers 键,而不是 mcpServers:

    {
      "servers": {
        "etf-holdings": {
          "type": "stdio",
          "command": "uvx",
          "args": ["mcp-etf-holdings"]
        }
      }
    }
    
  3. 重启 VS Code。

Cursor

使用与 Claude Desktop 相同的 JSON。单个项目使用 .cursor/mcp.json,所有项目使用 ~/.cursor/mcp.json。重启 Cursor。

Antigravity

Antigravity 会从 mcp_config.json 读取 mcpServers。所有项目使用 ~/.gemini/config/mcp_config.json,单个项目使用 <workspace>/.agents/mcp_config.json:

{
  "mcpServers": {
    "etf-holdings": {
      "command": "uvx",
      "args": ["mcp-etf-holdings"]
    }
  }
}

在 IDE 中,可以通过 Agent 面板打开配置:MCP Servers → Manage MCP Servers → View raw config。

也可以从此仓库的检出副本中将其安装为插件(该插件只是相同的配置文件加上清单,位于 antigravity/etf-holdings):

agy plugin install /path/to/mcp-etf-holdings/antigravity/etf-holdings

在 IDE 中,将该文件夹复制到 .agents/plugins/(单个工作区)或 ~/.gemini/config/plugins/(所有工作区)。

如需使用可选的 HTTP 传输方式,Antigravity 将 URL 字段命名为 serverUrl: {"mcpServers": {"etf-holdings": {"serverUrl": "http://127.0.0.1:8000/mcp"}}}。

验证是否正常运行

向客户端询问以下问题:

  • “哪些 ETF 持有 NVDA?” — 调用 find_etfs_holding_stock
  • “比较 SPY、QQQ 和 VTI” — 调用 compare_etfs,并返回一张表
  • “哪些 ETF 持有 Nvidia?” — 将名称解析为 NVDA 并说明这一点

如果返回了真实数据,就大功告成了。


示例提示词

将以下任意内容复制到已连接该服务的客户端中。

比较基金

比较 SPY、VOO、IVV 和 SPLG——它们都跟踪 S&P 500,那么哪只费率最低?

比较 QQQ、VGT、XLK 和 SMH 的费率和 5 年回报。

按名称或代码搜索

哪些 ETF 持有 Nvidia?

Berkshire Hathaway 的代码是什么?

帮我找出 Vanguard 全市场股票基金,并列出它的主要持仓。

寻找持有某只股票的最低成本方式

持有 Nvidia 的最低成本 ETF 是哪只?

我想获得 AMD 敞口,但不直接购买该股票。有哪些选择,成本分别是多少?

检查投资组合是否有重仓重复

我持有 VOO、QQQ 和 VGT。我的持仓是否有重复?

列出同时出现在 SPY、SCHD 和 DGRO 中任意两只以上基金里的所有持仓。

按主题查找基金

找出半导体 ETF,并比较规模最大的三只。

有哪些股息 ETF?哪只收益率最高?

深入研究某只基金

深入分析 SCHD。

QQQ 的持仓有多集中?前 5 大持仓占比是多少?

提示词模板

该服务注册了五种提示词模板。Claude Desktop 和 Claude Code 会将它们显示为斜杠命令,因此你不必自己编写提示词。

模板参数功能
etf_deep_diveticker分析单只基金的成本、规模、回报和持仓集中度
compare_fundstickers并排表格,以及成本和回报比较
stock_exposurestock按权重和成本对持有某只股票的 ETF 排名
portfolio_checkuptickers找出你持有的基金之间重复的持仓
theme_explorertheme查找某个主题的基金,并比较领头基金

工具参考

返回多行结果的工具会将结果格式化为 Markdown 表格。

etf_info(ticker)

获取单只 ETF 的元数据。要查询两只或更多基金,请使用 compare_etfs。

  • ticker(字符串)——ETF 代码,例如 "SPY"

返回名称、类别、资产管理规模(AUM)、费率、股息收益率、净值/价格以及年初至今、3 年和 5 年回报。

compare_etfs(tickers)

在一张表格中比较多只 ETF。

  • tickers(字符串数组)——例如 ["SPY", "QQQ", "VTI", "SCHD"]。不区分大小写,并会去重。每次调用最多比较 10 只基金。

返回代码、名称、类别、资产管理规模、费率、收益率、年初至今回报、3 年回报和 5 年回报。没有数据的代码仍会显示一行,并附上说明标明该代码,因此即使有一处拼写错误,也不会影响其余结果。

etf_holdings(ticker)

获取 ETF 的主要持仓及其在投资组合中的权重。

  • ticker(字符串)——ETF 代码,例如 "QQQ"

返回按排名排列的表格,包含代码、名称和权重百分比。

find_etfs_holding_stock(stock_ticker, limit, custom_etf_universe)

反向查询,查找披露的主要持仓中持有指定股票的 ETF。

  • stock_ticker(字符串)——股票代码,例如 "NVDA",或公司名称,例如 "Nvidia"。名称会被解析为股票代码,输出会说明使用了哪个代码。
  • limit(整数,默认值为 20)——上限为 50
  • custom_etf_universe(JSON 字符串,可选)——搜索指定列表,而非默认范围,例如 '["SPY","QQQ","XLK"]'

返回匹配的 ETF,并按该股票的持仓权重从高到低排序。

仅检查主要持仓,每只 ETF 大约 10–15 个持仓。若某只股票不在这些持仓之列,则不会出现在结果中。

stock_exposure_summary(stock, limit)

此工具执行相同的反向查询,并结合各基金的成本和规模。可用于回答“持有这只股票的最低成本或规模最大的方式是什么?”。

  • stock(字符串)——股票代码或公司名称,例如 "NVDA" 或 "Nvidia"
  • limit(整数,默认值为 10)——上限为 25

返回 ETF、名称、权重、排名、费率和资产管理规模,并按该股票的持仓权重排序。

lookup_symbol(query, limit, asset_type)

将公司或基金名称解析为股票代码。

  • query(string)——例如 "Nvidia" 或 "Vanguard total stock market"
  • limit(int,默认值为 10)——上限为 25
  • asset_type(string,默认值为 "any")——"any"、"stock" 或 "etf"

返回代码、名称、类型和交易所。

search_etfs(query, limit)

按名称、主题或类别查找 ETF。

  • query(string)——例如 "semiconductor" 或 "dividend"
  • limit(int,默认值为 10)——上限为 25

返回匹配的 ETF 代码、名称和交易所。若要解析股票名称,而不是查找基金, 请使用 lookup_symbol。


从源码运行

用于开发,或无需等待发布即可运行:

git clone https://github.com/vlearner/mcp-etf-holdings.git
cd mcp-etf-holdings
uv sync

不使用 uv:

python3 -m venv .venv && .venv/bin/pip install -e ".[dev]"

此仓库附带指向工作树的 .vscode/mcp.json,因此 VS Code 无需额外设置即可获取 本地更改。其他客户端请指向:

{
  "command": "uv",
  "args": ["run", "--directory", "/absolute/path/to/mcp-etf-holdings", "mcp-etf-holdings"]
}

检查服务是否启动:

uv run mcp-etf-holdings

它会保持静默,等待从 stdin 接收 JSON-RPC。这是 stdio MCP 服务的正常行为。

手动试用该协议:

npx @modelcontextprotocol/inspector uv run mcp-etf-holdings
HTTP 传输(可选)

stdio 是默认传输方式,也是上述所有编辑器配置使用的方式。若要改为通过可流式 HTTP 提供服务:

uv run mcp-etf-holdings --transport http            # http://127.0.0.1:8000/mcp
uv run mcp-etf-holdings --transport http --port 9000

将客户端指向它,配置为 { "type": "http", "url": "http://127.0.0.1:8000/mcp" } (VS Code 中位于 servers 下)。MCP_TRANSPORT、MCP_HOST 和 MCP_PORT 可设置相同选项。

默认情况下,服务绑定到环回地址,且没有身份验证。除非传入 --allow-insecure(或设置 MCP_ALLOW_INSECURE=1),否则不允许绑定到其他地址;在将其暴露到本机之外之前,请在前面 部署身份验证代理。

在 Docker 中试用

示例 Dockerfile 可从此检出版本构建服务:

docker build -t mcp-etf-holdings .
docker run --rm -e MCP_ALLOW_INSECURE=1 -p 127.0.0.1:8000:8000 mcp-etf-holdings

由于容器会绑定到所有接口,因此必须设置 MCP_ALLOW_INSECURE=1。保留端口映射中的 127.0.0.1::它能防止网络中的其他机器访问该容器。服务会在容器内记录无身份验证警告; 这是预期行为。此方式仅用于试用该功能,并非托管方案。

测试
uv run pytest -q

整个测试套件完全离线运行。yf.Ticker 和 yf.Search 均使用了模拟对象,后者由 自动使用的 fixture 提供,因此测试不会意外访问 Yahoo。

查看覆盖率:

uv run pytest -q --cov=mcp_etf_holdings --cov-report=term-missing
目录结构
src/mcp_etf_holdings/
  server.py       ← FastMCP entry point, 7 tools
  prompts.py      ← prompt templates, exposed as client slash-commands
  fetcher.py      ← async wrappers around yfinance + 24h TTL cache
  formatting.py   ← markdown tables and shared number formatting
  top_etfs.py     ← ~365 ETF tickers scanned for reverse lookups
  __main__.py     ← enables `python -m mcp_etf_holdings`
tests/            ← pytest suite, fully offline
.vscode/mcp.json  ← VS Code config pointing at the working tree
pyproject.toml

依赖项:mcp(协议 SDK)、yfinance(数据)、pandas(持仓数据框)、 httpx(传输)。


故障排除

症状解决方法
command not found: uvx安装 uv,然后重启编辑器,使其获取新的 PATH。
客户端中找不到服务编辑器只会在启动时读取 MCP 配置。请完全退出并重新打开。检查客户端的 MCP 日志,查看启动错误。
在终端中能运行,在编辑器中却不行GUI 应用通常不会继承 shell 的 PATH。请使用 uvx 的绝对路径——运行 which uvx 获取路径。
工具调用返回 "No data found"检查代码是否有效。Yahoo 有时会进行速率限制,请稍后重试。
安装时出现 Python 版本错误需要 3.11 或更高版本。运行 python3 --version 检查。

限制

信任数据前,建议了解以下限制:

  • 每只 ETF 仅公布排名靠前的约 10–15 项持仓。任何基于持仓得出的结果—— 反向查询、敞口摘要、重叠检查——都是下限,而非完整情况。
  • 默认覆盖范围约为 365 只基金。若某只股票仅由小型或小众 ETF 持有,可能无法 查到。
  • 响应会在内存中缓存 24 小时。可通过 ETF_CACHE_TTL_SECONDS 修改。
  • 数据实时从 Yahoo Finance 获取。无需 API 密钥,但须遵守 Yahoo 的 条款和速率限制。 归属信息请参阅 NOTICE。

贡献

欢迎提交 PR。最有价值的贡献是扩展 top_etfs.py 中的 ETF 范围。 覆盖面越广,小众行业和国际市场的反向查询结果就越好。

较大的更改请先提交 issue。


免责声明

与 Yahoo Finance、yfinance 或任何金融机构均无关联。数据在运行时从 Yahoo Finance 获取,具体取决于其可用性,并受其服务条款约束。本内容不构成财务建议。

评论

支持 Markdown

第一次接触 MCP?

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

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