WordPress 7.2 Abilities API Implementation: Schema per Custom AI Capabilities, Plugin Integration e REST Endpoint Exposure — Developer Blueprint

WordPress 7.2 Abilities API Implementation: Schema per Custom AI Capabilities, Plugin Integration e REST Endpoint Exposure — Developer Blueprint

La Abilities API di WordPress 7.2 rappresenta il framework nativo per esporre capacità applicative strutturate, machine-readable e automaticamente scopribili. A differenza degli hook tradizionali o dei custom post type, l’Abilities API fornisce un’interfaccia deterministica per agent AI, plugin terzi e sistemi MCP (Model Context Protocol), consentendo di registrare, validare ed eseguire operazioni con schemi JSON-LD precisi e callback di autorizzazione centralizzati.

Per publisher, SaaS e newsroom italiani che implementano Generative Engine Optimization (GEO) e integrazione di agentic content workflows, la capacità di esporre abilità personalizzate tramite REST Endpoint crea superfici di attacco per automazione, interoperabilità tra plugin e orchestrazione coordinata di processi editoriali. Questa guida tecnica descrive il ciclo di vita completo: registrazione di categorie, definizione di schemi semantici AI-ready, callback di sicurezza e test end-to-end di REST exposure.

Architettura Fondamentale: Abilities vs Hook Tradizionali

Un hook WordPress tradizionale è un evento o un filtro: esegue codice al verificarsi di un evento (es. save_post) o modifica un valore al passaggio. Manca di semantica strutturale: nessuno strumento esterno sa quali hook sono disponibili, quali parametri si aspettano, quali autorizzazioni sono richieste.

L’Abilities API rende le capacità del sito sia machine-readable che eseguibili, fornendo un registro standard per le azioni che il sito può eseguire. Un’ability è un’unità discreta di lavoro: ha un nome univoco (plugin-slug/action-name), una descrizione leggibile dall’LLM, schemi JSON Schema per input e output, callback di esecuzione e autorizzazione.

Il vantaggio strategico: fornisce una libreria standardizzata per scoprire e eseguire le capacità di WordPress, permettendo a strumenti AI esterni, agent MCP, dashboard amministrativi e plugin terzi di autoconfigurare le proprie operazioni senza hardcoding.

Ciclo di Registrazione: Categorie e Ability

Step 1: Registrazione della Categoria

Ogni ability appartiene a una categoria. La categoria organizza le abilità in spazi semantici (es. content-management, analytics, media-processing). Per aggiungere capacità personalizzate, è necessario prima registrare una categoria di abilità collegandosi a wp_abilities_api_categories_init. La funzione di registrazione accetta uno slug di categoria univoco e un array di metadati.

Implementation

add_action( 'wp_abilities_api_categories_init', function () {
    wp_register_ability_category(
        'ai-content-ops',
        array(
            'label'       => __( 'AI Content Operations', 'my-publisher' ),
            'description' => __( 'Generate, process, and orchestrate structured content via LLM providers.', 'my-publisher' ),
        )
    );
} );

Step 2: Registrazione dell’Ability con Schema

Per registrare un’ability personalizzata, chiama wp_register_ability() all’interno dell’hook wp_abilities_api_init, passando un nome in formato plugin-slug/ability-name e un array $args contenente almeno label, description, category, output_schema, execute_callback e permission_callback.

L’esempio seguente implementa un’ability per il restyling semantico di articoli tramite vision model Gemini:

add_action( 'wp_abilities_api_init', function () {
    wp_register_ability(
        'publisher/restyle-article-semantic',
        array(
            'label'              => __( 'Restyle Article via Vision Model', 'publisher-plugin' ),
            'description'        => __( 'Analyzes article structure via Gemini Vision API, identifies missing semantic sections (summary, entity mentions, call-to-action), and generates JSON-LD suggestions for GEO compliance.', 'publisher-plugin' ),
            'category'           => 'ai-content-ops',
            'input_schema'       => array(
                'type'       => 'object',
                'properties' => array(
                    'post_id' => array(
                        'type'        => 'integer',
                        'description' => 'The post ID to restyle.',
                    ),
                    'include_vision_analysis' => array(
                        'type'        => 'boolean',
                        'description' => 'Extract entities and visual semantics via Gemini 3.7.',
                        'default'     => true,
                    ),
                    'target_schema_types' => array(
                        'type'        => 'array',
                        'items'       => array( 'type' => 'string' ),
                        'description' => 'Desired schema.org types: e.g., ["NewsArticle", "FAQPage", "BreadcrumbList"].',
                    ),
                ),
                'required' => array( 'post_id' ),
            ),
            'output_schema'      => array(
                'type'       => 'object',
                'properties' => array(
                    'post_id'           => array(
                        'type'        => 'integer',
                        'description' => 'The processed post ID.',
                    ),
                    'semantic_sections' => array(
                        'type'        => 'object',
                        'description' => 'Identified semantic sections: title, summary, entities, faq, cta.',
                    ),
                    'json_ld_suggestions' => array(
                        'type'        => 'array',
                        'description' => 'Array of suggested JSON-LD blocks for AI readiness.',
                    ),
                    'execution_time_ms' => array(
                        'type'        => 'integer',
                        'description' => 'Latency in milliseconds.',
                    ),
                ),
                'required' => array( 'post_id', 'semantic_sections', 'json_ld_suggestions' ),
            ),
            'execute_callback'   => 'publisher_restyle_article_execute',
            'permission_callback' => 'publisher_restyle_article_permission',
            'meta'               => array(
                'show_in_rest'  => true,
                'annotations'   => array(
                    'readonly'      => false,
                    'destructive'   => false,
                    'idempotent'    => false,
                    'instructions'  => 'Transforms article semantic structure and validates compliance with GEO schema standards.',
                ),
            ),
        )
    );
} );

function publisher_restyle_article_execute( $input ) {
    $post_id = $input['post_id'] ?? 0;
    $post = get_post( $post_id );

    if ( ! $post ) {
        return new WP_Error(
            'ability_post_not_found',
            sprintf( 'Post %d not found.', $post_id )
        );
    }

    $start_time = microtime( true );

    // Chiama Gemini Vision API per analisi strutturale
    $vision_analysis = publisher_call_gemini_vision( $post );
    $semantic_sections = publisher_extract_semantic_sections( $vision_analysis );
    $json_ld_suggestions = publisher_generate_json_ld( $semantic_sections );

    $end_time = microtime( true );

    return array(
        'post_id'               => $post_id,
        'semantic_sections'     => $semantic_sections,
        'json_ld_suggestions'   => $json_ld_suggestions,
        'execution_time_ms'     => (int) ( ( $end_time - $start_time ) * 1000 ),
    );
}

function publisher_restyle_article_permission( $input ) {
    return current_user_can( 'edit_posts' ) ? true : new WP_Error(
        'rest_forbidden',
        __( 'You do not have permission to restyle articles.' ),
        array( 'status' => 403 )
    );
}

Schema Design per AI Readiness

Lo schema fornito per le capacità non è solo documentazione, ma il modo primario con cui gli agenti AI comprendono cosa fa la tua capacità e come usarla. Scrivilo come scriveresti documentazione per uno sviluppatore che non ha mai visto il tuo plugin.

Best Practice per Input Schema

  • Esplicita i tipi: Specifica integer, string, boolean, array per ogni parametro. Non affidarti al casting implicito.
  • Descrizioni su ogni proprietà: Includi descrizioni per ogni parametro. Gli agenti AI le usano per determinare quale parametro corrisponde a quale intento dell’utente. Un parametro denominato id senza descrizione è ambiguo; uno con descrizione “The post ID of the item to update” non lo è.
  • Marchia required vs optional: L’array required in JSON Schema è utilizzato dal registro per la validazione automatica. I parametri opzionali dovrebbero avere default sensati definiti.
  • Usa enum per valori vincolati: Se un parametro accetta solo un set fisso di valori (stati post, ordinamento), elencali.

Best Practice per Output Schema

  • Documenta la struttura di successo: quali chiavi sono garantite, quali sono opzionali.
  • Includi side effect nella descrizione dell’ability (es. “Crea un post bozza e innesca l’hook save_post“).
  • Ogni proprietà dello schema deve avere una description. Gli agenti AI leggono le descrizioni dello schema letteralmente — trattale come il contratto.

REST Endpoint Exposure e Autenticazione

L’esposizione REST è disabilitata per impostazione predefinita. Un plugin accetta per ability con meta.show_in_rest. Una volta abilitata, i client autenticati possono elencare le ability sotto /wp-json/wp-abilities/v1/abilities, recuperarne una per namespace e nome, e chiamare il suo endpoint /run.

// Scopri tutte le ability disponibili
GET /wp-json/wp-abilities/v1/abilities
Authorization: Bearer {token}

// Scopri una ability specifica
GET /wp-json/wp-abilities/v1/abilities/publisher/restyle-article-semantic
Authorization: Bearer {token}

// Esegui l'ability
POST /wp-json/wp-abilities/v1/abilities/publisher/restyle-article-semantic/run
Content-Type: application/json
Authorization: Bearer {token}

{
  "post_id": 42,
  "include_vision_analysis": true,
  "target_schema_types": ["NewsArticle", "FAQPage"]
}

Autenticazione: Application Passwords vs OAuth2

Gli endpoint REST delle Abilities utilizzano l’autenticazione standard di WordPress. L’autenticazione tramite cookie è disponibile per richieste same-origin. La documentazione ufficiale di REST consiglia le Application Passwords per accesso esterno e consente anche plugin di autenticazione personalizzati.

Per MCP bridge o agenti AI:

  • Application Passwords: Genera un token a lungo termine dall’admin di WordPress, con scope limitato. Adatto a service account persistenti.
  • OAuth 2.0: Se il publisher consente accesso delegato di terzi, implementa OAuth2 via plugin (OAuth2 Provider è mantenuto attivamente nel 2026).
  • JWT: Token temporanei e stateless per architetture headless; JWT Authentication for WP REST APIs è mantenuto nel 2026.

Plugin Integration Pattern: Interoperabilità Cross-Plugin

I plugin possono chiamarsi reciprocamente le ability registrate in modo sicuro, senza accoppiamento profondo o hook nascosti. Questo è il pattern fondamentale per workflow multi-stage in newsroom italiane.

Scenario: Content Triage Workflow

Supponiamo tre plugin:

  • publisher-seo: espone publisher-seo/analyze-keyphrases
  • publisher-fact-check: espone publisher-fact-check/validate-claims
  • publisher-orchestrator: chiama le due ability precedenti in sequenza
add_action( 'wp_abilities_api_init', function () {
    wp_register_ability(
        'publisher-orchestrator/content-quality-gate',
        array(
            'label'       => __( 'Content Quality Gate', 'publisher-orchestrator' ),
            'description' => __( 'Runs SEO analysis and fact-checking on a post draft. Halts if claims fail validation.', 'publisher-orchestrator' ),
            'category'    => 'content-workflow',
            'input_schema' => array(
                'type'       => 'object',
                'properties' => array(
                    'post_id' => array(
                        'type'        => 'integer',
                        'description' => 'Draft post to validate.',
                    ),
                ),
                'required' => array( 'post_id' ),
            ),
            'output_schema' => array(
                'type'       => 'object',
                'properties' => array(
                    'post_id'        => array( 'type' => 'integer' ),
                    'seo_analysis'   => array( 'type' => 'object' ),
                    'fact_check'     => array( 'type' => 'object' ),
                    'gate_status'    => array(
                        'type'        => 'string',
                        'enum'        => array( 'pass', 'fail', 'review' ),
                        'description' => 'Quality gate outcome.',
                    ),
                ),
            ),
            'execute_callback'    => 'publisher_orchestrator_quality_gate',
            'permission_callback' => function() {
                return current_user_can( 'edit_posts' );
            },
        )
    );
} );

function publisher_orchestrator_quality_gate( $input ) {
    $post_id = $input['post_id'];

    // Step 1: Chiama ability SEO
    $seo_ability = wp_get_ability( 'publisher-seo/analyze-keyphrases' );
    $seo_result = $seo_ability->execute( array( 'post_id' => $post_id ) );
    if ( is_wp_error( $seo_result ) ) {
        return $seo_result;
    }

    // Step 2: Chiama ability fact-check
    $fact_ability = wp_get_ability( 'publisher-fact-check/validate-claims' );
    $fact_result = $fact_ability->execute( array( 'post_id' => $post_id ) );
    if ( is_wp_error( $fact_result ) ) {
        return $fact_result;
    }

    // Step 3: Determina status gate
    $gate_status = ( $fact_result['failed_claims'] > 0 ) ? 'fail' : 'pass';

    return array(
        'post_id'      => $post_id,
        'seo_analysis' => $seo_result,
        'fact_check'   => $fact_result,
        'gate_status'  => $gate_status,
    );
}

Annotazioni: Controllo del Verbo HTTP e del Comportamento

Le annotazioni readonly, destructive, idempotent guidano il verbo HTTP sull’endpoint REST. Questo è critico per la sicurezza e per comunicare ai client il tipo di operazione.

  • readonly: true → GET (nessuna modifica di stato)
  • destructive: true → DELETE (rimuove dati permanentemente)
  • idempotent: true → PUT (esecuzioni ripetute = medesimo risultato)
  • Nessuna annotazione: POST (creazione o stato mutabile)
'meta' => array(
    'annotations' => array(
        'readonly'    => false,  // Modifica post
        'destructive' => false,  // Non cancella
        'idempotent'  => false,  // Può produrre risultati diversi
    ),
),

Schema Preparation per AI Client e MCP

WordPress 7.1 ha introdotto wp_prepare_json_schema_for_client(), una funzione che converte schema interni WordPress (con callback, required a livello di proprietà, etc.) in JSON Schema standard Draft 4 compatibile con AI tool, MCP adapter e frontend validator.

WordPress 7.1 aggiunge uno strato condiviso di preparazione JSON Schema che rende gli schemi REST, Abilities API e AI provider portabili per impostazione predefinita.

// Nel tuo REST endpoint o MCP bridge
$ability = wp_get_ability( 'publisher/restyle-article-semantic' );
$input_schema = $ability->get_input_schema();

// Prepara per AI client
$prepared_schema = wp_prepare_json_schema_for_client(
    $input_schema,
    array( 'profile' => 'draft-04' )
);

// Ora compatibile con Gemini, Claude, o agenti MCP

Mantieni lo schema canonico di WordPress per uso lato server; prepara solo una copia per i client. Questo evita che la validazione lato server perda i callback di cui ha bisogno.

Testing e Validazione End-to-End

Test di Autorizzazione

Testa che permission_callback nega correttamente accesso a utenti non autorizzati:

// Test: Utente subscriber non può eseguire
$user = wp_create_user( 'subscriber', 'pass', 'subscriber@test.local' );
wp_update_user_meta( $user, 'wp_user_level', 0 );

wp_set_current_user( $user );
$ability = wp_get_ability( 'publisher/restyle-article-semantic' );
$result = $ability->execute( array( 'post_id' => 42 ) );

assert( is_wp_error( $result ), 'Should deny subscriber.' );

Test di Validazione Input

JSON Schema del plugin valida input prima dell'esecuzione:

// Input non valido: post_id è string invece che integer
wp_set_current_user( 1 );
$ability = wp_get_ability( 'publisher/restyle-article-semantic' );
$result = $ability->execute( array( 'post_id' => '42' ) );

// WordPress valida automaticamente contro input_schema
assert( is_wp_error( $result ), 'Should fail type validation.' );

Test REST Endpoint

// Scopri ability via REST
$response = wp_remote_get(
    home_url( '/wp-json/wp-abilities/v1/abilities/publisher/restyle-article-semantic' ),
    array(
        'headers' => array(
            'Authorization' => 'Bearer ' . wp_create_nonce( 'wp_rest' ),
        ),
    )
);

assert( 200 === wp_remote_retrieve_response_code( $response ) );
$data = json_decode( wp_remote_retrieve_body( $response ), true );
assert( 'publisher/restyle-article-semantic' === $data['name'] );

Integrazione con GEO e Content Enrichment

Secondo l'approccio GEO Content Engineering, l'Abilities API abilita il Semantic Content Enrichment automatico. Le ability possono:

Il risultato: articoli nativamente AI-ready, visibili in AI Overviews e schema STRUCTURED_DATA conforme GEO.

Compliance e Sicurezza

  • Permission Callback Obbligatorio: Ogni ability richiede un callback di autorizzazione. Controlla il capability minimo sensato.
  • Input Validation: JSON Schema valida input automaticamente prima dell'esecuzione. Bad input non raggiunge mai il callback.
  • GDPR Compliance: Se un'ability accede a dati utente, documenta il trattamento nella descrizione e registra le esecuzioni per audit trail.
  • MCP Bridge Gating: WordPress core non espone automaticamente un endpoint MCP o manifest plugin specifico per provider. Un bridge deve autenticarsi a WordPress, selezionare le ability consentite, tradurre schemi, applicare i suoi limiti e mappare errori al client. Dovrebbe esporre meno operazioni di quante l'utente WordPress può eseguire, non ogni ability scoperta.

FAQ

Qual è la differenza tra un'Ability e un Custom Endpoint REST?

Un Custom Endpoint REST è una singola rotta HTTP con logica proprietaria. Un'Ability è una unità semantica di lavoro con schema, autorizzazione e annotatione strutturate. Un'Ability può essere esposta via REST, ma la sua vera forza è la scoperta e orchestrazione machine-readable: agenti AI, plugin terzi e MCP client sanno come usarla senza hardcoding.

Posso registrare un'Ability senza esporre REST (show_in_rest: false)?

Se nessun client esterno ha bisogno dell'ability, ometti show_in_rest e richiama l'ability internamente tramite wp_get_ability(). Questo è utile per operazioni interne che solo il core del plugin orchestrate, non pubbliche.

Come gestisco le dipendenze tra ability? (es. SEO + Fact-Check in sequenza)

Il Core fornisce registrazione, scoperta, validazione ed esecuzione. Non crea un planner di workflow da un campo depends_on personalizzato. Se più operazioni devono eseguirsi in un ordine fisso, implementa un'ability lato server che possiede la transazione o lascia che un livello di orchestrazione revisionato chiami ability separate. Questo è esattamente il pattern publisher-orchestrator/content-quality-gate mostrato sopra.

Qual è il modo migliore per versioning di un'Ability?

Non modificare direttamente un'ability registrata: crea una nuova ability con nome versioned (es. publisher/restyle-article-semantic-v2). Mantieni quella vecchia per backward compatibility. Aggiorna gradualmente i client verso la versione nuova. Questo evita breaking change negli orchestrator legacy che dipendono dalla v1.

Come integro MCP (Model Context Protocol) con le mie Ability?

Crea un bridge MCP che:

  1. Si autentica a WordPress via Application Password
  2. Scopre le ability tramite GET /wp-json/wp-abilities/v1/abilities
  3. Converti ogni schema tramite wp_prepare_json_schema_for_client( schema, 'draft-04' )
  4. Esponi come MCP Tool (uno per ability)
  5. Quando un LLM invoca un MCP Tool, chiama l'endpoint REST POST /wp-json/wp-abilities/v1/abilities/{name}/run

See WordPress 7.2 AI Client Deep Dive per l'implementazione completa.

Conclusion

La Abilities API di WordPress 7.2 trasforma il modo in cui i plugin si comunicano, agenti AI orchestrano editori e MCP bridge espongono capacità WordPress. Registrando ability con schemi JSON Schema precisi, callback di autorizzazione centralizzati e annotazioni semantiche, gli sviluppatori di newsroom italiane costruiscono workflow multi-stage deterministi, testabili e conforme GDPR.

La chiave: tratta gli schemi come contratti pubblici. Scrivili come se un LLM novizio dovesse usarli senza leggere il codice. Mantieni le canoniche lato server, prepara copie per client AI. Testa autorizzazione e validazione input end-to-end. Integra con GEO Content Engineering per garantire che i contenuti arricchiti sono nativamente AI-ready.

Le Ability API non sono un dettaglio tecnico — sono l'infrastruttura di base per il Generative Engine Optimization, l'automazione editoriale e il futuro decentralizzato di WordPress come application platform.

Related articles