Skip to content

Commit a8cfd35

Browse files
authoredApr 7, 2025
Improve mcp server CRUD functionality (#55)
1 parent 2c57b42 commit a8cfd35

File tree

4 files changed

+109
-15
lines changed

4 files changed

+109
-15
lines changed
 

‎composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"authors": [],
88
"require": {
99
"php": "^8.2",
10-
"logiscape/mcp-sdk-php": "^1.0",
10+
"logiscape/mcp-sdk-php": "dev-main",
1111
"mcaskill/composer-exclude-files": "^4.0",
1212
"mcp-wp/mcp-server": "dev-main",
1313
"wp-cli/wp-cli": "^2.11"

‎features/load-wp-cli.feature

Lines changed: 0 additions & 10 deletions
This file was deleted.

‎features/mcp-server.feature

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
Feature: MCP server command
2+
3+
Background:
4+
Given an empty directory
5+
And an empty {HOME} directory
6+
7+
Scenario: CRUD
8+
When I run `wp mcp server add foo "https://foo.example.com/mcp"`
9+
Then STDOUT should contain:
10+
"""
11+
Server added.
12+
"""
13+
14+
When I run `wp mcp server add bar "https://bar.example.com/mcp"`
15+
And I run `wp mcp server add baz "https://baz.example.com/mcp"`
16+
And I run `wp mcp server list`
17+
Then STDOUT should be a table containing rows:
18+
| name | server | status |
19+
| foo | https://foo.example.com/mcp | active |
20+
| bar | https://bar.example.com/mcp | active |
21+
| baz | https://baz.example.com/mcp | active |
22+
23+
When I run `wp mcp server remove bar baz`
24+
Then STDOUT should contain:
25+
"""
26+
Success: Removed 2 of 2 servers.
27+
"""
28+
29+
When I run `wp mcp server list`
30+
Then STDOUT should contain:
31+
"""
32+
foo.example.com
33+
"""
34+
And STDOUT should not contain:
35+
"""
36+
bar.example.com
37+
"""
38+
And STDOUT should not contain:
39+
"""
40+
baz.example.com
41+
"""
42+
43+
When I try `wp mcp server add foo "https://foo.example.com/mcp"`
44+
Then STDERR should contain:
45+
"""
46+
Server already exists.
47+
"""
48+
49+
When I run `wp mcp server add bar "https://bar.example.com/mcp"`
50+
And I run `wp mcp server add baz "https://baz.example.com/mcp"`
51+
And I run `wp mcp server update bar --status=inactive`
52+
Then STDOUT should contain:
53+
"""
54+
Server updated.
55+
"""
56+
57+
When I run `wp mcp server list --status=inactive`
58+
Then STDOUT should be a table containing rows:
59+
| name | server | status |
60+
| bar | https://bar.example.com/mcp | inactive |
61+
62+
And STDOUT should not contain:
63+
"""
64+
foo.example.com
65+
"""
66+
And STDOUT should not contain:
67+
"""
68+
baz.example.com
69+
"""
70+
71+
When I run `wp mcp server update foo --name=fabulous`
72+
Then STDOUT should contain:
73+
"""
74+
Server updated.
75+
"""
76+
77+
When I run `wp mcp server list`
78+
Then STDOUT should be a table containing rows:
79+
| name | server | status |
80+
| fabulous | https://foo.example.com/mcp | active |

‎src/McpServerCommand.php

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ class McpServerCommand extends WP_CLI_Command {
1919
*
2020
* ## OPTIONS
2121
*
22+
* [--<field>=<value>]
23+
* : Filter results by key=value pairs.
24+
*
2225
* [--format=<format>]
2326
* : Render output in a particular format.
2427
* ---
@@ -42,6 +45,8 @@ class McpServerCommand extends WP_CLI_Command {
4245
*
4346
* @subcommand list
4447
*
48+
* @when before_wp_load
49+
*
4550
* @param array $args Indexed array of positional arguments.
4651
* @param array $assoc_args Associative array of associative arguments.
4752
*/
@@ -51,6 +56,13 @@ public function list_( $args, $assoc_args ): void {
5156
$servers = [];
5257

5358
foreach ( $config as $name => $server ) {
59+
// Support features like --status=active.
60+
foreach ( array_keys( $server ) as $field ) {
61+
if ( isset( $assoc_args[ $field ] ) && ! in_array( $server[ $field ], array_map( 'trim', explode( ',', $assoc_args[ $field ] ) ), true ) ) {
62+
continue 2;
63+
}
64+
}
65+
5466
$servers[] = [
5567
'name' => $name,
5668
'server' => $server['server'],
@@ -83,6 +95,8 @@ public function list_( $args, $assoc_args ): void {
8395
* $ wp mcp server add "server-filesystem" "npx -y @modelcontextprotocol/server-filesystem /my/allowed/folder/"
8496
* Success: Server added.
8597
*
98+
* @when before_wp_load
99+
*
86100
* @param array $args Indexed array of positional arguments.
87101
*/
88102
public function add( $args ): void {
@@ -93,7 +107,7 @@ public function add( $args ): void {
93107
} else {
94108
$config[ $args[0] ] = [
95109
'server' => $args[1],
96-
'status' => 'enabled',
110+
'status' => 'active',
97111
];
98112

99113
$result = $this->get_config()->update_config( $config );
@@ -123,6 +137,8 @@ public function add( $args ): void {
123137
* $ wp mcp server remove "server-filesystem"
124138
* Success: Server removed.
125139
*
140+
* @when before_wp_load
141+
*
126142
* @param array $args Indexed array of positional arguments.
127143
*/
128144
public function remove( $args, $assoc_args ): void {
@@ -143,7 +159,7 @@ public function remove( $args, $assoc_args ): void {
143159
WP_CLI::warning( "Server '$server' not found." );
144160
++$errors;
145161
} else {
146-
unset( $config[ $args[0] ] );
162+
unset( $config[ $server ] );
147163
++$successes;
148164
}
149165
}
@@ -172,9 +188,11 @@ public function remove( $args, $assoc_args ): void {
172188
* ## EXAMPLES
173189
*
174190
* # Remove server.
175-
* $ wp mcp server update "server-filesystem" --status=disabled
191+
* $ wp mcp server update "server-filesystem" --status=inactive
176192
* Success: Server updated.
177193
*
194+
* @when before_wp_load
195+
*
178196
* @param array $args Indexed array of positional arguments.
179197
*/
180198
public function update( $args, $assoc_args ): void {
@@ -187,12 +205,18 @@ public function update( $args, $assoc_args ): void {
187205
foreach ( $config[ $args[0] ] as $key => $value ) {
188206
if ( isset( $assoc_args[ $key ] ) ) {
189207
if ( 'status' === $key ) {
190-
$value = 'disabled' === $value ? 'enabled' : 'disabled';
208+
$value = 'inactive' === $value ? 'active' : 'inactive';
191209
}
192210
$config[ $args[0] ][ $key ] = $value;
193211
}
194212
}
195213

214+
// Special case for renaming an entry.
215+
if ( isset( $assoc_args['name'] ) ) {
216+
$config[ $assoc_args['name'] ] = $config[ $args[0] ];
217+
unset( $config[ $args[0] ] );
218+
}
219+
196220
$result = $this->get_config()->update_config( $config );
197221

198222
if ( ! $result ) {

0 commit comments

Comments
 (0)