What 1.7.8 changes: bridged tools now show up in the tool list

If you use the Bridge, version 1.7.8 changes what your agent sees. Thirty-seven bridged tools from WooCommerce, Meta Box, SiteOrigin, Premium Addons, SEOPress, WPForms, Elementor and ElementsKit worked when called by name but never showed in the tool list. They now list for users who can edit posts, and the plugin that owns each tool still decides whether a call is allowed.

The Bridge is the part of Agent Abilities for MCP that exposes abilities other active plugins register through the WordPress Abilities API. It is documented here, and every bridged ability is off until you turn it on. The tool-list change below only matters for the bridged abilities you have enabled.

Tools that worked but never showed in the list

An agent asks the site what tools exist before it picks one. To answer, the plugin asks each bridged tool’s source plugin whether the current user may use it, with no arguments attached. Some plugins guard their tools on an object ID, such as a post or an order, so with no ID they answer no.

The result was a tool that vanished from the list for every role while a call by name still worked. The changelog counts 37 such tools across the eight plugins above. Your number depends on which of them you run and which of their abilities you have enabled.

Now, when a source plugin answers no, discovery falls back to a floor of edit_posts. On a stock WordPress site that means contributors, authors, editors and administrators see the tool. A source plugin that crashes during the check still hides its tool, and your role and connection allowlists still apply before any of this.

The tradeoff

For a bridged tool whose source plugin answers no to that probe, the list can now include tools the user cannot run. The call check still decides.

Listing a bridged tool versus calling it Listing a bridged tool, which changed in 1.7.8, requires that you enabled the tool and that any role or connection allowlist permits it. The plugin then asks the source plugin with no object ID. If the answer is no, users who can edit posts still see the tool in the list. A source plugin that crashes hides the tool. Calling the tool is unchanged: the source plugin's own permission check runs with the real arguments, a denied call is refused and logged, and an allowed call runs. AN AGENT ASKS WHAT TOOLS EXIST, THEN CALLS ONE Two different checks, at two different moments LISTING (CHANGED IN 1.7.8) You enabled it, and any role or connection allowlist allows it Source plugin asked with no object ID If it says no Users who can edit posts still see the tool Raise the floor with the aafm_bridge_discovery_capability filter CALLING (UNCHANGED) Source plugin's own permission check runs with the real arguments Denied Refused, and logged as a denied call Allowed The call runs

The probe cannot tell “no, because the object ID is missing” from “no, because your role is wrong”. So a tool restricted to higher roles can also appear for a user who holds only edit_posts. If that user tries it, the source plugin refuses the call and the Activity Log records a denied row. Listing a tool never grants the right to run it.

We took that trade over leaving 37 working tools invisible. If you want a higher floor, return a different capability from the aafm_bridge_discovery_capability filter. See abilities from other plugins for the Bridge as a whole, and the plugin directory for which plugins register abilities.

Errors now name the source namespace

A bridged tool’s failure used to reach the agent as the source plugin’s bare error text, with no hint who said it. It now reads “The woocommerce plugin returned an error: …” followed by the original message. The name is the ability’s namespace, not a display name, so you will see woocommerce or acf rather than a product title. The original error code and data are kept, and the prefix is skipped when the message already names the plugin.

The Activity Log gets the plugin’s error code too, with limits:

  • The code is recorded only when it is 1 to 64 letters, digits, underscores or hyphens.
  • It sits behind a foreign: prefix, so a plugin that returns this plugin’s own refusal string cannot pass for the Bridge.
  • The message and the error data are never recorded.

The agent still sees the plugin’s message. What we keep out of the log is the free text. A plugin that builds its error code out of its own input could put a short, key-shaped fragment of that input into the column, so the rule is identifiers and short codes, not “nothing that came from another plugin”. What the Activity Log actually stores has the full account.

Three bridged results that went wrong

ACF delete

Deleting through a bridged ACF tool returned an error after the item was already deleted. ACF’s REST abilities override core’s output check. The bridge checked anyway and reported failure. It now returns ACF’s own result, and tools whose source plugin skips core’s output check, ACF’s REST abilities among them, advertise no output schema. We have not tried that against every MCP client, so a strict one may still object to a result that does not match a schema.

Plain objects

Some plugins, PixelYourSite and Premium Addons among them, build their results with (object) casts. The bridge refused those results after the write had already happened, so the change landed and the agent was told it failed. Plain objects now come through. Other object types, such as WP_User or WP_Post, are still refused, and the message says the ability ran, so the agent knows to check the site before repeating a call. A refused call is now logged as an error instead of success. The bridge does not redact what a source plugin returns, and a plain object now travels the way an array always did.

Exception text

From WordPress 7.0, core catches a throw inside a source ability and hands back an error carrying the exception’s own text, which can include the value that failed. That text used to reach the agent. On 7.0 and later it now gets the same static message the plugin gives for any unexpected error. On WordPress 6.9 core lets the throw escape and the plugin handles it, except on a development site with WP_DEBUG on, where the plugin rethrows on purpose so you can see the exception. Keep WP_DEBUG off in production.

What did not change

The built-in catalog is still 179 abilities, 85 in core and 94 across the integrations. The Bridge is a separate layer on top, bridged abilities stay off until you enable them, and the source plugin still decides each call.

The two releases before this one are 1.7.6, which confined OAuth tokens to the MCP route, and 1.7.7, which gave the Abilities tab one Save button. The full history is on the changelog.