*/ public static function get_ability_names(): array { $names = array_keys( self::get_registry() ); if ( ! Agentmatica_Ability_Delegation::should_register_fallback_catalog() ) { $names = array_values( array_filter( $names, static function ( string $name ): bool { return Agentmatica_Ability_Delegation::FALLBACK_PRODUCTS_LIST !== $name; } ) ); } return array_values( array_unique( array_merge( $names, Agentmatica_Ability_Delegation::get_exposed_names() ) ) ); } /** * @return array|null */ public static function get_ability( string $name ): ?array { $registry = self::get_registry(); if ( isset( $registry[ $name ] ) ) { return $registry[ $name ]; } return Agentmatica_Ability_Delegation::get_definition( $name ); } /** * @param array|null $params * @return array */ public static function execute( string $name, $params = null ): array { if ( Agentmatica_Ability_Delegation::is_delegated( $name ) ) { return Agentmatica_Ability_Delegation::execute( $name, $params ); } $ability = self::get_ability( $name ); if ( null === $ability ) { return array( 'success' => false, 'message' => sprintf( /* translators: %s: ability name */ __( 'Unknown ability: %s', 'agentmatica-mcp-connector' ), $name ), ); } $callback = $ability['callback'] ?? null; if ( ! is_callable( $callback ) ) { return array( 'success' => false, 'message' => __( 'Ability callback is not available.', 'agentmatica-mcp-connector' ), ); } $params = is_array( $params ) ? $params : array(); $result = call_user_func( $callback, $params ); return is_array( $result ) ? $result : array( 'result' => $result ); } /** * @return array> */ private static function get_registry(): array { return Agentmatica_Module_Registry::get_abilities(); } public static function register_category(): void { if ( ! function_exists( 'wp_register_ability_category' ) ) { return; } wp_register_ability_category( 'agentmatica', array( 'label' => __( 'Agentmatica', 'agentmatica-mcp-connector' ), 'description' => __( 'Visitor chat abilities exposed by the Agentmatica WordPress plugin.', 'agentmatica-mcp-connector' ), ) ); } public static function register_core_abilities(): void { if ( ! function_exists( 'wp_register_ability' ) ) { return; } foreach ( self::get_registry() as $name => $ability ) { $readonly = ! empty( $ability['readonly'] ); $idempotent = ! empty( $ability['idempotent'] ); wp_register_ability( $name, array( 'label' => $ability['label'], 'description' => $ability['description'], 'category' => 'agentmatica', 'input_schema' => $ability['input_schema'], 'execute_callback' => $ability['callback'], 'permission_callback' => array( __CLASS__, 'ability_permission_callback' ), 'meta' => array( 'mcp' => array( 'public' => true, 'type' => 'tool', ), 'annotations' => array( 'readonly' => $readonly, 'destructive' => false, 'idempotent' => $idempotent, ), ), ) ); } } /** * Permission check for every ability this plugin registers. * * Abilities are meant to run through the plugin's own MCP route, which already * enforces the Bearer integration token. Anything else that resolves this * ability (core Abilities REST endpoints, other MCP adapters, WP-CLI) has to * present the same Bearer token or be a logged-in administrator. * * @return bool */ public static function ability_permission_callback(): bool { if ( Agentmatica_Ability_Delegation::is_mcp_authenticated() ) { return true; } if ( Agentmatica_Auth::verify_request_token() ) { return true; } return current_user_can( 'manage_options' ); } }