You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Derive REST method enums from registered routes dynamically
Replace the hardcoded GET/POST/PATCH/DELETE allowlist with methods extracted
from live route data via new get_rest_api_methods_from_routes() helper.
- Tool schemas for api-function-list, api-function-details-get, and
api-function-run now use lazy closures so enums reflect actual registered
routes (e.g. PUT appears when any route supports it).
- Sanitize the methods filter input with strtoupper/strval normalization.
- Add mock rest_get_server() fixture in tests/run.php and assertions covering
schema enum content, PUT filtering, and MCP route exclusion.
- Add README note clarifying that method schemas are derived at discovery time.
Copy file name to clipboardExpand all lines: README.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -152,6 +152,8 @@ WP-CLI execution is disabled by default. To enable it, define `WP_FORGE_MCP_ENAB
152
152
|`wp-forge-api-function-details-get`| Get detailed metadata for a specific REST API route and HTTP method |
153
153
|`wp-forge-api-function-run`| Execute a REST API request by route, method, and parameters |
154
154
155
+
REST method schemas are derived from the registered WordPress REST routes at discovery time, so methods such as `PUT` appear when the underlying API supports them.
156
+
155
157
## Copy-Paste MCP Configuration
156
158
157
159
Replace `https://example.com` with your site URL. Create a WordPress Application Password from your user profile, then replace the username and password placeholders below.
Copy file name to clipboardExpand all lines: src/Tools/RestCatalogTools.php
+38-26Lines changed: 38 additions & 26 deletions
Original file line number
Diff line number
Diff line change
@@ -21,36 +21,48 @@ trait RestCatalogTools {
21
21
* @return void
22
22
*/
23
23
privatefunctionadd_rest_catalog_abilities() {
24
-
$this->add_ability( self::INTERNAL_PREFIX . 'api-function-list', 'List API Functions', 'List available WordPress REST API endpoints that support CRUD', $this->schema(
25
-
array(
26
-
'namespace' => $this->string_prop( 'REST namespace, such as wp/v2.' ),
$this->add_ability( self::INTERNAL_PREFIX . 'api-function-list', 'List API Functions', 'List available WordPress REST API endpoints that support CRUD', $list_schema, function ( $params ) {
35
41
return$this->list_api_functions( $params );
36
42
} );
37
-
$this->add_ability( self::INTERNAL_PREFIX . 'api-function-details-get', 'Get Function Details', 'Get detailed metadata for a specific REST API route and HTTP method', $this->schema(
38
-
array(
39
-
'route' => $this->string_prop( 'REST route.' ),
40
-
'method' => $this->string_prop( 'HTTP method.' ),
41
-
),
42
-
array( 'route', 'method' )
43
-
), function ( $params ) {
43
+
$details_schema = function () use ( $method_prop ) {
44
+
return$this->schema(
45
+
array(
46
+
'route' => $this->string_prop( 'REST route.' ),
47
+
'method' => $method_prop(),
48
+
),
49
+
array( 'route', 'method' )
50
+
);
51
+
};
52
+
$this->add_ability( self::INTERNAL_PREFIX . 'api-function-details-get', 'Get Function Details', 'Get detailed metadata for a specific REST API route and HTTP method', $details_schema, function ( $params ) {
$this->add_ability( self::INTERNAL_PREFIX . 'api-function-run', 'Run API Function', 'Execute a REST API request by route, method, and parameters', $this->schema(
$this->add_ability( self::INTERNAL_PREFIX . 'api-function-run', 'Run API Function', 'Execute a REST API request by route, method, and parameters', $run_schema, function ( $params ) {
assert_true( ! isset( $comment_schema['input_schema']['properties']['status']['enum'] ), 'Comment status schema should stay flexible when custom statuses cannot be reliably discovered.' );
assert_same( array( 'page' ), array_column( $public_hierarchical_post_types['message']['post_types'], 'slug' ), 'Post type list should pass filters through to get_post_types().' );
470
539
540
+
$put_api_functions = $abilities->call(
541
+
'wp-forge-api-function-list',
542
+
array(
543
+
'namespace' => 'wp/v2',
544
+
'methods' => array( 'PUT' ),
545
+
)
546
+
);
547
+
assert_same( 'success', $put_api_functions['status'], 'REST function list should accept route-derived PUT filters.' );
assert_same( false, $registered_abilities['wp-forge/plugin-activate']['meta']['annotations']['destructive'], 'Activation should not be marked destructive.' );
490
592
assert_same( true, $registered_abilities['wp-forge/plugin-activate']['meta']['annotations']['idempotent'], 'Activation should be marked idempotent.' );
491
593
assert_same( true, $registered_abilities['wp-forge/plugin-uninstall']['meta']['annotations']['destructive'], 'Uninstall should be marked destructive.' );
'Registered WordPress REST runner ability should use route-derived methods.'
598
+
);
492
599
assert_same( true, $registered_abilities['wp-forge/content-search']['permission_callback'](), 'Permission callback should allow users with the ability capability.' );
0 commit comments