Debugg AI
oficialPermita que seus agentes de geração de código criem e executem testes ponta a ponta sem configuração contra novas alterações de código em navegadores remotos por meio da plataforma de testes Debugg AI.
O que você pode fazer com Debugg AI MCP?
- Executar testes de IA no navegador — Peça para testar qualquer URL ou aplicativo localhost com instruções em linguagem natural via
check_app_in_browser, retornando aprovação/reprovação com capturas de tela. - Explorar várias páginas rapidamente — Use
probe_pagepara verificar em lote 1-20 URLs em busca de erros de console, problemas de rede e estado renderizado, sem custos de LLM. - Gerenciar ambientes de teste — Crie, atualize ou liste ambientes com credenciais e hosts SSO autorizados usando a ferramenta
environment. - Disparar rastreamentos de site — Acione
trigger_crawlpara popular o grafo de conhecimento do projeto com rastreamento via agente no navegador do lado do servidor. - Executar e acompanhar suítes de teste — Crie suítes, dispare execuções assíncronas e busque resultados por teste via ações de
test_suite. - Inspecionar artefatos de execução — Recupere detalhes completos de execução, rastros de rede HAR e logs de console por meio de
executionspara depurar problemas em tempo de execução.
Documentação
Debugg AI — Servidor MCP
Testes de navegador com IA via Model Context Protocol. Aponte para qualquer URL (ou localhost) e descreva o que testar — um agente de IA navega pelo seu aplicativo e retorna aprovação/reprovação com capturas de tela.
Configuração
Requer Node.js 20.20.0 ou posterior (requisito transitivo de posthog-node@^5.26.0).
Testar URLs http://localhost:... requer o binário caddy — check_app_in_browser,
probe_page e trigger_crawl fazem túnel de destinos localhost através de um proxy reverso Caddy local.
Isso é instalado automaticamente: a dependência npm @radically-straightforward/caddy baixa uma
versão fixada do Caddy para sua plataforma durante npm install/npx — nada para instalar manualmente no
caso normal. Agora é o único binário que este pacote baixa; o cliente de túnel em si é
TypeScript puro — ele substituiu o pacote ngrok, que buscava o agente ngrok.
Se esse download nunca ocorreu (npm install --ignore-scripts, instalação offline/isolada), aponte CADDY_BIN para
sua própria instalação (brew install caddy / apt install caddy / veja
caddyserver.com/docs/install) — a ausência aparece como um
erro claro na primeira chamada de URL localhost, não um travamento silencioso. Chamadas de URL pública, todas as
ferramentas que não são de navegador e test_suite {action:"run"} (que usa seu próprio túnel dedicado e
ignora o Caddy completamente) não precisam dele de qualquer forma.
Obtenha uma chave de API em debugg.ai e adicione à configuração do seu cliente MCP:
{
"mcpServers": {
"debugg-ai": {
"command": "npx",
"args": ["-y", "@debugg-ai/debugg-ai-mcp"],
"env": {
"DEBUGGAI_API_KEY": "your_api_key_here"
}
}
}
}
Ou com Docker:
docker run -i --rm --init -e DEBUGGAI_API_KEY=your_api_key quinnosha/debugg-ai-mcp
A etapa npm install do Dockerfile captaria caddy da mesma forma automática que instalações locais
fazem, em princípio — mas no momento em que este texto foi escrito, o Dockerfile não COPY vários diretórios que o
build agora precisa (handlers, tools, types, config) e ainda referencia um diretório tunnels/
que não existe mais, então um build novo provavelmente falha antes que isso importe. Essa é uma
lacuna pré-existente, não relacionada ao Caddy. A imagem quinnosha/debugg-ai-mcp atualmente publicada
é anterior à dependência do Caddy de qualquer forma — chamadas de URL localhost para
check_app_in_browser/probe_page/trigger_crawl falharão com CaddyBinaryNotFoundError
dentro dessa imagem até que ela seja reconstruída (Dockerfile corrigido) e republicada, ou CADDY_BIN aponte para
uma incorporada separadamente. Chamadas de URL pública, as ferramentas que não são de navegador e test_suite {action:"run"}
não são afetadas de qualquer forma.
Ferramentas
O servidor expõe 8 ferramentas: três ferramentas de Navegador mais uma ferramenta baseada em ação por entidade gerenciada. As ferramentas principais são check_app_in_browser (agente de IA completo) e probe_page (sonda de página leve sem LLM). As demais — project, environment, test_suite, test_case, executions — cada uma recebe um discriminador action (ex.: {"action":"list"}) que seleciona a operação. Ações destrutivas de delete exigem confirmação (um prompt de elicitação quando suportado, caso contrário confirm: true).
Navegador
check_app_in_browser
Executa um agente de navegador com IA contra seu aplicativo. O agente navega, interage e reporta com capturas de tela. URLs localhost são automaticamente tuneladas através do servidor de túnel debugg.
| Parâmetro | Tipo | Descrição |
|---|---|---|
description | string obrigatório | O que testar (linguagem natural) |
url | string obrigatório | URL alvo — http://localhost:3000 é tunelada automaticamente |
environmentId | string | UUID de um ambiente específico |
credentialId | string | UUID de uma credencial específica |
credentialRole | string | Escolher uma credencial por papel (ex.: admin, guest) |
username | string | Nome de usuário para login (efêmero — não persistido) |
password | string | Senha para login (efêmera — não persistida) |
loginCredentials | array | Contas para logins que o agente encontra durante a tarefa — [{username, password, label?}] |
useEnvironmentCredentials | boolean | Padrão true. false proíbe o preenchimento automático das credenciais armazenadas do ambiente; sem conta nomeada significa não fazer login de forma alguma |
freshSession | boolean | Padrão false. true força um login real em vez de reutilizar a sessão ativa mantida para aquela conta |
auth | object | Pré-condição de autenticação — {precondition, entryUrl, deepUrl, environmentId, username, password} |
repoName | string | Substituir o nome do repositório git detectado automaticamente (ex.: my-org/my-repo) |
Uma verificação focada por chamada. O agente tem um orçamento interno de ~25 passos; divida suítes maiores em várias chamadas.
Credenciais: passe-as como parâmetros, não em prosa
Nomear uma conta apenas em description não faz o agente usá-la — ele recorre à credencial armazenada do ambiente, e a rejeição do aplicativo à conta errada parece uma falha do aplicativo. Qualquer coisa que você passe como parâmetro supera o padrão do ambiente para todos os logins na execução, não apenas o primeiro:
username/password(oucredentialId/credentialRole) — a identidade da execução.auth.username/auth.password— fixa o login de pré-condição quando você também usaauth.precondition: "login".loginCredentials— contas para um formulário de login que o agente encontra no meio da tarefa. Esta é a opção para fluxos como definir senha → ser redirecionado para login → entrar como a conta que você acabou de criar, onde dividir em chamadas separadas perderia o estado do navegador.
Defina useEnvironmentCredentials: false quando uma substituição silenciosa pelo usuário de teste padrão invalidaria a verificação.
SSO entre domínios? Uma execução só digita credenciais no host do próprio aplicativo e seus subdomínios; uma página de login em outro domínio é recusada como offscope_host. Adicione o host do provedor de identidade ao authorizedCredentialHosts do ambiente (veja environment).
Verificando uma página que não precisa de login? Passe useEnvironmentCredentials: false e não nomeie nenhuma conta. Essa combinação significa exatamente o que diz — não fazer login — e a execução pula a autenticação completamente em vez de procurar um formulário de login. Use para páginas públicas, sites de marketing, documentação e qualquer coisa pré-autenticação. Também é mais rápido: no padrão (auto), o agente seguirá um link "Entrar" para fora da sua página e tentará a conta armazenada do ambiente antes de avaliar qualquer coisa.
Reutilização de sessão: por que uma verificação pode reportar "sem formulário de login"
As execuções não fazem login toda vez. Após um login verificado, o backend captura a sessão daquela conta e a restaura na próxima execução para a mesma identidade, o que pula o login completamente — é por isso que uma verificação pode legitimamente retornar com submitted: false e sem formulário de login: já estava autenticada. Uma execução restaurada se reporta em logins com reason: "restored_session", para que você possa distingui-la de uma execução que genuinamente não encontrou formulário.
As sessões são chaveadas por conta, então nomear uma conta diferente nunca reutiliza a de outra pessoa. Duas maneiras de contornar a reutilização:
freshSession: trueem uma única chamada — faça login de verdade desta vez e recapture. Use quando o fluxo de login é o que você está verificando, quando suspeitar que a sessão armazenada está desatualizada, ou quando a única rota do aplicativo entre personas é um logout.- Ferramenta
environment,action: "clearSessions"— invalida as sessões armazenadas para que execuções subsequentes façam login. Restrinja comusername/credentialId; limpezas sem escopo exigem confirmação porque todas as contas do ambiente então reautenticam.
Use action: "sessions" para ver o que um ambiente está mantendo atualmente e se cada uma seria reutilizada.
Os resultados reportam a identidade realmente usada, então uma errada é visível em vez de se passar por um aplicativo quebrado:
"logins": [
{ "username": "qa+invitefix@example.com", "source": "task", "submitted": true, "authenticated": true },
{ "username": "qatest123@example.com", "source": "env_default", "submitted": false, "authenticated": false,
"reason": "offscope_host", "detail": "refused to enter credentials on auth.idp.example: not part of this run's scope …" }
],
"credentialWarning": {
"requested": "qa+invitefix@example.com",
"used": ["qatest123@example.com"]
}
source é task | explicit | credential_id (uma conta que você nomeou) ou env | env_default (a conta armazenada do ambiente). submitted é verdadeiro apenas quando credenciais foram realmente digitadas e enviadas; reason diz o que aconteceu (ex.: offscope_host, restored_session), e detail, quando presente, é uma explicação legível dele — para uma recusa offscope_host ele nomeia o host e como autorizá-lo. credentialWarning aparece apenas quando você nomeou uma conta e um padrão do ambiente para uma conta diferente foi realmente enviado — nunca para um login recusado ou pulado. loginError aparece quando uma conta nomeada não pôde ser resolvida e a execução se recusou a substituí-la por outra.
Toda execução bem-sucedida retorna um bloco browserSession junto com a captura de tela — URLs S3 pré-assinadas para o HAR capturado (rastro completo de rede) e o log do console (todas as mensagens do console JS). Use-os para detectar loops de refetch, erros de hidratação e outros problemas de runtime que passam por type-checks e testes unitários:
"browserSession": {
"harUrl": "https://...session_18139.har?X-Amz-...",
"consoleLogUrl": "https://...session_18139_console.json?X-Amz-...",
"recordingUrl": "https://...session_18139_recording.webm?X-Amz-...",
"harStatus": "downloaded",
"consoleLogStatus": "downloaded",
"harRedactionStatus": "redacted",
"consoleLogRedactionStatus": "redacted"
}
As URLs são S3 pré-assinadas de curta duração — busque novamente a execução pai via executions {action:"get", uuid} para renovar. harStatus / consoleLogStatus desambiguam 'downloaded' (URL buscável), 'not_available' (a página não emitiu nada), 'failed' (a captura falhou). Em uma execução nova, as URLs são comumente null porque a captura é enviada de forma assíncrona após o agente terminar — faça polling de executions {action:"get", uuid: executionId} até o status atingir 'downloaded'. Cabeçalhos de Autorização / Cookie / token/secret/api_key são removidos no servidor antes que os artefatos sejam persistidos.
trigger_crawl
Dispara um rastreamento de agente de navegador no servidor para popular o grafo de conhecimento do projeto. URLs localhost são tuneladas automaticamente. Retorna {executionId, status, targetUrl, durationMs, outcome?, crawlSummary?, knowledgeGraph?, browserSession?} com knowledgeGraph.skipped === false na ingestão bem-sucedida. crawlSummary e knowledgeGraph carregam apenas as chaves que os nós de rastreamento/importação do backend reportaram — uma contagem ausente está ausente, nunca um 0 preenchido. O bloco browserSession (URLs de HAR + log do console, mesma forma que acima) também está presente em rastreamentos concluídos.
probe_page
Sonda de página em lote leve sem LLM. Passe 1-20 URLs; cada uma navega, estabiliza no conteúdo (o DOM ficando quieto, com limite — nunca em silêncio de rede, que um aplicativo ao vivo nunca atinge) e retorna o estado renderizado — captura de tela + metadados da página + erros estruturados do console + resumo de rede. Sem loop de agente, sem custo de LLM, sem asserções de cenário. Use para "será que eu quebrei /settings?", fumaça multi-rota após um refactor, varreduras de CI por PR e verificações rápidas de "está no ar" onde o loop de agente de 60-150s do check_app_in_browser é exagero.
| Parâmetro | Tipo | Descrição |
|---|---|---|
targets | array obrigatório | 1-20 entradas: [{url, waitForSelector?, waitForLoadState?, timeoutMs?}] |
targets[].url | string obrigatório | URL pública ou localhost (tunelada automaticamente) |
targets[].waitForLoadState | enum | 'domcontentloaded' (padrão, + uma estabilização de conteúdo com limite) / 'load' (também aguarda embeds de terceiros) / 'networkidle' (aceito, nunca emitido — a rede de um site ao vivo não fica ociosa) |
targets[].waitForSelector | string | Seletor CSS opcional para aguardar após a navegação |
targets[].timeoutMs | number | Timeout por URL, 1000-30000 (padrão 10000) |
includeHtml | boolean | Retornar HTML bruto em cada resultado (padrão false) |
captureScreenshots | boolean | Retornar um PNG por alvo (padrão true) |
Todos os alvos em um lote compartilham um túnel de sessão, mas apenas lotes de mesma porta (ou todos públicos) compartilham uma única execução de backend — 5 URLs em uma porta em uma chamada é dramaticamente mais rápido que 5 chamadas paralelas de URL única. Um lote que mistura múltiplas portas locais se decompõe em uma execução sequencial de backend por grupo de porta (ainda uma chamada, ainda um results[] mesclado na sua ordem original, mas N viagens de ida e volta de backend em vez de uma — mais lento, não rejeitado). O campo error por URL preserva a resiliência do lote: um único alvo com falha não falha os outros.
networkSummary chave de agregação é origin + pathname — loops de refetch (?n=0..4 atingindo repetidamente o mesmo endpoint) são colapsados em uma única entrada com a contagem, então /api/poll aparecendo com count: 47 é o sinal acionável de "loop de refetch infinito" que os usuários pediram originalmente.
Orçamento de desempenho: <10s para 1 URL, <25s para 20. Porta morta do localhost retorna LocalServerUnreachable em <2s sem queimar uma execução de workflow.
project
| Ação | Parâmetros | Resultado |
|---|---|---|
get | {uuid} | Detalhe do projeto curado |
list | {q?, page?, pageSize?} | Resumos paginados |
create | {name, platform, (teamUuid|teamName), (repoUuid|repoName)} | Projeto criado |
Time e repositório são resolvidos por uuid ou nome (correspondência exata sem diferenciar maiúsculas/minúsculas; NotFound se nenhum, AmbiguousMatch se múltiplos). Não há update/delete — renomeie ou exclua um projeto no aplicativo web DebuggAI.
environment
| Ação | Parâmetros | Resultado |
|---|---|---|
get | {uuid, projectUuid?} | Ambiente com credenciais embutidas (senhas nunca retornadas) |
list | {projectUuid?, q?, page?, pageSize?} | Ambientes paginados, cada um com um array de credenciais |
create | {name, url, description?, projectUuid?, credentials?, authorizedCredentialHosts?} | Ambiente criado (opcionalmente semeia credenciais) |
update | {uuid, name?, url?, description?, addCredentials?, updateCredentials?, removeCredentialIds?, authorizedCredentialHosts?} | Ambiente corrigido; operações de credencial executam remover → atualizar → adicionar |
delete | {uuid, projectUuid?, confirm?} | Exclui ambiente (cascateia credenciais) — requer confirmação |
sessions | {uuid, username?, credentialId?} | Sessões de login capturadas que o ambiente mantém, por conta, cada uma com seu próprio isUsable |
clearSessions | {uuid, username?, credentialId?, confirm?} | Invalida-as para que a próxima execução faça login de verdade — limpezas sem escopo requerem confirmação |
projectUuid resolve automaticamente a partir do repositório git quando omitido. Falhas por credencial aparecem em credentialWarnings[] sem bloquear a operação do ambiente.
authorizedCredentialHosts lista hosts onde uma execução pode inserir as credenciais deste ambiente além do host do próprio aplicativo — para SSO entre domínios, adicione o host do IdP aqui (ex.: ["auth.example.com"]). Apenas nomes de host nus: sem esquema, caminho, porta ou curinga (subdomínios do host do aplicativo já estão no escopo). Em update substitui a lista; [] limpa-a. get/list retornam-na quando o servidor suporta. A resposta ecoa a lista salva; se o servidor não a persistiu (servidores mais antigos ignoram o campo), o resultado carrega authorizedCredentialHostsWarning: {requested, returned} em vez de um sucesso silencioso.
sessions / clearSessions gerenciam as sessões autenticadas quentes que o backend reutiliza para pular o login (veja Reutilização de sessão). O conteúdo das sessões nunca é retornado — um cookie de sessão é uma credencial de portador. clearSessions marca sessões como inválidas em vez de excluir as linhas, então a reutilização para imediatamente enquanto o histórico de captura permanece legível.
test_suite
| Ação | Parâmetros | Resultado |
|---|---|---|
list | {projectUuid|projectName, search?, page?, pageSize?} | Suítes paginadas com status + taxa de aprovação |
create | {name, description, projectUuid|projectName} | Suíte criada |
run | {suiteUuid|(suiteName+project), targetUrl?} | Dispara todos os testes de forma assíncrona |
results | {suiteUuid|(suiteName+project)} | Suíte + resultados por teste |
delete | {suiteUuid|(suiteName+project), confirm?} | Exclusão suave — requer confirmação |
test_case
| Ação | Parâmetros | Resultado |
|---|---|---|
create | {name, description, agentTaskDescription, suiteUuid|(suiteName+project), relativeUrl?, maxSteps?} | Caso de teste criado (não executado automaticamente) |
update | {testUuid, name?, description?, agentTaskDescription?} | Caso de teste corrigido |
delete | {testUuid, confirm?} | Exclusão suave — requer confirmação |
executions
| Ação | Parâmetros | Resultado |
|---|---|---|
get | {uuid} | Detalhe completo (nodeExecutions + estado + errorInfo) + artefatos de screenshot/gif |
list | {status?, projectUuid?, page?, pageSize?} | Resumos paginados |
404 do backend aparece como isError: true com {error: 'NotFound', message, uuid}. Credenciais são sempre retornadas sem senhas.
Paginação
Toda resposta list é paginada. Formato da resposta:
{
"pageInfo": { "page": 1, "pageSize": 20, "totalCount": 47, "totalPages": 3, "hasMore": true },
"<items>": [ ... ]
}
Passe page opcional (indexado a partir de 1, padrão 1) e pageSize (padrão 20, máximo 200; valores acima do limite são ajustados). Nenhuma resposta é silenciosamente truncada.
Um get retorna o único objeto sob seu nome singular — {project}, {execution}, {project, environment} — sem pageInfo.
Recursos
Além das ferramentas, o servidor expõe as entidades somente leitura como recursos MCP para que os clientes possam navegar e mencioná-los com @ como contexto:
| URI | O quê |
|---|---|
debugg-ai://projects | Todos os projetos (primeira página) |
debugg-ai://environments | Ambientes para o projeto auto-detectado |
debugg-ai://executions | Execuções recentes (primeira página) |
debugg-ai://project/{uuid} | Um projeto, detalhe completo |
debugg-ai://environment/{uuid} | Um ambiente (credenciais embutidas, senhas ocultas) |
debugg-ai://execution/{uuid} | Uma execução, detalhe completo do nó + links de artefatos |
As leituras despacham para os mesmos manipuladores das ferramentas project / environment /
executions, então os dados e a autenticação são idênticos. Os recursos são aditivos —
clientes sem suporte a recursos continuam usando as ferramentas.
Invariantes de segurança
- Senhas são somente gravação. Elas nunca aparecem em nenhum corpo de resposta de nenhuma ferramenta.
- URLs de túnel (
*.tunnel.debugg.ai, e o aposentado*.ngrok.debugg.aique execuções históricas ainda referenciam) são removidas de todas as respostas do agente de navegador, incluindo texto escrito pelo agente. - 404s do backend aparecem como
isError: truecom{error: 'NotFound', ...}, nunca como exceções lançadas. DEBUGGAI_API_KEYausente aparece como um erro de ferramenta estruturado na primeira invocação — o servidor ainda registra e lista ferramentas normalmente.
Migração para v6.0.0 (vereditos do backend, sem texto escrito pelo MCP)
Um veredito de execução é pass | fail | error, com o reason do backend retransmitido literalmente. Uma execução que
nunca tentou um teste lê outcome: null, skipped: true, skipReason.
| Removido | Substituição |
|---|---|
success | outcome |
failureCategory | outcome + reason |
stepsTaken / stepsBudget / stepsRemaining | budget: {maxSteps, usedSteps} |
failedNode | errorInfo |
get → projects[0] / executions[0] / environments[0] + pageInfo + filter | {project} / {execution} / {project, environment} |
message / note em avisos e resultados | campos estruturados apenas |
Lista completa: CHANGELOG.md 6.0.0.
Migração para v3.0.0 (ferramentas baseadas em ação)
A v3 consolidou as 20 ferramentas por verbo em 8 ferramentas baseadas em ação. Ferramenta antiga → novo tool {action}:
| Removido | Substituição |
|---|---|
search_projects | project {action:"get"} / project {action:"list"} |
create_project | project {action:"create"} |
update_project, delete_project | Removidas — use o aplicativo web DebuggAI |
search_environments | environment {action:"get"} / {action:"list"} |
create_environment / update_environment / delete_environment | environment {action:"create"|"update"|"delete"} |
create_test_suite / search_test_suites / run_test_suite / get_test_suite_results / delete_test_suite | test_suite {action:"create"|"list"|"run"|"results"|"delete"} |
create_test_case / update_test_case / delete_test_case | test_case {action:"create"|"update"|"delete"} |
search_executions | executions {action:"get"|"list"} |
trigger_crawl headless parâmetro | Removido — sempre headless |
Ações delete agora requerem confirmação (prompt de elicitação, ou confirm: true). Os clientes captam a nova superfície na reinicialização do MCP.
Migração da v1.x (mudança que quebra na v2.0.0)
A v2 colapsou uma superfície de 22 ferramentas para 11. Mapeamento ferramenta antiga → ferramenta nova:
| Removido | Substituição |
|---|---|
list_projects, get_project | search_projects (modo uuid vs modo filtro) |
list_environments, get_environment | search_environments |
list_credentials, get_credential | search_environments — credenciais embutidas em cada ambiente |
create_credential | create_environment({credentials: [...]}) seed, ou update_environment({addCredentials: [...]}) |
update_credential | update_environment({updateCredentials: [{uuid, ...patch}]}) |
delete_credential | update_environment({removeCredentialIds: [uuid]}) |
list_teams, list_repos | create_project({teamName, repoName}) — resolução de nome com tratamento de ambiguidade |
list_executions, get_execution | search_executions |
cancel_execution | Removida — o desligamento do backend é automático |
Mudanças no formato da resposta: o campo count simples em respostas de lista desapareceu — use pageInfo.totalCount.
Configuração
| Variável de ambiente | Obrigatória | Propósito |
|---|---|---|
DEBUGGAI_API_KEY | sim | Chave de API do backend. Aliases: DEBUGGAI_API_TOKEN, DEBUGGAI_JWT_TOKEN. |
DEBUGGAI_API_URL | não | URL base do backend. Padrão: https://api.debugg.ai. |
DEBUGGAI_TOKEN_TYPE | não | token (padrão) ou bearer. |
DEBUGGAI_EVAL_TEMPLATE | não | Substitui o slug do workflow de Avaliação de Aplicativo que check_app_in_browser despacha. Padrão: flow/e2es/app-eval. O despacho fixa este slug para que uma renomeação de template do backend não possa quebrá-lo. |
LOG_LEVEL | não | error / warn / info (padrão) / debug. |
POSTHOG_API_KEY | não | Substitui a chave de projeto de telemetria embutida (ex.: fork privado). |
DEBUGGAI_TELEMETRY_DISABLED | não | Defina como 1 / true / yes / on para desabilitar a telemetria completamente. |
DEBUGGAI_API_KEY=your_api_key
Transporte remoto / HTTP (opcional)
Por padrão, o servidor fala stdio (npx local). Ele pode, em vez disso, rodar como um
MCP remoto hospedado e multiusuário sobre Streamable HTTP sem estado + OAuth:
DEBUGGAI_MCP_TRANSPORT=http PORT=3000 DEBUGGAI_TOKEN_TYPE=bearer npx -y @debugg-ai/debugg-ai-mcp@latest
É um Resource Server OAuth: cada POST /mcp precisa de
Authorization: Bearer <token>; tokens ausentes/inválidos recebem um 401 com um
WWW-Authenticate apontando para os metadados RFC 9728, e os clientes executam o fluxo
OAuth contra o servidor de autorização anunciado. O bearer é escopado por requisição —
api.debugg.ai valida-o.
| Endpoint | Propósito |
|---|---|
POST /mcp | MCP Streamable HTTP (protegido por bearer) |
GET /.well-known/oauth-protected-resource | Metadados RFC 9728 (descoberta do servidor de autorização) |
GET /health | Verificação de saúde do balanceador de carga / ECS |
| Variável de ambiente | Padrão | Propósito |
|---|---|---|
DEBUGGAI_MCP_TRANSPORT | stdio | Defina como http para o transporte remoto |
PORT | 3000 | Porta de escuta HTTP |
DEBUGGAI_MCP_PUBLIC_URL | https://mcp.debugg.ai | URL de recurso público deste servidor (RFC 9728 resource) |
DEBUGGAI_OAUTH_ISSUER | https://auth.debugg.ai | Servidor de autorização anunciado aos clientes |
DEBUGGAI_TOKEN_TYPE | token | Defina como bearer para que tokens OAuth sejam encaminhados como Authorization: Bearer |
Instalações stdio não precisam de nenhuma dessas.
Implantações multi-réplica (go/no-go antes do rollout): o estado do túnel (o túnel de sessão,
sua instância Caddy e seu bloqueio de rota de porta) está em processo, chaveado por chamador por um hash do
token bearer — não há coordenação entre processos. Rodar várias réplicas atrás de um balanceador
de carga round-robin simples significa que as chamadas de um chamador podem cair em réplicas diferentes e criar um
túnel por réplica que atingem em vez de um para a sessão inteira (limitado pela
contagem de réplicas, auto-curável via o desligamento automático por inatividade de 55 minutos existente — nunca um bug
de correção entre sessões, já que qualquer chamada de ferramenta única permanece em uma réplica durante toda a sua duração). Para obter
o comportamento pretendido de "um túnel por sessão" em uma implantação HTTP multi-réplica, configure
roteamento com afinidade de sessão no balanceador de carga (sticky/consistent-hash chaveado na mesma identidade
que getSessionKey() deriva — na prática, o token bearer Authorization do chamador). Veja
docs/local-tunnel-multiplexer-architecture-2026-07-31.md §2.1 para o raciocínio completo e o
caminho de degradação honesto se isso não for configurado.
Telemetria
O servidor MCP vem com telemetria habilitada por padrão — uma chave de projeto PostHog embutida somente para escrita (phc_*) para que a equipe possa observar taxas de acerto de cache, cadência de polling, confiabilidade do túnel e outras métricas operacionais em toda a base de instalação. Eventos capturados:
| Evento | Quando |
|---|---|
tool.executed / tool.failed | Por chamada de ferramenta |
workflow.executed | Por execução do agente de navegador (carrega pollCount, durationMs, finalIntervalMs) |
tunnel.provisioned / tunnel.provision_retry / tunnel.stopped | Por evento do ciclo de vida do túnel |
template.lookup / project.lookup | Acerto/erro de cache com durationMs em chamada fria |
Postura de privacidade:
- O ID distinto é
SHA-256(api_key).slice(0, 16)— nunca a chave bruta, sem PII. - As chaves
phc_*são somente para escrita por convenção do PostHog; seguras para incorporar no código-fonte. - Defina
DEBUGGAI_TELEMETRY_DISABLED=1para desativar completamente (resolve para um provedor no-op; nenhum evento sai do processo).
O modo ativo é registrado na inicialização:
Telemetry enabled (PostHog, DebuggAI default project). Set DEBUGGAI_TELEMETRY_DISABLED=1 to opt out.
Telemetry enabled (PostHog, custom POSTHOG_API_KEY)
Telemetry disabled (DEBUGGAI_TELEMETRY_DISABLED is set)
Desenvolvimento Local
npm install
npm run build
npm run test:e2e # real end-to-end evals against the backend
A suíte de avaliação inicia o servidor MCP compilado como um subprocesso, exercita cada ferramenta contra um backend real e grava artefatos por fluxo em scripts/evals/artifacts/<timestamp>/. Consulte scripts/evals/flows/ para os cenários individuais.
Registro MCP: debugg-ai-local vs debugg-ai
Este repositório inclui um .mcp.json que registra um servidor com escopo de projeto chamado debugg-ai-local apontando para node dist/index.js — o código local recém-compilado. Ele só é ativado quando o diretório de trabalho do Claude Code é este repositório.
Seus outros projetos devem usar o registro debugg-ai com escopo de usuário que puxa do pacote npm publicado:
npm run mcp:global # registers debugg-ai in ~/.claude.json to npx -y @debugg-ai/debugg-ai-mcp
Após editar o código aqui, execute npm run mcp:local (que apenas recompila) para que a próxima invocação de debugg-ai-local capture suas alterações.
Links
Dashboard · Docs · Issues · Discord
Licença Apache-2.0 © 2025 DebuggAI