abilities-for-ai · v1.5 · Architecture
How an ability callactually executes.
From MCP Client to WordPress Core to your callback — every hop, every gate, every branch. Permission layers, schema validation, and error handling shown exactly where they fire.
Execution Flow · Sequence Diagram
abilities-for-ai · wp_get_ability() → $ability→execute() → callback
sequenceDiagram
Client
MCP Client
Adapter
MCP Adapter
WordPress
Core · WP 6.9+
Callback
Ability + Gates
tools/call {ability_name, input}
wp_get_ability(name)
$ability object
$ability→execute(input)
validate input vs input_schema
WP_Error if invalid · callback not invoked
alt
[ Validation fails ]
WP_Error · schema_violation
MCP error response
else
[ Validation passes ]
execute_callback(input)
abilities_for_ai_ability_enabled()
alt
[ Denied ]
WP_Error 403 · ability_disabled
else
[ Granted ]
result array
result
MCP response
Client
MCP Client
Adapter
MCP Adapter
WordPress
Core · WP 6.9+
Callback
Ability + Gates
Execution focus
alt / else frame
Dark: brand colours · Light: ink scale, amber accent only
Key execution mechanics
🔍
No wp_execute_ability()
Execution goes through the ability object. The Adapter retrieves it then calls execute directly — no global execute function exists.
wp_get_ability($name)→execute($input)
✓
Schema validation is automatic
WordPress Core validates input against input_schema before the callback is called. Invalid data never reaches your code.
WP_Error on failure · callback not called
⛔
Permission gate fires inside callback
The Registrar wraps every callback with an enable-check. The ability always registers — it returns WP_Error 403 at execution time if disabled.
WP_Error · code: ability_disabled · status: 403
🪝
Registration hook is critical
Abilities must register on wp_abilities_api_init. Any other hook silently fails — no error, no log.
add_action('wp_abilities_api_init', ...)
Two permission layers · resolution order
Layer 1 · Runs first · Before callback
WordPress Capability Check
The permission_callback fires before execution. Fails here — the ability never reaches your code.
current_user_can($capability)
then
Layer 2 · Inside callback · Runtime
Ability Enable / Disable Toggle
Registrar wraps your callback with an enable-check. Per-ability overrides win over module defaults. Read=ON, Write=ON, Delete=OFF by default.
abilities_for_ai_ability_enabled()
The ability always registers.The gate decides at runtime.
abilities-for-ai · helpers.php · Permission gating pattern · 2026