Wrapping guardTool around createTool doesn't cover the Linear MCP that you mounted. That tool has no local execute function. Mastra calls the host. The comment posts, then afterToolCall writes a line. Confusing those facts is how a "fully wrapped" agent still files the issue.
How do you secure Mastra MCP tools?
Use guardHooks to gate the MCP, workspace, and toolset tools that you didn't pass through guardTool. Arcjet's Mastra agent guard sits on Mastra's tool hooks, which already run on every tool source, including MCP.
beforeToolCall is the deny. On DENY, it returns { proceed: false, output }, and Mastra doesn't contact the host. afterToolCall is observe-only.
import { guardHooks } from "@arcjet/guard/mastra/v1";import { tokenBucket } from "@arcjet/guard";import { arcjet } from "./arcjet.js";
const mcpLimit = tokenBucket({ bucket: "mcp-access", refillRate: 20, intervalSeconds: 60, maxTokens: 20,});
export const hooks = guardHooks(arcjet, { action: ({ toolName }) => `${toolName}.invoked`, rules: ({ toolName }) => [mcpLimit({ key: toolName, requested: 1 })],});Pass hooks to the Agent constructor, or to generate or stream. Don't apply both helpers to the same authored tool. That double-calls the guard.
Why doesn't guardTool cover MCP and workspace tools?
guardTool wraps createTool({ execute }). A wrap sits on execute. On deny, the function never runs.
An MCP, workspace, or toolset tool isn't that function. The server publishes the schema and Mastra invokes it. There is nothing in your repository to wrap. Applying guardTool to every authored tool leaves the mounted host untouched.
Where does beforeToolCall sit?
Mastra's beforeToolCall runs before the tool executes. It sees the tool name and the arguments. If the hook returns a stop, then Mastra doesn't contact the host. That is the last reversible point for a tool that you didn't author.
A Linear create_comment with a pasted private issue is the lethal trifecta in one call: private data, untrusted text, and an external send.
protect() is the HTTP check on a route. The model asks Linear to comment. Mastra calls Linear from your process.
Helpers default to onGuardError: "deny". If the Arcjet evaluation can't complete, then the tool doesn't run.
How is this different from securing an MCP server's own handlers?
How to secure an MCP server or AI agent tool calls is handler-side: you own the stdio or Streamable HTTP server, and you enforce inside the tool. This document is the other side. You mounted someone else's MCP. There is no local handler to wrap. The gate is the hook.
Does requireApproval or a guardrail replace this?
No. requireApproval parks the call for a person. That is a hold, not a policy. Rubber-stamping every MCP tool doesn't remove a trifecta leg.
requireApproval is the human hold. Channels already call processInput.
A detector isn't this control. For more information, see Mastra guardrails vs an action gate. Processors stop messages, and beforeToolCall refuses the send.
Put guardHooks on the MCP and workspace tools. If you wrapped only createTool, then the Linear comment has already posted. afterToolCall is the log.
Frequently asked questions
How do I secure Mastra MCP tools?
Gate MCP, workspace, and toolset tools you did not pass through guardTool with guardHooks. beforeToolCall returns { proceed: false, output } on DENY so the host is not contacted.
Can I apply guardTool and guardHooks to the same authored tool?
No. Applying both to the same authored tool double-calls the guard. Use guardTool on createTool. Use guardHooks for MCP, workspace, and toolset tools you did not wrap.
Does Mastra requireApproval stop an MCP tool?
No. requireApproval parks the call for a person. That is a hold, not a policy. The deny for unwrapped tools is beforeToolCall.
What if Arcjet is down on beforeToolCall?
Mastra helpers default to onGuardError: deny. If the guard cannot be evaluated, the tool does not run.
Does afterToolCall stop the host call?
No. afterToolCall is observe-only. The side effect already happened. Use it for audit, not as the deny.
AI runtime security in your code
Protect your AI agent workflows with Arcjet
Get allow, deny, and redact on agent actions before the side effect.