MCP Trust Pack: a security layer for MCP tool calls WasmAgent released MCP Trust Pack, a security layer for MCP tool calls that adds vetting, policy, consent, and taint checks. The open-source package includes a gateway, server cards, request identity, and scope leases to gate state-changing tools. It integrates with AEP emitters for audit logging. MCP makes it easy for agents to call tools. Too easy. When your agent calls fs write or shell exec , something needs to answer: is this allowed? Is this state-changing? Who authorized it? By default, MCP has no answer. Here's how to add that layer in ~20 lines. js import { MCPGateway, buildServerCard, createRequestIdentity, isStateChangingTool, } from "@wasmagent/mcp-firewall"; // Register the server at startup const card = buildServerCard { serverId: "filesystem", tools: await mcpClient.listTools , operatorVerified: true, } ; const gateway = new MCPGateway { serverCards: card } ; const identity = createRequestIdentity { principal: "agent:run-abc123", sessionId: "sess-xyz", } ; // Before every tool call: const decision = gateway.evaluate { identity, serverId: "filesystem", tool, args } ; if decision.invocation.decision == "allow" { throw new Error Blocked: ${decision.invocation.reason} ; } const result = await mcpClient.callTool tool.name, args ; const obs = gateway.wrapResult tool.name, result, decision ; // marks trust level Four layers run in evaluate : vetting → policy → consent → taint. One call, full coverage. isStateChangingTool { name: "fs write", description: "write a file" } // true isStateChangingTool { name: "fs read", description: "read a file" } // false isStateChangingTool { name: "send email", description: "send email" } // true State-changing tools can be gated behind a ScopeLease — a time-bounded grant that expires: js import { createScopeLease, isScopeLeaseValid } from "@wasmagent/mcp-firewall"; const lease = createScopeLease { principalHash: identity.principalHash, serverId: "filesystem", grantedTools: "fs write" , ttlSeconds: 300, // 5 min maxInvocations: 10, stateChanging: true, } ; if isScopeLeaseValid lease throw new Error "Lease expired" ; The decision's evidenceRef slots straight into AEPEmitter — no manual wiring: emitter.addAction { tool name: decision.invocation.toolName, state changing: decision.stateChanging, capability decision: { decision: decision.invocation.decision, reason code: decision.evidenceRef.policyDecision, }, tool descriptor digest: decision.evidenceRef.toolManifestDigest, } ; git clone https://github.com/WasmAgent/wasmagent-js bun test packages/mcp-firewall/ Code: packages/mcp-firewall https://github.com/WasmAgent/wasmagent-js/tree/main/packages/mcp-firewall · packages/mcp-gateway https://github.com/WasmAgent/wasmagent-js/tree/main/packages/mcp-gateway Series: AEP part 1 · MCP Trust Pack part 2 · Trace-to-Training part 3