30 days free. No credit card. Full access from the moment you connect your site.

Start free trial

v0.2.8 — close MCP resource/prompt AC bypass + F042 fail-closed + server list redesign

Three PRs merged into main since 0.2.7 ship in this release; two are ⚠️ security behavior-changes surfaced by the 2026-08-13 adversarial review of the MCP two-gate access-control stack.

PRs included

PRKindTitle
#77⚠️ securityfix(access-control): close resource/prompt bypass + fail-closed on missing vendor
#76admin UXfeat(admin): server list — drop Slug/Version, merge Route, Edit + tab quick-links
#75UI copyfeat(admin): rename AI Connectors tab label to Connectors/Integrations

⚠️ Security — F1: MCP resources & prompts now gated (was silently bypassed)

Before 0.2.8 the plugin only hooked mcp_adapter_pre_tool_call. The vendor's sibling pre-dispatch filters — mcp_adapter_pre_resource_read (ResourcesHandler.php:138) and mcp_adapter_pre_prompt_get (PromptsHandler.php:157) — had no subscriber.

Combined with F042 deliberately returning 'read' at the transport layer for rule-configured servers (so any authenticated user passes the transport gate, on the assumption that F015 would then enforce), any authenticated user could POST {"method":"resources/read","params":{"uri":"…"}} or {"method":"prompts/get"} against a server configured "Editors only" and the operator's rule was never consulted.

Fix: extracted the enforcement body of gate_mcp_tool_call into a private apply_ac_gate() helper. Added two sibling public callbacks — gate_mcp_resource_read + gate_mcp_prompt_get — wired adjacent to the existing tool-call filter in Main::define_public_hooks(). Deny path returns WP_Error with a gate value of mcp_resource_read / mcp_prompt_get. Observability hooks (acrossai_mcp_access_control_denied, acrossai_mcp_access_control_missing_server) now fire from three MCP boundary sites — $context arg discriminates; $subject arg is polymorphic (tool name / resource URI / prompt name).

Operator action: audit any server that exposes MCP resources or prompts AND has a rule configured. Non-privileged users who previously succeeded on resources/read / prompts/get will now receive HTTP 403 with the same acrossai_mcp_access_denied error code the tool-call gate has emitted since 0.0.7.

⚠️ Security — F2: F042 fails CLOSED on missing wpb-access-control (was fail-open)

Before 0.2.8 both AC gates failed OPEN under the same condition: F015 returned $args (allow) when class_exists( AccessControlManager::class ) was false; F042 returned the vendor 'read' default under the mirror condition (class_exists( RuleQuery::class )). Because both degraded in the same direction, a single dependency failure — composer breakage, autoloader race, missed dependency after site clone, vendor package rename — collapsed the entire two-gate stack, letting every authenticated user reach every tool on every server.

Fix: F042's missing-vendor branch now returns 'manage_options'. Paired with F015's fail-open on the same condition, the stack degrades to admin-only rather than "wide open." Class docblock on TransportPermissionDefault explicitly documents the intentional asymmetry — "F015 fails open + F042 fails closed = admin-only when the vendor breaks" — so the invariant survives future refactors. Class-exists check moved behind a protected has_access_control_library() seam for direct test coverage.

Operator action: none in the healthy-vendor case. If your deploy pipeline can produce a missing-vendor state, non-admin MCP traffic will get 401 instead of full access until the vendor package is restored.

Admin — Server list redesigned

Server list at ?page=acrossai_mcp_manager gets a tighter, more actionable layout.

Column changes:

  • Removed Slug (redundant with Route/Route Namespace and the Name column's inline edit link)
  • Merged Route Namespace + Route into a single Route column (<namespace>/<route>, duplicate slashes at the join collapsed)
  • Removed Version (still surfaced on the per-server-edit Overview tab)
  • Final column order: ☐ | Name | Status | Registered From | Route | Actions

Actions column extended — the existing Enable/Disable toggle is now bundled with 5 quick-access buttons:

  1. Edit (primary-styled) — links to the server-edit page
  2. Enable / Disable — existing per-row nonce'd toggle
  3. Connectorstab=ai-connectors
  4. Access Controltab=access-control
  5. Abilitiestab=abilities
  6. MCP Clientstab=clients

Quick-links render as subtle rounded pill-badges with dashicon prefixes (admin-plugins / shield / superhero-alt / admin-users). New .acrossai-actions-cell flex wrapper keeps the button cluster wrapping cleanly on narrow viewports; Status + Registered From columns capped at 120px so the freed horizontal space flows to Route + Actions.

UI — AI Connectors tab renamed to "Connectors/Integrations"

The per-server-edit tab label at ?page=acrossai_mcp_manager&action=edit&server=<id>&tab=ai-connectors now reads Connectors/Integrations instead of "AI Connectors". Tab slug (ai-connectors) is intentionally unchanged so the last-wins tab-registration override from the acrossai-ai-connectors companion plugin keeps landing on the same placeholder — no companion-plugin coordination required.


Internal: ACROSSAI_MCP_MANAGER_VERSION constant + Stable tag bumped to 0.2.8 matching the plugin header.

Full changelog: main…v0.2.8


Keep reading