# elementor/4.3.2/modules/mcp/rest-api/mcp-proxy-rest-api.php

Elementor Website Builder – more than just a page builder, version 4.3.2. 164 lines.

- Page: https://pluginprobe.com/plugins/elementor/4.3.2/code/modules/mcp/rest-api/mcp-proxy-rest-api.php
- Raw: https://pluginprobe.com/plugins/elementor/4.3.2/raw/modules/mcp/rest-api/mcp-proxy-rest-api.php
- Modified: 2026-09-01T11:47:36+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/elementor/4.3.2/code/modules/mcp/rest-api/mcp-proxy-rest-api.php#L10-L20`.

```php
<?php

namespace Elementor\Modules\Mcp\RestApi;

use Elementor\Core\Utils\Api\Error_Builder;
use Elementor\Core\Utils\Api\Response_Builder;
use Elementor\Modules\Mcp\Module as Mcp_Module;
use Elementor\Modules\Mcp\Registry\Ability_Registry;
use Elementor\Plugin;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class Mcp_Proxy_REST_API {
	const API_NAMESPACE = 'elementor/v1';
	const API_BASE      = 'mcp-proxy';

	private ?Ability_Registry $registry;

	public function __construct( ?Ability_Registry $registry = null ) {
		$this->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();
		}
	}
}

```
