Create and register WordPress Abilities for Voyager Orbit — schemas, permissions, MCP exposure, AbilityBridge, Chat tool integration.
All abilities register on the wp_abilities_api_init hook. Data abilities go in src/Abilities.php, content generation abilities in .
src/Modules/ContentGeneration/abilities.phpadd_action('wp_abilities_api_init', function() {
wp_register_ability('voyager-orbit/my-ability', [
'label' => __('My Ability', 'voyager-orbit'),
'description' => __('Clear description of what this does and what it returns.', 'voyager-orbit'),
'category' => 'voyager-leads', // Must be pre-registered
'input_schema' => [
'type' => 'object',
'properties' => [
'param1' => [
'type' => 'string',
'description' => 'What this parameter does',
],
'per_page' => [
'type' => 'integer',
'default' => 20,
'minimum' => 1,
'maximum' => 100,
],
],
'additionalProperties' => false,
],
'output_schema' => [
'type' => 'object',
'properties' => [
'data' => ['type' => 'array'],
'total' => ['type' => 'integer'],
],
],
'execute_callback' => function (array $input = []): array {
// Use existing REST endpoints when possible
$request = new \WP_REST_Request('GET', '/voyager/v1/leads');
foreach ($input as $key => $value) {
$request->set_param($key, $value);
}
return rest_do_request($request)->get_data();
},
'permission_callback' => fn(): bool => current_user_can('manage_options'),
'meta' => [
'annotations' => [
'readonly' => true, // Does not modify state
'destructive' => false, // Does not delete data
'idempotent' => true, // Same input = same output
],
'show_in_rest' => true, // Discoverable via REST API
'mcp' => ['public' => true], // Exposed as MCP tool
],
]);
});
Categories register on wp_abilities_api_categories_init:
add_action('wp_abilities_api_categories_init', function() {
wp_register_ability_category('voyager-my-category', [
'label' => __('My Category', 'voyager-orbit'),
'description' => __('What this category groups.', 'voyager-orbit'),
]);
});
Existing categories:
voyager-leads — Lead data queriesvoyager-analytics — Reports and insightsvoyager-activity — Admin activity trackingvoyager-site-management — Health, plugins, configvoyager-reporting — Structured client reportsvoyager-publishing — Content CRUD operationsvoyager-media — Media uploadsvoyager-content — AI content generation (blocks)voyager-theme-content — Theme CPT contentvoyager-theme-design — Design tokens, accessibilityvoyager-content-utilities — Rewriting, translation, FAQvoyager-content-agents — Multi-step agent workflowsAny ability with 'mcp' => ['public' => true] in meta is automatically exposed as an MCP tool by the MCP Adapter plugin. No additional code needed.
The MCP Adapter converts:
The AbilityBridge module (src/Modules/AbilityBridge/) exposes all abilities via HMAC-authenticated REST endpoints:
GET /voyager/v1/abilities — List all abilities with schemasGET /voyager/v1/abilities/manifest — Lightweight manifest for cachingPOST /voyager/v1/abilities/execute — Execute by namePortal calls these endpoints with HMAC signatures to run abilities remotely.
To make an ability usable by the Chat module:
ToolExecutor::ALLOWED_ABILITIES in src/Modules/Chat/Services/ToolExecutor.phpwp_register_ability()AbilityExecutor::execute() with the allowlist checkFor abilities that call the AI Client:
'execute_callback' => function (array $input = []): array {
if (!function_exists('wp_ai_client_prompt')) {
return ['error' => 'AI provider not configured.'];
}
$schema = voyager_strict_schema([
'type' => 'object',
'properties' => [
'result' => ['type' => 'string'],
],
'required' => ['result'],
]);
$result = wp_ai_client_prompt($prompt)
->using_model_preference(voyager_content_model_preference())
->using_system_instruction($system)
->using_temperature(0.7)
->as_json_response($schema)
->generate_text();
if (is_wp_error($result)) {
return ['error' => $result->get_error_message()];
}
return json_decode($result, true) ?: ['error' => 'Invalid response'];
},
Important: Use voyager_strict_schema() to add additionalProperties: false recursively — required by Anthropic's structured output.
GET /wp-json/wp-abilities/v1/abilitieswp mcp-adapter serve tool list<tool_call> tagswp_abilities_api_init fires after initmcp.public = true in meta AND MCP Adapter plugin is activeadditionalProperties: false on all objects — use voyager_strict_schema()wp-includes/abilities-api.php (WordPress 6.9+)https://github.com/WordPress/mcp-adaptersrc/Abilities.php (data) + src/Modules/ContentGeneration/abilities.php (content)