Problem
A rug-pull attack ships a clean tool catalog at install time, then mutates tool definitions after the user has granted trust — silently changing descriptions, schemas, or behavior without triggering re-approval. CVE-2025-54136 formalised this class. The real-world postmark-mcp npm incident (Sep 2025) BCC'd every outbound email to an attacker for weeks before detection.
fuzzd has corpus records for rug-pull attacks (corpus/rug_pull/RUG-001 through RUG-003) and the ConditionalActivation signal catches static text that describes conditional behavior — but there is no runtime detection that actually compares tool definitions across time.
mcp-scan's tool pinning is its primary differentiator over other MCP scanners. fuzzd needs an equivalent.
Design
Storage: .fuzzd/pins.toml
[pins."server-name"]
"tool_name" = "<sha256 of name+description+inputSchema JSON>"
"other_tool" = "<sha256>"
pinned_at = "2026-06-13T00:00:00Z"
Analogous to .fuzzd/suppress.toml — checked into version control, reviewed on change.
CLI flows
# First run: save hashes
fuzzd audit --transport stdio --cmd "node server.js" --pin
# Subsequent runs: diff against saved hashes
fuzzd audit --transport stdio --cmd "node server.js" --check-pins
# Both: gate CI with exit 1 if a tool changed since pinning
Detection
On --check-pins:
- Connect to server, enumerate
tools/list
- Hash each tool's
name + description + inputSchema (canonical JSON, deterministic field order)
- Compare against
.fuzzd/pins.toml
- Flag any tool that: changed description/schema, was added, or was removed
- New signal
ToolDefinitionChanged or reuse existing ConditionalActivation with a runtime context
Acceptance criteria
References
Problem
A rug-pull attack ships a clean tool catalog at install time, then mutates tool definitions after the user has granted trust — silently changing descriptions, schemas, or behavior without triggering re-approval. CVE-2025-54136 formalised this class. The real-world
postmark-mcpnpm incident (Sep 2025) BCC'd every outbound email to an attacker for weeks before detection.fuzzd has corpus records for rug-pull attacks (
corpus/rug_pull/RUG-001throughRUG-003) and theConditionalActivationsignal catches static text that describes conditional behavior — but there is no runtime detection that actually compares tool definitions across time.mcp-scan's tool pinning is its primary differentiator over other MCP scanners. fuzzd needs an equivalent.
Design
Storage:
.fuzzd/pins.tomlAnalogous to
.fuzzd/suppress.toml— checked into version control, reviewed on change.CLI flows
Detection
On
--check-pins:tools/listname + description + inputSchema(canonical JSON, deterministic field order).fuzzd/pins.tomlToolDefinitionChangedor reuse existingConditionalActivationwith a runtime contextAcceptance criteria
PinStoretype insrc/suppress.rsor a newsrc/pins.rs(analogous toSuppressConfig)--pinflag onfuzzd audit— writes/updates.fuzzd/pins.toml--check-pinsflag onfuzzd audit— diffs and gates on changesToolDefinitionChangedfinding type (severity: High) carrying old-hash / new-hash contextReferences