admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('gosmtp_ajax'), 'endpoint_url' => trailingslashit(home_url()) . ltrim(self::$ABILITIES_ENDPOINT, '/'), 'i18n' => [ 'installing' => esc_html__('Installing...', 'gosmtp'), 'activating' => esc_html__('Activating...', 'gosmtp'), 'updating' => esc_html__('Updating...', 'gosmtp'), 'generating' => esc_html__('Generating...', 'gosmtp'), 'testing' => esc_html__('Testing...', 'gosmtp'), 'genErrTitle' => esc_html__('Could not generate the password.', 'gosmtp'), 'testOkPrefix' => esc_html__('Success:', 'gosmtp'), 'testFailPrefix'=> esc_html__('Failed:', 'gosmtp'), ], ]); // Status probes (kept cheap; safe to run on each render). $abilities_api_available = function_exists('wp_register_ability'); $adapter_active = is_plugin_active('mcp-adapter/mcp-adapter.php'); $adapter_installed = '' !== self::get_installed_mcp_adapter_file(); $has_app_password = self::current_user_has_mcp_app_password(); $test_status = self::get_test_connection_status(); $site_url = trailingslashit(rtrim(home_url(), '/')); $endpoint_url = $site_url . ltrim(self::$ABILITIES_ENDPOINT, '/'); $mcp_server_url = $site_url . ltrim(self::$MCP_SERVER_ENDPOINT, '/'); $username = function_exists('wp_get_current_user') ? wp_get_current_user()->user_login : ''; $app_pass_placeholder = esc_html__('your-application-password', 'gosmtp'); $user_placeholder = $username ? $username : esc_html__('', 'gosmtp'); $adapter_installed_version = $adapter_installed ? self::get_installed_mcp_adapter_version() : ''; $adapter_latest_version = ''; $adapter_update_available = false; if($adapter_installed && $adapter_installed_version){ $release = self::get_mcp_adapter_release(); if(!empty($release['version']) && version_compare($release['version'], $adapter_installed_version, '>')){ $adapter_latest_version = $release['version']; $adapter_update_available = true; } } ?>

esc_html__('Abilities', 'gosmtp'), 'state' => $abilities_api_available ? 'done' : 'todo'], ['label' => esc_html__('MCP Adapter', 'gosmtp'),'state' => $adapter_active ? 'done' : 'todo'], ['label' => esc_html__('Password', 'gosmtp'), 'state' => $has_app_password ? 'done' : 'todo'], ['label' => esc_html__('Test', 'gosmtp'), 'state' => !empty($test_status['ok']) ? 'done' : 'todo'], ]; foreach($step_states as $idx => $st){ echo '
'; echo '' . ($st === 'done' ? '✓' : esc_html((string)($idx + 1))) . ''; echo '' . esc_html($chips[$idx]['label']) . ''; echo '
'; } ?>
' . sprintf(esc_html__('Next up: %s', 'gosmtp'), '' . esc_html($next_step) . '') . '

'; }else{ echo '

' . esc_html__('All steps complete. Your AI client can now connect.', 'gosmtp') . '

'; } ?>
' . esc_html__('GoSMTP exposes the abilities listed below. They are picked up automatically by any installed MCP adapter and surfaced to AI clients as tools.', 'gosmtp') . '

'; echo wp_kses_post(self::render_abilities_list()); }else{ echo '

' . esc_html__('The WordPress Abilities API ships in WordPress 6.9+. GoSMTP can still work today — installing the MCP Adapter backfills the API so your AI client can connect immediately. Consider updating WordPress for native abilities support.', 'gosmtp') . '

'; } ?>
' . esc_html__('The MCP Adapter plugin is installed and active. Your site now exposes an MCP server that AI clients can connect to.', 'gosmtp') . '

'; if($adapter_update_available){ echo '

' . sprintf(esc_html__('A newer version of the MCP Adapter is available (installed: %1$s, latest: %2$s).', 'gosmtp'), '' . esc_html($adapter_installed_version) . '', '' . esc_html($adapter_latest_version) . '') . '

'; echo ''; } }elseif($adapter_installed){ echo '

' . esc_html__('The MCP Adapter is installed but not active. Activate it to enable the MCP server.', 'gosmtp') . '

'; echo ''; }else{ echo '

' . esc_html__('Install the official WordPress MCP Adapter plugin with a single click. It bridges your site to any MCP-compatible AI client. GoSMTP requires the MCP Adapter to expose its abilities to AI clients.', 'gosmtp') . '

'; echo ''; } ?>

' . esc_html(($test_ok ? __('Success: ', 'gosmtp') : __('Failed: ', 'gosmtp')) . $test_message) . '
'; }else{ echo '
'; } ?>

' . wp_json_encode([ 'siteUrl' => $site_url, 'mcpServerUrl' => $mcp_server_url, 'endpointUrl' => $endpoint_url, 'username' => $username, 'passwordHolder' => $app_pass_placeholder, 'userPlaceholder'=> $user_placeholder, 'serverName' => 'gosmtp-site', 'adapterActive' => $adapter_active, 'hasAppPassword' => $has_app_password, 'i18n' => [ 'copy' => esc_html__('Copy snippet', 'gosmtp'), 'copied' => esc_html__('Copied!', 'gosmtp'), 'installing' => esc_html__('Installing...', 'gosmtp'), 'activating' => esc_html__('Activating...', 'gosmtp'), 'updating' => esc_html__('Updating...', 'gosmtp'), 'generating' => esc_html__('Generating...', 'gosmtp'), 'testing' => esc_html__('Testing...', 'gosmtp'), 'genErrTitle' => esc_html__('Could not generate the password.', 'gosmtp'), 'testOkPrefix' => esc_html__('Success:', 'gosmtp'), 'testFailPrefix'=> esc_html__('Failed:', 'gosmtp'), ], ]) . ''; // Segmented tab bar $clients = [ 'claude-desktop' => ['label' => esc_html__('Claude Desktop', 'gosmtp'), 'icon' => 'C'], 'claude-code' => ['label' => esc_html__('Claude Code CLI', 'gosmtp'), 'icon' => '>_'], 'cursor' => ['label' => esc_html__('Cursor', 'gosmtp'), 'icon' => 'Cu'], 'vscode' => ['label' => esc_html__('VS Code', 'gosmtp'), 'icon' => 'VS'], 'antigravity' => ['label' => esc_html__('Antigravity', 'gosmtp'), 'icon' => 'AG'], 'opencode' => ['label' => esc_html__('OpenCode', 'gosmtp'), 'icon' => 'OC'], 'gemini-cli' => ['label' => esc_html__('Gemini CLI', 'siteseo-pro'), 'icon' => 'G', 'deprecated' => true], ]; echo '
'; $first = true; foreach($clients as $id => $data){ $badge = ''; if(!empty($data['deprecated'])){ $badge = ' ' . esc_html__('Deprecated', 'gosmtp') . ''; } echo ''; $first = false; } ?>

								
							

    >

    ' . esc_html__('No GoSMTP abilities are currently exposed. Activate the MCP Adapter to surface them.', 'gosmtp') . '

    '; } $html = '
    '; foreach($groups as $group => $items){ $html .= '
    '; $html .= '

    ' . esc_html($group) . '

    '; $html .= '
      '; foreach($items as $ability){ $html .= '
    • '; $html .= '' . esc_html($ability['label']) . ''; if(!empty($ability['description'])){ $html .= '' . esc_html($ability['description']) . ''; } if(!empty($ability['pro'])){ $html .= '' . esc_html__('Pro', 'gosmtp') . ''; } $html .= '
    • '; } $html .= '
    '; $html .= '
    '; } $html .= '
    '; return $html; } /** * The catalogue of GoSMTP abilities exposed to MCP clients. Mirrors the * abilities registered in main/abilitiesregister.php (Free) and * main/abilitiesregister.php in Pro. The Pro section is only merged when * the GoSMTP Pro plugin is installed and active. * * @return array */ static function get_registered_abilities(){ $free = [ esc_html__('Settings', 'gosmtp') => [ [ 'label' => esc_html__('Get GoSMTP Settings', 'gosmtp'), 'description' => esc_html__('Returns global from email/name, force flags, return path and logging toggles. Credentials are never exposed.', 'gosmtp'), ], ], esc_html__('Mailer', 'gosmtp') => [ [ 'label' => esc_html__('List Configured Mailers', 'gosmtp'), 'description' => esc_html__('Lists configured SMTP connections with their nickname, mailer type and backup connection.', 'gosmtp'), ], ], esc_html__('Test', 'gosmtp') => [ [ 'label' => esc_html__('Send a Test Email', 'gosmtp'), 'description' => esc_html__('Sends a test email through the configured mailer and reports the result.', 'gosmtp'), ], ], ]; // Allow GoSMTP Pro to register additional abilities. return apply_filters('gosmtp_registered_abilities', $free); } /** * Scan installed plugins for the MCP Adapter (folder prefix: mcp-adapter/). * * @return string */ static function get_installed_mcp_adapter_file(){ if(!function_exists('get_plugins')){ require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $all_plugins = get_plugins(); $target_file = 'mcp-adapter/mcp-adapter.php'; if(isset($all_plugins[ $target_file ])){ return $target_file; } return ''; } /** * Read the installed MCP Adapter version from the plugin headers. * * @return string Empty string when the adapter is not installed. */ static function get_installed_mcp_adapter_version(){ $file = self::get_installed_mcp_adapter_file(); if('' === $file){ return ''; } if(!function_exists('get_plugins')){ require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $all_plugins = get_plugins(); if(!isset($all_plugins[ $file ]['Version'])){ return ''; } return (string)$all_plugins[ $file ]['Version']; } /** * Does the current user already have an MCP app password created by GoSMTP? * * @return bool */ static function current_user_has_mcp_app_password(){ $user_id = get_current_user_id(); if(!$user_id || !class_exists('WP_Application_Passwords')){ return false; } foreach(\WP_Application_Passwords::get_user_application_passwords($user_id) as $app){ if(!empty($app['app_id']) && $app['app_id'] === self::$APP_PASSWORD_APP_ID){ return true; } } return false; } /** * Read the saved test-connection status for the current user. * * @return array */ static function get_test_connection_status(){ $user_id = get_current_user_id(); if(!$user_id){ return ['ok' => false, 'message' => '']; } $stored = get_user_meta($user_id, self::$TEST_STATUS_META, true); if(!is_array($stored)){ return ['ok' => false, 'message' => '']; } return [ 'ok' => !empty($stored['ok']), 'message' => !empty($stored['message']) ? $stored['message'] : '', ]; } /** * Persist the test-connection status for the current user. * * @param bool $ok * @param string $message * @return void */ static function save_test_connection_status($ok, $message){ $user_id = get_current_user_id(); if(!$user_id){ return; } update_user_meta($user_id, self::$TEST_STATUS_META, [ 'ok' => !empty($ok), 'message' => (string)$message, ]); } // Fetch the latest MCP Adapter release info from GitHub (cached 1 day). static function get_mcp_adapter_release(){ $cached = get_transient(\GOSMTP\Abilities::$MCP_ADAPTER_RELEASE_CACHE); if(false !== $cached && is_array($cached)){ return $cached; } $response = wp_remote_get(\GOSMTP\Abilities::$MCP_ADAPTER_RELEASE_URL, [ 'timeout' => 10, 'headers' => ['Accept' => 'application/vnd.github+json'], ]); if(is_wp_error($response) || 200 !== wp_remote_retrieve_response_code($response)){ return []; } $body = json_decode(wp_remote_retrieve_body($response), true); if(!is_array($body) || empty($body['tag_name']) || empty($body['assets'][0]['browser_download_url'])){ return []; } $payload = [ 'version' => ltrim((string)$body['tag_name'], 'v'), 'download_url' => esc_url_raw($body['assets'][0]['browser_download_url']), ]; set_transient(\GOSMTP\Abilities::$MCP_ADAPTER_RELEASE_CACHE, $payload, DAY_IN_SECONDS); return $payload; } }