
Eu construí um servidor MCP mentiroso de propósito — aqui está como você o captura
TL;DR — O README de um servidor pode dizer qualquer coisa. Sua resposta tools/list ou confirma isso ou não.
Eu construí mcp-worse — um segundo binário, compartilhando dois dos nomes de ferramentas de mcp-better, que deliberadamente omite os carimbos de cache da lista e serve as ferramentas na ordem errada — para que um teste pudesse provar a diferença. Esse teste é contrast-smoke: um comando, clientes MCP reais, tráfego real na rede. O código de saída 0 apenas se o bom servidor passar o contrato e o ruim falhar.
Isso é o que "claim = wire" parece quando você para de dizer e começa a entregar.
O problema em confiar em um README
Os documentos de cada servidor MCP fazem afirmações: sem estado, lista cacheável, ordem de ferramentas estável. Nada no protocolo impede que um servidor afirme os três e não faça nenhum deles. O cliente não pode dizer a partir dos nomes das ferramentas — health e echo parecem idênticos, independentemente de o servidor por trás deles ser honesto ou não.
Então a questão não é "este servidor tem um endpoint tools/list?" É: se a documentação estiver errada, o que quebra, e quando?
A maioria dos servidores nunca responde a isso, porque nada é construído para falhar de propósito. Você só descobre que uma afirmação era falsa em produção, a partir de um cliente que se comportou de forma imprevisível contra um servidor que "funcionou" em todas as verificações manuais.
Construa a mentira de propósito
A maneira mais limpa de testar um verificador de contrato é entregá-lo algo que viola o contrato — não uma hipótese, um binário real.
mcp-worse é esse binário. Mesma versão de protocolo na rede, mesmo transporte, e ele espelha duas das ferramentas de mcp-better pelo nome (health, echo) — mcp-better desde então cresceu uma terceira (confirm_echo, uma demonstração de fluxo de retry MRTR) que o companheiro mentiroso nunca foi atualizado para corresponder, então a contagem de ferramentas sozinha agora faz parte da lacuna também, ao lado de duas quebras deliberadas:
// src/worse.rs
/// Ordem anti-intencional (BETTER é health → echo).
const WORSE_TOOL_ORDER: &[&str] = &["echo", "health"];
/// Lista sem carimbo com ordem invertida — a mentira.
pub fn lying_list_tools(&self) -> ListToolsResult {
let mut tools = self.tool_router.list_all();
tools.sort_by(/* ...WORSE_TOOL_ORDER... */);
// Omitir deliberadamente with_ttl_ms / with_cache_scope.
ListToolsResult::with_all_items(tools)
}
Sem ttlMs. Sem cacheScope. Ferramentas invertidas. O resultado da ferramenta health até diz isso em voz alta:
{
"status": "ok",
"server": "mcp-worse",
"version": "0.4.3",
"protocol": "2026-07-28",
"tier": "LYING-DEMO",
"warning": "Este binário deliberadamente falha no contrato da lista BETTER para ensino."
}
Não é um truque que um cliente cairia em um ambiente real — está rotulado, é apenas para ensino, nunca é enviado para um registro. Seu único trabalho é ser errado de propósito, de forma confiável, para que algo mais possa provar que pega uma mentira.
Execute a auditoria
contrast-smoke gera ambos os binários como processos filhos reais, conversa MCP real através do stdio e verifica a rede — não o código-fonte, não a documentação:
// examples/contrast_smoke.rs
fn is_better_contract(p: &ListProbe) -> bool {
p.names == better_names()
&& matches!(p.ttl_ms, Some(ms) if ms > 0)
&& p.cache_scope == Some(CacheScope::Public)
}
fn is_lying_surface(p: &ListProbe) -> bool {
let unstamped = p.ttl_ms.is_none() || p.cache_scope.is_none();
let wrong_order = p.names != better_names();
unstamped || wrong_order
}
O artigo apresenta uma abordagem prática para testar a integridade de servidores MCP, algo que pode ser útil para empresas que dependem de protocolos de comunicação confiáveis. A capacidade de identificar falhas em tempo real pode melhorar a confiança em sistemas críticos.
