PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.8.2
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.8.2
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
243 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 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
35 'outputSchema' => $this->build_output_schema(),
36 ];
37 break;
38 }
39 }
40 }
41
42 if ( isset( $routes[ $item ] ) ) {
43 foreach ( $routes[ $item ] as $endpoint ) {
44 if ( ! empty( $endpoint['methods']['GET'] ) ) {
45 $tools[ "get_{$resource}" ] = [
46 'name' => "get_{$resource}",
47 'description' => "Get single {$resource} by ID",
48 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
49 'outputSchema' => $this->build_output_schema(),
50 ];
51 break;
52 }
53 }
54 }
55
56 if ( isset( $routes[ $base ] ) ) {
57 foreach ( $routes[ $base ] as $endpoint ) {
58 if ( ! empty( $endpoint['methods']['POST'] ) ) {
59 $tools[ "create_{$resource}" ] = [
60 'name' => "create_{$resource}",
61 'description' => "Create {$resource}",
62 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
63 'outputSchema' => $this->build_output_schema(),
64 ];
65 break;
66 }
67 }
68 }
69
70 if ( isset( $routes[ $item ] ) ) {
71 foreach ( $routes[ $item ] as $endpoint ) {
72 $methods = array_keys( $endpoint['methods'] );
73 if ( array_intersect( [ 'POST', 'PUT', 'PATCH' ], $methods ) ) {
74 $tools[ "update_{$resource}" ] = [
75 'name' => "update_{$resource}",
76 'description' => "Update {$resource}",
77 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
78 'outputSchema' => $this->build_output_schema(),
79 ];
80 break;
81 }
82 }
83 }
84
85 if ( isset( $routes[ $item ] ) ) {
86 foreach ( $routes[ $item ] as $endpoint ) {
87 if ( ! empty( $endpoint['methods']['DELETE'] ) ) {
88 $tools[ "delete_{$resource}" ] = [
89 'name' => "delete_{$resource}",
90 'description' => "Delete {$resource}",
91 'inputSchema' => $this->build_schema_from_args( $endpoint['args'] ),
92 'outputSchema' => $this->build_output_schema(),
93 ];
94 break;
95 }
96 }
97 }
98 }
99
100 set_transient( $this->cache_key, $tools, DAY_IN_SECONDS );
101 $cached = $tools;
102 }
103
104 return array_merge( array_values( $cached ), $prevTools );
105 }
106
107 private function build_schema_from_args( $args ) {
108 $schema = [
109 'type' => 'object',
110 'properties' => [],
111 'required' => [],
112 ];
113
114 foreach ( $args as $name => $def ) {
115 $schema['properties'][ $name ] = [
116 'type' => $def['type'] ?? 'string',
117 'description' => $def['description'] ?? '',
118 ];
119
120 if ( ! empty( $def['required'] ) ) {
121 $schema['required'][] = $name;
122 }
123 }
124
125 return $schema;
126 }
127
128 private function build_output_schema() {
129 return [
130 'type' => 'object',
131 'properties' => [
132 'content' => [
133 'type' => 'array',
134 'items' => [
135 'type' => 'object',
136 'properties' => [
137 'type' => [
138 'type' => 'string',
139 'description' => 'Block type, e.g. text or image',
140 ],
141 'text' => [
142 'type' => 'string',
143 'description' => 'Human-readable content',
144 ],
145 ],
146 'required' => [ 'type', 'text' ],
147 ],
148 ],
149 ],
150 'required' => [ 'content' ],
151 ];
152 }
153
154 public function handle_call( $existing, $tool, $args, $id ) {
155 if ( !empty( $existing ) ) {
156 return $existing;
157 }
158
159 $tools = get_transient( $this->cache_key );
160 if ( ! isset( $tools[ $tool ] ) ) {
161 return $existing;
162 }
163
164 $current_user = wp_get_current_user();
165 if ( ! $current_user->has_cap( 'administrator' ) ) {
166 wp_set_current_user( 1 );
167 }
168
169 list( $action, $resource ) = explode( '_', $tool, 2 );
170 $path = "/wp/v2/{$resource}";
171 $method = 'GET';
172
173 if ( in_array( $action, [ 'get', 'update', 'delete' ], true ) ) {
174 if ( empty( $args['id'] ) ) {
175 return [
176 'jsonrpc' => '2.0',
177 'id' => $id,
178 'error' => [
179 'code' => -32602,
180 'message' => 'Missing parameter: id',
181 ],
182 ];
183 }
184 $path .= '/' . intval( $args['id'] );
185 }
186
187 switch ( $action ) {
188 case 'create':
189 case 'update':
190 $method = 'POST';
191 break;
192 case 'delete':
193 $method = 'DELETE';
194 break;
195 default:
196 $method = 'GET';
197 break;
198 }
199
200 $request = new WP_REST_Request( $method, $path );
201
202 if ( $method === 'GET' ) {
203 foreach ( $args as $key => $value ) {
204 $request->set_param( $key, $value );
205 }
206 }
207 else {
208 $request->set_body_params( $args );
209 }
210
211 $response = rest_do_request( $request );
212 $reply = [ 'jsonrpc' => '2.0', 'id' => $id ];
213
214 if ( is_wp_error( $response ) || $response->get_status() >= 400 ) {
215 $error_obj = is_wp_error( $response ) ? $response : $response->as_error();
216
217 return [
218 'jsonrpc' => '2.0',
219 'id' => $id,
220 'error' => [
221 'code' => (int) ( $error_obj->get_error_code() ?: $response->get_status() ),
222 'message' => $error_obj->get_error_message(),
223 'data' => $error_obj->get_error_data() ?: null,
224 ],
225 ];
226 }
227
228 $data = $response->get_data();
229
230 $reply['result'] = [
231 'content' => [
232 [
233 'type' => 'text',
234 'text' => wp_json_encode( $data, JSON_PRETTY_PRINT ),
235 ],
236 ],
237 'data' => $data,
238 ];
239
240 return $reply;
241 }
242 }
243