← All projects
MCPAgentSecuritySymfony SecurityAuditHuman in the Loop

Tool Guard — a prompt is not a lock

When an AI agent can refund, email or delete, its rules can’t live in its prompt: a persuasive user talks the model out of them. Tool Guard puts the rules in code, on the tools themselves, with the same PHP attributes for Symfony AI agent tools and for MCP tools: #[Granted] (Symfony Security voters, with a tool argument as subject — on MCP tools too, beyond per-tool OAuth scopes), #[Limit] (numeric ceilings: deny, or hold for a human above a threshold), #[RateLimit] and #[RequiresApproval]. Each agent also has its own role: a call runs only if the user and the agent are allowed, so the boss’s support assistant still cannot export every customer. Below the limits the agent acts alone. A refused call never runs and the model is told why in plain words; a held call waits for the app owner, who is told through Symfony Notifier (Slack, Teams, Telegram, email, SMS) or by a phone push, and approves or rejects the exact arguments, never text written by the model. Every call and decision goes to a hash-chained journal, so a deleted attempt breaks the chain. Works with symfony/ai-bundle, symfony/mcp-bundle and the PHP MCP SDK. The demo runs in one command with a scripted hostile agent, no API key needed, and the same attack can be played against a real model (gpt-oss-120b on Hugging Face).

Play the video on YouTube 1:30

0 comments

Join the conversation with your SymfonyConnect account. Sign in