registry = $registry; } public function register_hooks() { add_action( 'rest_api_init', fn() => $this->register_routes() ); } private function register_routes() { register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE, [ [ 'methods' => 'POST', 'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->handle_tool( $request ) ), 'permission_callback' => fn() => current_user_can( 'edit_posts' ), 'args' => [ 'tool' => [ 'type' => 'string', 'required' => true, ], 'input' => [ 'type' => 'object', 'required' => true, ], ], ], [ 'methods' => 'GET', 'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->handle_resource( $request ) ), 'permission_callback' => fn() => current_user_can( 'edit_posts' ), 'args' => [ 'uri' => [ 'type' => 'string', 'required' => true, ], ], ], ] ); } private function handle_tool( \WP_REST_Request $request ) { $tool = $request->get_param( 'tool' ); $input = $request->get_param( 'input' ); $ability = $this->resolve_registry()->find_by_proxy_slug( (string) $tool ); if ( null === $ability ) { return Error_Builder::make( 'unknown_tool' ) ->set_status( 404 ) // translators: By tool name ->set_message( sprintf( __( 'Unknown tool: %s', 'elementor' ), $tool ) ) ->build(); } if ( ! $ability->check_permission() ) { return $this->build_response( $this->forbidden_error() ); } $result = $ability->execute_guarded( is_array( $input ) ? $input : [] ); return $this->build_response( $result ); } private function handle_resource( \WP_REST_Request $request ) { $uri = $request->get_param( 'uri' ); $ability = $this->resolve_registry()->find_resource_by_uri( (string) $uri ); if ( null === $ability ) { return Error_Builder::make( 'unknown_resource' ) ->set_status( 404 ) // translators: By resource URI ->set_message( sprintf( __( 'Unknown resource: %s', 'elementor' ), $uri ) ) ->build(); } if ( ! $ability->check_permission() ) { return $this->build_response( $this->forbidden_error() ); } $result = $ability->execute(); return $this->build_response( $result ); } private function resolve_registry(): Ability_Registry { if ( $this->registry instanceof Ability_Registry ) { return $this->registry; } $module = Plugin::$instance->modules_manager->get_modules( 'mcp' ); $this->registry = $module instanceof Mcp_Module ? $module->registry() : Mcp_Module::build_core_registry(); return $this->registry; } private function forbidden_error(): \WP_Error { return new \WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to perform this action.', 'elementor' ), [ 'status' => \WP_Http::FORBIDDEN ] ); } private function build_response( $result ) { if ( is_wp_error( $result ) ) { $data = $result->get_error_data(); $status = is_array( $data ) && isset( $data['status'] ) ? $data['status'] : 400; return Error_Builder::make( $result->get_error_code() ) ->set_status( $status ) ->set_message( $result->get_error_message() ) ->build(); } $http_status = $this->resolve_http_status( $result ); return Response_Builder::make( $result )->set_status( $http_status )->build(); } private function resolve_http_status( $result ): int { $status = is_array( $result ) ? ( $result['status'] ?? 'ok' ) : 'ok'; $status_map = [ 'error' => 422, 'partial_error' => 207, ]; return $status_map[ $status ] ?? 200; } private function route_wrapper( callable $cb ) { try { return $cb(); } catch ( \Exception $e ) { return Error_Builder::make( 'unexpected_error' ) ->set_message( __( 'Something went wrong', 'elementor' ) ) ->build(); } } }