PluginProbe
ZIP AI – AI Website Builder & AI Agent (Beta) / 0.0.8
ZIP AI – AI Website Builder & AI Agent (Beta) v0.0.8
0.0.10 0.0.9 trunk 0.0.4 0.0.5 0.0.6 0.0.7 0.0.8
zip-ai / lib / mcp-adapter / includes / Core / McpServer.php

McpServer.php in ZIP AI – AI Website Builder & AI Agent (Beta) 0.0.8, at lib/mcp-adapter/includes/Core/McpServer.php

449 lines 12.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WordPress MCP Server class for managing server-specific tools, resources, and prompts.
4 *
5 * @package McpAdapter
6 */
7
8 declare( strict_types=1 );
9
10 namespace WP\MCP\Core;
11
12 use WP\MCP\Domain\Prompts\Contracts\McpPromptBuilderInterface;
13 use WP\MCP\Domain\Prompts\McpPrompt;
14 use WP\MCP\Domain\Resources\McpResource;
15 use WP\MCP\Domain\Tools\McpTool;
16 use WP\MCP\Infrastructure\ErrorHandling\Contracts\McpErrorHandlerInterface;
17 use WP\MCP\Infrastructure\ErrorHandling\NullMcpErrorHandler;
18 use WP\MCP\Infrastructure\Observability\Contracts\McpObservabilityHandlerInterface;
19 use WP\MCP\Infrastructure\Observability\NullMcpObservabilityHandler;
20 use WP\MCP\Transport\Infrastructure\McpTransportContext;
21 use WP\McpSchema\Server\Prompts\DTO\Prompt as PromptDto;
22
23 /**
24 * WordPress MCP Server - Represents a single MCP server with its tools, resources, and prompts.
25 */
26 class McpServer {
27 /**
28 * Error handler instance.
29 *
30 * @var \WP\MCP\Infrastructure\ErrorHandling\Contracts\McpErrorHandlerInterface
31 */
32 public McpErrorHandlerInterface $error_handler;
33
34 /**
35 * Observability handler instance.
36 *
37 * @var \WP\MCP\Infrastructure\Observability\Contracts\McpObservabilityHandlerInterface
38 */
39 public McpObservabilityHandlerInterface $observability_handler;
40
41 /**
42 * Server ID.
43 *
44 * @var string
45 */
46 private string $server_id;
47
48 /**
49 * Server URL.
50 *
51 * @var string
52 */
53 private string $server_route_namespace;
54
55 /**
56 * Server route.
57 *
58 * @var string
59 */
60 private string $server_route;
61
62 /**
63 * Server name.
64 *
65 * @var string
66 */
67 private string $server_name;
68
69 /**
70 * Server description.
71 *
72 * @var string
73 */
74 private string $server_description;
75
76 /**
77 * Server version.
78 *
79 * @var string
80 */
81 private string $server_version;
82
83 /**
84 * Component registry for managing tools, resources, and prompts.
85 *
86 * @var \WP\MCP\Core\McpComponentRegistry
87 */
88 private McpComponentRegistry $component_registry;
89
90 /**
91 * Transport factory for initializing transports.
92 *
93 * @var \WP\MCP\Core\McpTransportFactory
94 */
95 private McpTransportFactory $transport_factory;
96
97 /**
98 * Whether MCP validation is enabled.
99 *
100 * @var bool
101 */
102 private bool $mcp_validation_enabled;
103
104 /**
105 * Transport permission callback.
106 *
107 * @var callable|null
108 */
109 private $transport_permission_callback;
110
111
112 /**
113 * Constructor.
114 *
115 * @param string $server_id Unique identifier for the server.
116 * @param string $server_route_namespace Server route namespace.
117 * @param string $server_route Server route.
118 * @param string $server_name Human-readable server name.
119 * @param string $server_description Server description.
120 * @param string $server_version Server version.
121 * @param array<class-string<\WP\MCP\Transport\Contracts\McpTransportInterface>> $mcp_transports Array of MCP transport class names to initialize (e.g., [McpRestTransport::class]).
122 * @param class-string<\WP\MCP\Infrastructure\ErrorHandling\Contracts\McpErrorHandlerInterface>|null $error_handler Error handler class to use (e.g., NullMcpErrorHandler::class). Must implement McpErrorHandlerInterface. If null, NullMcpErrorHandler will be used.
123 * @param class-string<\WP\MCP\Infrastructure\Observability\Contracts\McpObservabilityHandlerInterface>|null $observability_handler Observability handler class to use (e.g., NullMcpObservabilityHandler::class). Must implement McpObservabilityHandlerInterface. If null, NullMcpObservabilityHandler will be used.
124 * @param list<string> $tools Optional ability names to register as tools during construction.
125 * @param list<string> $resources Optional resources to register during construction.
126 * @param list<string> $prompts Optional prompts to register during construction.
127 * @param callable|null $transport_permission_callback Optional custom permission callback for transport-level authentication. If null, defaults to is_user_logged_in().
128 *
129 * @throws \Exception Thrown if the MCP transport class does not extend AbstractMcpTransport.
130 */
131 public function __construct(
132 string $server_id,
133 string $server_route_namespace,
134 string $server_route,
135 string $server_name,
136 string $server_description,
137 string $server_version,
138 array $mcp_transports,
139 ?string $error_handler,
140 ?string $observability_handler,
141 array $tools = array(),
142 array $resources = array(),
143 array $prompts = array(),
144 ?callable $transport_permission_callback = null
145 ) {
146 // Store server configuration
147 $this->server_id = $server_id;
148 $this->server_route_namespace = $server_route_namespace;
149 $this->server_route = $server_route;
150 $this->server_name = $server_name;
151 $this->server_description = $server_description;
152 $this->server_version = $server_version;
153 $this->transport_permission_callback = $transport_permission_callback;
154
155 /**
156 * Filters whether MCP protocol validation is enabled for a server.
157 *
158 * Validation is disabled by default for performance, as the Abilities API
159 * also validates all abilities. Enable this filter for stricter MCP protocol
160 * compliance checking during development or debugging.
161 *
162 * @since 0.3.0
163 *
164 * @param bool $enabled Whether validation is enabled. Default false.
165 * @param string $server_id The server ID being configured.
166 * @param \WP\MCP\Core\McpServer $server The McpServer instance being constructed.
167 */
168 $this->mcp_validation_enabled = apply_filters( 'mcp_adapter_validation_enabled', false, $this->server_id, $this );
169
170 // Setup handlers and components
171 $this->setup_handlers( $error_handler, $observability_handler );
172 $this->setup_components( $tools, $resources, $prompts, $mcp_transports );
173 }
174
175 /**
176 * Setup error and observability handlers.
177 *
178 * @param string|null $error_handler Error handler class name.
179 * @param string|null $observability_handler Observability handler class name.
180 */
181 private function setup_handlers( ?string $error_handler, ?string $observability_handler ): void {
182 // Instantiate error handler
183 if ( $error_handler && class_exists( $error_handler ) ) {
184 /** @var \WP\MCP\Infrastructure\ErrorHandling\Contracts\McpErrorHandlerInterface $handler */
185 $handler = new $error_handler();
186 $this->error_handler = $handler;
187 } else {
188 $this->error_handler = new NullMcpErrorHandler();
189 }
190
191 // Instantiate observability handler
192 if ( $observability_handler && class_exists( $observability_handler ) ) {
193 /** @var \WP\MCP\Infrastructure\Observability\Contracts\McpObservabilityHandlerInterface $handler */
194 $handler = new $observability_handler();
195 $this->observability_handler = $handler;
196 } else {
197 $this->observability_handler = new NullMcpObservabilityHandler();
198 }
199 }
200
201 /**
202 * Setup component registry and transport factory.
203 *
204 * @param list<string> $tools Tools to register.
205 * @param list<string> $resources Resources to register.
206 * @param list<string> $prompts Prompts to register.
207 * @param array<class-string<\WP\MCP\Transport\Contracts\McpTransportInterface>> $mcp_transports Transport classes to initialize.
208 *
209 * @throws \Exception
210 */
211 private function setup_components( array $tools, array $resources, array $prompts, array $mcp_transports ): void {
212 // Initialize component registry
213 $this->component_registry = new McpComponentRegistry(
214 $this,
215 $this->error_handler,
216 $this->observability_handler
217 );
218
219 // Initialize transport factory
220 $this->transport_factory = new McpTransportFactory( $this );
221
222 // Register tools, resources, and prompts
223 $this->register_mcp_components( $tools, $resources, $prompts );
224
225 // Initialize transports
226 $this->transport_factory->initialize_transports( $mcp_transports );
227 }
228
229 /**
230 * Register initial tools, resources, and prompts.
231 *
232 * @param list<string> $tools Tools to register.
233 * @param list<string> $resources Resources to register.
234 * @param list<string> $prompts Prompts to register.
235 */
236 private function register_mcp_components( array $tools, array $resources, array $prompts ): void {
237 // Register tools if provided
238 if ( ! empty( $tools ) ) {
239 $this->component_registry->register_tools( $tools );
240 }
241
242 // Register resources if provided
243 if ( ! empty( $resources ) ) {
244 $this->component_registry->register_resources( $resources );
245 }
246
247 // Register prompts if provided
248 if ( empty( $prompts ) ) {
249 return;
250 }
251
252 $this->component_registry->register_prompts( $prompts );
253 }
254
255 /**
256 * Get server ID.
257 *
258 * @return string
259 */
260 public function get_server_id(): string {
261 return $this->server_id;
262 }
263
264 /**
265 * Get server route namespace.
266 *
267 * @return string
268 */
269 public function get_server_route_namespace(): string {
270 return $this->server_route_namespace;
271 }
272
273 /**
274 * Get server route.
275 *
276 * @return string
277 */
278 public function get_server_route(): string {
279 return $this->server_route;
280 }
281
282 /**
283 * Get the server name.
284 *
285 * @return string
286 */
287 public function get_server_name(): string {
288 return $this->server_name;
289 }
290
291 /**
292 * Get server description.
293 *
294 * @return string
295 */
296 public function get_server_description(): string {
297 return $this->server_description;
298 }
299
300 /**
301 * Get server version.
302 *
303 * @return string
304 */
305 public function get_server_version(): string {
306 return $this->server_version;
307 }
308
309 /**
310 * Get the transport permission callback.
311 *
312 * @return callable|null
313 */
314 public function get_transport_permission_callback(): ?callable {
315 return $this->transport_permission_callback;
316 }
317
318 /**
319 * Get the observability handler instance.
320 *
321 * @return \WP\MCP\Infrastructure\Observability\Contracts\McpObservabilityHandlerInterface
322 */
323 public function get_observability_handler(): McpObservabilityHandlerInterface {
324 return $this->observability_handler;
325 }
326
327 /**
328 * Get the error handler instance.
329 *
330 * @since 0.5.0
331 *
332 * @return \WP\MCP\Infrastructure\ErrorHandling\Contracts\McpErrorHandlerInterface
333 */
334 public function get_error_handler(): McpErrorHandlerInterface {
335 return $this->error_handler;
336 }
337
338 /**
339 * Get all tools registered to this server.
340 *
341 * @return array<string, \WP\McpSchema\Server\Tools\DTO\Tool>
342 */
343 public function get_tools(): array {
344 return $this->component_registry->get_tools();
345 }
346
347 /**
348 * Get all resources registered to this server.
349 *
350 * @return array<string, \WP\McpSchema\Server\Resources\DTO\Resource>
351 */
352 public function get_resources(): array {
353 return $this->component_registry->get_resources();
354 }
355
356 /**
357 * Get all prompts registered to this server.
358 *
359 * @return array<string, \WP\McpSchema\Server\Prompts\DTO\Prompt>
360 */
361 public function get_prompts(): array {
362 return $this->component_registry->get_prompts();
363 }
364
365 /**
366 * Get a specific McpTool by name.
367 *
368 * @param string $tool_name Tool name.
369 *
370 * @return \WP\MCP\Domain\Tools\McpTool|null
371 * @internal
372 * @since 0.3.0
373 *
374 */
375 public function get_mcp_tool( string $tool_name ): ?McpTool {
376 return $this->component_registry->get_mcp_tool( $tool_name );
377 }
378
379 /**
380 * Get a specific McpResource by URI.
381 *
382 * @param string $resource_uri Resource URI.
383 *
384 * @return \WP\MCP\Domain\Resources\McpResource|null
385 * @internal
386 * @since 0.3.0
387 *
388 */
389 public function get_mcp_resource( string $resource_uri ): ?McpResource {
390 return $this->component_registry->get_mcp_resource( $resource_uri );
391 }
392
393 /**
394 * Get a specific prompt by name.
395 *
396 * @param string $prompt_name Prompt name.
397 *
398 * @return \WP\McpSchema\Server\Prompts\DTO\Prompt|null
399 */
400 public function get_prompt( string $prompt_name ): ?PromptDto {
401 $mcp_prompt = $this->component_registry->get_mcp_prompt( $prompt_name );
402
403 return $mcp_prompt ? $mcp_prompt->get_protocol_dto() : null;
404 }
405
406 /**
407 * Get an McpPrompt by name.
408 *
409 * @param string $prompt_name Prompt name.
410 *
411 * @return \WP\MCP\Domain\Prompts\McpPrompt|null
412 * @internal
413 * @since 0.3.0
414 *
415 */
416 public function get_mcp_prompt( string $prompt_name ): ?McpPrompt {
417 return $this->component_registry->get_mcp_prompt( $prompt_name );
418 }
419
420 /**
421 * Get a prompt builder instance by prompt name (builder-based prompts).
422 *
423 * @param string $prompt_name Prompt name.
424 *
425 * @return \WP\MCP\Domain\Prompts\Contracts\McpPromptBuilderInterface|null
426 */
427 public function get_prompt_builder( string $prompt_name ): ?McpPromptBuilderInterface {
428 return $this->component_registry->get_prompt_builder( $prompt_name );
429 }
430
431 /**
432 * Create transport context with all required dependencies.
433 *
434 * @return \WP\MCP\Transport\Infrastructure\McpTransportContext
435 */
436 public function create_transport_context(): McpTransportContext {
437 return $this->transport_factory->create_transport_context();
438 }
439
440 /**
441 * Check if MCP validation is enabled.
442 *
443 * @return bool
444 */
445 public function is_mcp_validation_enabled(): bool {
446 return $this->mcp_validation_enabled;
447 }
448 }
449