Voltar as noticias
Como Encontrei um Bug Silencioso em uma API de um Servidor MCP com 3.548 Estrelas
MCP ProtocolAltaEN

Como Encontrei um Bug Silencioso em uma API de um Servidor MCP com 3.548 Estrelas

Dev.to - MCP·29 de junho de 2026

Como Encontrei um Bug Silencioso na API em um Servidor MCP com 3.548 Estrelas

A API aceitou sua solicitação. Retornou HTTP 200. E então, silenciosamente, não fez nada.

Sem erro. Sem rastreamento de pilha. Apenas um resultado vazio onde sua consulta Cypher deveria ter sido executada.

Esta é a história de como encontrei esse bug no CodeGraphContext — um servidor MCP que indexa bases de código locais em um banco de dados gráfico para fornecer contexto real de código a assistentes de IA. 3.548 estrelas. Ativamente mantido. Usado por desenvolvedores que constroem sobre Claude e outras cadeias de ferramentas LLM.

E havia uma falha silenciosa em seu ponto de extremidade de consulta HTTP pública.

O que é o CodeGraphContext?

Antes do bug — um rápido contexto.

CodeGraphContext é um servidor MCP (Modelo de Protocolo de Contexto). Ele permite que você aponte para uma base de código, indexe-a em um banco de dados gráfico (FalkorDB ou Kuzu) e, em seguida, consulte esse gráfico usando Cypher — a linguagem de consulta para bancos de dados gráficos. A ideia é que assistentes de IA possam usá-lo para entender a estrutura do código, dependências e relacionamentos em uma profundidade que leituras de arquivos planos não oferecem.

Ele expõe tanto uma interface MCP quanto uma API HTTP padrão. A API HTTP é o que é relevante aqui.

Como Eu Encontrei

Eu não estava caçando bugs. Eu estava lendo o código-fonte.

Quando contribuo para um novo repositório, começo rastreando uma única solicitação de ponta a ponta através da base de código. Escolho um ponto de extremidade, sigo-o desde a definição da rota até o manipulador, passando por quaisquer chamadas subsequentes, e volto. É a maneira mais rápida de realmente entender o que uma base de código faz.

Comecei com /api/v1/query — o ponto de extremidade que permite enviar uma consulta Cypher via HTTP e obter resultados de volta.

A rota está em src/codegraphcontext/api/router.py. Aqui está o que encontrei na linha 89:

server.handle_tool_call("execute_cypher_query", {
    "query": request.query,
    "params": request.params
})

A rota estava chamando handle_tool_call com o nome da ferramenta execute_cypher_query e passando a consulta como "query".

Então fui para o manipulador. src/codegraphcontext/tools/handlers/query_handlers.py, linha 16:

cypher_query = args.get("cypher_query")
if not cypher_query:
    return {"error": "A consulta Cypher não pode estar vazia."}

O manipulador lê cypher_query. Não query. cypher_query.

A rota passa query. O manipulador lê cypher_query. Eles nunca se encontram.

Assim, args.get("cypher_query") retorna None. O manipulador atinge a verificação de vazio. Retorna {"error": "A consulta Cypher não pode estar vazia."}. HTTP 200.

Uma solicitação válida, carregando uma consulta Cypher real, falhou silenciosamente — não porque a consulta estava errada, mas porque o nome da chave não correspondia através de uma fronteira de chamada de função interna.

Por que Isso é Fácil de Perder

O modo de falha é o problema.

Se isso lançasse uma exceção, você veria um 500. Se retornasse um 4xx, você saberia que a API rejeitou sua entrada. Mas retornou 200 com uma carga de erro que parece um erro de validação. A leitura natural é: "Enviei uma consulta ruim." O problema real é: a camada da API e o manipulador da ferramenta estavam falando línguas diferentes sobre o que chamar o mesmo campo.

Aqui está a reprodução do problema que eu relatei:

curl -X POST http://localhost:8000/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{"query":"MATCH (n) RETURN count(n) AS count","params":{}}'

Cypher válido. JSON válido. Solicitação HTTP válida. Mas o manipulador da ferramenta não vê nenhuma chave cypher_query — porque a rota a chamou de query — e retorna vazio.

O corpo da solicitação parece correto na fronteira da API. A falha acontece após a tradução interna. Isso torna o caminho de depuração confuso. Você inspecionaria a solicitação, veria uma carga útil válida e não teria uma razão óbvia para olhar o nome da chave sendo passada entre a rota e o manipulador.

A Solução

Uma mudança de linha em router.py:

# Antes
server.handle_tool_call("execute_cypher_query", {
    "query": request.query,
    "params": request.params
})

# Depois
server.handle_tool_call("execute_cypher_query", {
    "cypher_query": request.query,
    "params": request.params
})

Altere a chave de "query" para "cypher_query" para que corresponda ao que o manipulador espera.

Eu mantive a correção estreita — apenas alinhando o nome da chave, sem refatoração, sem mudanças de esquema. Depois adicionei um teste de regressão em tests/unit/api/test_query_router.py que verifica se um POST para /api/v1/query chega a execute_cypher_query com a chave correta. Assim, isso não pode quebrar silenciosamente novamente.

O que Eu Adicionei: O Teste de Regressão

Esta é a parte que eu empurraria qualquer um que estivesse corrigindo um bug como este a fazer

Contexto Triplo Up

A descoberta de bugs em APIs é crucial para garantir a funcionalidade de sistemas que suportam assistentes de IA. Empresas brasileiras que utilizam servidores MCP devem estar atentas a esse tipo de falha para melhorar a confiabilidade de suas aplicações. A correção e testes adicionais ajudam a prevenir problemas futuros.

Noticias relacionadas

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.