PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / vendor / wordpress / mcp-adapter / includes / Cli / McpCommand.php

McpCommand.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF trunk, at vendor/wordpress/mcp-adapter/includes/Cli/McpCommand.php

188 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * WP-CLI Command for MCP STDIO Transport
4 *
5 * @package McpAdapter
6 */
7
8 declare( strict_types=1 );
9
10 namespace WP\MCP\Cli;
11
12 use WP\MCP\Core\McpAdapter;
13 use function WP_CLI\Utils\format_items;
14
15 /**
16 * Manage MCP servers via WP-CLI.
17 *
18 * Provides commands to serve MCP servers over STDIO transport for
19 * communication with MCP clients via subprocess.
20 */
21 class McpCommand extends \WP_CLI_Command { // phpcs:ignore
22
23 /**
24 * Serve an MCP server via STDIO transport.
25 *
26 * This command starts an MCP server that communicates via standard input/output
27 * using the JSON-RPC 2.0 protocol. It's designed to be launched as a subprocess
28 * by MCP clients.
29 *
30 * ## OPTIONS
31 *
32 * [--server=<server-id>]
33 * : The ID of the MCP server to serve. If not specified, uses the first available server.
34 *
35 * [--user=<id|login|email>]
36 * : Run as a specific WordPress user for permission checks.
37 * : Without this, runs as unauthenticated (limited capabilities).
38 *
39 * ## EXAMPLES
40 *
41 * # Serve the default MCP server as admin user
42 * wp mcp serve --user=admin
43 *
44 * # Serve a specific server as user with ID 1
45 * wp mcp serve --server=my-mcp-server --user=1
46 *
47 * # Serve without authentication (limited capabilities)
48 * wp mcp serve --server=public-server
49 *
50 * @when after_wp_load
51 * @synopsis [--server=<server-id>] [--user=<id|login|email>]
52 */
53 public function serve( array $args, array $assoc_args ): void {
54
55 // Get the MCP adapter instance
56 $adapter = McpAdapter::instance();
57
58 // Get all registered servers
59 $servers = $adapter->get_servers();
60
61 if ( empty( $servers ) ) {
62 \WP_CLI::error( 'No MCP servers are registered. Please register at least one server first.' );
63 }
64
65 // Determine which server to use
66 $server_id = $assoc_args['server'] ?? null;
67 $server = null;
68
69 if ( $server_id ) {
70 $server = $adapter->get_server( $server_id );
71 if ( ! $server ) {
72 \WP_CLI::error( sprintf( 'Server with ID "%s" not found.', $server_id ) );
73 }
74 } else {
75 // Use the first available server
76 $server = array_values( $servers )[0];
77 $server_id = $server->get_server_id();
78 \WP_CLI::line( sprintf( 'Using server: %s', $server_id ) );
79 }
80
81 // Set user context if specified
82 if ( isset( $assoc_args['user'] ) ) {
83 $user = $this->get_user( $assoc_args['user'] );
84 if ( ! $user ) {
85 \WP_CLI::error( sprintf( 'User "%s" not found.', $assoc_args['user'] ) );
86 }
87
88 wp_set_current_user( $user->ID );
89 \WP_CLI::debug( sprintf( 'Running as user: %s (ID: %d)', $user->user_login, $user->ID ) );
90 } else {
91 \WP_CLI::debug( 'Running without authentication. Some capabilities may be limited.' );
92 }
93
94 // Create and start STDIO server bridge
95 try {
96 \WP_CLI::debug( sprintf( 'Starting STDIO bridge for server: %s', $server_id ) );
97
98 // Create STDIO server bridge
99 $stdio_bridge = new StdioServerBridge( $server );
100
101 // Start serving (this blocks until terminated)
102 $stdio_bridge->serve();
103 } catch ( \RuntimeException $e ) {
104 \WP_CLI::error( $e->getMessage() );
105 } catch ( \Throwable $e ) {
106 \WP_CLI::error( 'Failed to start STDIO bridge: ' . $e->getMessage() );
107 }
108 }
109
110 /**
111 * Get a user by ID, login, or email.
112 *
113 * @param string $user User identifier (ID, login, or email).
114 *
115 * @return \WP_User|false User object or false if not found.
116 */
117 private function get_user( string $user ) {
118 // Try as ID first
119 if ( is_numeric( $user ) ) {
120 return get_user_by( 'id', (int) $user );
121 }
122
123 // Try as login
124 $user_obj = get_user_by( 'login', $user );
125 if ( $user_obj ) {
126 return $user_obj;
127 }
128
129 // Try as email
130 return get_user_by( 'email', $user );
131 }
132
133 /**
134 * List all registered MCP servers.
135 *
136 * ## OPTIONS
137 *
138 * [--format=<format>]
139 * : Render output in a particular format.
140 * ---
141 * default: table
142 * options:
143 * - table
144 * - csv
145 * - json
146 * - yaml
147 * ---
148 *
149 * ## EXAMPLES
150 *
151 * # List all MCP servers
152 * wp mcp list
153 *
154 * # List servers in JSON format
155 * wp mcp list --format=json
156 *
157 * @when after_wp_load
158 * @synopsis [--format=<format>]
159 */
160 public function list( array $args, array $assoc_args ): void {
161 $adapter = McpAdapter::instance();
162
163 $servers = $adapter->get_servers();
164
165 if ( empty( $servers ) ) {
166 \WP_CLI::line( 'No MCP servers registered.' );
167
168 return;
169 }
170
171 $items = array();
172 foreach ( $servers as $server ) {
173 $items[] = array(
174 'ID' => $server->get_server_id(),
175 'Name' => $server->get_server_name(),
176 'Version' => $server->get_server_version(),
177 'Tools' => count( $server->get_tools() ),
178 'Resources' => count( $server->get_resources() ),
179 'Prompts' => count( $server->get_prompts() ),
180 'Description' => $server->get_server_description(),
181 );
182 }
183
184 $format = $assoc_args['format'] ?? 'table';
185 format_items( $format, $items, array( 'ID', 'Name', 'Version', 'Tools', 'Resources', 'Prompts' ) );
186 }
187 }
188