Skip to content

Default abilities fail to register: wp_abilities_api_init hook fires before adapter initializes #117

@mdjwel

Description

@mdjwel

Bug Description

The default MCP adapter abilities (mcp-adapter/discover-abilities, mcp-adapter/get-ability-info, mcp-adapter/execute-ability) fail to register because the ability registration hooks are added too late.

Expected Behavior

When the plugin loads, the default abilities should register successfully via the wp_abilities_api_init hook.

Actual Behavior

The abilities are NOT registered because:

  1. McpAdapter::instance() defers initialization to rest_api_init (line 64)
  2. maybe_create_default_server() is called during init() which runs on rest_api_init
  3. But wp_abilities_api_init fires during the init hook (via WP_Abilities_Registry::get_instance())
  4. Since rest_api_init fires AFTER init, the add_action('wp_abilities_api_init', ...) calls are too late

Error in Debug Log

[ERROR] WordPress ability 'mcp-adapter/discover-abilities' does not exist.
[ERROR] WordPress ability 'mcp-adapter/get-ability-info' does not exist.
[ERROR] WordPress ability 'mcp-adapter/execute-ability' does not exist.

Root Cause

In includes/Core/McpAdapter.php, the instance() method schedules initialization on rest_api_init:

add_action( 'rest_api_init', array( self::$instance, 'init' ), 15 );

But the wp_abilities_api_init hook fires during init, which happens BEFORE rest_api_init.

Proposed Fix

Move the ability registration hooks out of maybe_create_default_server() and into a new method register_ability_hooks() that's called immediately during instance():

public static function instance(): self {
    if ( ! isset( self::$instance ) ) {
        self::$instance = new self();

        // Register ability hooks IMMEDIATELY so they fire before wp_abilities_api_init
        self::$instance->register_ability_hooks();

        if ( defined( 'WP_CLI' ) && constant( 'WP_CLI' ) ) {
            add_action( 'init', array( self::$instance, 'init' ), 20 );
        } else {
            add_action( 'rest_api_init', array( self::$instance, 'init' ), 15 );
        }
    }
    return self::$instance;
}

private function register_ability_hooks(): void {
    if ( ! apply_filters( 'mcp_adapter_create_default_server', true ) ) {
        return;
    }
    add_action( 'wp_abilities_api_categories_init', array( $this, 'register_default_category' ) );
    add_action( 'wp_abilities_api_init', array( $this, 'register_default_abilities' ) );
}

Environment

  • WordPress: 6.9.0
  • MCP Adapter: 0.4.1
  • PHP: 7.4+

Steps to Reproduce

  1. Install MCP Adapter plugin v0.4.1
  2. Activate the plugin
  3. Make a REST API request to /wp-json/mcp/mcp-adapter-default-server
  4. Check wp-content/debug.log for errors about missing abilities

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions