Tell a blocked connection apart from a plugin problem

MaintenanceIntermediate~5 minUpdated

Before you start

An admin account. The Activity Log read requires the manage-options capability, so run this from an administrator connection that already works, not from the connection you are trying to debug.

An agent reports that it cannot do something on your site, and now you are guessing. Is the ability switched off? Is the bound user missing a capability? Or did the request never arrive in the first place, because something sitting in front of WordPress quietly dropped it? Those failures look identical from the agent’s side, and they have completely different fixes.

The Activity Log settles it, mostly. It records every tool call, every sign-in, and the requests that reach WordPress and fail, as (transport) rows, so what the log contains (and what it does not) tells you which failure you are dealing with. This prompt reads that log and reports the verdict. It changes nothing.

The prompt
Something is failing on this site and I want to know where. Read only, change
nothing.
First confirm which site this connection is bound to, so I know we are looking
at the right install. I have just asked the failing agent to make one small
read, so there is a fresh attempt to find. Read the Activity Log for [the last
two hours], newest first, 200 rows a page, and keep paging until created_at (it
is UTC) is older than that. There is no date filter on this read.
Walk me through what you find, in this order:
1. Sign-in rows, whose ability starts with "oauth:". Tell me whether any tool
calls follow them or whether the log goes quiet straight after.
2. Front-door rows, whose ability is "(transport)". Give me the status, the
detail and the timestamp on each.
3. Tool calls that were denied, then tool calls that errored, then the ones
that succeeded, with the ability name and timestamp on each.
Finish with a plain verdict on which of these it looks like: the agent was
stopped before it reached WordPress, it arrived and was refused at the front
door, it arrived and a tool was denied, or it arrived and a tool hit a real
error. Say which rows you based that on.

Why this is safe to run

Both abilities here are reads. Reading the Activity Log reports history that already happened and cannot rewrite a row of it, and the site-info read returns the site name, tagline, URL, and language. Neither can touch a setting, a post, or a connection, so the worst case is a quiet window and no verdict.

One honest note on the method, because the most useful signal in this recipe is an absence rather than a reading. When the log shows an agent signing in and then nothing at all, the plugin is not telling you a request failed. It is telling you no tool call arrived, and you are inferring the rest. That inference is a good one, because a request that reaches WordPress and fails usually leaves a front-door row, but it points at a layer the plugin cannot see into.

Two things the agent cannot give you, and where to find them. Why a tool was denied, and the source IP of a front-door refusal, are recorded in the Activity Log tab since 1.9.0 and left out of what the agent reads. Open the tab, click Denied, and read the Detail and IP columns. A front-door row with a valid user and no detail is usually your IP allowlist refusing the address, and the IP column will say which one. Behind a proxy or CDN that address is the proxy’s.

The other thing to plan for is who runs it. The Activity Log read is gated behind the manage-options capability, which a properly scoped agent user should not hold, and a connection that cannot reach WordPress cannot run anything anyway. So this is an administrator’s read: you run it from a connection that works, and it tells you about the one that is failing.

Already connected? Skip the paste. From an admin connection, ask your agent for the “tell a blocked connection apart from a plugin problem” recipe, or just ask why the other agent’s calls are not showing up, and it runs the same reads against your own log.

How it works

  1. Confirm which site the working connection is actually bound to.
  2. Have the failing agent make one small read, then read the Activity Log for that window, newest first.
  3. Look for sign-in rows and check whether any calls follow them.
  4. Separate the front-door rows, tool denials, tool errors and successes.
  5. Read the pattern back as a verdict: stopped before arrival, refused at the front door, denied on a tool, or a real error.

Questions

What does it mean when the log shows a sign-in and then nothing?
It means no tool call from that agent reached WordPress. Every tool call and every sign-in is logged, and a request that arrives and fails at the front door usually leaves its own row, so silence after a sign-in usually points at something in front of WordPress, such as a CDN or firewall filtering the request at the edge. A request that succeeds without calling a tool, such as listing the tools, leaves no row, so silence can also mean the client connected but never chose a tool. That is why the prompt has the failing agent make one small read first.
Can it tell me which CDN or firewall is doing the blocking?
No. A request that never reaches WordPress leaves no row at all, so no log inside the plugin can name what stopped it. That answer lives in your host's or CDN's own security events, where you look for a blocked request to the plugin's endpoint (its path ends in /mcp). What this prompt saves you is the hour you would otherwise spend debugging a plugin that never saw the request.
What is a (transport) row?
A row with the ability name (transport) records a request that reached WordPress and was refused or failed before any tool ran: a wrong Application Password, a token sent over plain HTTP, an address your IP allowlist blocks, or a protocol or session error on the MCP route. Its detail names the failure. These rows are capped at five per source address every ten minutes, so a burst of failures does not produce one row each, and a failing request that is not one of the recognized kinds leaves none.
Why can't I run this from the connection that is broken?
Two reasons. The Activity Log read is gated behind the manage-options capability, which a least-privilege agent user should not hold, and a connection that cannot reach WordPress cannot run any ability at all. So this is a check you run from an admin connection that works, looking at what the failing one did or did not manage to do.