Voltar as noticias
Seu MCP Pin Bloqueia Todas as Atualizações. A Maioria Nunca Quebrou Você.
MCP ProtocolAltaEN

Seu MCP Pin Bloqueia Todas as Atualizações. A Maioria Nunca Quebrou Você.

Dev.to - MCP·24 de julho de 2026

Há um mês, eu enviei um cadeado de 40 linhas para ferramentas MCP: fixar o hash do manifesto, bloquear o rug-pull. Funciona. Também tem uma falha sobre a qual escrevi no último parágrafo e depois tive que construir uma correção, porque isso continuava me incomodando. O pin dispara em qualquer alteração na definição de uma ferramenta. Um servidor que honestamente adiciona um parâmetro opcional ativa o alarme exatamente tão alto quanto um servidor que remove um parâmetro obrigatório debaixo de você. Mesmo alarme, mesmo bloqueio, mesma página às 3 da manhã. O pin sabe que o contrato mudou. Não tem ideia se a mudança quebrou você.

Resumindo: uma mudança de esquema de ferramenta MCP reduz o conjunto de chamadas válidas, então uma chamada que seu agente faz hoje para de validar amanhã. Uma mudança retrocompatível amplia ou deixa esse conjunto inalterado, então chamadas antigas permanecem válidas. Um pin de byte não pode diferenciá-los. compat_gate.py compara o inputSchema e reproduz as chamadas que seu agente gravou: silencioso em compatíveis, falha em fechamentos em quebrados.

Divulgação de IA: Eu escrevi compat_gate.py com a ajuda de um assistente de IA e executei todos os casos eu mesmo antes de publicar. Cada bloco de terminal abaixo é colado de uma execução real no Python 3.13.5. O caso compatível (C2) é um real diff datado entre dois esquemas de especificação MCP publicados, obtidos via curl e verificados; os casos quebrados (C3 a C5) são fixações sintéticas que construí e confirmei por reprodução, e eu os rotulo como tal. Não tenho um incidente de produção para vender aqui; bot2 é novo e sua contagem de execuções vitalícias é zero. O que eu tenho é uma ferramenta que funciona e um diff que você pode reproduzir.

Por que fixar um manifesto dispara em cada mudança?

Porque um hash tem um bit de memória: igual ou diferente. O pin de junho pega um SHA-256 canônico sobre nome + descrição + inputSchema e bloqueia quando o manifesto ao vivo para de corresponder ao que você aprovou. Essa canonização já é o bom tipo de pin: ela ordena chaves e remove espaços em branco, então um manifesto re-serializado, mas idêntico, não dispara isso. Eu verifiquei isso primeiro, e se mantém. O pin não é paranóico sobre a formatação JSON.

Ele é paranóico sobre o significado. E esse é o problema, porque a maioria das mudanças de significado em um esquema são inofensivas para suas chamadas. A própria especificação MCP é a evidência mais clara. O protocolo envia revisões datadas, capazes de quebrar, em uma cadência; o diretório de esquemas em o repositório da especificação atualmente carrega 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25, e um draft/ ao vivo. Eu puxei dois desses e comparei manualmente (mais sobre isso abaixo). Servidores rastreiam a especificação. Ferramentas são re-versionadas. Descrições são reescritas para o modelo. Cada um desses eventos altera o bit único do pin, e o pin bloqueia dutifully.

Aqui está a pergunta em aberto que deixei para mim em junho e não consegui responder com minha própria caixa de ferramentas: onde está a linha entre uma atualização legítima da ferramenta e a deriva? A franquia deste blog continua aterrissando na mesma forma. Rastrear não é controlar. Ter uma credencial não é delimitá-la. Aprovação não é imutabilidade. Este post adiciona a próxima linha: um contrato alterado não é um quebrado. Um pin não é uma verificação de compatibilidade. O pin rastreia mudanças. Ele não controla se uma mudança que quebraria seu agente chega à chamada. Esse é um trabalho diferente, um nível abaixo do hash, e precisa de uma ferramenta diferente.

O que torna uma mudança de esquema de ferramenta quebrada?

Há uma verdade fundamental aqui, e ela é mais antiga que o MCP. É subtipagem. Um esquema descreve um conjunto: o conjunto de objetos de argumento que ele chama de válidos. Uma mudança é retrocompatível quando o novo conjunto contém o antigo, então cada chamada que costumava validar ainda valida. Uma mudança é quebrada quando o novo conjunto é menor, então alguma chamada anteriormente válida agora falha. Esse é o teste completo, e não requer uma opinião.

Em um objeto inputSchema, os movimentos quebrados são aqueles que diminuem o conjunto válido:

  • Adicionar uma propriedade obrigatória. Chamadas antigas que a omitiram estavam bem e agora não estão.
  • Remover uma propriedade quando additionalProperties: false. Uma chamada que passou essa chave agora é rejeitada como extra.
  • Restringir um tipo. number para integer descarta 3.5. Qualquer troca de tipo incompatível pode deixar um valor antigo sem uso.
  • Reduzir um enum. Remover "csv" de ["json", "csv"] e cada chamada que pediu CSV desaparece.
  • Transformar uma propriedade opcional em obrigatória, ou restringir additionalProperties de true para false.

E os movimentos compatíveis, aqueles que ampliam ou preservam o conjunto:

  • Adicionar uma propriedade opcional. Ninguém era obrigado a enviá-la; chamadas antigas permanecem inalteradas.
  • Ampliar um enum, relaxar um tipo (integer para number), remover uma restrição obrigatória, ou reescrever uma descrição. Nenhuma dessas pode invalidar uma chamada que já era válida.

Essa lista é toda a lógica do classificador. O objetivo da ferramenta não é ser inteligente sobre isso. O objetivo é executá-la contra esquemas reais e, criticamente, verificar o veredicto do classificador contra algo independente: as chamadas em si.

O portão: reproduza as chamadas que seu agente realmente faz

compat_gate.py é sem chave, offline e apenas da biblioteca padrão (json, sys, hashlib). Ele carrega um validador de JSON-Schema deliberadamente pequeno que entende exatamente seis palavras-chave: type, required, properties, enum, additionalProperties, const. Qualquer outra coisa em um esquema (um format, um items, um $ref) é tratada como sem restrição. Esse é um limite real e eu volto a isso no final. É o subconjunto certo para o corpus aqui e pequeno o suficiente para ser lido em uma única sessão.

Dois sinais funcionam lado a lado, e eles devem concordar:

def classify(old_is, new_is):
    """Difira dois inputSchemas. Retorne [(veredicto, razão), ...] em uma ordem estável."""
    changes = []
    old_props, new_props = old_is.get("properties", {}), new_is.get("properties", {})
    old_req, new_req = set(old_is.get("required", []), )
Contexto Triplo Up

As empresas brasileiras que utilizam ferramentas MCP devem estar cientes das implicações de mudanças em esquemas, pois isso pode impactar a funcionalidade de suas aplicações. A implementação de um sistema de verificação de compatibilidade pode evitar interrupções inesperadas em serviços. A compreensão das diferenças entre mudanças compatíveis e quebradoras é crucial para a manutenção da integridade dos sistemas.

Noticias relacionadas

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.