PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.8.3
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.8.3
3.5.9 3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / labs / mcp_rest.php
ai-engine / labs Last commit date
mcp.conf 1 year ago mcp.js 1 year ago mcp.md 1 year ago mcp.php 1 year ago mcp_core.php 1 year ago mcp_rest.php 1 year ago realtime.php 1 year ago
mcp_rest.php
240 lines
1 <?php
2
3 class Meow_MWAI_Labs_MCP_Rest {
4 private $cache_key = 'mwai_mcp_tools_cache';
5 private $allowed = [ 'posts', 'pages', 'media' ];
6
7 public function __construct() {
8 add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
9 }
10
11 public function rest_api_init() {
12 add_filter( 'mwai_mcp_tools', [ $this, 'register_rest_tools' ] );
13 add_filter( 'mwai_mcp_callback', [ $this, 'handle_call' ], 10, 4 );
14 }
15
16 public function register_rest_tools( $prevTools ) {
17 $cached = get_transient( $this->cache_key );
18
19 if ( !$cached ) {
20 $tools = [];
21 $server = rest_get_server();
22 $routes = $server->get_routes();
23
24 foreach ( $this->allowed as $resource ) {
25 $base = "/wp/v2/{$resource}";
26 $item = "{$base}/(?P<id>[\d]+)";
27
28 if ( isset( $routes[ $base ] ) ) {
29 foreach ( $routes[ $base ] as $endpoint ) {
30 if ( ! empty( $endpoint['methods']['GET'] ) ) {
31 $tools[ "list_{$resource}" ] = [
32 'name' => "list_{$resource}",
33 'description' => "List {$resource}",
34 'category' => 'Dynamic REST',
35 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
36 'outputSchema' => $this->build_output_schema(),
37 ];
38 break;
39 }
40 }
41 }
42
43 if ( isset( $routes[ $item ] ) ) {
44 foreach ( $routes[ $item ] as $endpoint ) {
45 if ( ! empty( $endpoint['methods']['GET'] ) ) {
46 $tools[ "get_{$resource}" ] = [
47 'name' => "get_{$resource}",
48 'description' => "Get single {$resource} by ID",
49 'category' => 'Dynamic REST',
50 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
51 'outputSchema' => $this->build_output_schema(),
52 ];
53 break;
54 }
55 }
56 }
57
58 if ( isset( $routes[ $base ] ) ) {
59 foreach ( $routes[ $base ] as $endpoint ) {
60 if ( ! empty( $endpoint['methods']['POST'] ) ) {
61 $tools[ "create_{$resource}" ] = [
62 'name' => "create_{$resource}",
63 'description' => "Create {$resource}",
64 'category' => 'Dynamic REST',
65 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
66 'outputSchema' => $this->build_output_schema(),
67 ];
68 break;
69 }
70 }
71 }
72
73 if ( isset( $routes[ $item ] ) ) {
74 foreach ( $routes[ $item ] as $endpoint ) {
75 $methods = array_keys( $endpoint['methods'] );
76 if ( array_intersect( [ 'POST', 'PUT', 'PATCH' ], $methods ) ) {
77 $tools[ "update_{$resource}" ] = [
78 'name' => "update_{$resource}",
79 'description' => "Update {$resource}",
80 'category' => 'Dynamic REST',
81 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
82 'outputSchema' => $this->build_output_schema(),
83 ];
84 break;
85 }
86 }
87 }
88
89 if ( isset( $routes[ $item ] ) ) {
90 foreach ( $routes[ $item ] as $endpoint ) {
91 if ( ! empty( $endpoint['methods']['DELETE'] ) ) {
92 $tools[ "delete_{$resource}" ] = [
93 'name' => "delete_{$resource}",
94 'description' => "Delete {$resource}",
95 'category' => 'Dynamic REST',
96 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
97 'outputSchema' => $this->build_output_schema(),
98 ];
99 break;
100 }
101 }
102 }
103 }
104
105 set_transient( $this->cache_key, $tools, DAY_IN_SECONDS );
106 $cached = $tools;
107 }
108
109 return array_merge( array_values( $cached ), $prevTools );
110 }
111
112 private function build_schema_from_args( $args ) {
113 $schema = [
114 'type' => 'object',
115 'properties' => [],
116 'required' => [],
117 ];
118
119 foreach ( $args as $name => $def ) {
120 $schema['properties'][ $name ] = [
121 'type' => $def['type'] ?? 'string',
122 'description' => $def['description'] ?? '',
123 ];
124
125 if ( ! empty( $def['required'] ) ) {
126 $schema['required'][] = $name;
127 }
128 }
129
130 return $schema;
131 }
132
133 private function build_output_schema() {
134 return [
135 'type' => 'object',
136 'properties' => [
137 'content' => [
138 'type' => 'array',
139 'items' => [
140 'type' => 'object',
141 'properties' => [
142 'type' => [
143 'type' => 'string',
144 'description' => 'Block type, e.g. text or image',
145 ],
146 'text' => [
147 'type' => 'string',
148 'description' => 'Human-readable content',
149 ],
150 ],
151 'required' => [ 'type', 'text' ],
152 ],
153 ],
154 ],
155 'required' => [ 'content' ],
156 ];
157 }
158
159 public function handle_call( $existing, $tool, $args, $id ) {
160 if ( !empty( $existing ) ) {
161 return $existing;
162 }
163
164 $tools = get_transient( $this->cache_key );
165 if ( ! isset( $tools[ $tool ] ) ) {
166 return $existing;
167 }
168
169 $current_user = wp_get_current_user();
170 if ( ! $current_user->has_cap( 'administrator' ) ) {
171 wp_set_current_user( 1 );
172 }
173
174 list( $action, $resource ) = explode( '_', $tool, 2 );
175 $path = "/wp/v2/{$resource}";
176 $method = 'GET';
177
178 if ( in_array( $action, [ 'get', 'update', 'delete' ], true ) ) {
179 if ( empty( $args['id'] ) ) {
180 return [
181 'jsonrpc' => '2.0',
182 'id' => $id,
183 'error' => [
184 'code' => -32602,
185 'message' => 'Missing parameter: id',
186 ],
187 ];
188 }
189 $path .= '/' . intval( $args['id'] );
190 }
191
192 switch ( $action ) {
193 case 'create':
194 case 'update':
195 $method = 'POST';
196 break;
197 case 'delete':
198 $method = 'DELETE';
199 break;
200 default:
201 $method = 'GET';
202 break;
203 }
204
205 $request = new WP_REST_Request( $method, $path );
206
207 if ( $method === 'GET' ) {
208 foreach ( $args as $key => $value ) {
209 $request->set_param( $key, $value );
210 }
211 }
212 else {
213 $request->set_body_params( $args );
214 }
215
216 $response = rest_do_request( $request );
217
218 if ( is_wp_error( $response ) || $response->get_status() >= 400 ) {
219 $error_obj = is_wp_error( $response ) ? $response : $response->as_error();
220
221 // Return error in old format for backward compatibility
222 // The execute_tool method will detect this and not re-wrap it
223 return [
224 'jsonrpc' => '2.0',
225 'id' => $id,
226 'error' => [
227 'code' => (int) ( $error_obj->get_error_code() ?: $response->get_status() ),
228 'message' => $error_obj->get_error_message(),
229 'data' => $error_obj->get_error_data() ?: null,
230 ],
231 ];
232 }
233
234 $data = $response->get_data();
235
236 // Return just the data - execute_tool will wrap it properly
237 return $data;
238 }
239 }
240