Ships two features that together tighten the default MCP access posture and improve cache-exclusion visibility.
⚠️ Behavior change — MCP endpoints default to administrators only
Feature 042 — MCP servers now default to admin-only access when no wpb-access-control rule is configured for them. Previously fail-open at the tool-call layer (any authenticated user could hit a rules-less server's /wp-json/{namespace}/{route} endpoint).
New runtime filter mcp_adapter_default_transport_permission_user_capability, hooked by \AcrossAI_MCP_Manager\Includes\AccessControl\TransportPermissionDefault, hard-blocks non-admins at the REST permission_callback stage whenever the vendor "Who can access" dropdown reads "No user access added by admin". Together with the existing F015 mcp_adapter_pre_tool_call gate, forms a two-filter, per-server permission stack (defense-in-depth):
| Layer | Filter | Behavior |
|---|---|---|
| 1 | mcp_adapter_default_transport_permission_user_capability (F042) | Returns manage_options when no rule → subscribers/editors/etc. 401. Returns vendor default read when a rule exists → any subscriber+ passes to layer 2. |
| 2 | mcp_adapter_pre_tool_call (F015, unchanged) | No rule → fail-open. Rule set → wpb-ac evaluates rule; deny returns WP_Error 403. |
Both filters resolve the current server independently per request. Neither has any hardcoded server slug — adding a new server via Add New Server applies both filters automatically. Zero DB writes; a static info banner on the Access Control tab explains the default policy to operators.
Operator action
If you were relying on the previous fail-open default (subscribers/editors reaching MCP endpoints without a rule set), open each MCP server's Access Control tab and configure the "Who can access" dropdown:
- Want the old behavior? → set the rule to Anyone
- Only logged-in users? → Any logged-in user
- Specific roles/users/capabilities? → configure via the dropdown
Rules-less servers are admin-only until you configure them.
Test coverage
26 PHPUnit tests across 2 new files under tests/phpunit/Includes/AccessControl/:
TransportPermissionDefaultTest— 14 unit tests covering every branch of the filter callback in isolation (route parsing, server lookup, rule presence, default passthrough, memoization, filter-wiring regression guard).TransportPermissionRoleMatrixTest— 12 composed integration tests exercising both filters end-to-end across 6 user roles × 4 rule shapes × ≥4 servers per test, including a 5×4 truth-table matrix that directly proves per-server independence.
Cache-exclusion notice for the CLI (npm/npx) flow
Feature 041 — When Settings → MCP → Allow CLI connections via npm / npx (acrossai_mcp_npm_login_enabled = true) is enabled, a persistent warning card now appears in the AcrossAI Notices submenu (and in the WP-native dismissible summary) instructing operators to exclude the CLI auth URL (https://<site>/acrossai-mcp-manager/) from page caching. The URL carries per-request nonces + single-use auth codes; caching plugins that treat it as static content silently break the login flow.
The existing inline banner in the settings section is preserved — this feature adds a second, higher-visibility surface that co-admins and future visitors see even if they never open that specific settings section.
Under the hood
- New singleton
\AcrossAI_MCP_Manager\Includes\AccessControl\TransportPermissionDefaultwith per-request memoization (one DB lookup per unique route per MCP request). - Both filter registrations sit adjacent in
Main.php::define_public_hooks()under a documented "MCP two-filter, per-server permission stack (F015 + F042)" block. - New info banner method
AccessControlTab::render_default_policy_notice()prepended torender_body(). - Feature-041 notice appended to
Notices::register_shared_notices()(uses the sharedacrossai_noticesfilter fromacrossai-co/main-menu0.0.30+). - Version bumped in
acrossai-mcp-manager.php,Main.phpACROSSAI_MCP_MANAGER_VERSIONconstant, andreadme.txtStable tag.
Migration
Operator action required only if you were relying on the fail-open default from previous versions — see the "Operator action" callout above.
No database migration. No composer changes. No rebuilds required.
Spec-kit dossiers
- Feature 042:
specs/042-default-manage-options-access-rule/ - Feature 041:
specs/041-cli-auth-cache-exclusion-notice/