IBKR Portfolio Builder
Pesquisa de portfólio top-down para Interactive Brokers com catálogo tipado de 468 screeners da IBKR marcados por intenção de estratégia. Somente leitura.
Documentação
ibkr-portfolio-builder-mcp
Um servidor MCP remoto para construção de portfólio top-down com a Interactive Brokers. Construído para ser usado como conector personalizado do Claude.ai, MCP do Claude Code ou qualquer cliente HTTP MCP.
A maioria dos servidores ibkr-mcp expõe primitivas de consulta individuais —
get_quote,get_position,place_order. Este expõe o fluxo de pesquisa: um catálogo tipado de 468 screeners em 16 categorias marcadas por intenção de estratégia (value / growth / income / momentum / quality / events / …), instrumentos aplicáveis por varredura, links de pares inversos e acesso a notícias/contas em tempo real — para que um LLM possa fazer construção de portfólio top-down real (escolher setores / estratégias → executar varreduras → cruzar com notícias → reduzir a candidatos) em vez de pesca de tickers bottom-up.
Por que isso existe
Construí isso porque os servidores IBKR-MCP existentes na comunidade tratam a IBKR como uma fonte de dados "consulta-um-ticker". Isso espelha como a maioria das interfaces de corretoras de varejo funciona, mas não é assim que uma boa construção de portfólio realmente acontece.
Um bom fluxo de trabalho top-down se parece com:
- Tese macro ("as taxas estão prestes a cair, pagadores de dividendos devem se reavaliar") →
- Intenção de estratégia ("mostre-me telas de renda com viés de qualidade em large caps dos EUA") →
- Composição do screener (executar telas de rendimento de dividendos + ROE + baixa dívida; cruzar) →
- Contexto de eventos/notícias ("algum desses tem lucros nas próximas duas semanas? alguma ação negativa de analistas?") →
- Conjunto de candidatos reduzido ("cinco tickers, classificados pelos meus critérios, prontos para diligência mais profunda").
Para fazer isso com um LLM, o servidor MCP precisa expor o vocabulário de pesquisa, não apenas a API bruta. Essa é a lacuna que este servidor preenche:
- Um catálogo de varreduras tipado — 468 códigos de varredura IBKR em 16 categorias (
Fundamentals,Price Movement,Dividends,Options & Volatility,Events & Earnings,52/26/13 Week High-Low,ESG,Bonds, …) automaticamente marcados com 28 tags de intenção de estratégia (value,growth,quality,income,momentum_up,momentum_down,analyst,technical,gap,volatility,events,leverage,efficiency,risk_adjusted, …). O LLM pergunta "quais varreduras de valor existem para ações dos EUA?" e obtém uma resposta limpa e filtrável em vez de tentar adivinhar códigos de varredura a partir de dados de treinamento. - Links de pares inversos — cada par
HIGH_X ↔ LOW_XeX_ASC ↔ X_DESCé pré-computado, para que o LLM possa inverter a polaridade ("qual é o oposto de LOW_PE_RATIO?") sem adivinhar. - Mapa de instrumentos por varredura — o catálogo sabe qual varredura se aplica a
STK,ETF,OPT,BOND, etc. O LLM para de enviar varreduras Refinitiv para instrumentos de títulos e obter resultados vazios. - Catálogo de filtros — mapa tipado separado dos filtros numéricos (
priceAbove,peRatioBelow,divYieldAbove,growthRateAbove,avgVolumeAbove,marketCapAbove, …) agrupados por categoria, com notas de aplicabilidade por instrumento. - Notícias + screeners em uma única superfície de ferramentas — mesmo conector, mesma autenticação, mesma conversa. O LLM pode cruzar um resultado de varredura com manchetes recentes ou lucros futuros sem trocar de contexto.
- Dois modos de autenticação — OAuth 2.1 completo (DCR + PKCE + well-knowns) para conectores personalizados do Claude.ai, além de um token bearer estático para todo o resto. Mesmo servidor, mesmas ferramentas.
Ainda é um servidor inicial. A API IBKR tem várias restrições sobre o que uma conta de papel pode realmente ver (notavelmente direito a notícias históricas). Mas o catálogo e o formato do fluxo de trabalho estão prontos para produção, e são a peça central para um loop de pesquisa orientado por LLM.
Fatos rápidos
- Transporte: HTTP Streamable em
/mcp. - Autenticação: OAuth 2.1 (PKCE + RFC 7591 Dynamic Client Registration) E/OU token bearer estático. Selecionável via
AUTH_MODE. - Persistência: apenas em memória hoje (sessões / clientes DCR / tokens OAuth são redefinidos na reinicialização do contêiner). Redis está no roadmap — veja abaixo.
- Conexão IBKR: ib-gateway (
ghcr.io/gnzsnz/ib-gateway:stable) roda como serviço irmão neste compose; conta de papel em modo API somente leitura por padrão. - Construído sobre: FastMCP + ib_async.
Ferramentas
Paridade com o MCP oficial da IBKR para as 9 ferramentas somente leitura (pulando as duas ferramentas de escrita/instrução de ordem — veja o roadmap), além das 5 ferramentas de screener/notícias/catálogo que são a razão de existir deste servidor.
| Ferramenta | O que faz |
|---|---|
ib_account_summary | NetLiquidation / BuyingPower / TotalCashValue / AvailableFunds / UnrealizedPnL para a conta de papel ou real conectada. |
ib_positions | Posições abertas em contas gerenciadas, com quantidade / custo médio / mark-to-market / PnL não realizado. |
ib_open_orders | Ordens atualmente em andamento com status, quantidade preenchida / restante, preço médio de preenchimento. |
ib_trades | Execuções preenchidas recentes (janela de days_back, IBKR limita histórico a ~7 dias). |
ib_price_snapshot | Bid / ask / último / alta / baixa / volume atuais para uma ação dos EUA. Expõe mensagens de restrição de dados de mercado da IBKR claramente. |
ib_price_history | Barras OHLCV para qualquer duração / tamanho de barra (1 day, 1 hour, 5 mins, ...). Sempre funciona independentemente da assinatura de dados de mercado. |
ib_search_contracts | Busca difusa no banco de contratos da IBKR por nome / ticker parcial. |
ib_contract_details | Metadados completos do contrato — long_name, industry, category, subcategory, horários de negociação, bolsas válidas. O gancho para triagem top-down ciente de setor. |
ib_scan_catalog | O catálogo de varreduras tipado. Filtrar por category, strategy, instrument, texto livre query; opcionalmente retornar a lista completa de categorias + estratégias disponíveis via list_meta=true. |
ib_filter_catalog | Códigos de parâmetros de filtro agrupados por categoria (price, volume, market_cap, fundamentals, technical, options), com nota de aplicabilidade por instrumento. |
ib_screener_codes | Busca por substring sobre os códigos scan-parameters.xml brutos (legado / fallback). Útil para códigos de fornecedores mais novos ainda não no catálogo curado. |
ib_screener | Executar uma varredura IBKR — passar scan_code, instrument, location, filtros opcionais de preço / volume. Retorna classificação + ticker + bolsa. |
ib_news_providers | Listar provedores de notícias IBKR inscritos (Briefing.com, Dow Jones, etc.). |
ib_news_for_symbol | Buscar manchetes para uma ação dos EUA em todos os provedores inscritos. Apenas manchetes; expõe um campo notice claro quando a conta não tem direito a notícias históricas. |
ib_news_article | Buscar o corpo de um único artigo por provider_code + article_id. ⚠️ pode incorrer em taxa por artigo (Dow Jones em particular). |
Nota sobre colocação de ordens. O MCP oficial da IBKR também expõe
Create Order InstructioneDelete Order Instruction. Este servidor intencionalmente não — ele roda ib-gateway em modoREAD_ONLY_API=yespara que mesmo uma chamada de ferramenta mal roteada não possa colocar uma ordem. Execução de ordens pertence a um serviço separado com seu próprio portão de aprovação. Veja o roadmap para uma possível ferramenta de instrução "somente encenada" que escreveria em um armazenamento local sem nunca tocar na IBKR.
Autenticação
AUTH_MODE seleciona quais mecanismos o servidor aceita. O padrão é both.
| Modo | O que é aceito | Env necessário |
|---|---|---|
oauth | Apenas tokens emitidos por OAuth. Necessário para conectores personalizados do Claude.ai. | LOGIN_PASSWORD |
bearer | Apenas um Authorization: Bearer <token> estático. Pula o fluxo OAuth — melhor para clientes CLI, Claude Code, seus próprios scripts. | STATIC_BEARER_TOKEN |
both (padrão) | Tokens OAuth ou o token bearer estático. | Pelo menos um de LOGIN_PASSWORD ou STATIC_BEARER_TOKEN. |
Os endpoints OAuth (/authorize, /token, /register, /.well-known/*, /login) são sempre registrados. No modo bearer eles são inertes — nada no seu README precisa apontar para eles.
Gerando segredos
uv run --no-project python -c "import secrets; print(secrets.token_urlsafe(48))" # bearer token
uv run --no-project python -c "import secrets; print(secrets.token_urlsafe(48))" # session secret
Usando o token bearer estático
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"}'
Conectando do Claude.ai (OAuth)
Configurações → Conectores → Adicionar conector personalizado → URL: https://YOUR.DOMAIN/mcp → deixe o ID do cliente OAuth / segredo em branco (Claude.ai usa DCR). Quando o Claude.ai abrir o fluxo OAuth, você será solicitado a fornecer LOGIN_PASSWORD.
Executar
cp .env.example .env
# edit .env: set TWS_USERID / TWS_PASSWORD (paper account), LOGIN_PASSWORD, STATIC_BEARER_TOKEN, PUBLIC_BASE_URL
docker compose up -d
Por padrão, isso puxa a imagem multi-arquitetura publicada do GitHub Container Registry: ghcr.io/adwiteeymauriya/ibkr-portfolio-builder-mcp:latest. Para construir localmente em vez disso (por exemplo, ao iterar no código-fonte), execute docker compose build ibkr-mcp primeiro.
O ib-gateway leva ~60–90 s para concluir o login na IBKR após a primeira inicialização. Acompanhe os logs com docker logs -f ibkr-mcp-gateway.
Para uso somente local (clientes com token bearer, sem Claude.ai), isso é suficiente — http://localhost:8000/mcp está agora servindo. Conectores personalizados do Claude.ai exigem uma URL HTTPS na internet pública, então um proxy reverso com TLS na frente é necessário.
Colocando TLS na frente para Claude.ai
Escolha um. Ambos terminam com um https://your-host/mcp funcional e um certificado válido.
Opção 1 — Cloudflare Tunnel (sem IP público, sem encaminhamento de porta). Melhor se o servidor roda em uma rede doméstica ou VM atrás de NAT. Cloudflare fornece um hostname e TLS gratuitamente; o daemon do túnel faz chamadas de saída do servidor para a borda da Cloudflare.
# One-time: install cloudflared, then
cloudflared tunnel login
cloudflared tunnel create ibkr-mcp
cloudflared tunnel route dns ibkr-mcp ibkr-mcp.your-domain.com
~/.cloudflared/config.yml:
tunnel: ibkr-mcp
credentials-file: /home/you/.cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: ibkr-mcp.your-domain.com
service: http://localhost:8000
- service: http_status:404
Execute com cloudflared tunnel run ibkr-mcp (ou instale como unidade systemd via cloudflared service install). Em seguida, defina PUBLIC_BASE_URL=https://ibkr-mcp.your-domain.com em .env e docker compose restart ibkr-mcp.
Opção 2 — Proxy reverso Caddy com Let's Encrypt. Melhor se o servidor tem IP público e portas 80/443 abertas. Caddy busca certificados automaticamente.
Caddyfile:
ibkr-mcp.your-domain.com {
reverse_proxy localhost:8000
}
Execute com caddy run (ou instale como serviço de sistema: sudo caddy start + uma unidade systemd). Mesma mudança de .env acima.
Em ambos os casos, PUBLIC_BASE_URL deve corresponder exatamente à URL que você dá ao Claude.ai — Claude.ai valida o emissor OAuth contra ela.
Exemplos de prompts LLM (fluxo de trabalho top-down)
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
| Área | Item |
|---|---|
| Autenticação | Sessões, clientes DCR, tokens OAuth com suporte a Redis |
| Autenticação | Escopos por token (read-only, read-news, screener-only, ...) |
| Instrumentos | Opções (cadeias, gregas, cálculo IV/preço) |
| Instrumentos | Futuros (ContFuture, combos via Bag) |
| Instrumentos | Títulos (busca + cotação) |
| Instrumentos | Forex + cripto |
| Bolsas | Roteamentos de ações não-EUA (UE, HK, JP, AU) |
| Bolsas | ib_account_summary ciente de moeda |
| Pesquisa | Fundamentos Reuters (reqFundamentalDataAsync) |
| Pesquisa | Barras de streaming em tempo real + tick a tick |
| Pesquisa | Livro de ordens Nível 2 |
| Pesquisa | Fluxos de PnL diário (pnlAsync, pnlSingleAsync) |
| Pesquisa | Subcontas de consultor (reqFamilyCodesAsync) |
| Pesquisa | Catálogo → Memgraph para consultas multi-hop |
| Pesquisa | ib_news_search mais amplo |
| Risco | ib_what_if_order (pré-visualização de margem, sem execução) |
| Risco | Ferramentas de instrução encenadas localmente (sem escrita IBKR) |
Issues abertas / PRs são bem-vindos em qualquer um desses.
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
Licença
MIT.
Agradecimentos
- gnzsnz/ib-gateway-docker pela imagem ib-gateway headless.
- ib_async pelo cliente IBKR assíncrono.
- FastMCP pelo framework de servidor MCP com suporte OAuth integrado.
Aviso legal
Este software fala com sua conta da Interactive Brokers. Por padrão, ele roda contra uma conta de papel em modo API somente leitura — ordens não podem ser colocadas mesmo se uma ferramenta tentar. Se você mudar para uma conta real, faz isso por sua conta e risco. Nenhuma saída de ferramenta constitui aconselhamento de investimento; a marcação de estratégia é um auxiliar de vocabulário, não um mecanismo de recomendação.