' . esc_html( $texts[ $msg ] ) . '
' . esc_html__( 'Your new access token. Copy it now, it is shown only once:', 'handymcp' ) . '
'; echo '
' . esc_html__( 'Paste this URL into your AI app.', 'handymcp' ) . '
' . esc_html( $ap_txt ) . '
' . $this->mini_form( 'app_passwords', array( 'value' => $on ? '0' : '1' ), $on ? __( 'Turn off for MCP', 'handymcp' ) : __( 'Allow for MCP only', 'handymcp' ) ) . '' . '' . '
' . esc_html( $line ) . ' ' . esc_html( $when ) . ( in_array( $state, array( 'fail', 'warn' ), true ) && self::show_help() ? ' ' . esc_html__( 'See fixes', 'handymcp' ) . '' : '' ) . '
' . esc_html( (string) $diag['summary'] ) . ' ' . esc_html( $when ) . '
' . esc_html( $chk['fix'] ) . '' : '' ) . ( 'ok' !== $st && isset( $fixes[ $chk['id'] ?? '' ] ) && self::show_help() ? '' . esc_html__( 'How to fix this', 'handymcp' ) . '' : '' ) . '
' . esc_html__( 'For apps without OAuth sign-in.', 'handymcp' ) . '
' . esc_html__( 'Last 30 days. Older ones are removed automatically.', 'handymcp' ) . '
' . esc_html( $blocked ? __( 'SiteGround blocks part of the connection. Its Anti-Bot AI has no switch in Site Tools, so send this text to SiteGround support (Site Tools > Help > Contact us).', 'handymcp' ) : __( 'SiteGround caches the connection. Add these exclusions in Speed Optimizer, then purge the cache.', 'handymcp' ) ) . '
' . esc_html__( 'If an AI app ever fails to connect, send this text to SiteGround support.', 'handymcp' ) . '
'; $html .= $box( 'handymcp-sg-ticket', __( 'Support ticket', 'handymcp' ), Blockers::siteground_ticket(), 10 ) . '' . esc_html( Blockers::wellknown_steps() ) . '' . $box( 'handymcp-wk-as', '.well-known/oauth-authorization-server', (string) wp_json_encode( $oauth->server_metadata(), $flags ), 10 ) . $box( 'handymcp-wk-prm', '.well-known/oauth-protected-resource', (string) wp_json_encode( $oauth->resource_metadata(), $flags ), 8 ); if ( $path ) { // Handled automatically: one short line, the optional steps folded away. $html = '
' . esc_html( $intro ) . '
' . esc_html__( 'OAuth sign-in looks blocked on this site. Apps that let you add a header can connect with an access token, which skips the sign-in pages.', 'handymcp' ) . '
' . esc_html__( 'The token can read and edit content, expires in 90 days and is shown once. The setup text below then includes it.', 'handymcp' ) . '
'; } else { $html .= '' . esc_html__( 'Your token is filled in below. Copy the setup now: the token is shown only once.', 'handymcp' ) . '
'; } $json = (string) wp_json_encode( array( 'mcpServers' => array( 'handymcp' => array( 'command' => 'npx', 'args' => array( '-y', 'mcp-remote', $endpoint, '--header', 'Authorization:${AUTH_HEADER}' ), 'env' => array( 'AUTH_HEADER' => 'Bearer ' . $token ) ) ) ), JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ); $html .= $box( 'handymcp-tf-cc', __( 'Claude Code (terminal)', 'handymcp' ), 'claude mcp add --transport http handymcp ' . $endpoint . ' --header "Authorization: Bearer ' . $token . '"', 3 ); $html .= $box( 'handymcp-tf-json', __( 'Claude Desktop and other apps (claude_desktop_config.json or the app\'s MCP settings)', 'handymcp' ), $json, 14 ); echo wp_kses( $html . '' . esc_html__( 'Use this when an AI app keeps failing to sign in. It removes app registrations that have no active sign-in, pending sign-in codes, and expired or revoked tokens. Connected apps and your access tokens keep working. Then connect the app again.', 'handymcp' ) . '
' . $this->mini_form( 'reset_oauth', array(), __( 'Reset OAuth state', 'handymcp' ), true, '', __( 'Remove unused app registrations, pending sign-in codes and expired or revoked tokens? Connected apps and access tokens are kept.', 'handymcp' ) ) . '' . esc_html( $g['label'] . ': ' . $g['error'] ) . '
' . esc_html( $desc ) . '
' : '' ) . '' . esc_html__( 'Requests from AI apps show up here.', 'handymcp' ) . '
' . esc_html( (string) wp_json_encode( json_decode( (string) $row->args, true ), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) ) . '
' . esc_html__( 'Older activity', 'handymcp' ) . '
'; } } /** * OAuth client id => app name. * * @return array' . esc_html( sprintf( /* translators: %d days */ __( 'The last 20 changes made by AI apps appear here and can be undone for %d days.', 'handymcp' ), $days ) ) . '
' . esc_html__( 'Older changes', 'handymcp' ) . '
'; } } /** * One task card. * * @param array' . esc_html__( 'Older changes are removed after the number of days set in Settings.', 'handymcp' ) . '
| ' . esc_html__( 'Field', 'handymcp' ) . ' | ' . esc_html__( 'Before', 'handymcp' ) . ' | ' . esc_html__( 'Now', 'handymcp' ) . ' |
|---|---|---|
| ' . esc_html( $f['name'] ) . ' | ' . ( '' === $f['before'] ? '' . esc_html__( '(empty)', 'handymcp' ) . '' : esc_html( $f['before'] ) ) . ' | ' . ( '' === $f['after'] ? '' . esc_html__( '(empty)', 'handymcp' ) . '' : esc_html( $f['after'] ) ) . ' |
' . esc_html__( 'HandyMCP is built and maintained by Sukesh Das, an independent web developer. I build WordPress, WooCommerce and custom websites for agencies, coaches, healthcare practices and small businesses, and I made this plugin so AI apps can do real work on those sites safely, with every change checked and easy to undo.', 'handymcp' ) . '
'; echo '' . esc_html__( 'Need more than the plugin? I take on projects and ongoing work.', 'handymcp' ) . '
' . esc_html__( 'Questions, bugs or ideas go straight to me.', 'handymcp' ) . '
' . esc_html( sprintf( __( 'HandyMCP %s. Thank you for using it.', 'handymcp' ), HANDYMCP_VERSION ) ) . '
'; } /** * Upgrade tab: what HandyMCP Pro adds. */ private function tab_upgrade(): void { $url = self::pro_url( 'upgrade' ); $trial = self::trial_url( 'upgrade' ); $this->page_head( __( 'HandyMCP Pro', 'handymcp' ), __( 'Everything in HandyMCP, plus the rest of your site.', 'handymcp' ), '' . esc_html__( 'See plans and pricing', 'handymcp' ) . '' ); $groups = array( array( 'yes-alt', __( 'Approval mode and protected pages', 'handymcp' ), __( 'AI changes to live pages wait for you, with the text and a live desktop and mobile preview side by side. Lock pages AI apps must never change, and fix any page with AI from the Pages, Posts and Products lists.', 'handymcp' ), ), array( 'layout', __( 'Every page builder', 'handymcp' ), __( 'WPBakery, Avada, Divi, Beaver Builder, Flatsome UX Builder, GeneratePress Elements, Blocksy, Astra and XStore, plus Elementor Pro Theme Builder (headers, footers, single and archive templates, popups with display conditions) and Elementor addon packs.', 'handymcp' ), ), array( 'cart', __( 'WooCommerce and Easy Digital Downloads', 'handymcp' ), __( 'The free plugin edits products, prices, stock and simple coupons. Pro adds variations, order updates and refunds, coupon product rules, customers, reviews, sales reports, shipping and taxes, dynamic pricing and cart abandonment.', 'handymcp' ), ), array( 'translation', __( 'Languages and custom fields', 'handymcp' ), __( 'WPML, Polylang and translation plugins. ACF, Meta Box, Pods and JetEngine fields and post types.', 'handymcp' ), ), array( 'chart-line', __( 'All SEO plugins', 'handymcp' ), __( 'All in One SEO, SEOPress and The SEO Framework, canonical URLs and noindex, and bulk fixes for pages with missing titles or descriptions.', 'handymcp' ), ), array( 'feedback', __( 'Forms and email', 'handymcp' ), __( 'Create and edit Contact Form 7, Gravity Forms, WPForms and MetForm forms, manage entries, and check mail delivery.', 'handymcp' ), ), array( 'admin-plugins', __( 'Plugins, themes, users and settings', 'handymcp' ), __( 'Install and update plugins and themes with a backup and automatic rollback, scheduled updates with email reports, Customizer, site settings, users and comments.', 'handymcp' ), ), array( 'shield', __( 'Speed, security and backups', 'handymcp' ), __( 'Cache plugins, full Wordfence control (who is blocked, block and unblock, login attempts, every setting), security scans, backups before risky work, site and page audits, brand kit and ready sections.', 'handymcp' ), ), array( 'media-code', __( 'Code and developer tools', 'handymcp' ), __( 'Build a new block theme from a design and review it on a private preview link before it goes live. Run familiar WP-CLI commands without a shell. Edit theme and plugin files and switch on code snippets: every change is checked, backed up and undone automatically if the site breaks. Also search and replace, REST routes and WordPress abilities.', 'handymcp' ), ), array( 'update', __( 'Safe scheduled updates', 'handymcp' ), __( 'Daily or weekly updates of plugins and themes. Each one is backed up first, then the home page, login, REST API and admin-ajax are checked. If the update broke the site, the old version is put back automatically and the report says so. WordPress auto-updates leave a broken site broken.', 'handymcp' ), ), array( 'warning', __( 'Malware cleanup', 'handymcp' ), __( 'Start scans in Wordfence, Sucuri or Defender and read what they found. Then let the AI clean infected theme and plugin files and spam in the database, with backups and undo. HandyMCP does not scan by itself; it works with your security plugin.', 'handymcp' ), ), array( 'backup', __( 'Full undo history', 'handymcp' ), __( 'Undo any change for as long as you keep the history, not only the last 20.', 'handymcp' ), ), array( 'networking', __( 'For agencies', 'handymcp' ), __( 'White label on client sites with every Pro plan. The Agency plan adds a client sites hub to see, update and manage every site from one dashboard and one AI connection.', 'handymcp' ), ), ); $rows = array( array( __( 'Posts, pages, media, menus and terms', 'handymcp' ), true, true ), array( __( 'Block editor (Gutenberg) pages', 'handymcp' ), true, true ), array( __( 'Elementor pages, widgets, templates, global colors and fonts', 'handymcp' ), true, true ), array( __( 'Stock photos (Openverse, Pexels, Unsplash) with alt text and credit', 'handymcp' ), true, true ), array( __( 'Stock videos from Pexels', 'handymcp' ), true, true ), array( __( 'Upload images from the chat or any image URL', 'handymcp' ), true, true ), array( __( 'Crop, resize, rotate and convert images to WebP, rebuild thumbnails', 'handymcp' ), true, true ), array( __( 'Replace an image and keep its URL, with a backup to restore', 'handymcp' ), true, true ), array( __( 'SEO titles and descriptions, and a list of pages missing them (Yoast SEO, Rank Math)', 'handymcp' ), true, true ), array( __( 'WooCommerce products, prices, stock and categories', 'handymcp' ), true, true ), array( __( 'WooCommerce coupons', 'handymcp' ), __( 'Create and edit', 'handymcp' ), __( 'Plus product and category rules', 'handymcp' ) ), array( __( 'WooCommerce orders', 'handymcp' ), __( 'View', 'handymcp' ), __( 'View, update and refund', 'handymcp' ) ), array( __( 'Contact Form 7 and WPForms', 'handymcp' ), __( 'Create and edit', 'handymcp' ), __( 'Create and edit', 'handymcp' ) ), array( __( 'Gravity Forms', 'handymcp' ), __( 'Read only', 'handymcp' ), __( 'Create and edit', 'handymcp' ) ), array( __( 'Build MetForm forms and manage form entries', 'handymcp' ), false, true ), array( __( 'Check that site email is being delivered', 'handymcp' ), false, true ), array( __( 'Change history and undo', 'handymcp' ), __( 'Last 20 changes', 'handymcp' ), __( 'Full history', 'handymcp' ) ), array( __( 'Before and after view of every AI change', 'handymcp' ), true, true ), array( __( 'Clear crash reports that name the plugin or theme at fault', 'handymcp' ), true, true ), array( __( 'Activity log, OAuth, roles and rate limits', 'handymcp' ), true, true ), array( __( 'Site brief: your voice and rules for every AI app', 'handymcp' ), true, true ), array( __( 'No daily limits, credits or per-call fees', 'handymcp' ), true, true ), array( __( 'Approval mode: check AI changes with a live before and after preview', 'handymcp' ), false, true ), array( __( 'Protected pages AI apps cannot change', 'handymcp' ), false, true ), array( __( 'Fix with AI from the Pages, Posts and Products lists', 'handymcp' ), false, true ), array( __( 'Elementor Pro Theme Builder and popups', 'handymcp' ), false, true ), array( __( 'WPBakery, Avada, Divi, Beaver Builder, Flatsome and Elementor addon packs', 'handymcp' ), false, true ), array( __( 'WooCommerce variations, customers and sales reports', 'handymcp' ), false, true ), array( __( 'Easy Digital Downloads, dynamic pricing and cart abandonment', 'handymcp' ), false, true ), array( __( 'WPML, Polylang, ACF, Meta Box, Pods and JetEngine', 'handymcp' ), false, true ), array( __( 'All SEO plugins and bulk SEO fixes', 'handymcp' ), false, true ), array( __( 'Plugin and theme updates with backup and rollback', 'handymcp' ), false, true ), array( __( 'Safe scheduled updates with site checks, automatic rollback and email reports', 'handymcp' ), false, true ), array( __( 'Malware cleanup with your security plugin, with backups and undo', 'handymcp' ), false, true ), array( __( 'Search and replace across the whole site, with preview and undo', 'handymcp' ), false, true ), array( __( 'Theme settings, Flatsome, GeneratePress, Blocksy, XStore and Ultimate Addons', 'handymcp' ), false, true ), array( __( 'Brand kit, ready sections and page audits', 'handymcp' ), false, true ), array( __( 'Users, roles and comments', 'handymcp' ), false, true ), array( __( 'Customizer and site settings', 'handymcp' ), false, true ), array( __( 'Redirection, GTM4WP, MailPoet, TablePress, Events Calendar, WP Mail SMTP', 'handymcp' ), false, true ), array( __( 'Cache, security and backup plugins, with a backup before risky work', 'handymcp' ), false, true ), array( __( 'Build custom themes and plugins, checked file edits and code snippets', 'handymcp' ), false, true ), array( __( 'Build a new block theme with a private preview before it goes live', 'handymcp' ), false, true ), array( __( 'WP-CLI style commands, no shell or WP-CLI install needed', 'handymcp' ), false, true ), array( __( 'Switch on PHP snippets safely: site check and automatic switch-off', 'handymcp' ), false, true ), array( __( 'Full Wordfence control: blocked IPs, unblock, login attempts and settings', 'handymcp' ), false, true ), array( __( 'REST routes and WordPress abilities from other plugins', 'handymcp' ), false, true ), array( __( 'Priority email support', 'handymcp' ), false, true ), array( __( 'White label: hide the plugin on client sites', 'handymcp' ), false, true ), array( __( 'Client sites hub: manage every site from one dashboard', 'handymcp' ), false, __( 'Agency plan', 'handymcp' ) ), ); $cell = static function ( $v ): string { if ( true === $v ) { return '' . esc_html__( 'Included', 'handymcp' ) . ''; } if ( false === $v ) { return '' . esc_html__( 'Not included', 'handymcp' ) . ''; } return esc_html( (string) $v ); }; echo '| ' . esc_html__( 'Feature', 'handymcp' ) . ' | ' . esc_html__( 'Free', 'handymcp' ) . '' . esc_html__( 'This plugin', 'handymcp' ) . ' | ' . esc_html__( 'Pro', 'handymcp' ) . '' . esc_html__( 'Everything, plus the rest of your site', 'handymcp' ) . ' |
|---|---|---|
| ' . esc_html( $r[0] ) . ' | ' . $cell( $r[1] ) . ' | ' . $cell( $r[2] ) . ' |
' . esc_html( $g[2] ) . '
' . esc_html__( 'Install HandyMCP Pro and activate it. It turns this plugin off and keeps your connected apps, settings, activity and undo history, so your AI apps keep working without connecting again.', 'handymcp' ) . '
' . esc_html__( 'WooCommerce, every builder, safe updates and full undo. No card needed.', 'handymcp' ) . '
' . esc_html__( 'Start free trial', 'handymcp' ) . '', \HandyMCP\Support\Html::allowed() ); if ( $count ) { /* translators: %d: number of plugins and themes. */ echo esc_html( sprintf( _n( 'Pro works with %d plugin or theme you already use, plus the rest of your site.', 'Pro works with %d plugins and themes you already use, plus the rest of your site.', $count, 'handymcp' ), $count ) ); } else { echo esc_html__( 'Let the AI work with the rest of your site: other builders, stores, languages, fields and site care.', 'handymcp' ); } echo '
' . esc_html( $field[1] ) . '
' . esc_html( sprintf( /* translators: %s: estimated number of tokens. */ __( 'About %s tokens, sent to every app when it connects. The detailed style guide is sent only when an app needs it.', 'handymcp' ), number_format_i18n( (int) round( array_sum( array_map( static function ( $k ) use ( $b ) { return 'guide' === $k ? 0 : strlen( (string) ( $b[ $k ] ?? '' ) ); }, array_keys( \HandyMCP\Support\SiteBrief::fields() ) ) ) / 4 ) ) ) ) . '
' . esc_html__( 'A plugin or custom code on this site adds more rules to the brief (they are included in the preview below). Move them into the fields above so you can edit them here, then remove the code.', 'handymcp' ) . '
' . esc_html__( 'Nothing yet. Fill in any field above and save.', 'handymcp' ) . '
' . esc_html( $text ) . '
' . esc_html( $help ) . '
' : '' ) . '' . esc_html( sprintf( /* translators: %s: plugin name. */ __( 'HandyMCP now works with %s.', 'handymcp' ), $g['label'] ) ) . ' ' . esc_html( 'off' === $g['mode'] ? __( 'It is switched off, so AI apps cannot use it yet.', 'handymcp' ) : ( $limited ? __( 'AI apps can read it. Changes are off until you allow them.', 'handymcp' ) : __( 'AI apps can use it now. Your existing connections work with it, no need to reconnect.', 'handymcp' ) ) ) . ' ' . ( $limited ? '' . esc_html__( 'Allow changes', 'handymcp' ) . ' ' : '' ) . '' . esc_html__( 'Review in Abilities', 'handymcp' ) . ' ' . '' . esc_html__( 'Dismiss', 'handymcp' ) . '
'; } echo wp_kses( '