Bundles Feature 008 (Server-wide AI Connectors UI + Others bucket + Google Gemini profile + P1 Gemini /authorize bypass fix + RFC 8252 §7.3 loopback matcher) into a single 0.6.0 release.
Merged via #22.
New capabilities — Feature 008
- Server-wide admin UI — the per-server AI Connectors tab is refactored from N per-connector sub-tabs into a two-row layout:
[ ChatGPT | Claude | Gemini | Grok | Others ]connector selector on top,[ Connections | Approved Users | Settings ]server-wide sub-tabs on the bottom. Settings collapses N per-slug forms into one server-wide form. New nuclear "Revoke all connections on this server" button on the Settings tab revokes every outstanding token and approval for the current server in one action. - Google Gemini connector profile — new
GeminiConnectorProfileregisters Gemini againstacrossai_ai_connectors_profileswith a two-callback redirect URI whitelist (vertexaisearch.cloud.google.com+antigravity.google) and a three-host DCR matcher. Gemini CLI's ephemeral-port loopback callback is covered by the new RFC 8252 §7.3 loopback matcher (see Security below). - Others bucket — new server-wide "Any other OAuth-compliant MCP client" toggle (default OFF) admits DCR clients whose
connector_slugis empty or unclaimed by a registered profile (e.g. Frog AI, other RFC 7591 clients). Others bucket force-requires per-user admin approval, even when the server-wide approval toggle is off. - Server-scoped per-connector config — server-wide settings migrated from per-slug
wp_optionskeys onto twometa_keyrows onwp_acrossai_mcp_servers_metaviaMCPServerMeta\Query. Rows cascade-clean when a server is deleted. Read-path soft migration seeds the new record from legacywp_optionskeys on first load; nothing writes back towp_options, and no schema changes ship.
Security — Feature 008
- [SECURITY-P1] Closed the Gemini bypass at
/authorize. Enforcement gates guarded byif ( '' !== $slug )silently fell through for DCR clients whoseconnector_slugwas empty or unclaimed — the class of client the new "Others" bucket now models. Unrecognized DCR clients hit an unconditional gate atAuthorizationController::handle_get; the "Others" toggle (default OFF) is the sole admission path. - [SECURITY-P2] DCR client attribution hardened —
matches_dcr_client()rewritten to prefer redirect URI host matching overclient_namesubstring matching. ChatGPT + Grok are now DCR-only (empty manual whitelist → generate-credentials UI hidden +409on direct POST). Claude whitelist addsclaude.comalongsideclaude.aifor Anthropic forward-compat. - [SECURITY-P2] RFC 8252 §7.3 loopback exception —
AuthorizationController::assert_redirect_uri_or_diegains a scoped loopback fallback:127.0.0.1/::1/localhostURIs accept any port variance (native CLI clients bind an ephemeral port per invocation). Non-loopback URIs stay strict byte-match. Fixes silent connect failures for Claude Code, Gemini CLI, Codex, Cursor, and other native OAuth CLIs.
New public surface
POST /oauth/server-settings— save the server-wide settings blob.POST /oauth/approve-server-pending— approve a user server-wide for the current server.POST /oauth/deny-server-pending— remove a user from the server-wide pending list.POST /oauth/revoke-server-approval— server-wide approval revoke + cascade.POST /oauth/revoke-server-tokens— nuclear revoke of every token on the current server.- New filter contribution:
acrossai_ai_connectors_profilesnow also contributesGeminiConnectorProfile. - New sentinel:
ConnectorApprovedUsersQuery::SERVER_WIDE_SLUG = '*'marks approvals that apply to any connector on a server.
Preserved contracts
- No schema changes.
- No new
wp_optionskeys. - No new composer runtime dependencies.
- Public plugin-load filter
acrossai_ai_connectors_loaduntouched. - Upgrade is a runtime no-op for existing Claude / ChatGPT / Grok connections — no re-auth required, no data migration, table names and hook action strings preserved byte-for-byte.
Requirements
- WordPress 6.9 or later
- PHP 8.1 or later
- AcrossAI MCP Manager must be active
Full changelog
Full diff: v0.5.2…v0.6.0