IBKR Portfolio Builder

io.github.adwiteeymauriya由 GitHub 账号 adwiteeymauriya 发布v0.1.4更新于 Oct 24, 2026

Top-down IBKR research: 468 typed screeners tagged by strategy intent, news, account access.

发布方自己的服务:PortfolioFit

已验证Streamable HTTP可网页运行网页搜索与抓取金融数据与分析

概览

AI 生成的概览

面向 IBKR 自上而下组合研究的远程 MCP 服务器:提供 468 个带类型标签的筛选器目录、新闻以及只读账户数据。

可以做什么
  • 按类别、策略意图和适用品种浏览并筛选 468 个 IBKR 筛选器目录,含反向配对链接与数值过滤参数代码
  • 运行 IBKR 扫描并返回带交易所的排名股票列表,另可对原始扫描代码做子串搜索
  • 按名称模糊查找合约、读取完整合约元数据,并获取价格快照或 OHLCV 历史数据
  • 读取账户摘要、持仓、挂单和近期成交
  • 列出已订阅的新闻源,并按股票代码获取新闻标题或单篇文章正文
适用场景
适合让助手围绕 Interactive Brokers 账户做自上而下的筛选与组合研究:先确定策略意图,运行并交叉比对多个扫描,再结合新闻和财报事件缩小候选范围,而不是逐个代码查询。
运行要求
需要自行部署的远程 Streamable HTTP 端点(路径 /mcp),配套 ib-gateway 服务以及 IBKR 模拟账户凭据(TWS_USERID、TWS_PASSWORD)。认证方式由 AUTH_MODE 决定:OAuth 需要 LOGIN_PASSWORD,bearer 模式需要 STATIC_BEARER_TOKEN,并通过 Authorization 请求头传递。Claude.ai 连接器需要与 PUBLIC_BASE_URL 一致的公网 HTTPS 地址。
安装前请注意
该服务器会连接你的 Interactive Brokers 账户;默认使用只读 API 模式的模拟账户且不提供下单工具,但切换到真实账户需自行承担风险。获取新闻正文可能按篇收费,Dow Jones 尤其如此。会话、OAuth 客户端和令牌仅存于内存,重启即失效。工具输出不构成投资建议。

安装

在 SourceWeft 中

  1. 打开 控制台中的 IBKR Portfolio Builder,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

ibkr-portfolio-builder-mcp

A remote MCP server for top-down portfolio construction with Interactive Brokers. Built to be used as a Claude.ai custom connector, Claude Code MCP, or any HTTP MCP client.

Most ibkr-mcp servers expose individual lookup primitives — get_quote, get_position, place_order. This one exposes the research workflow: a typed catalog of 468 screeners across 16 categories tagged by strategy intent (value / growth / income / momentum / quality / events / …), per-scan applicable instruments, inverse-pair links, and live news/account access — so an LLM can do real top-down portfolio construction (pick sectors / strategies → run scans → cross-reference with news → narrow to candidates) instead of bottoms-up ticker fishing.

Why this exists

I built this because the existing IBKR-MCP servers in the community treat IBKR as a "look-up-one-ticker" data source. That mirrors how most retail brokerage UIs work, but it's not how good portfolio construction actually happens.

A good top-down workflow looks like:

  1. Macro thesis ("rates are about to fall, dividend payers should re-rate") →
  2. Strategy intent ("show me income screens with quality bias on US large caps") →
  3. Screener composition (run dividend yield + ROE + low debt screens; intersect) →
  4. Event/news context ("any of these have earnings in the next two weeks? any negative analyst actions?") →
  5. Narrow candidate set ("five tickers, ranked by my criteria, ready for deeper diligence").

To do that with an LLM, the MCP server needs to expose the research vocabulary, not just the raw API. That's the gap this server fills:

  • A typed scan catalog — 468 IBKR scan codes across 16 categories (Fundamentals, Price Movement, Dividends, Options & Volatility, Events & Earnings, 52/26/13 Week High-Low, ESG, Bonds, …) auto-tagged with 28 strategy intent tags (value, growth, quality, income, momentum_up, momentum_down, analyst, technical, gap, volatility, events, leverage, efficiency, risk_adjusted, …). The LLM asks "what value scans exist for US stocks?" and gets a clean, filterable answer instead of trying to guess scan codes from training data.
  • Inverse pair links — every HIGH_X ↔ LOW_X and X_ASC ↔ X_DESC pair is precomputed, so the LLM can flip polarity ("what's the opposite of LOW_PE_RATIO?") without guessing.
  • Per-scan instrument map — the catalog knows which scan applies to STK, ETF, OPT, BOND, etc. The LLM stops sending Refinitiv scans to bond instruments and getting empty results.
  • Filter catalog — separate typed map of the numeric filters (priceAbove, peRatioBelow, divYieldAbove, growthRateAbove, avgVolumeAbove, marketCapAbove, …) grouped by category, with per-instrument applicability notes.
  • News + screeners in one tool surface — same connector, same auth, same conversation. The LLM can intersect a scan result with recent headlines or upcoming earnings without context-switching.
  • Two auth modes — full OAuth 2.1 (DCR + PKCE + well-knowns) for Claude.ai custom connectors, plus a static bearer token for everything else. Same server, same tools.

It's still an early server. The IBKR API has plenty of restrictions on what a paper account can actually see (notably historical news entitlement). But the catalog and workflow shape are production-ready, and they're the load-bearing piece for an LLM-driven research loop.

Quick facts

  • Transport: Streamable HTTP at /mcp.
  • Auth: OAuth 2.1 (PKCE + RFC 7591 Dynamic Client Registration) AND/OR static bearer token. Selectable via AUTH_MODE.
  • Persistence: in-memory only today (sessions / DCR clients / OAuth tokens reset on container restart). Redis is on the roadmap — see below.
  • IBKR connection: ib-gateway (ghcr.io/gnzsnz/ib-gateway:stable) runs as a sibling service in this compose; paper account in read-only API mode by default.
  • Built on: FastMCP + ib_async.

Tools

Parity with IBKR's official MCP for the 9 read-only tools (skipping the two write/order-instruction tools — see roadmap), plus the 5 screener/news/catalog tools that are this server's reason for existing.

ToolWhat it does
ib_account_summaryNetLiquidation / BuyingPower / TotalCashValue / AvailableFunds / UnrealizedPnL for the connected paper or live account.
ib_positionsOpen positions across managed accounts, with quantity / avg cost / mark-to-market / unrealized PnL.
ib_open_ordersCurrently working orders with status, filled / remaining quantity, average fill price.
ib_tradesRecent executed fills (days_back window, IBKR caps history ~7 days).
ib_price_snapshotCurrent bid / ask / last / high / low / volume for a US stock. Surfaces IBKR market-data restriction messages clearly.
ib_price_historyOHLCV bars for any duration / bar size (1 day, 1 hour, 5 mins, ...). Always works regardless of market-data subscription.
ib_search_contractsFuzzy-search IBKR's contract database by name / partial ticker.
ib_contract_detailsFull contract metadata — long_name, industry, category, subcategory, trading hours, valid exchanges. The hook for sector-aware top-down screening.
ib_scan_catalogThe typed scan catalog. Filter by category, strategy, instrument, free-text query; optionally return the full list of available categories + strategies via list_meta=true.
ib_filter_catalogFilter parameter codes grouped by category (price, volume, market_cap, fundamentals, technical, options), with an instrument applicability note.
ib_screener_codesSubstring search over the raw scan-parameters.xml codes (legacy / fallback). Useful for newer vendor codes not yet in the curated catalog.
ib_screenerRun an IBKR scan — pass scan_code, instrument, location, optional price / volume filters. Returns rank + ticker + exchange.
ib_news_providersList subscribed IBKR news providers (Briefing.com, Dow Jones, etc.).
ib_news_for_symbolFetch headlines for a US stock across all subscribed providers. Headlines only; surfaces a clear notice field when the account lacks historical-news entitlement.
ib_news_articleFetch a single article body by provider_code + article_id. ⚠️ may incur a per-article fee (Dow Jones in particular).

Note on order placement. IBKR's official MCP also exposes Create Order Instruction and Delete Order Instruction. This server intentionally does not — it runs ib-gateway in READ_ONLY_API=yes mode so even a misrouted tool call cannot place an order. Order execution belongs in a separate service with its own approval gate. See the roadmap for a possible "staged-only" instruction tool that would write to a local store without ever touching IBKR.

Authentication

AUTH_MODE selects which mechanisms the server accepts. The default is both.

ModeWhat's acceptedRequired env
oauthOAuth-issued tokens only. Required for Claude.ai custom connectors.LOGIN_PASSWORD
bearerA static Authorization: Bearer <token> only. Skips the OAuth dance — best for CLI clients, Claude Code, your own scripts.STATIC_BEARER_TOKEN
both (default)Either OAuth tokens or the static bearer token.At least one of LOGIN_PASSWORD or STATIC_BEARER_TOKEN.

The OAuth endpoints (/authorize, /token, /register, /.well-known/*, /login) are always registered. In bearer mode they're inert — nothing in your README needs to point at them.

Generating secrets

bash
uv run --no-project python -c "import secrets; print(secrets.token_urlsafe(48))"   # bearer tokenuv run --no-project python -c "import secrets; print(secrets.token_urlsafe(48))"   # session secret

Using the static bearer token

bash
curl -X POST https://YOUR.DOMAIN/mcp \  -H "Authorization: Bearer $STATIC_BEARER_TOKEN" \  -H "Content-Type: application/json" \  -H "Accept: application/json, text/event-stream" \  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Connecting from Claude.ai (OAuth)

Settings → Connectors → Add custom connector → URL: https://YOUR.DOMAIN/mcp → leave OAuth client id/secret blank (Claude.ai uses DCR). When Claude.ai opens the OAuth flow, you'll be prompted for LOGIN_PASSWORD.

Run

bash
cp .env.example .env# edit .env: set TWS_USERID / TWS_PASSWORD (paper account), LOGIN_PASSWORD, STATIC_BEARER_TOKEN, PUBLIC_BASE_URLdocker compose up -d

By default this pulls the published multi-arch image from GitHub Container Registry: ghcr.io/adwiteeymauriya/ibkr-portfolio-builder-mcp:latest. To build locally instead (e.g. when iterating on the source), run docker compose build ibkr-mcp first.

ib-gateway takes ~60–90 s to finish IBKR login after first start. Tail logs with docker logs -f ibkr-mcp-gateway.

For local-only use (bearer-token clients, no Claude.ai) this is enough — http://localhost:8000/mcp is now serving. Claude.ai custom connectors require an HTTPS URL on the public internet, so a reverse proxy with TLS in front is needed.

Putting TLS in front for Claude.ai

Pick one. Both end with a working https://your-host/mcp and a valid cert.

Option 1 — Cloudflare Tunnel (no public IP, no port forwarding). Best if the server runs on a home network or a VM behind NAT. Cloudflare gives you a hostname and TLS for free; the tunnel daemon dials out from the server to Cloudflare's edge.

bash
# One-time: install cloudflared, thencloudflared tunnel logincloudflared tunnel create ibkr-mcpcloudflared tunnel route dns ibkr-mcp ibkr-mcp.your-domain.com

~/.cloudflared/config.yml:

yaml
tunnel: ibkr-mcpcredentials-file: /home/you/.cloudflared/<TUNNEL_ID>.jsoningress:  - hostname: ibkr-mcp.your-domain.com    service: http://localhost:8000  - service: http_status:404

Run with cloudflared tunnel run ibkr-mcp (or install as a systemd unit via cloudflared service install). Then set PUBLIC_BASE_URL=https://ibkr-mcp.your-domain.com in .env and docker compose restart ibkr-mcp.

Option 2 — Caddy reverse proxy with Let's Encrypt. Best if the server has a public IP and ports 80/443 open. Caddy fetches certs automatically.

Caddyfile:

ibkr-mcp.your-domain.com {    reverse_proxy localhost:8000}

Run with caddy run (or install as a system service: sudo caddy start + a systemd unit). Same .env change as above.

In both cases PUBLIC_BASE_URL must match exactly the URL you give Claude.ai — Claude.ai validates the OAuth issuer against it.

Example LLM prompts (top-down workflow)

1. Discovery:   "List the strategies and categories available in ib_scan_catalog."
2. Strategy intent:   "Find me value scans for US stocks. Show me their inverse codes too."
3. Composition:   "Run LOW_PE_RATIO on STK.US.MAJOR with priceAbove $20 and avgVolumeAbove    1,000,000, top 30. Cross-reference with HIGH_RETURN_ON_EQUITY top 30.    Show me overlap."
4. Event context:   "For the overlap list, check ib_news_for_symbol for any negative    headlines in the last 7 days, and Events & Earnings scans for    upcoming earnings within 14 days."
5. Narrow:   "Rank the survivors by liquidity and tell me which two you'd dig    into next."

Roadmap

AreaItem
AuthRedis-backed sessions, DCR clients, OAuth tokens
AuthPer-token scopes (read-only, read-news, screener-only, ...)
InstrumentsOptions (chains, greeks, IV/price calc)
InstrumentsFutures (ContFuture, combos via Bag)
InstrumentsBonds (search + quote)
InstrumentsForex + crypto
ExchangesNon-US equity routings (EU, HK, JP, AU)
ExchangesCurrency-aware ib_account_summary
ResearchReuters fundamentals (reqFundamentalDataAsync)
ResearchReal-time streaming bars + tick-by-tick
ResearchLevel 2 order book
ResearchDaily PnL streams (pnlAsync, pnlSingleAsync)
ResearchAdvisor sub-accounts (reqFamilyCodesAsync)
ResearchCatalog → Memgraph for multi-hop queries
ResearchBroader ib_news_search
Riskib_what_if_order (margin preview, no execution)
RiskLocal staged-instruction tools (no IBKR write)

Open issues / PRs welcome on any of these.

Layout

.├── Dockerfile├── docker-compose.yml             # connector + ib-gateway, internal IBKR network├── pyproject.toml                 # uv-managed: fastmcp, itsdangerous, uvicorn, ib_async├── uv.lock├── .env.example├── LICENSE                        # MIT├── scan-parameters.xml            # IBKR's authoritative scan params (raw XML)├── scanner_reference.json         # IBKR-categorized scanner reference├── scanner_params.json            # Flat dump of scan codes + filters├── scripts/│   └── build_catalog.py           # Regenerates src/connector/data/* from the three source files above└── src/    └── connector/        ├── settings.py            # env-driven config (incl. AUTH_MODE)        ├── auth.py                # LoginGatedOAuthProvider + static bearer override + /login        ├── ibkr.py                # ib_async connection helper (connect-per-call)        ├── screener.py            # raw scan-parameters.xml substring search (fallback tool)        ├── catalog.py             # typed scan + filter catalog loaders + filtering        ├── tools.py               # 15 MCP tools wired into FastMCP        ├── server.py              # FastMCP + Starlette wiring + uvicorn entry        └── data/            ├── scan_catalog.json  # generated            └── filter_catalog.json # generated

License

MIT.

Acknowledgements

Disclaimer

This software talks to your Interactive Brokers account. By default it runs against a paper account in read-only API mode — orders cannot be placed even if a tool tries. If you switch to a live account, you do so at your own risk. None of the tool output constitutes investment advice; the strategy tagging is a vocabulary helper, not a recommendation engine.

来源:README.md,提交 337a5e1

工具

0
SourceWeft 尚未读取此服务器的工具。

版本历史

1
  1. v0.1.4最新Sep 16, 2026

评分

已满足适用检查项的 60%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式必需10 分
  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

其他 Portfolio 集成