API ВЕГА
English

mcp-etf-holdings

MCP-сервер для работы с данными ETF. Узнайте, какие фонды владеют акциями выбранной компании, сравните комиссии или получите список крупнейших активов. Данные поступают напрямую из Yahoo Finance. API-ключ не требуется.


Что можно спросить

Спросите ClaudeВызываемый инструмент
«Какие ETF владеют акциями NVDA?»find_etfs_holding_stock
«Какой ETF с наименьшими расходами даёт доступ к акциям Nvidia?»stock_exposure_summary
«Сравни SPY, VOO, QQQ и SCHD»compare_etfs
«Какие активы входят в крупнейшие позиции SPY?»etf_holdings
«Каковы коэффициент расходов и AUM у QQQ?»etf_info
«Найди ETF на полупроводниковые компании»search_etfs
«Какой тикер у Berkshire Hathaway?»lookup_symbol

Ищите по названию компании или тикеру. Запросы «Какие ETF владеют акциями Nvidia?» и «Какие ETF владеют акциями NVDA?» работают одинаково. Можно указать сразу несколько фондов — результатом будет одна сравнительная таблица.


Требования

  • Python 3.11+

  • MCP-клиент: Claude Code, Claude Desktop, VS Code или Cursor

  • 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

  • Откройте файл конфигурации:

    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Добавьте сервер:

{
  "mcpServers": {
    "etf-holdings": {
      "command": "uvx",
      "args": ["mcp-etf-holdings"]
    }
  }
}
  • Полностью закройте Claude Desktop и запустите его снова. Просто закрыть окно недостаточно.

VS Code

  • Создайте файл .vscode/mcp.json в рабочей области. Чтобы настроить сервер глобально, вместо этого выполните команду

MCP: Open User Configuration.

  • Добавьте сервер. В VS Code используется ключ servers, а не mcpServers:
{
  "servers": {
    "etf-holdings": {
      "type": "stdio",
      "command": "uvx",
      "args": ["mcp-etf-holdings"]
    }
  }
}
  • Перезапустите VS Code.

Cursor

Используйте тот же JSON, что и для Claude Desktop. Для одного проекта поместите его в .cursor/mcp.json, а для всех проектов —

в ~/.cursor/mcp.json. Перезапустите Cursor.

Проверка работы

Задайте клиенту любой из следующих вопросов:

  • «Какие 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 на весь рынок акций и покажи его крупнейшие активы.

Поиск ETF с наименьшими расходами для инвестиций в акцию

Какой ETF позволяет вложиться в Nvidia с наименьшими расходами?

Я хочу вложиться в AMD, но не покупать акции напрямую. Какие есть варианты и сколько они стоят?

Проверка пересечений в портфеле

У меня есть VOO, QQQ и VGT. Не дублируют ли они друг друга?

Покажи все активы, которые входят более чем в один фонд из SPY, SCHD и DGRO.

Поиск фондов по тематике

Найди ETF на полупроводниковые компании и сравни три крупнейших.

Какие есть ETF на дивидендные акции и у какого из них самая высокая доходность?

Анализ отдельного фонда

Подробно проанализируй SCHD.

Насколько концентрирован QQQ? Какую долю занимают его пять крупнейших позиций?

Шаблоны запросов

Сервер регистрирует пять шаблонов запросов. Claude Desktop и Claude Code отображают их как

команды, начинающиеся с косой черты, поэтому вводить запрос самостоятельно не нужно.

ШаблонАргументНазначение
etf_deep_divetickerРасходы, размер, доходность и степень концентрации одного фонда
compare_fundstickersСравнительная таблица, а также сопоставление расходов и доходности
stock_exposurestockРанжирует ETF, владеющие акциями компании, по доле и расходам
portfolio_checkuptickersНаходит позиции, которые дублируются в принадлежащих вам фондах
theme_explorerthemeНаходит фонды по тематике и сравнивает лидеров

Справочник инструментов

Инструменты, возвращающие несколько строк, форматируют результат в виде таблицы Markdown.

etf_info(ticker)

Сведения об одном ETF. Для сравнения двух и более фондов используйте compare_etfs.

  • ticker (string) — тикер ETF, например "SPY"

Возвращает название, категорию, AUM, коэффициент расходов, дивидендную доходность, NAV/цену, а также доходность за текущий год, 3 и

5 лет.

compare_etfs(tickers)

Сравнивает несколько ETF в одной таблице.

  • tickers (array of strings) — например, ["SPY", "QQQ", "VTI", "SCHD"]. Регистр не учитывается,

повторяющиеся тикеры удаляются. За один вызов можно сравнить не более 10 фондов.

Возвращает тикер, название, категорию, AUM, расходы, доходность, а также показатели YTD, за 3 и 5 лет. Если для тикера нет

данных, он всё равно попадёт в таблицу с пояснением. Поэтому опечатка в одном тикере не приведёт к потере остальных результатов.

etf_holdings(ticker)

Крупнейшие активы ETF и их доли в портфеле.

  • ticker (string) — тикер ETF, например "QQQ"

Возвращает таблицу с активами, отсортированными по убыванию доли, и включает тикер, название и долю в процентах.

find_etfs_holding_stock(stock_ticker, limit, custom_etf_universe)

Обратный поиск: находит ETF, в раскрытых крупнейших позициях которых есть указанная акция.

  • stock_ticker (string) — тикер, например "NVDA", или название компании, например "Nvidia".

Название компании преобразуется в тикер; результат показывает, какой именно тикер был использован.

  • limit (int, default 20) — максимум 50

  • custom_etf_universe (JSON string, optional) — поиск в указанном списке вместо

списка по умолчанию, например '["SPY","QQQ","XLK"]'

Возвращает подходящие ETF, отсортированные по доле указанной акции от наибольшей к наименьшей.

Проверяются только крупнейшие позиции — обычно около 10–15 активов каждого ETF. Акции, не входящие в этот список, в результатах не появятся.

stock_exposure_summary(stock, limit)

Тот же обратный поиск, дополненный сведениями о расходах и размере каждого фонда. Используйте этот инструмент, чтобы узнать, какой фонд позволяет вложиться в акцию с наименьшими расходами или какой фонд для этого крупнейший.

  • stock (string) — тикер или название компании, например "NVDA" или "Nvidia"

  • limit (int, default 10) — максимум 25

Возвращает ETF, название, долю, позицию в рейтинге, расходы и AUM. Результат отсортирован по доле акции в фонде.

lookup_symbol(query, limit, asset_type)

Находит тикер компании или фонда по названию.

  • query (string) — например, "Nvidia" или "Vanguard total stock market"

  • limit (int, default 10) — максимум 25

  • asset_type (string, default "any") — "any", "stock" или "etf"

Возвращает тикер, название, тип актива и биржу.

search_etfs(query, limit)

Находит ETF по названию, тематике или категории.

  • query (string) — например, "semiconductor" или "dividend"

  • limit (int, default 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

Сервер не выводит сообщений и ожидает JSON-RPC в stdin. Для MCP-сервера со stdio-транспортом это нормальное поведение.

Чтобы проверить протокол вручную:

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.

По умолчанию сервер принимает подключения только с локального компьютера и не использует аутентификацию. При привязке к другому адресу сервер выведет предупреждение. Прежде чем открывать к нему доступ за пределами своего компьютера, установите прокси-сервер с аутентификацией.

Запуск в Docker

Пример Dockerfile собирает сервер из этой рабочей копии:

docker build -t mcp-etf-holdings .
docker run --rm -p 127.0.0.1:8000:8000 mcp-etf-holdings

Не удаляйте 127.0.0.1: из параметра сопоставления портов: именно он не позволяет другим устройствам в сети подключаться к контейнеру. Сервер выводит в контейнере предупреждение об отсутствии аутентификации — это ожидаемо. Такой способ предназначен для проверки функции, а не для размещения сервера в рабочей среде.

Тесты

uv run pytest -q

Все тесты выполняются без подключения к сети. Вызовы yf.Ticker и yf.Search имитируются; для последнего используется автоматически применяемая фикстура, поэтому тесты не смогут случайно обратиться к Yahoo.

Чтобы получить отчёт о покрытии:

uv run pytest -q --cov=mcp_etf_holdings --cov-report=term-missing

Структура проекта

src/mcp_etf_holdings/
  server.py       ← точка входа FastMCP, 7 инструментов
  prompts.py      ← шаблоны запросов, доступные клиенту как slash-команды
  fetcher.py      ← асинхронные обёртки для yfinance и кэш с TTL 24 часа
  formatting.py   ← таблицы в формате markdown и общие функции форматирования чисел
  top_etfs.py     ← около 365 тикеров ETF для обратного поиска
  __main__.py     ← позволяет запускать `python -m mcp_etf_holdings`
tests/            ← набор тестов pytest, полностью автономный
.vscode/mcp.json  ← конфигурация VS Code с указанием на рабочую копию
pyproject.toml

Зависимости: mcp (SDK протокола), yfinance (данные), pandas (таблицы с активами),

httpx (транспорт).


Устранение неполадок

ПроблемаРешение
command not found: uvxУстановите uv, затем перезапустите редактор, чтобы он обнаружил новый PATH.
Сервер не отображается в клиентеРедакторы считывают конфигурацию MCP только при запуске. Полностью закройте редактор и откройте его снова. Проверьте журналы MCP клиента: в них может быть указана ошибка запуска.
В терминале работает, а в редакторе — нетГрафические приложения часто не наследуют 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. Самый полезный вклад — расширение списка ETF в top_etfs.py.

Более широкий охват позволит улучшить результаты обратного поиска в узкоспециализированных секторах и на международных рынках.

Перед внесением крупных изменений сначала создайте issue.


Отказ от ответственности

Проект не связан с Yahoo Finance, yfinance или какими-либо финансовыми организациями. Данные загружаются из Yahoo Finance во время работы и зависят от доступности сервиса и его условий использования. Это не является финансовой рекомендацией.