Summary
Two abilities ship input/output schemas that are not valid JSON Schema. ai/alt-text-generation puts an object-bound callable (array( $this, 'method' )) in sanitize_callback, and ai/get-post-terms has a structurally malformed output_schema. Any strict JSON-Schema consumer of these schemas breaks. Concretely, exposing them through WordPress/mcp-adapter causes a stack overflow (alt-text) and a validation failure (get-post-terms), so these abilities cannot become MCP tools.
Environment
|
|
WordPress/ai |
1.0.1 |
| WordPress |
7.0 (Abilities API in core) |
| PHP |
8.3 |
| Surfaced via |
wordpress/mcp-adapter 0.5.0 |
Problem 1: object-valued sanitize_callback in ai/alt-text-generation
includes/Abilities/Image/Alt_Text_Generation.php:
'image_url' => array(
'type' => 'string',
'sanitize_callback' => array( $this, 'sanitize_image_reference_input' ), // object-bound callable
'description' => '...',
),
The exported input schema therefore contains a live PHP object. A JSON-Schema consumer that walks the schema descends into that object graph. In mcp-adapter 0.5.0 this recurses until the Zend stack limit: Maximum call stack size ... reached. Infinite recursion?. The string-valued callbacks on attachment_id (absint) and context (sanitize_textarea_field) are fine; only the object-bound one is a problem.
Problem 2: malformed output_schema in ai/get-post-terms
includes/Abilities/Utilities/Posts.php:
'output_schema' => array(
'type' => 'object',
'properties' => array(
'type' => 'array', // 'properties' should be a map of name => sub-schema
'items' => array( ... ), // this looks like an array schema placed under 'properties'
),
),
properties must be an object mapping property names to sub-schemas. Here it holds type (string "array") and items, which reads like an array schema was pasted into the properties slot. A strict validator reports Expected array or object for key "type", got string. The output is presumably meant to be an array of term objects, so the schema shape is wrong.
Expected behavior
input_schema and output_schema should be valid JSON Schema. WordPress-only concerns such as sanitization belong in execution or validation, not as object-valued keys inside the exported schema. The get-post-terms output schema should describe an array of term objects correctly.
Proposed fix
- For
alt-text-generation: keep sanitization server-side, but do not emit an object-bound callable in the exported schema. Either reference a named function, or strip callable keys from the schema exposed via REST and MCP.
- For
get-post-terms: correct the output_schema to a proper array-of-objects shape (for example type: array with items: { type: object, properties: { term_id, name, slug, ... } }), rather than nesting that under properties.
- Consider a unit test that asserts every registered
ai/* ability schema round-trips through wp_json_encode() and validates as JSON Schema, so non-clean schemas are caught in CI.
Context
Discovered while exposing the WordPress/ai abilities as MCP tools via mcp-adapter. A companion robustness issue is filed on WordPress/mcp-adapter (it should strip WordPress-only keys and guard against recursion regardless), but the schemas themselves should also be JSON-Schema clean. Happy to open a PR.
Summary
Two abilities ship input/output schemas that are not valid JSON Schema.
ai/alt-text-generationputs an object-bound callable (array( $this, 'method' )) insanitize_callback, andai/get-post-termshas a structurally malformedoutput_schema. Any strict JSON-Schema consumer of these schemas breaks. Concretely, exposing them throughWordPress/mcp-adaptercauses a stack overflow (alt-text) and a validation failure (get-post-terms), so these abilities cannot become MCP tools.Environment
WordPress/aiwordpress/mcp-adapter0.5.0Problem 1: object-valued
sanitize_callbackinai/alt-text-generationincludes/Abilities/Image/Alt_Text_Generation.php:The exported input schema therefore contains a live PHP object. A JSON-Schema consumer that walks the schema descends into that object graph. In
mcp-adapter0.5.0 this recurses until the Zend stack limit:Maximum call stack size ... reached. Infinite recursion?. The string-valued callbacks onattachment_id(absint) andcontext(sanitize_textarea_field) are fine; only the object-bound one is a problem.Problem 2: malformed
output_schemainai/get-post-termsincludes/Abilities/Utilities/Posts.php:propertiesmust be an object mapping property names to sub-schemas. Here it holdstype(string"array") anditems, which reads like an array schema was pasted into thepropertiesslot. A strict validator reportsExpected array or object for key "type", got string. The output is presumably meant to be an array of term objects, so the schema shape is wrong.Expected behavior
input_schemaandoutput_schemashould be valid JSON Schema. WordPress-only concerns such as sanitization belong in execution or validation, not as object-valued keys inside the exported schema. Theget-post-termsoutput schema should describe an array of term objects correctly.Proposed fix
alt-text-generation: keep sanitization server-side, but do not emit an object-bound callable in the exported schema. Either reference a named function, or strip callable keys from the schema exposed via REST and MCP.get-post-terms: correct theoutput_schemato a proper array-of-objects shape (for exampletype: arraywithitems: { type: object, properties: { term_id, name, slug, ... } }), rather than nesting that underproperties.ai/*ability schema round-trips throughwp_json_encode()and validates as JSON Schema, so non-clean schemas are caught in CI.Context
Discovered while exposing the
WordPress/aiabilities as MCP tools viamcp-adapter. A companion robustness issue is filed onWordPress/mcp-adapter(it should strip WordPress-only keys and guard against recursion regardless), but the schemas themselves should also be JSON-Schema clean. Happy to open a PR.