Documentation

Servidor MCP (Live)

Conecte um agente de IA diretamente à Live Execution API via Model Context Protocol — gerencie subscriptions ao vivo e receba webhooks assinados, sem código de integração customizado.

#Visão geral

O emidlabs-live-mcp é um servidor Model Context Protocol (MCP) hospedado que expõe a Live Execution API como tools chamáveis por agente — a contraparte ao vivo do emidlabs-backtest-mcp. Aponte qualquer cliente compatível com MCP ou coding agent pra ele e ele consegue criar e gerenciar subscriptions ao vivo e ler sinais emitidos diretamente, sem você escrever uma integração REST.

Endpoint: https://mcp.live.emidlabs.com/mcp (transporte Streamable HTTP).

Esse servidor é um adaptador de protocolo fino — não tem lógica própria além de validar entrada e repassar pro live.emidlabs.com. Toda subscription que ele cria usa sua própria API key da EmidLabs e conta pro limite de subscriptions concorrentes da sua conta, do mesmo jeito que chamar a API REST diretamente.

#Conectando um agente

Funciona comClaudeChatGPTCursor+ any MCP client
1

Escolha seu cliente

Claude e ChatGPT descobrem esse servidor automaticamente via OAuth. Cursor e a maioria dos coding agents preferem o bloco JSON cru abaixo.

2

Adicione o conector

Adicione o servidor na configuração do seu cliente MCP. O arquivo exato varia por cliente, mas o formato é o mesmo em todo lugar — um nome e uma URL:

mcp config (ex: claude_desktop_config.json)
{
  "mcpServers": {
    "emidlabs-live": {
      "url": "https://mcp.live.emidlabs.com/mcp"
    }
  }
}
Alguns clientes (ex: o diálogo "Add custom connector" do Claude) pedem uma URL simples em vez desse bloco JSON. Cole o endereço completo incluindo o caminho /mcp https://mcp.live.emidlabs.com/mcp, não só mcp.live.emidlabs.com. Esquecer o caminho é o motivo mais comum de um conector falhar ao registrar, e o erro resultante raramente deixa a causa real óbvia.
3

Autentique

Três formas de autenticar, e você pode combinar mais de uma — o conector tenta na ordem abaixo:

MétodoComoMelhor para
Login via OAuth (recomendado)Só adicione o conector sem configuração extra. Claude/ChatGPT descobrem o fluxo de login automaticamente e pedem pra você entrar com sua conta EmidLabs — uma API key dedicada é criada pra sua conta na primeira vez e reutilizada depois disso.Conectores pessoais no Claude.ai / ChatGPT. Nada pra copiar, colar ou digitar — nunca.
Header x-api-keyConfigure uma API key específica da EmidLabs uma vez ao adicionar o conector (ex: a opção "custom header" / static_headers do Claude) — anexada automaticamente em toda requisição a partir daí.Conectores gerenciados por organização, onde um admin quer que todo membro compartilhe uma key específica em vez de logins OAuth individuais.
Argumento na toolPasse uma API key como liveApiKey em cada chamada — o agente recebe a key diretamente (ex: na conversa).Coding agents, uso local/CLI, ou qualquer cliente sem suporte a autenticação no nível do conector.
Precedência quando mais de um está presente: header, depois OAuth, depois o argumento — se nenhum se aplica, toda chamada de tool falha rápido com um erro claro nomeando as três opções, nunca uma falha de autenticação silenciosa ou ambígua. Entrar via OAuth concede automaticamente a mesma key que o servidor Backtest MCP já usa (ou cria uma, na primeira vez) — um login cobre os dois conectores, sem etapa de registro separada.

#Tools

create_subscription

Inscreve uma estratégia pra avaliação ao vivo num par de ativo. A estratégia reavalia toda vez que um candle fecha no seu timeframe configurado, emitindo um sinal de Entry ou Exit sempre que decision.entry/decision.exit vira true — sem tracking de posição, só sinal.

provider escuta diretamente naCoinbaseBinance

Sem lista fixa de ativos pra consultar antes — qualquer par que a corretora escolhida realmente liste pode ser inscrito. Isso é mais amplo que submit_backtest, que só cobre ativos que a EmidLabs já extraiu e armazenou candles históricos.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
assetPairstringDeve estar no formato exato que a corretora escolhida espera — nenhuma tradução acontece em lugar nenhum. Coinbase: "BTC-USDC" (com hífen). Binance: "BTCUSDC" (sem hífen).
providerstring (opcional)Qual provedor de dados de mercado escutar: "coinbase" ou "binance". Usa "coinbase" por padrão quando omitido.
strategySnapshotJsonobjectO objeto de Strategy DSL — veja o resource strategy-dsl-spec abaixo. Formato idêntico ao de submit_backtest.
webhookUrlstring (opcional)URL https:// absoluta. Quando definida, todo sinal emitido também é enviado via POST pra ela — veja Webhooks abaixo.
modelstring (opcional)"stateless" (padrão quando omitido) ou "stateful" — veja Signal Model abaixo.
isPositionedboolean (opcional)Só tem significado quando model é "stateful". Usa false (ainda não posicionado) por padrão quando omitido.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.

Não há verificação de que assetPair realmente existe na corretora escolhida no momento da criação — um par inválido, ou o par certo no formato errado de provider, é aceito imediatamente e depois o status da subscription muda pra "Errored" em cerca de um minuto. Confira get_subscription logo após criar se você não tem certeza que o formato estava certo.

webhookSecret só é retornado nessa resposta, uma única vez — salve imediatamente. Nenhuma tool ou endpoint o repete depois, a mesma regra de revelação única que as API keys da EmidLabs já seguem.

create_subscriptions_batch

Inscreve a MESMA estratégia pra avaliação ao vivo em vários pares de ativo de uma vez, uma subscription por entrada em assetPairs. Best-effort por item — um par de ativo ruim nunca falha o resto do batch, confira o status/erro de cada item.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
assetPairsstring[]Uma entrada por subscription a criar. Máximo de 50 por chamada.
strategySnapshotJsonobjectCompartilhado por toda subscription desse batch — formato idêntico ao próprio campo de create_subscription.
providerstring (opcional)Compartilhado por toda subscription desse batch. Usa "coinbase" por padrão quando omitido.
webhookUrlstring (opcional)Compartilhado por toda subscription desse batch — cada uma ainda ganha suas próprias entregas assinadas e seu próprio secret.
modelstring (opcional)Compartilhado por toda subscription desse batch. "stateless" (padrão quando omitido) ou "stateful" — veja Signal Model abaixo.
isPositionedboolean (opcional)Compartilhado por toda subscription desse batch, só tem significado quando model é "stateful". Usa false por padrão quando omitido.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.
Cada item bem-sucedido ganha seu próprio webhookSecret quando webhookUrl é definida — retornado uma vez por item nessa resposta, mesma regra de revelação única de create_subscription.

stop_subscription

Para uma subscription ao vivo. Idempotente — parar uma subscription já parada só retorna o status atual dela.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
subscriptionIdstringO id retornado por create_subscription.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.

stop_subscriptions

Para uma lista específica de subscriptions ao vivo, numa chamada. Idempotente por id — uma subscription já parada é simplesmente ignorada, não é erro.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
idsstring[]Ids de subscription a parar, como retornados por create_subscription/list_subscriptions. Máximo de 200 por chamada.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.

stop_all_subscriptions

Para toda subscription ao vivo atualmente ativa nessa conta, numa chamada. Idempotente — subscriptions já paradas são simplesmente ignoradas.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.
Sem jeito de restringir isso a um subconjunto das suas subscriptions — age na conta inteira. Use stop_subscriptions com uma lista explícita de ids se você só quer parar algumas.

update_subscription

Atualiza model/isPositioned/webhookUrl de uma subscription. assetPair, timeframe, provider, e a estratégia em si nunca podem ser mudados depois da criação — stop_subscription e create_subscription pra isso.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
subscriptionIdstringO id retornado por create_subscription.
modelstring (opcional)"stateless" ou "stateful". Omita pra manter inalterado — veja Signal Model abaixo.
isPositionedboolean (opcional)Só tem significado quando o model dessa subscription é (ou está sendo definido pra) "stateful". Omita pra manter inalterado.
webhookUrlstring (opcional)Uma nova URL https:// absoluta, ou uma string vazia pra remover o webhook existente. Omita pra manter inalterado.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.
Mudar webhookUrl pra um valor não-vazio gera um webhookSecret novo, retornado só nessa resposta — salve imediatamente.

get_subscription

Busca o status atual de uma subscription ao vivo pelo id — par de ativo, provider, timeframe, status, model/isPositioned, e o último candle avaliado.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
subscriptionIdstringO id retornado por create_subscription.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.

list_subscriptions

Lista subscriptions ao vivo dessa conta, paginado.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
pageinteger (opcional)Número da página, começando em 1. Padrão 1.
pageSizeinteger (opcional)Resultados por página, 1-100. Padrão 20.
statusstring (opcional)Filtro de correspondência exata: "Active", "Stopped" ou "Errored". Omita pra retornar todos os status.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.

get_subscription_signals

Lista os sinais de Entry/Exit que uma subscription ao vivo emitiu, paginado, cada um com o candle em que disparou, quais conditions nomeadas eram true, o detalhamento do score, e — pra sinais de Entry — os níveis de preço de stop-loss/take-profit calculados.

ArgumentoTipoDescrição
liveApiKeystring (opcional)Desnecessário se você conectou via login OAuth ou o header x-api-key está configurado nesse conector.
subscriptionIdstringO id retornado por create_subscription.
pageinteger (opcional)Número da página, começando em 1. Padrão 1.
pageSizeinteger (opcional)Resultados por página, 1-100. Padrão 20.
typestring (opcional)Filtro de correspondência exata: "Entry" ou "Exit". Omita pra retornar os dois.
liveBaseUrlstring (opcional)Usa a API pública de produção por padrão.

#Signal Model: Stateless vs Stateful

Toda subscription começa "stateless" — um sinal é registrado/entregue toda vez que decision.entry/decision.exit avalia true, mesmo repetidamente, se a condition subjacente não é edge-triggered (ex: um simples rsi14 > 55 em vez de crossUp(...)/crossDown(...) — permanece true por vários candles consecutivos). Mude uma subscription pra "stateful" via update_subscription pra fazer ela rastrear sua própria posição de Entry/Exit internamente (nunca consultada da sua corretora) e só disparar numa transição de verdade — o resto é suprimido silenciosamente.

isPositioned é uma correção manual, nunca inferida de um saldo real da corretora — esse servidor não tem integração própria com corretora nenhuma. Corrija o desvio você mesmo via update_subscription quando acontecer (ex: um trade feito manualmente fora desse sistema).

Tabela completa de comportamento: Live Execution API — Signal Model.

#Webhooks

Passe webhookUrl pra create_subscription e todo sinal que essa subscription emitir também é enviado via POST pra lá como JSON — sem precisar de polling. Cada entrega é assinada pra você poder verificar que realmente veio da EmidLabs:

HeaderFormatoVerificação
X-Emidlabs-Signaturet={timestamp unix},v1={HMAC-SHA256 hex}Recompute HMAC-SHA256(webhookSecret, `${timestamp}.${rawBody}`) e compare com v1 — o mesmo esquema que a própria EmidLabs usa pra verificar webhooks de entrada do Stripe, aplicado aqui do lado de envio.

Entrega tenta de novo até 3 vezes (backoff curto) em erros de rede, timeouts, 429s e respostas 5xx do seu endpoint — um webhook lento ou inacessível nunca bloqueia ou atrasa a avaliação de sinal em si.

#Resources

strategy-dsl-spec

Uma referência condensada, em markdown, pro formato JSON exato de Strategy DSL esperado pelo campo strategySnapshotJson de create_subscription (emidlabs://strategy-dsl-spec) — formato idêntico à própria cópia do emidlabs-backtest-mcp e ao bloco Copiar Spec para IA da página Strategy System.

A seção de inputs/conditions/score é buscada em tempo real do dono do domínio do emidlabs-strategy-mcp (o próprio GET /dsl-core-reference do strategy-api) e cacheada por alguns minutos, em vez de copiada à mão — o mesmo núcleo que o emidlabs-backtest-mcp e o emidlabs-strategy-mcp também buscam, então essa parte não consegue dessincronizar entre eles. A parte local desse servidor deliberadamente omite entryFeePct/exitFeePct (só de backtest), e documenta riskManagement como apenas informativo — uma subscription ao vivo nunca fecha nada automaticamente, ao contrário de um backtest.

Ler esse resource primeiro é opcional, não obrigatório — todo campo no próprio schema da tool create_subscription já documenta seu formato exato diretamente, já que clientes MCP não buscam de forma confiável um resource separado antes de gerar uma chamada.

#Limites de taxa

Dois limites independentes se aplicam, e eles aparecem de forma diferente de propósito pra nunca serem confundidos entre si:

LimiteEscopoO que protegeO que você vê
Cota do live-api / limite de subscriptions concorrentesPor API keyO limite real de uso/faturamento da sua contaUm 4xx do live-api, repassado como erro de tool do MCP.
Guarda de infra do MCPPor IP/conexãoO processo do MCP em si, contra loops descontrolados ou enxurradas malformadasUm 429 com uma mensagem identificando explicitamente que é a guarda da própria camada MCP, não a cota da sua conta.
O servidor MCP não aplica sua própria cópia do limite de subscription da sua conta — isso arriscaria dois contadores discordando pra mesma chamada. Ele só adiciona uma guarda baseada em IP, folgada e generosa, pra proteger o próprio processo do servidor.

#Escopo

Esse servidor só expõe gestão de subscription ao vivo — criar, parar, inspecionar subscriptions, e ler seus sinais. Ele não expõe nenhuma ação do Console (criar ou rotacionar API keys, mudar planos de cobrança, gestão de conta). Essas continuam sendo ações só-humano na UI do Console, mantidas de propósito fora do que um agente autônomo pode fazer sem supervisão.