MCP security model
The MCP server gives an AI app the agent's administrator power, so every request is checked in full, in this order.
Who can connect
- The switch. While the server is off it answers every request with 403 and lists nothing.
- Only agent tokens. A request must carry
Authorization: Bearer pfam_…. WordPress passwords, application passwords and login cookies are not accepted here, and an agent token is not accepted anywhere else: it opens no other WordPress route. - Only administrators, checked every time. The token's owner must hold the
manage_optionscapability on every single request. Demote or delete the owner and their tokens stop at once, not when they expire. Deleting an account deletes its tokens. - Browsers from other sites are refused. A request whose
Originis not this site is refused (403), which protects against DNS rebinding. Other origins can be allowed with thepfa_mcp_allowed_originsfilter.
The tokens
- 160 random bits, shown once; the site stores only their SHA-256.
- Every token expires: 30 days by default, 365 at most.
- Each one records when it was created, when it expires, when it was last used and from which address, and whether it was revoked.
- Scope read reaches only the tools that read. Scope write reaches every tool the owner's account may use.
What a write token may do
The agent's permission rules — the same ones the chat's confirmation dialog follows, and like there they govern the tools that change the site — apply:
deny— the tool is not listed and a call is refused.allow— the call runs without the second confirmation step.- otherwise (the default) — your AI app marks each change as needing your approval and asks you before the call.
Destructive calls take two steps. A call is destructive when it can take away something that exists and no tool can give it back:
- deleting a data model, record or application, or a workflow;
- changing a data model with the data-loss guard overridden (
force); - saving over an active workflow, which puts it back to draft;
- moving content to the trash, unpublishing it, or replacing its terms;
- rewriting a user account or a site setting;
- trashing or marking as spam a comment or a form entry;
- with WooCommerce, LearnDash or MemberPress: changing an order's status, cancelling it, removing a line, unpublishing a product, unenrolling a student, revoking a membership.
The first call changes nothing and answers with a summary of exactly what would be lost — the data model and how many records go with it, the title of the post, the setting with its current and new value. Only the identical call carrying the single-use confirmation it returned runs, within ten minutes. A different call, a changed argument or a reused confirmation is refused.
What is recorded
Every tool call is written to the agent's trace log: which token (by its id, never the token itself), which tool, the outcome, how long it took, and the arguments — shortened, with anything shaped like a secret removed. Requests turned away at the door are recorded too.
Each token is rate-limited on its own (120 requests a minute by default; the pfa_rate_limit_defaults filter changes it). The agent's AI provider keys are never reachable through the server.
Protocol
MCP over Streamable HTTP, stateless: JSON-RPC messages (or batches of them) sent by POST and answered with JSON — no event stream, no session. Protocol versions 2025-11-25, 2025-06-18, 2025-03-26 and 2024-11-05. Requests larger than 1 MB are refused, and very large tool answers are cut with a notice saying so.
Troubleshooting
- 401 — the token is missing, mistyped, expired or revoked. Create a new one.
- 403 — the server is switched off, the token's owner is no longer an administrator, or the request came from another site's page.
- 401 even with a valid token — the web server may be dropping the
Authorizationheader before WordPress sees it. WordPress's standard.htaccesspasses it on; custom server configurations must too.