Directory / plugin
Agentic Daisy AI Agent Firewall – Approvals, Audit & Undo for MCP
v2.1.0 · by agenticdaisy
AI agent firewall for MCP and the Abilities API: hold risky agent writes for your approval, audit every action, and undo mistakes in one click.
About this plugin
Install this before you give an AI agent an application password.
Connecting Claude, ChatGPT, Cursor or any other MCP client to WordPress hands it a real login. From then on it can edit, publish, change settings and delete as fast as it can act – including when it has misunderstood you, or been talked into something by text it read along the way. Agent Firewall sits between those agents and your site:
- Every agent has its own identity, tied to a least-privilege WordPress user, so you always know which one did what.
- Risky writes wait for you. Deletions and changes to settings, users, plugins and themes are held for your approval out of the box, while everyday content edits keep flowing.
- No stale approvals. If a person edits the content while an agent’s change is waiting, approving it aborts instead of overwriting the newer work.
- Every action is on the record, in a tamper-evident audit ledger that names the rule behind each decision.
- Mistakes undo in one click, from revisions, the trash, or stored snapshots.
- You hear about trouble, by email or in Slack, Discord or Google Chat, and one button pauses every agent at once.
It does not replace your MCP server. Keep the official MCP Adapter or whichever MCP plugin you already use; Agent Firewall governs what arrives through it, whether that is a WordPress ability, a REST API call or an MCP tool call.
Pro and Agency
Everything else on this page is free, with no limits, and stays free. The paid editions add tools for people answering to clients, and for agencies running many sites:
- An AI evaluator that reviews the actions your rules send to it, approves routine content edits a person could undo, and holds everything else for you (Pro+)
- Ledger CSV export, with the chain hashes that prove nothing was altered, for the evidence clients and auditors ask for (Pro+)
- A digest email when something needs a person, and a weekly all-clear when nothing does, to the recipients you choose (Pro+)
- Exposure-scan history: each scan shows what is new, resolved and changed since the last one (Pro+)
- Network rules every site must follow, one switch that stops agents across the network, network-wide activity, and agents created on many sites at once, each with its own token (Agency+)
- Webhook routing: send chosen events from chosen agents to several destinations, including Microsoft Teams, with retries and a delivery log (Agency+)
- Starter policy packs for publisher, store and membership sites, previewed before they apply and removable as a group (Agency+)
Pro and Agency are sold at agenticdaisy.com, with a 14-day free trial and no card needed.
How it works
This plugin restricts AI agents; it is not an AI tool. It neither generates nor executes code, and every decision is made by deterministic PHP running locally against rules you write. Nothing leaves your site unless you ask for it: the only request it can make outward is to an alert webhook address you enter yourself.
Each agent gets its own identity, tied to a WordPress user of your choosing. Usually that is a bearer token (ag_live_...), stored as a SHA-256 hash and displayed a single time at issuance. For clients that can only send a username and password – most MCP clients – you can instead bind one of that user’s application passwords to the agent, which identifies it just as the token does. An agent can never exceed the capabilities of its linked user, and scopes can pin it down further, to specific action categories or ability patterns.
Write actions are intercepted at both doors. Ability execution callbacks are wrapped at registration, and direct REST writes are caught just before their handler runs – after WordPress has checked the linked user’s permissions and validated the input – so switching transports doesn’t dodge the rules, and nothing WordPress would refuse anyway ever waits for your approval. A REST write WordPress refuses is still recorded, with the “refused” status – up to 20 per agent for each kind of target every ten minutes, so an agent hammering a door it cannot open cannot flood the ledger, while one that turns to a different kind of target is still seen doing so. Policies match on ability name, action category, entity type or id, source, and whether the ability declares its own action destructive, in priority order. Each rule decides: allow, deny, log only, or require human approval. If nothing matches, destructive actions require approval and reads pass. A sliding-window rate limiter shuts down runaway loops, and the admin gets an email when it trips – or a message in Slack, Google Chat or Discord, if you give it a webhook address.
Held actions land in an approval queue along with the target’s modification timestamp. If a person edits that content before you approve, the stored action aborts with a conflict rather than overwriting the newer work. (That check covers posts, pages and media, which record when they last changed; users, terms, plugins and settings do not, so for them the queue cannot tell whether someone got there first.) If you have set a webhook address, each held action announces itself there with a link straight to the queue, so nothing waits on someone happening to open the dashboard.
Every decision is written to an append-only audit ledger. Each entry carries a SHA-256 hash chained to the previous one, so any after-the-fact tampering breaks verification. Secrets in action payloads (passwords, API keys, tokens) are redacted before they reach the ledger.
Executed actions can be undone from the dashboard. Post edits restore through the normal revision history, deletions come back from trash, and settings changes restore from stored snapshots. Where a clean undo isn’t possible (say, user creation), the ledger says so instead of pretending.
The plugin also watches for two quieter risks: it fingerprints every registered ability and alerts you when one appears or changes definition (a known tool-poisoning pattern), and it records REST writes made with an application password that no agent has claimed – automation carrying no identity for a policy to apply to – in the audit ledger as “untracked”. A setting on the Agents screen refuses those outright instead.
All decisions are made by plain PHP on your server. The plugin collects no telemetry and calls no third-party service; the one outbound request it can make is to the alert webhook you configure, if you configure one. The admin dashboard (Agent Firewall menu) runs on permission-checked REST endpoints. The Abilities API interception itself is what sets the WordPress 6.9 floor.
What this does and does not claim
Every agent write that reaches WordPress is evaluated, and every one that succeeds is recorded. That is the promise, and it is deliberately narrower than “blocks all AI attacks”.
What it cannot see, stated plainly so you can judge the fit:
- Writes that bypass WordPress. Anything with direct database access is invisible to any plugin, including this one.
- What an agent decided. Prompt injection happens in the model, before a request exists. This governs what an agent tries to do, not what it was talked into wanting.
- MCP servers that never touch your site. If a tool call is handled entirely elsewhere, there is nothing here to intercept.
- A plugin that answers a request first. Another plugin can hook the same point in WordPress’s request handling at the same priority and answer a write itself before the firewall sees it. Nothing in WordPress lets one plugin guarantee it goes first, so such a write is recorded afterward with the “bypassed” status and counted against the agent’s rate limit, rather than passing unseen.
- Two rejections WordPress reports to nobody. An agent attempt refused before the action runs is now recorded with the “refused” status – a permission failure on every supported version, and malformed input from WordPress 7.1, the first version to expose that. Two cases stay invisible because core returns before any hook fires: an ability registered without a valid permission callback, and one whose input schema is missing entirely.
Inside that boundary the guarantee is strict: no policy decision depends on a language model, nothing is sent anywhere but an alert endpoint you chose yourself, and the audit trail is tamper-evident rather than merely append-only.