$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.
ob_start();
?>
-
' . esc_html( $client_id ) . ''
);
?>
__( 'ChatGPT wants to connect to your site', 'acrossai-mcp-manager' ),
'subtitle' => __( 'This will let ChatGPT 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 an
* OpenAI-owned host. Prefer host-based matching over substring name
* matching — "OpenAI" and "ChatGPT" appear in third-party client names
* frequently enough that name-only matching risked false positives
* (e.g., "OpenAI Community Bot" for an unrelated tool).
*
* @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 — narrow, whole-word `chatgpt` match. No
// `openai` fallback because that string is too common in
// unrelated third-party client names.
return (bool) preg_match( '/\bchatgpt\b/i', $client_name );
}
/**
* ChatGPT-branded "How to connect" panel. Verified against
* help.openai.com's Plugins + Developer Mode docs (2026): the surface
* ChatGPT surfaces custom MCP servers under is now called Plugins (the
* old "Connectors" label was retired in July 2026), Developer Mode has
* to be flipped on first, and the feature is limited to paid workspaces.
*
* @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' => 'ChatGPT',
'lead' => __( 'ChatGPT lists custom MCP servers under Plugins once Developer Mode is on.', 'acrossai-mcp-manager' ),
'open_label' => __( 'Open ChatGPT settings', 'acrossai-mcp-manager' ),
'open_url' => 'https://chatgpt.com/',
'steps' => array(
array(
'text' => __( 'In ChatGPT, open Settings > Plugins', 'acrossai-mcp-manager' ),
'note' => __( 'Custom MCP servers need Developer Mode on — enable it under Settings > Security and login. On Business and Enterprise an admin turns it on for the workspace first.', 'acrossai-mcp-manager' ),
),
array( 'text' => __( 'Click Add, then choose Add custom MCP server', '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 server in your list. Icon and Description are optional.', 'acrossai-mcp-manager' ),
),
array(
'text' => __( 'Leave Connection set to Server URL, not Tunnel, and paste the MCP endpoint URL', 'acrossai-mcp-manager' ),
'url' => true,
),
array(
'text' => __( 'Set Authentication to OAuth and leave Advanced OAuth settings alone', 'acrossai-mcp-manager' ),
'note' => __( 'ChatGPT discovers the settings and registers itself — no client ID or secret to enter.', 'acrossai-mcp-manager' ),
),
array(
'text' => __( 'Tick "I understand and want to continue", click Create as a plugin, then approve the consent screen', 'acrossai-mcp-manager' ),
'open' => true,
),
),
'plan' => __( 'Available on paid ChatGPT plans.', 'acrossai-mcp-manager' ),
'docs_url' => 'https://acrossai.co/docs/connect-chatgpt-troubleshooting/',
);
return $spec;
}
/**
* Override the shared card body so the ChatGPT "How to connect" panel
* renders on the tab immediately, without requiring the operator to
* click Generate first.
*
* @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.
}