8 min read

How to secure your MCP server — fingerprint pinning, scope locks, rug-pull defense

Model Context Protocol went 0 → 200,000+ servers in 9 months. The April 2026 Anthropic RCE flaw + the Invariant Labs tool-poisoning class disclosures forced every MCP-using team to harden their server hygiene. This guide walks the four attack classes (unknown-server smuggle, fingerprint drift, tool smuggle, scope escalation) and the operator-authored TOML catalog that closes them.

If you're running MCP servers in production — Claude Desktop, Cursor, Continue, custom agents — the April 2026 wave (Anthropic design-RCE on 200,000+ servers, Invariant Labs tool-poisoning disclosures, GitGuardian's 24,008 leaked MCP-config secrets) has made one thing clear: MCP server hygiene is now table stakes. This guide walks the four attack classes, the operator-authored TOML catalog that closes them, and the Securie mcp-guard layer that enforces the catalog at runtime.

What it is

MCP (Model Context Protocol) lets AI agents call external tools. The protocol's trust model is implicit — servers describe their tools in a catalog, agents read the catalog and dispatch calls. Four attack classes exploit this: (1) unknown-server smuggle (server not in catalog runs anyway), (2) fingerprint drift (trusted server's binary changes silently), (3) tool smuggle (server adds undeclared tools post-install), (4) scope escalation (declared tool widens its scope after install). Without operator-authored validation, every install is a trust bet.

Vulnerable example

// claude-desktop config without fingerprint pinning OR scope declaration
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"]
    },
    "weather": {
      "command": "node",
      "args": ["/path/to/weather-mcp-server.js"]
    }
  }
}
// No fingerprint, no scope, no version pin. Server can update silently.
// Server can add undeclared tools. Server can widen scope. No defense.

Fixed example

// operator-authored catalog with fingerprint + scope locks
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github@0.6.2"],
      "fingerprint": "sha256:abc123...",  // pin the binary
      "maxAllowedScope": ["FS_READ", "HTTP_EGRESS:api.github.com"],
      "rejectScopeDrift": true             // refuse if server declares wider scope
    }
  },
  "rejectUnknownServers": true,            // any server not in catalog is denied
  "rejectFingerprintDrift": true           // re-fingerprint on every spawn
}

How Securie catches it

Securie findingmedium
apps/web/app/api/route.ts:22

How to secure your MCP server

Securie's mcp-guard crate (`crates/mcp-guard/src/lib.rs`) implements the three-layer architecture: TrustedCatalog (operator-authored TOML-signed allow-list), Validator (parses incoming McpManifest + checks every invariant against the catalog), ScopeGuard (O(1) check on every tool dispatch — HashMap lookup + bitflags compare). An agent invoked with FS_READ scope cannot dispatch to a sandbox.execute tool regardless of what the LLM emits. The April 2026 Anthropic MCP RCE relies on dynamic tool-definition mutation — exactly what mcp-guard refuses by construction.

Suggested fix — ready as a PR
// operator-authored catalog with fingerprint + scope locks
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github@0.6.2"],
      "fingerprint": "sha256:abc123...",  // pin the binary
      "maxAllowedScope": ["FS_READ", "HTTP_EGRESS:api.github.com"],
      "rejectScopeDrift": true             // refuse if server declares wider scope
    }
  },
  "rejectUnknownServers": true,            // any server not in catalog is denied
  "rejectFingerprintDrift": true           // re-fingerprint on every spawn
}
Catch this in my repo →Securie scans every PR · ships the fix as a one-click merge · free during early access

Checklist

  • Operator-authored TOML catalog of every MCP server you trust (no implicit trust)
  • Every server entry has a sha256 fingerprint pinning the binary
  • Every tool entry has a declared maxAllowedScope (bitflags)
  • rejectScopeDrift: true on every server config
  • rejectUnknownServers: true on the global config
  • Run `mcp-scan` (Invariant Labs) periodically against installed servers
  • Securie's mcp-guard crate enforces all of the above at agent-runtime

FAQ

Why isn't 'install only from official MCP registry' enough?

Because the April 2026 Anthropic RCE was in the official MCP itself. The official registry is a necessary baseline but the design-flaw class affects every server using the standard dispatch shape. Operator-authored catalogs + fingerprint pinning + scope locks are the actual defense.

How often should I re-fingerprint?

Every spawn, if you can afford the boot-time hash. mcp-guard's default is per-spawn fingerprint + a daily fleet-wide drift check that compares against the operator-pinned baseline.

What about hot-reload of MCP servers?

Hot-reload is deferred in mcp-guard's launch scope precisely because the rug-pull pattern exploits hot-reload. If you need it, treat every reload as a fresh server install + re-fingerprint + re-scope.

Related guides

Guide
Detecting MCP server rug-pulls — when the tool catalog mutates after install

The rug-pull pattern: an MCP server ships a safe v1 catalog at install time, then mutates to a v2 catalog (with attacker-controlled tools) once it's running in your trust boundary. Invariant Labs disclosed this class in 2025; the Apr 2026 Anthropic RCE incident exploited a related design flaw. This guide ships the fingerprint-pinning + signature-verification defense.

Guide
MCP server security — scope, tool surface, and the prompt-injection routing problem

Model Context Protocol (MCP) servers expose tools to LLM agents — file reads, git commands, HTTP fetches, database queries. The risk surface is the tool catalogue: an LLM agent that can call dangerous tools at the prompt-injection-attacker's instruction is the canonical MCP failure. Here are the patterns that work and the ones that don't.

Guide
Defending MCP agents from indirect prompt injection (2026 playbook)

Indirect prompt injection — adversarial instructions embedded in data the agent reads — is the single most common attack class against MCP-using agents. Microsoft's Apr 2026 advisory + Unit42's MCP attack-vector taxonomy converged on the same defense: pre-prompt-output sanitization + scope-bounded egress + Llama Guard 4 classification. This guide ships the layered defense.

Guide
How Securie's mcp-guard crate validates every MCP tool dispatch

mcp-guard is the Securie crate that enforces operator-authored MCP catalogs at agent runtime. Three layers — TrustedCatalog + Validator + ScopeGuard — close the four attack classes (unknown-server smuggle, fingerprint drift, tool smuggle, scope escalation) at the boundary between inference-router and MCP client. This guide walks the architecture + how to wire it into your agent runtime.