From 7f58f0235c57bca8a417069e526d280581191a53 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Fri, 22 Aug 2025 22:57:46 +0100 Subject: [PATCH 01/13] MCP: add settings to API --- ....wpcom-json-api-site-settings-endpoint.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index 09e1a4ef3096b..62be5cafbdd5f 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -385,6 +385,7 @@ public function get_settings_response() { $newsletter_category_ids = Jetpack_Newsletter_Category_Helper::get_category_ids(); $api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true; + $mcp_settings = get_option( 'wpcom_mcp_settings', array() ); $response[ $key ] = array( // also exists as "options". @@ -514,6 +515,7 @@ public function get_settings_response() { 'jetpack_waf_automatic_rules_last_updated_timestamp' => (int) get_option( 'jetpack_waf_automatic_rules_last_updated_timestamp' ), 'is_fully_managed_agency_site' => (bool) get_option( 'is_fully_managed_agency_site' ), 'wpcom_hide_action_bar' => (bool) get_option( 'wpcom_hide_action_bar' ), + 'mcp_settings' => $mcp_settings, ); require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php'; @@ -1186,6 +1188,32 @@ function ( &$value ) { } break; + case 'mcp_settings': + if ( ! is_array( $value ) ) { + break; + } + + $allowed_keys = array( 'mcp_server_active' ); + $filtered_value = array_filter( + $value, + function ( $key ) use ( $allowed_keys ) { + return in_array( $key, $allowed_keys, true ); + }, + ARRAY_FILTER_USE_KEY + ); + + if ( empty( $filtered_value ) ) { + break; + } + + $old_mcp_settings = get_option( 'mcp_settings' ); + $new_mcp_settings = array_merge( $old_mcp_settings, $filtered_value ); + + if ( update_option( $key, $new_mcp_settings ) ) { + $updated[ $key ] = $filtered_value; + } + break; + default: // allow future versions of this endpoint to support additional settings keys. if ( has_filter( 'site_settings_endpoint_update_' . $key ) ) { From 1e051846451b8989a80ad633b1f1b8bbd80e629e Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Fri, 22 Aug 2025 22:59:23 +0100 Subject: [PATCH 02/13] changelog --- projects/plugins/jetpack/changelog/add-mcp-settings | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/add-mcp-settings diff --git a/projects/plugins/jetpack/changelog/add-mcp-settings b/projects/plugins/jetpack/changelog/add-mcp-settings new file mode 100644 index 0000000000000..51f087f7053a6 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-mcp-settings @@ -0,0 +1,4 @@ +Significance: minor +Type: other + +Add MCP settings to settings endpoint From 2c270378ca23d0640bda1340dc601b4c58b91a35 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Sat, 23 Aug 2025 13:05:07 +0100 Subject: [PATCH 03/13] fix lint --- .../class.wpcom-json-api-site-settings-endpoint.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index 62be5cafbdd5f..1b7d6849128a0 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -384,7 +384,7 @@ public function get_settings_response() { } $newsletter_category_ids = Jetpack_Newsletter_Category_Helper::get_category_ids(); - $api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true; + $api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true; $mcp_settings = get_option( 'wpcom_mcp_settings', array() ); $response[ $key ] = array( From ffe75395544d2a248c003cfcc73dd08ba8783c8b Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Tue, 26 Aug 2025 17:02:19 +0100 Subject: [PATCH 04/13] add mcp_setting get/set --- ....wpcom-json-api-site-settings-endpoint.php | 91 +++++++++++++++---- ...m-json-api-site-settings-v1-4-endpoint.php | 1 + 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index 1b7d6849128a0..13def4a22fee5 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -139,6 +139,7 @@ 'jetpack_waf_share_data' => '(bool) Whether the WAF should share basic data with Jetpack', 'jetpack_waf_share_debug_data' => '(bool) Whether the WAF should share debug data with Jetpack', 'jetpack_waf_automatic_rules_last_updated_timestamp' => '(int) Timestamp of the last time the automatic rules were updated', + 'mcp_settings' => '(string) Whether MCP Settings is enabled and list of enabled abilities', ), 'response_format' => array( @@ -384,8 +385,48 @@ public function get_settings_response() { } $newsletter_category_ids = Jetpack_Newsletter_Category_Helper::get_category_ids(); - $api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true; - $mcp_settings = get_option( 'wpcom_mcp_settings', array() ); + $api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true; + + // MCP Settings + // Define default state for abilities if not already set + $mcp_abilities_default_state = array( + 'wpcom-mcp/user-sites' => true, + 'wpcom-mcp/posts-search' => true, + ); + + // Get Sites MCP settings + $mcp_settings = get_option( 'mcp_settings', array() ); + $stored_abilities = $mcp_settings['mcp_abilities'] ?? array(); + + $abilities = array(); + if ( function_exists( 'wp_get_abilities' ) ) { + $abilities = wp_get_abilities(); + } + + $mcp_abilities = array(); + foreach ( $abilities as $ability ) { + $ability_name = $ability->get_name(); + if ( ! empty( $ability_name ) ) { + // Check stored abilities first, then default state, then false + $is_enabled = $stored_abilities[ $ability_name ] ?? $mcp_abilities_default_state[ $ability_name ] ?? false; + + // Convert string/numeric values to boolean + $is_enabled = ! empty( $is_enabled ); + + $mcp_abilities[ $ability_name ] = array( + 'label' => $ability->get_label(), + 'description' => $ability->get_description(), + 'enabled' => $is_enabled, + ); + } + } + + $mcp_settings = wp_json_encode( + array( + 'mcp_enabled' => ! empty( $mcp_settings['mcp_enabled'] ?? true ), + 'mcp_abilities' => $mcp_abilities, + ) + ); $response[ $key ] = array( // also exists as "options". @@ -1189,27 +1230,45 @@ function ( &$value ) { break; case 'mcp_settings': - if ( ! is_array( $value ) ) { + if ( ! is_string( $value ) ) { break; } - $allowed_keys = array( 'mcp_server_active' ); - $filtered_value = array_filter( - $value, - function ( $key ) use ( $allowed_keys ) { - return in_array( $key, $allowed_keys, true ); - }, - ARRAY_FILTER_USE_KEY - ); - - if ( empty( $filtered_value ) ) { + $new_mcp_settings = json_decode( $value, true ); + if ( ! is_array( $new_mcp_settings ) ) { break; } - $old_mcp_settings = get_option( 'mcp_settings' ); - $new_mcp_settings = array_merge( $old_mcp_settings, $filtered_value ); + // Get list of valid abilities for validation + $valid_abilities = array(); + if ( function_exists( 'wp_get_abilities' ) ) { + foreach ( wp_get_abilities() as $ability ) { + $valid_abilities[] = $ability->get_name(); + } + } + + $filtered_value = array( + 'mcp_enabled' => ! empty( $new_mcp_settings['mcp_enabled'] ), + 'mcp_abilities' => array(), + ); + + if ( ! empty( $new_mcp_settings['mcp_abilities'] ) && is_array( $new_mcp_settings['mcp_abilities'] ) ) { + foreach ( $new_mcp_settings['mcp_abilities'] as $ability_name => $ability ) { + // Validate ability name exists in registered abilities + if ( ! in_array( $ability_name, $valid_abilities, true ) ) { + continue; + } + + // Ensure ability is array with enabled key + if ( ! is_array( $ability ) || ! isset( $ability['enabled'] ) ) { + continue; + } + + $filtered_value['mcp_abilities'][ $ability_name ] = ! empty( $ability['enabled'] ); + } + } - if ( update_option( $key, $new_mcp_settings ) ) { + if ( update_option( $key, $filtered_value ) ) { $updated[ $key ] = $filtered_value; } break; diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php index 80c1679b9ffec..65010314287c8 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php @@ -153,6 +153,7 @@ 'jetpack_comment_form_color_scheme' => '(string) The color scheme for the comment form', 'is_fully_managed_agency_site' => '(bool) Whether the site is a fully managed agency site', 'wpcom_hide_action_bar' => '(bool) Whether to hide the Action bar', + 'mcp_settings' => '(string) Whether MCP Settings is enabled and list of enabled abilities', ), 'response_format' => array( From dd8885a9db6245dae9b228065b42449e49c970a1 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Tue, 26 Aug 2025 21:24:08 +0100 Subject: [PATCH 05/13] add tests --- ...N_API_Site_Settings_V1_4_Endpoint_Test.php | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php b/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php index a2399f6cced33..e533e1be07ef1 100644 --- a/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php +++ b/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php @@ -272,6 +272,7 @@ public function make_post_request( $setting ) { 'page_on_front' => '(string) The page ID of the page to use as the site\'s homepage. It will apply only if \'show_on_front\' is set to \'page\'.', 'page_for_posts' => '(string) The page ID of the page to use as the site\'s posts page. It will apply only if \'show_on_front\' is set to \'page\'.', 'subscription_options' => '(array) Array of two options used in subscription email templates: \'invitation\' and \'comment_follow\' strings.', + 'mcp_settings' => '(string) Whether MCP Settings is enabled and list of enabled abilities', ), 'response_format' => array( @@ -302,6 +303,14 @@ public static function setting_default_key_values() { 'woocommerce_default_country' => array( 'woocommerce_default_country', '' ), 'woocommerce_store_postcode' => array( 'woocommerce_store_postcode', '' ), 'woocommerce_onboarding_profile' => array( 'woocommerce_onboarding_profile', array() ), + // Add MCP settings default + 'mcp_settings' => array( + 'mcp_settings', + array( + 'mcp_enabled' => true, + 'mcp_abilities' => array(), + ), + ), ); } @@ -318,6 +327,18 @@ public static function setting_value_pairs_get_request() { 'woocommerce_default_country' => array( 'woocommerce_default_country', 'woocommerce_default_country', 'US:NY' ), 'woocommerce_store_postcode' => array( 'woocommerce_store_postcode', 'woocommerce_store_postcode', '98738' ), 'woocommerce_onboarding_profile' => array( 'woocommerce_onboarding_profile', 'woocommerce_onboarding_profile', array( 'test' => 'test value' ) ), + // Add MCP settings GET test + 'mcp_settings' => array( + 'mcp_settings', + 'mcp_settings', + array( + 'mcp_enabled' => true, + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => true, + 'wpcom-mcp/user-sites' => false, + ), + ), + ), ); } @@ -351,6 +372,44 @@ public static function setting_value_pairs_post_request() { 'comment_follow' => "Test string 2\n\n Other line", ), ), + // Add MCP settings POST tests + 'mcp_settings valid json' => array( + 'mcp_settings', + wp_json_encode( + array( + 'mcp_enabled' => true, + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => array( 'enabled' => true ), + 'wpcom-mcp/user-sites' => array( 'enabled' => false ), + ), + ) + ), + array( + 'mcp_enabled' => true, + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => true, + 'wpcom-mcp/user-sites' => false, + ), + ), + ), + 'mcp_settings disabled' => array( + 'mcp_settings', + wp_json_encode( + array( + 'mcp_enabled' => false, + 'mcp_abilities' => array(), + ) + ), + array( + 'mcp_enabled' => false, + 'mcp_abilities' => array(), + ), + ), + 'mcp_settings malformed json' => array( + 'mcp_settings', + 'invalid json string', + false, // Should fail validation + ), ); } } From 3302343f5929136a77cd75ca66865f7b02573f4f Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Tue, 26 Aug 2025 23:03:28 +0100 Subject: [PATCH 06/13] fix tests --- ....wpcom-json-api-site-settings-endpoint.php | 51 +++++--- ...m-json-api-site-settings-v1-4-endpoint.php | 2 +- .../jetpack/tests/php.multisite.11.xml | 3 +- ...N_API_Site_Settings_V1_4_Endpoint_Test.php | 119 ++++++++++++++---- 4 files changed, 129 insertions(+), 46 deletions(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index 13def4a22fee5..c951ea45b5aed 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -139,7 +139,7 @@ 'jetpack_waf_share_data' => '(bool) Whether the WAF should share basic data with Jetpack', 'jetpack_waf_share_debug_data' => '(bool) Whether the WAF should share debug data with Jetpack', 'jetpack_waf_automatic_rules_last_updated_timestamp' => '(int) Timestamp of the last time the automatic rules were updated', - 'mcp_settings' => '(string) Whether MCP Settings is enabled and list of enabled abilities', + 'mcp_settings' => '(array) Whether MCP Settings is enabled and list of enabled abilities', ), 'response_format' => array( @@ -420,12 +420,11 @@ public function get_settings_response() { ); } } + $mcp_abilities = apply_filters( 'jetpack_mcp_abilities', $mcp_abilities ); - $mcp_settings = wp_json_encode( - array( - 'mcp_enabled' => ! empty( $mcp_settings['mcp_enabled'] ?? true ), - 'mcp_abilities' => $mcp_abilities, - ) + $mcp_settings = array( + 'mcp_enabled' => ! empty( $mcp_settings['mcp_enabled'] ?? true ), + 'mcp_abilities' => $mcp_abilities, ); $response[ $key ] = array( @@ -911,7 +910,7 @@ function ( &$value ) { } ); - $old_subscription_options = get_option( 'subscription_options' ); + $old_subscription_options = get_option( 'subscription_options', array() ); $new_subscription_options = array_merge( $old_subscription_options, $filtered_value ); if ( update_option( $key, $new_subscription_options ) ) { @@ -1230,12 +1229,7 @@ function ( &$value ) { break; case 'mcp_settings': - if ( ! is_string( $value ) ) { - break; - } - - $new_mcp_settings = json_decode( $value, true ); - if ( ! is_array( $new_mcp_settings ) ) { + if ( ! is_array( $value ) ) { break; } @@ -1248,12 +1242,12 @@ function ( &$value ) { } $filtered_value = array( - 'mcp_enabled' => ! empty( $new_mcp_settings['mcp_enabled'] ), + 'mcp_enabled' => ! empty( $value['mcp_enabled'] ), 'mcp_abilities' => array(), ); - if ( ! empty( $new_mcp_settings['mcp_abilities'] ) && is_array( $new_mcp_settings['mcp_abilities'] ) ) { - foreach ( $new_mcp_settings['mcp_abilities'] as $ability_name => $ability ) { + if ( ! empty( $value['mcp_abilities'] ) && is_array( $value['mcp_abilities'] ) ) { + foreach ( $value['mcp_abilities'] as $ability_name => $ability ) { // Validate ability name exists in registered abilities if ( ! in_array( $ability_name, $valid_abilities, true ) ) { continue; @@ -1269,7 +1263,30 @@ function ( &$value ) { } if ( update_option( $key, $filtered_value ) ) { - $updated[ $key ] = $filtered_value; + $response_abilities = array(); + + if ( function_exists( 'wp_get_abilities' ) ) { + $abilities = wp_get_abilities(); + foreach ( $abilities as $ability ) { + $ability_name = $ability->get_name(); + if ( ! empty( $ability_name ) ) { + $is_enabled = $filtered_value['mcp_abilities'][ $ability_name ] ?? false; + $response_abilities[ $ability_name ] = array( + 'label' => $ability->get_label(), + 'description' => $ability->get_description(), + 'enabled' => $is_enabled, + ); + } + } + } + + $response_abilities = apply_filters( 'jetpack_mcp_abilities', $response_abilities ); + + // Return enriched structure for API consistency + $updated[ $key ] = array( + 'mcp_enabled' => $filtered_value['mcp_enabled'], + 'mcp_abilities' => $response_abilities, + ); } break; diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php index 65010314287c8..1c93f1a7e2d0a 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php @@ -153,7 +153,7 @@ 'jetpack_comment_form_color_scheme' => '(string) The color scheme for the comment form', 'is_fully_managed_agency_site' => '(bool) Whether the site is a fully managed agency site', 'wpcom_hide_action_bar' => '(bool) Whether to hide the Action bar', - 'mcp_settings' => '(string) Whether MCP Settings is enabled and list of enabled abilities', + 'mcp_settings' => '(array) Whether MCP Settings is enabled and list of enabled abilities', ), 'response_format' => array( diff --git a/projects/plugins/jetpack/tests/php.multisite.11.xml b/projects/plugins/jetpack/tests/php.multisite.11.xml index 1dcd395085c61..2e837d2aefd53 100644 --- a/projects/plugins/jetpack/tests/php.multisite.11.xml +++ b/projects/plugins/jetpack/tests/php.multisite.11.xml @@ -39,7 +39,8 @@ php/json-api/Jetpack_Json_Api_Endpoints_Test.php php/json-api/Jetpack_Json_Api_Plugins_Endpoints_Test.php - + php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php + php/modules/infinite-scroll diff --git a/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php b/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php index e533e1be07ef1..b2b136fa7b5f5 100644 --- a/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php +++ b/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php @@ -71,6 +71,31 @@ public function set_up() { parent::set_up(); WPCOM_JSON_API::init()->token_details = array( 'blog_id' => $blog_id ); + + // Mock MCP abilities for testing + add_filter( + 'jetpack_mcp_abilities', + function () { + return array( + 'wpcom-mcp/posts-search' => array( + 'label' => 'Posts Search', + 'description' => 'Search posts', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'label' => 'User Sites', + 'description' => 'Access user sites', + 'enabled' => false, + ), + ); + } + ); + } + + public function tear_down() { + // Remove the filter to avoid affecting other tests + remove_all_filters( 'jetpack_mcp_abilities' ); + parent::tear_down(); } /** @@ -272,7 +297,7 @@ public function make_post_request( $setting ) { 'page_on_front' => '(string) The page ID of the page to use as the site\'s homepage. It will apply only if \'show_on_front\' is set to \'page\'.', 'page_for_posts' => '(string) The page ID of the page to use as the site\'s posts page. It will apply only if \'show_on_front\' is set to \'page\'.', 'subscription_options' => '(array) Array of two options used in subscription email templates: \'invitation\' and \'comment_follow\' strings.', - 'mcp_settings' => '(string) Whether MCP Settings is enabled and list of enabled abilities', + 'mcp_settings' => '(array) Whether MCP Settings is enabled and list of enabled abilities', ), 'response_format' => array( @@ -308,7 +333,18 @@ public static function setting_default_key_values() { 'mcp_settings', array( 'mcp_enabled' => true, - 'mcp_abilities' => array(), + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => array( + 'label' => 'Posts Search', + 'description' => 'Search posts', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'label' => 'User Sites', + 'description' => 'Access user sites', + 'enabled' => false, + ), + ), ), ), ); @@ -334,8 +370,16 @@ public static function setting_value_pairs_get_request() { array( 'mcp_enabled' => true, 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => true, - 'wpcom-mcp/user-sites' => false, + 'wpcom-mcp/posts-search' => array( + 'label' => 'Posts Search', + 'description' => 'Search posts', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'label' => 'User Sites', + 'description' => 'Access user sites', + 'enabled' => false, + ), ), ), ), @@ -373,43 +417,64 @@ public static function setting_value_pairs_post_request() { ), ), // Add MCP settings POST tests - 'mcp_settings valid json' => array( + 'mcp_settings valid params' => array( 'mcp_settings', - wp_json_encode( - array( - 'mcp_enabled' => true, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( 'enabled' => true ), - 'wpcom-mcp/user-sites' => array( 'enabled' => false ), - ), - ) + array( // This should be the actual input structure + 'mcp_enabled' => true, + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => array( 'enabled' => true ), + 'wpcom-mcp/user-sites' => array( 'enabled' => false ), + ), ), - array( + array( // Expected output 'mcp_enabled' => true, 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => true, - 'wpcom-mcp/user-sites' => false, + 'wpcom-mcp/posts-search' => array( + 'label' => 'Posts Search', + 'description' => 'Search posts', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'label' => 'User Sites', + 'description' => 'Access user sites', + 'enabled' => false, + ), ), ), ), 'mcp_settings disabled' => array( 'mcp_settings', - wp_json_encode( - array( - 'mcp_enabled' => false, - 'mcp_abilities' => array(), - ) + array( + 'mcp_enabled' => false, + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => array( + 'label' => 'Posts Search', + 'description' => 'Search posts', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'label' => 'User Sites', + 'description' => 'Access user sites', + 'enabled' => false, + ), + ), ), array( 'mcp_enabled' => false, - 'mcp_abilities' => array(), + 'mcp_abilities' => array( + 'wpcom-mcp/posts-search' => array( + 'label' => 'Posts Search', + 'description' => 'Search posts', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'label' => 'User Sites', + 'description' => 'Access user sites', + 'enabled' => false, + ), + ), ), ), - 'mcp_settings malformed json' => array( - 'mcp_settings', - 'invalid json string', - false, // Should fail validation - ), ); } } From 8bfe25e6ab59dc7146378a97de657ebef2cce6d1 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Tue, 26 Aug 2025 23:05:55 +0100 Subject: [PATCH 07/13] revert change to test config --- projects/plugins/jetpack/tests/php.multisite.11.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/projects/plugins/jetpack/tests/php.multisite.11.xml b/projects/plugins/jetpack/tests/php.multisite.11.xml index 2e837d2aefd53..1dcd395085c61 100644 --- a/projects/plugins/jetpack/tests/php.multisite.11.xml +++ b/projects/plugins/jetpack/tests/php.multisite.11.xml @@ -39,8 +39,7 @@ php/json-api/Jetpack_Json_Api_Endpoints_Test.php php/json-api/Jetpack_Json_Api_Plugins_Endpoints_Test.php - php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php - + php/modules/infinite-scroll From 4877e24a7a32bdb07f236c28147a3a6bedcf1ada Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Wed, 27 Aug 2025 08:34:56 +0100 Subject: [PATCH 08/13] suppress phan issue --- .../class.wpcom-json-api-site-settings-endpoint.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index c951ea45b5aed..040ff8c4cfdb4 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -400,7 +400,7 @@ public function get_settings_response() { $abilities = array(); if ( function_exists( 'wp_get_abilities' ) ) { - $abilities = wp_get_abilities(); + $abilities = wp_get_abilities(); // @phan-suppress-current-line PhanUndeclaredFunction -- We're checking the function exists first. } $mcp_abilities = array(); @@ -1236,7 +1236,7 @@ function ( &$value ) { // Get list of valid abilities for validation $valid_abilities = array(); if ( function_exists( 'wp_get_abilities' ) ) { - foreach ( wp_get_abilities() as $ability ) { + foreach ( wp_get_abilities() as $ability ) { // @phan-suppress-current-line PhanUndeclaredFunction -- We're checking the function exists first. $valid_abilities[] = $ability->get_name(); } } @@ -1266,7 +1266,7 @@ function ( &$value ) { $response_abilities = array(); if ( function_exists( 'wp_get_abilities' ) ) { - $abilities = wp_get_abilities(); + $abilities = wp_get_abilities(); // @phan-suppress-current-line PhanUndeclaredFunction -- We're checking the function exists first. foreach ( $abilities as $ability ) { $ability_name = $ability->get_name(); if ( ! empty( $ability_name ) ) { From e6a1516917768819288625a04c6e1b5661ce1741 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Fri, 29 Aug 2025 20:58:44 +0100 Subject: [PATCH 09/13] update to use AbilityRegistry --- ....wpcom-json-api-site-settings-endpoint.php | 219 ++++++++++-------- ...m-json-api-site-settings-v1-4-endpoint.php | 2 +- .../jetpack/tests/php.multisite.11.xml | 1 + ...N_API_Site_Settings_V1_4_Endpoint_Test.php | 157 ++++++------- 4 files changed, 192 insertions(+), 187 deletions(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index 040ff8c4cfdb4..c2ef37cce677a 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -139,7 +139,7 @@ 'jetpack_waf_share_data' => '(bool) Whether the WAF should share basic data with Jetpack', 'jetpack_waf_share_debug_data' => '(bool) Whether the WAF should share debug data with Jetpack', 'jetpack_waf_automatic_rules_last_updated_timestamp' => '(int) Timestamp of the last time the automatic rules were updated', - 'mcp_settings' => '(array) Whether MCP Settings is enabled and list of enabled abilities', + 'mcp_abilities' => '(array) List of MCP Abilities', ), 'response_format' => array( @@ -387,45 +387,8 @@ public function get_settings_response() { $api_cache = $site->is_jetpack() ? (bool) get_option( 'jetpack_api_cache_enabled' ) : true; - // MCP Settings - // Define default state for abilities if not already set - $mcp_abilities_default_state = array( - 'wpcom-mcp/user-sites' => true, - 'wpcom-mcp/posts-search' => true, - ); - // Get Sites MCP settings - $mcp_settings = get_option( 'mcp_settings', array() ); - $stored_abilities = $mcp_settings['mcp_abilities'] ?? array(); - - $abilities = array(); - if ( function_exists( 'wp_get_abilities' ) ) { - $abilities = wp_get_abilities(); // @phan-suppress-current-line PhanUndeclaredFunction -- We're checking the function exists first. - } - - $mcp_abilities = array(); - foreach ( $abilities as $ability ) { - $ability_name = $ability->get_name(); - if ( ! empty( $ability_name ) ) { - // Check stored abilities first, then default state, then false - $is_enabled = $stored_abilities[ $ability_name ] ?? $mcp_abilities_default_state[ $ability_name ] ?? false; - - // Convert string/numeric values to boolean - $is_enabled = ! empty( $is_enabled ); - - $mcp_abilities[ $ability_name ] = array( - 'label' => $ability->get_label(), - 'description' => $ability->get_description(), - 'enabled' => $is_enabled, - ); - } - } - $mcp_abilities = apply_filters( 'jetpack_mcp_abilities', $mcp_abilities ); - - $mcp_settings = array( - 'mcp_enabled' => ! empty( $mcp_settings['mcp_enabled'] ?? true ), - 'mcp_abilities' => $mcp_abilities, - ); + $mcp_abilities = $this->get_site_mcp_abilities(); $response[ $key ] = array( // also exists as "options". @@ -555,7 +518,7 @@ public function get_settings_response() { 'jetpack_waf_automatic_rules_last_updated_timestamp' => (int) get_option( 'jetpack_waf_automatic_rules_last_updated_timestamp' ), 'is_fully_managed_agency_site' => (bool) get_option( 'is_fully_managed_agency_site' ), 'wpcom_hide_action_bar' => (bool) get_option( 'wpcom_hide_action_bar' ), - 'mcp_settings' => $mcp_settings, + 'mcp_abilities' => $mcp_abilities, ); require_once JETPACK__PLUGIN_DIR . '/modules/memberships/class-jetpack-memberships.php'; @@ -658,6 +621,118 @@ protected function get_wpcom_gifting_subscription_default() { return false; } + /** + * Get list of all site level MCP abilities. + * + * @return array + */ + private function get_all_site_mcp_abilities(): array { + $all_abilities = array(); + $ability_registry_file = WP_CONTENT_DIR . '/mu-plugins/wpcom-mcp/includes/AbilitiesRegistry/Registry/AbilityRegistry.php'; + if ( file_exists( $ability_registry_file ) ) { + require_once $ability_registry_file; + $abilities_resources = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_resources_for_server( 'site-level' ); + $abilities_tools = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_tools_for_server( 'site-level' ); + $abilities_prompts = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_prompts_for_server( 'site-level' ); + $all_abilities = array_merge( $abilities_resources, $abilities_tools, $abilities_prompts ); + } + return apply_filters( 'jetpack_site_mcp_abilities', $all_abilities ); + } + + /** + * Get ability meta from config. + * + * @param string $ability_name Ability name, i.e. wpcom-mcp/posts-search. + * + * @return array + */ + private function get_mcp_abilities_metadata( string $ability_name ): array { + $ability_meta = array(); + $ability_registry_file = WP_CONTENT_DIR . '/mu-plugins/wpcom-mcp/includes/AbilitiesRegistry/Registry/AbilityRegistry.php'; + if ( file_exists( $ability_registry_file ) ) { + require_once $ability_registry_file; + $ability_meta = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_metadata( $ability_name ); + } + return apply_filters( 'jetpack_site_mcp_ability_meta', $ability_meta, $ability_name ); + } + + /** + * Get MCP abilities for the current site. + * + * @return array + */ + public function get_site_mcp_abilities(): array { + $current_mcp_abilities = get_option( 'mcp_abilities', array() ); + if ( ! is_array( $current_mcp_abilities ) ) { + $current_mcp_abilities = array(); + } + + $all_abilities = $this->get_all_site_mcp_abilities(); + if ( empty( $all_abilities ) ) { + return array(); + } + + $computed_abilities = array(); + foreach ( $all_abilities as $ability_name ) { + // Get base metadata first + $ability_meta = $this->get_mcp_abilities_metadata( $ability_name ); + if ( ! empty( $ability_meta ) ) { + // Use stored value or fall back to metadata default + $enabled = $current_mcp_abilities[ $ability_name ] ?? $ability_meta['enabled'] ?? false; + + $computed_abilities[ $ability_name ] = array( + 'name' => $ability_name, + 'description' => $ability_meta['description'] ?? '', + 'category' => $ability_meta['category'] ?? '', + 'type' => $ability_meta['type'] ?? '', + 'enabled' => (bool) $enabled, + ); + } + } + return $computed_abilities; + } + + /** + * Sets the MCP abilities for the current site. + * + * @param mixed $value MCP abilities array. + * + * @return true|WP_Error + */ + public function set_site_mcp_abilities( $value ) { + // Validate input format + if ( ! is_array( $value ) ) { + return new WP_Error( 'invalid_format', __( 'Site MCP abilities must be an array', 'jetpack' ) ); + } + + $all_abilities = $this->get_all_site_mcp_abilities(); + + // Filter ability names that don't exist + $value = array_filter( + $value, + function ( $ability_name ) use ( $all_abilities ) { + return in_array( $ability_name, $all_abilities, true ); + }, + ARRAY_FILTER_USE_KEY + ); + + // Validate each ability exists and value is boolean-like + foreach ( $value as $ability_name => $enabled ) { + if ( ! is_string( $ability_name ) || ( ! WPCOM_JSON_API::is_truthy( $enabled ) && ! WPCOM_JSON_API::is_falsy( $enabled ) ) ) { + $error_message = sprintf( + // Translators: %s is an MCP ability name + __( 'Invalid ability: %s', 'jetpack' ), + $ability_name + ); + return new WP_Error( 'invalid_ability', $error_message ); + } + } + + update_option( 'mcp_abilities', $value ); + + return true; + } + /** * Get locale. * @@ -1228,66 +1303,12 @@ function ( &$value ) { } break; - case 'mcp_settings': - if ( ! is_array( $value ) ) { - break; - } - - // Get list of valid abilities for validation - $valid_abilities = array(); - if ( function_exists( 'wp_get_abilities' ) ) { - foreach ( wp_get_abilities() as $ability ) { // @phan-suppress-current-line PhanUndeclaredFunction -- We're checking the function exists first. - $valid_abilities[] = $ability->get_name(); - } - } - - $filtered_value = array( - 'mcp_enabled' => ! empty( $value['mcp_enabled'] ), - 'mcp_abilities' => array(), - ); - - if ( ! empty( $value['mcp_abilities'] ) && is_array( $value['mcp_abilities'] ) ) { - foreach ( $value['mcp_abilities'] as $ability_name => $ability ) { - // Validate ability name exists in registered abilities - if ( ! in_array( $ability_name, $valid_abilities, true ) ) { - continue; - } - - // Ensure ability is array with enabled key - if ( ! is_array( $ability ) || ! isset( $ability['enabled'] ) ) { - continue; - } - - $filtered_value['mcp_abilities'][ $ability_name ] = ! empty( $ability['enabled'] ); - } - } - - if ( update_option( $key, $filtered_value ) ) { - $response_abilities = array(); - - if ( function_exists( 'wp_get_abilities' ) ) { - $abilities = wp_get_abilities(); // @phan-suppress-current-line PhanUndeclaredFunction -- We're checking the function exists first. - foreach ( $abilities as $ability ) { - $ability_name = $ability->get_name(); - if ( ! empty( $ability_name ) ) { - $is_enabled = $filtered_value['mcp_abilities'][ $ability_name ] ?? false; - $response_abilities[ $ability_name ] = array( - 'label' => $ability->get_label(), - 'description' => $ability->get_description(), - 'enabled' => $is_enabled, - ); - } - } - } - - $response_abilities = apply_filters( 'jetpack_mcp_abilities', $response_abilities ); - - // Return enriched structure for API consistency - $updated[ $key ] = array( - 'mcp_enabled' => $filtered_value['mcp_enabled'], - 'mcp_abilities' => $response_abilities, - ); + case 'mcp_abilities': + $result = $this->set_site_mcp_abilities( $value ); + if ( is_wp_error( $result ) ) { + return $result; } + $updated[ $key ] = $this->get_site_mcp_abilities(); break; default: diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php index 1c93f1a7e2d0a..1c57b1e77264a 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-v1-4-endpoint.php @@ -153,7 +153,7 @@ 'jetpack_comment_form_color_scheme' => '(string) The color scheme for the comment form', 'is_fully_managed_agency_site' => '(bool) Whether the site is a fully managed agency site', 'wpcom_hide_action_bar' => '(bool) Whether to hide the Action bar', - 'mcp_settings' => '(array) Whether MCP Settings is enabled and list of enabled abilities', + 'mcp_abilities' => '(array) List of MCP Abilities', ), 'response_format' => array( diff --git a/projects/plugins/jetpack/tests/php.multisite.11.xml b/projects/plugins/jetpack/tests/php.multisite.11.xml index 1dcd395085c61..9946a523fc783 100644 --- a/projects/plugins/jetpack/tests/php.multisite.11.xml +++ b/projects/plugins/jetpack/tests/php.multisite.11.xml @@ -39,6 +39,7 @@ php/json-api/Jetpack_Json_Api_Endpoints_Test.php php/json-api/Jetpack_Json_Api_Plugins_Endpoints_Test.php + php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php php/modules/infinite-scroll diff --git a/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php b/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php index b2b136fa7b5f5..46120a0850c40 100644 --- a/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php +++ b/projects/plugins/jetpack/tests/php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php @@ -72,23 +72,39 @@ public function set_up() { WPCOM_JSON_API::init()->token_details = array( 'blog_id' => $blog_id ); - // Mock MCP abilities for testing + // Mock available abilities (just names) add_filter( - 'jetpack_mcp_abilities', + 'jetpack_site_mcp_abilities', function () { return array( + 'wpcom-mcp/posts-search', + 'wpcom-mcp/user-sites', + ); + } + ); + + // Mock ability metadata + add_filter( + 'jetpack_site_mcp_ability_meta', + function ( $ability_meta, $ability_name ) { + $test_metadata = array( 'wpcom-mcp/posts-search' => array( - 'label' => 'Posts Search', 'description' => 'Search posts', + 'category' => 'search', + 'type' => 'tool', 'enabled' => true, ), 'wpcom-mcp/user-sites' => array( - 'label' => 'User Sites', 'description' => 'Access user sites', + 'category' => 'user', + 'type' => 'resource', 'enabled' => false, ), ); - } + return $test_metadata[ $ability_name ] ?? array(); + }, + 10, + 2 ); } @@ -297,7 +313,7 @@ public function make_post_request( $setting ) { 'page_on_front' => '(string) The page ID of the page to use as the site\'s homepage. It will apply only if \'show_on_front\' is set to \'page\'.', 'page_for_posts' => '(string) The page ID of the page to use as the site\'s posts page. It will apply only if \'show_on_front\' is set to \'page\'.', 'subscription_options' => '(array) Array of two options used in subscription email templates: \'invitation\' and \'comment_follow\' strings.', - 'mcp_settings' => '(array) Whether MCP Settings is enabled and list of enabled abilities', + 'mcp_abilities' => '(array) List of MCP Abilities', ), 'response_format' => array( @@ -329,21 +345,22 @@ public static function setting_default_key_values() { 'woocommerce_store_postcode' => array( 'woocommerce_store_postcode', '' ), 'woocommerce_onboarding_profile' => array( 'woocommerce_onboarding_profile', array() ), // Add MCP settings default - 'mcp_settings' => array( - 'mcp_settings', + 'mcp_abilities' => array( + 'mcp_abilities', array( - 'mcp_enabled' => true, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( - 'label' => 'Posts Search', - 'description' => 'Search posts', - 'enabled' => true, - ), - 'wpcom-mcp/user-sites' => array( - 'label' => 'User Sites', - 'description' => 'Access user sites', - 'enabled' => false, - ), + 'wpcom-mcp/posts-search' => array( + 'name' => 'wpcom-mcp/posts-search', + 'description' => 'Search posts', + 'category' => 'search', + 'type' => 'tool', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'name' => 'wpcom-mcp/user-sites', + 'description' => 'Access user sites', + 'category' => 'user', + 'type' => 'resource', + 'enabled' => false, ), ), ), @@ -364,22 +381,23 @@ public static function setting_value_pairs_get_request() { 'woocommerce_store_postcode' => array( 'woocommerce_store_postcode', 'woocommerce_store_postcode', '98738' ), 'woocommerce_onboarding_profile' => array( 'woocommerce_onboarding_profile', 'woocommerce_onboarding_profile', array( 'test' => 'test value' ) ), // Add MCP settings GET test - 'mcp_settings' => array( - 'mcp_settings', - 'mcp_settings', + 'mcp_abilities' => array( + 'mcp_abilities', // option name + 'mcp_abilities', // setting name array( - 'mcp_enabled' => true, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( - 'label' => 'Posts Search', - 'description' => 'Search posts', - 'enabled' => true, - ), - 'wpcom-mcp/user-sites' => array( - 'label' => 'User Sites', - 'description' => 'Access user sites', - 'enabled' => false, - ), + 'wpcom-mcp/posts-search' => array( + 'name' => 'wpcom-mcp/posts-search', + 'description' => 'Search posts', + 'category' => 'search', + 'type' => 'tool', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'name' => 'wpcom-mcp/user-sites', + 'description' => 'Access user sites', + 'category' => 'user', + 'type' => 'resource', + 'enabled' => true, ), ), ), @@ -417,61 +435,26 @@ public static function setting_value_pairs_post_request() { ), ), // Add MCP settings POST tests - 'mcp_settings valid params' => array( - 'mcp_settings', - array( // This should be the actual input structure - 'mcp_enabled' => true, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( 'enabled' => true ), - 'wpcom-mcp/user-sites' => array( 'enabled' => false ), - ), - ), - array( // Expected output - 'mcp_enabled' => true, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( - 'label' => 'Posts Search', - 'description' => 'Search posts', - 'enabled' => true, - ), - 'wpcom-mcp/user-sites' => array( - 'label' => 'User Sites', - 'description' => 'Access user sites', - 'enabled' => false, - ), - ), - ), - ), - 'mcp_settings disabled' => array( - 'mcp_settings', + 'mcp_abilities valid' => array( + 'mcp_abilities', array( - 'mcp_enabled' => false, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( - 'label' => 'Posts Search', - 'description' => 'Search posts', - 'enabled' => true, - ), - 'wpcom-mcp/user-sites' => array( - 'label' => 'User Sites', - 'description' => 'Access user sites', - 'enabled' => false, - ), - ), + 'wpcom-mcp/posts-search' => 1, + 'wpcom-mcp/user-sites' => 0, ), array( - 'mcp_enabled' => false, - 'mcp_abilities' => array( - 'wpcom-mcp/posts-search' => array( - 'label' => 'Posts Search', - 'description' => 'Search posts', - 'enabled' => true, - ), - 'wpcom-mcp/user-sites' => array( - 'label' => 'User Sites', - 'description' => 'Access user sites', - 'enabled' => false, - ), + 'wpcom-mcp/posts-search' => array( + 'name' => 'wpcom-mcp/posts-search', + 'description' => 'Search posts', + 'category' => 'search', + 'type' => 'tool', + 'enabled' => true, + ), + 'wpcom-mcp/user-sites' => array( + 'name' => 'wpcom-mcp/user-sites', + 'description' => 'Access user sites', + 'category' => 'user', + 'type' => 'resource', + 'enabled' => false, ), ), ), From 51a520c053de27030dd957cc7e6023dacd4c9eea Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Mon, 1 Sep 2025 12:32:17 +0100 Subject: [PATCH 10/13] remove test --- projects/plugins/jetpack/tests/php.multisite.11.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/plugins/jetpack/tests/php.multisite.11.xml b/projects/plugins/jetpack/tests/php.multisite.11.xml index 9946a523fc783..1dcd395085c61 100644 --- a/projects/plugins/jetpack/tests/php.multisite.11.xml +++ b/projects/plugins/jetpack/tests/php.multisite.11.xml @@ -39,7 +39,6 @@ php/json-api/Jetpack_Json_Api_Endpoints_Test.php php/json-api/Jetpack_Json_Api_Plugins_Endpoints_Test.php - php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php php/modules/infinite-scroll From 5973448a6dd8e95f21ac8cc5219119731c5bcbe3 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Mon, 1 Sep 2025 13:53:11 +0100 Subject: [PATCH 11/13] remove references to AbilitiesRegistry --- ....wpcom-json-api-site-settings-endpoint.php | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index c2ef37cce677a..6a20da4743410 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -627,16 +627,7 @@ protected function get_wpcom_gifting_subscription_default() { * @return array */ private function get_all_site_mcp_abilities(): array { - $all_abilities = array(); - $ability_registry_file = WP_CONTENT_DIR . '/mu-plugins/wpcom-mcp/includes/AbilitiesRegistry/Registry/AbilityRegistry.php'; - if ( file_exists( $ability_registry_file ) ) { - require_once $ability_registry_file; - $abilities_resources = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_resources_for_server( 'site-level' ); - $abilities_tools = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_tools_for_server( 'site-level' ); - $abilities_prompts = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_prompts_for_server( 'site-level' ); - $all_abilities = array_merge( $abilities_resources, $abilities_tools, $abilities_prompts ); - } - return apply_filters( 'jetpack_site_mcp_abilities', $all_abilities ); + return apply_filters( 'jetpack_site_mcp_abilities', array() ); } /** @@ -647,13 +638,7 @@ private function get_all_site_mcp_abilities(): array { * @return array */ private function get_mcp_abilities_metadata( string $ability_name ): array { - $ability_meta = array(); - $ability_registry_file = WP_CONTENT_DIR . '/mu-plugins/wpcom-mcp/includes/AbilitiesRegistry/Registry/AbilityRegistry.php'; - if ( file_exists( $ability_registry_file ) ) { - require_once $ability_registry_file; - $ability_meta = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_metadata( $ability_name ); - } - return apply_filters( 'jetpack_site_mcp_ability_meta', $ability_meta, $ability_name ); + return apply_filters( 'jetpack_site_mcp_ability_meta', array(), $ability_name ); } /** From 34f70c44460ce830b397ad8e32fa95c4f15f7851 Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Mon, 1 Sep 2025 14:09:06 +0100 Subject: [PATCH 12/13] suppress the phan errors --- ....wpcom-json-api-site-settings-endpoint.php | 23 +++++++++++++++++-- .../jetpack/tests/php.multisite.11.xml | 1 + 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php index 6a20da4743410..661c5495aa670 100644 --- a/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php +++ b/projects/plugins/jetpack/json-endpoints/class.wpcom-json-api-site-settings-endpoint.php @@ -627,7 +627,19 @@ protected function get_wpcom_gifting_subscription_default() { * @return array */ private function get_all_site_mcp_abilities(): array { - return apply_filters( 'jetpack_site_mcp_abilities', array() ); + $all_abilities = array(); + $ability_registry_file = WP_CONTENT_DIR . '/mu-plugins/wpcom-mcp/includes/AbilitiesRegistry/Registry/AbilityRegistry.php'; + if ( file_exists( $ability_registry_file ) ) { + require_once $ability_registry_file; + // @phan-suppress-next-line PhanUndeclaredClassMethod + $abilities_resources = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_resources_for_server( 'site-level' ); + // @phan-suppress-next-line PhanUndeclaredClassMethod + $abilities_tools = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_tools_for_server( 'site-level' ); + // @phan-suppress-next-line PhanUndeclaredClassMethod + $abilities_prompts = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_prompts_for_server( 'site-level' ); + $all_abilities = array_merge( $abilities_resources, $abilities_tools, $abilities_prompts ); + } + return apply_filters( 'jetpack_site_mcp_abilities', $all_abilities ); } /** @@ -638,7 +650,14 @@ private function get_all_site_mcp_abilities(): array { * @return array */ private function get_mcp_abilities_metadata( string $ability_name ): array { - return apply_filters( 'jetpack_site_mcp_ability_meta', array(), $ability_name ); + $ability_meta = array(); + $ability_registry_file = WP_CONTENT_DIR . '/mu-plugins/wpcom-mcp/includes/AbilitiesRegistry/Registry/AbilityRegistry.php'; + if ( file_exists( $ability_registry_file ) ) { + require_once $ability_registry_file; + // @phan-suppress-next-line PhanUndeclaredClassMethod + $ability_meta = Automattic\WpcomMcp\AbilitiesRegistry\Registry\AbilityRegistry::get_metadata( $ability_name ); + } + return apply_filters( 'jetpack_site_mcp_ability_meta', $ability_meta, $ability_name ); } /** diff --git a/projects/plugins/jetpack/tests/php.multisite.11.xml b/projects/plugins/jetpack/tests/php.multisite.11.xml index 1dcd395085c61..9946a523fc783 100644 --- a/projects/plugins/jetpack/tests/php.multisite.11.xml +++ b/projects/plugins/jetpack/tests/php.multisite.11.xml @@ -39,6 +39,7 @@ php/json-api/Jetpack_Json_Api_Endpoints_Test.php php/json-api/Jetpack_Json_Api_Plugins_Endpoints_Test.php + php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php php/modules/infinite-scroll From dcaf066979dbdac20a15a1120011e125fad247ff Mon Sep 17 00:00:00 2001 From: Eoin Gallagher Date: Mon, 1 Sep 2025 14:10:32 +0100 Subject: [PATCH 13/13] remove test again --- projects/plugins/jetpack/tests/php.multisite.11.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/projects/plugins/jetpack/tests/php.multisite.11.xml b/projects/plugins/jetpack/tests/php.multisite.11.xml index 9946a523fc783..1dcd395085c61 100644 --- a/projects/plugins/jetpack/tests/php.multisite.11.xml +++ b/projects/plugins/jetpack/tests/php.multisite.11.xml @@ -39,7 +39,6 @@ php/json-api/Jetpack_Json_Api_Endpoints_Test.php php/json-api/Jetpack_Json_Api_Plugins_Endpoints_Test.php - php/json-api/WPCOM_JSON_API_Site_Settings_V1_4_Endpoint_Test.php php/modules/infinite-scroll