Your MCP server can change what it does between versions — and you won't know Cleiton Augusto Correa Bezerra released CleiMesh, an open-source (MIT/Apache-2.0) tool that wraps MCP servers to enforce a pinned tool grant at runtime and produce signed receipts for every call. The tool addresses silent server drift — a census of 21,643 registry servers found roughly 40% changed behavior between versions — by refusing and recording any tool or argument outside the grant, and logging a server_sha256 that changes when a server's code does. The `wrap` mode does not sandbox native server processes (receipts record `confined: false`); a separate `serve` mode runs tools in a WebAssembly sandbox. MCP exploded: by mid-2026 there are 10,000+ public servers . But trust in the ecosystem is name-based , and that is the problem. The official registry does not review code or scan for malware — it checks that you own the GitHub repo or domain, and leaves scanning to "downstream aggregators." So "it's in the registry" means almost nothing for safety. Worse, servers drift . An August 2026 census of 21,643 registry servers found: And star counts barely help popularity was a weak safety signal . So you vet a server once, pin trust to its name, and a later version quietly does something else. Static scanners check a snapshot; drift happens after the scan. Two properties, at runtime, on every call: That's what I built into CleiMesh https://github.com/cleitonaugusto/cleimesh . You put any MCP server behind it: cleimesh mcp wrap --token fetch.json -- uvx mcp-server-fetch Now: run shell ? It's never exposed. An argument reaching outside the grant? Refused — and the refusal is receipted too. Unlike a scanner, this is continuous and after-the-fact provable : you don't trust a one-time scan, you get a signed record of what every call did, run after run. wrap does not sandbox a native server's own process — it reaches whatever its OS user can. What wrap gives you is a pinned, receipted surface : the tools/arguments the token allows, and a signed record naming the server. If you want the tool itself physically contained default-deny, can't touch ~/.ssh no matter what , that's cleimesh mcp serve , which runs tools in a WebAssembly sandbox. Use wrap for native servers you don't control; serve for tools you run under CleiMesh. A vetted MCP server advertises one tool, search . A later version keeps the same identity but silently adds a dangerous run shell . Behind cleimesh mcp wrap , with a token that grants only search : Token grants exactly one tool: search. == v1 vetted server: advertises only 'search' == client sees tools: 'search' search - ok == v2 SILENT DRIFT: same identity, now also advertises 'run shell' == client sees tools: 'search' search - ok run shell - REFUSED == What the signed receipts recorded == tool decision server sha256 names which server ran search allowed 4ae7d7e537ca9144... search allowed edcfb70e2b2e9ada... run shell denied - denied before dispatch Three things the signed receipts prove: the drifted run shell was never exposed the grant pins the tool surface ; the attempt was refused and recorded ; and the server sha256 changed between versions — so the drift is in the log, not silent. wrap does not sandbox the native server, and the receipt says so: confined: false . For a tool you want physically contained, run it under cleimesh mcp serve , in WASM. MCP trust today is "I vetted the name once." That doesn't survive 40% silent drift. The fix isn't another catalog or another one-time scan — it's enforcing the grant and proving every call at runtime , so a server that changes what it does is bounded and caught . Free and open MIT/Apache-2.0 : https://github.com/cleitonaugusto/cleimesh https://github.com/cleitonaugusto/cleimesh — the cleimesh-mcp skill on ClawHub sets it up. Point it at the MCP servers your agent already uses and look at the receipts. — Cleiton Augusto Correa Bezerra github.com/cleitonaugusto https://github.com/cleitonaugusto