$server Server row from the base plugin's
* MCP Servers table.
* @param string $client_id The freshly-generated OAuth client_id.
* @param string $client_secret The freshly-generated OAuth client_secret.
* @return string HTML block, escaped where necessary.
* @since 0.1.0
*/
public function get_setup_instructions( array $server, string $client_id, string $client_secret ): string {
unset( $server, $client_secret ); // Server-context + secret are shown separately in render_tab_section.
// Same values the site publishes at /.well-known/oauth-authorization-server.
// Rendered literally rather than named, because an operator filling in
// console.x.ai has no other way to discover them — omitting them is
// what left Business/Enterprise accounts stuck with credentials that
// could not be used.
$issuer = \AcrossAI_MCP_Manager\Includes\OAuth\DiscoveryController::issuer();
$authorize_url = $issuer . '/authorize';
$token_url = $issuer . '/token';
ob_start();
?>
-
' . esc_html( $client_id ) . ''
);
?>
-
' . esc_html( $authorize_url ) . ''
);
?>
-
' . esc_html( $token_url ) . ''
);
?>
-
mcp'
);
?>
-
client_secret_post'
);
?>
__( 'Grok wants to connect to your site', 'acrossai-mcp-manager' ),
'subtitle' => __( 'This will let Grok access the MCP tools this server exposes, acting as your WordPress user.', 'acrossai-mcp-manager' ),
'permissions_bullets' => array(
__( 'Read and act on the tools exposed on this MCP server', 'acrossai-mcp-manager' ),
__( 'Access the WordPress data your user account has permission to see', 'acrossai-mcp-manager' ),
__( 'Connect until you revoke access from the Connectors/Integrations tab', 'acrossai-mcp-manager' ),
),
);
}
/**
* Claim DCR-registered clients whose redirect URIs point at a
* Grok / xAI-owned host. Prefer host-based matching over substring
* name matching so short brand words don't false-positive against
* unrelated clients ("xai" is a two-letter root that could appear in
* random client names or paths).
*
* @param string $client_name DCR-submitted client_name.
* @param array $redirect_uris DCR-submitted redirect_uris.
* @return bool
*/
public function matches_dcr_client( string $client_name, array $redirect_uris ): bool {
if ( self::dcr_matches_by_host( $redirect_uris, self::DCR_HOSTS ) ) {
return true;
}
// Name-only fallback — whole-word `grok` match. No `xai` fallback
// since the two-letter root is too fragile.
return (bool) preg_match( '/\bgrok\b/i', $client_name );
}
/**
* Grok-branded "How to connect" panel. Covers the two Grok surfaces
* that accept a custom MCP server today — Grok on the web (grok.com)
* and the Grok mobile / X app — and links to
* acrossai.co/grok-connectors/ for the fuller walkthrough. Grok uses
* Dynamic Client Registration, so no credentials need to be pasted.
*
* @param string $mcp_url MCP endpoint URL.
* @return array Spec for the shared panel renderer.
*/
protected function get_setup_spec( string $mcp_url ): array {
$spec = array(
'name' => 'Grok',
'lead' => __( 'Grok reaches your site over OAuth. You approve once on a WordPress consent screen.', 'acrossai-mcp-manager' ),
'open_label' => __( 'Open Grok connectors', 'acrossai-mcp-manager' ),
'open_url' => 'https://grok.com/connectors',
'steps' => array(
array( 'text' => __( 'In Grok, open Settings > Connectors', 'acrossai-mcp-manager' ) ),
array( 'text' => __( 'Click New Connector, then choose Custom to open the "Custom Connector" dialog', 'acrossai-mcp-manager' ) ),
array(
'text' => __( 'Fill in Name', 'acrossai-mcp-manager' ),
'copy' => $this->get_connector_name(),
'note' => __( 'Anything works — the name is only so you recognise this connector in your list. This one matches the site.', 'acrossai-mcp-manager' ),
),
array(
'text' => __( 'Paste the MCP endpoint URL into Server URL', 'acrossai-mcp-manager' ),
'url' => true,
),
array(
'text' => __( 'Click Add Connector, then Connect, and approve the consent screen', 'acrossai-mcp-manager' ),
'note' => __( 'There is nothing else to fill in — Grok registers itself and signs in through your browser.', 'acrossai-mcp-manager' ),
'open' => true,
),
),
'plan' => __( 'Availability depends on your xAI plan. On Business and Enterprise an admin adds the connector from the console.x.ai admin surface instead — that one is different: it does not register itself, so the OAuth credentials must be filled in by hand.', 'acrossai-mcp-manager' ),
'docs_url' => 'https://acrossai.co/docs/connect-grok-troubleshooting/',
);
return $spec;
}
/**
* Render the Grok "How to connect" panel below the standard card.
*
* @param array $server Server row.
* @return void
*/
// F021 Phase 9 (2026-07-11): render_tab_section is now inherited from
// AbstractConnectorProfile::render_default_card. The base plugin's shared
// CSS + JS bundle (enqueued via Admin\Main::maybe_enqueue_ai_connectors_app)
// handles all card layout, Generate/Regenerate buttons, and copy behavior.
// This class is now pure metadata: get_slug + get_name + get_icon_url +
// get_redirect_uri_whitelist + get_setup_instructions + get_consent_branding +
// (F024) matches_dcr_client + get_mcp_url_setup_html.
}