Custom abilities
Abilities are operations defined with WordPress's Abilities API. Registering yours through VX gives it VX's shared settings: the administrator permission check, a category, and correct MCP exposure metadata. It then appears on the Abilities tab, where you choose whether assistants may use it.
php
add_action( 'vxframework/abilities/register', function ( string $registry ) {
$registry::register( 'my-plugin/count-bookings', [
'label' => 'Count bookings',
'description' => 'Returns the number of confirmed bookings for a Class. Read-only.',
'input_schema' => [
'type' => 'object',
'properties' => [ 'class_id' => [ 'type' => 'integer' ] ],
'required' => [ 'class_id' ],
'additionalProperties' => false,
],
'output_schema' => [ 'type' => 'object' ],
'execute_callback' => fn( array $input ) => [ 'ok' => true, 'count' => my_count_bookings( $input['class_id'] ) ],
'meta' => [ 'mode' => 'read', 'mcp' => [ 'public' => false ] ],
] );
} );Run it from the command line to test:
bash
wp vx-framework abilities run my-plugin/count-bookings --input='{"class_id":123}' --user=adminWrite the description for an AI assistant: say what it does, what it returns, and whether it changes anything. The assistant decides when to call it based on that text.
Things VX doesn't do for you
- Undo and activity logging come from VX's own write abilities. A custom write isn't recorded in the activity log unless you record it yourself.
- Exposure is off. Leave
meta.mcp.publicatfalseand turn the ability on from the Abilities tab. Don't rely onmeta.public: a separately installed MCP Adapter plugin could publish it outside VX's settings.
Technical details for LLMs
vxframework/abilities/registerpasses the class nameVxFramework\Modules\Abilities\Registry; call$registry::register( $name, $args ), a wrapper overwp_register_ability()that appliesprepare_args():manage_optionspermission floor (unless you passpermission_callback), normalizedmeta(mode,domain,tier,show_in_rest,mcp.publicpinned to false when omitted,annotations), category from domain, and for writes the shared description suffix and config lock.- Return
[ 'ok' => false, 'code', 'message' ]for refusals; over MCP they surface as tool errors. - Test:
wp vx-framework abilities list,wp vx-framework abilities run <name> --input=<json>,wp vx-framework abilities mcp. - Abilities under
vx-framework/are treated as VX's own by the exposure picker; use your own namespace.