跳到正文
DEV Community· Cleiton Augusto Correa Bezerra·· 4 小時前AI 評分61

MCP 伺服器可能在版本間改變行為,而你未必察覺

Your MCP server can change what it does between versions — and you won't know

AI 導讀

MCP 伺服器可能在版本間靜默改變所宣告的工具或遠端端點;作者以 CleiMesh 限制每次呼叫的授權範圍,並留下簽署收據。一項針對 21,643 個 registry 伺服器的 2026 年 8 月普查發現,多版本伺服器中 51% 曾改變不同版本所宣告的內容,40.6% 屬靜默變更,4.2% 更換遠端端點主機但保留相同 registry 身分。

正文

MCP trust is name-based: v1 vetted, v2 silently adds a tool

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 thing nobody tells you about MCP trust

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:

  • 51% of multi-version servers changed what they advertise between versions;
  • 40.6% did it silently;
  • 4.2% redirected their remote endpoint to a different host while keeping the same registry identity.

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.

What would actually catch this

Two properties, at runtime, on every call:

  1. Make drift non-silent — tie each call to which server actually ran, in evidence you can't quietly edit.
  2. Bound the surface — the client should only ever reach the tools and arguments it was granted, no matter what the server now advertises.

That's what I built into CleiMesh. You put any MCP server behind it:

cleimesh mcp wrap --token fetch.json -- uvx mcp-server-fetch

Enforce the grant, prove every call: the token grants only search; run_shell is refused; the receipt names the server by digest

Now:

  • Every call leaves a signed, hash-chained receipt that names the server by the digest of its command line. Swap the server, and the digest in the receipts changes — the drift is now in the log, provable, not silent. You can verify the whole chain offline.
  • The client only sees the tools the token grants, and each call is checked against the token's argument constraints (and taint). A version that suddenly advertises a new 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.

Being honest about the boundary

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.

See it — silent drift caught

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:

Recorded run: run_shell never exposed, refused + receipted, and server_sha256 changes v1 to v2

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.)

Why this matters now

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 — 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)

來源:DEV Community · dev.to