{"id":565,"date":"2026-10-08T07:10:12","date_gmt":"2026-10-08T05:10:12","guid":{"rendered":"https:\/\/aipublisherwp.com\/blog\/wordpress-7-2-abilities-api-custom-ai-capabilities-rest-endpoint\/"},"modified":"2026-10-08T07:10:12","modified_gmt":"2026-10-08T05:10:12","slug":"wordpress-7-2-abilities-api-custom-ai-capabilities-rest-endpoint","status":"publish","type":"post","link":"https:\/\/aipublisherwp.com\/blog\/wordpress-7-2-abilities-api-custom-ai-capabilities-rest-endpoint\/","title":{"rendered":"WordPress 7.2 Abilities API Implementation: Schema per Custom AI Capabilities, Plugin Integration e REST Endpoint Exposure \u2014 Developer Blueprint"},"content":{"rendered":"<p>La <strong>Abilities API di WordPress 7.2<\/strong> rappresenta il framework nativo per esporre capacit\u00e0 applicative strutturate, machine-readable e automaticamente scopribili. A differenza degli hook tradizionali o dei custom post type, l&#8217;Abilities API fornisce un&#8217;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.<\/p>\n<p>Per publisher, SaaS e newsroom italiani che implementano <em>Generative Engine Optimization (GEO)<\/em> e integrazione di <em>agentic content workflows<\/em>, la capacit\u00e0 di esporre abilit\u00e0 personalizzate tramite REST Endpoint crea superfici di attacco per automazione, interoperabilit\u00e0 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.<\/p>\n<h2>Architettura Fondamentale: Abilities vs Hook Tradizionali<\/h2>\n<p>Un hook WordPress tradizionale \u00e8 un evento o un filtro: esegue codice al verificarsi di un evento (es. <code>save_post<\/code>) 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.<\/p>\n<p><cite>L&#8217;Abilities API rende le capacit\u00e0 del sito sia machine-readable che eseguibili, fornendo un registro standard per le azioni che il sito pu\u00f2 eseguire.<\/cite> Un&#8217;ability \u00e8 un&#8217;unit\u00e0 discreta di lavoro: ha un nome univoco (<code>plugin-slug\/action-name<\/code>), una descrizione leggibile dall&#8217;LLM, schemi JSON Schema per input e output, callback di esecuzione e autorizzazione.<\/p>\n<p>Il vantaggio strategico: <cite>fornisce una libreria standardizzata per scoprire e eseguire le capacit\u00e0 di WordPress<\/cite>, permettendo a strumenti AI esterni, agent MCP, dashboard amministrativi e plugin terzi di autoconfigurare le proprie operazioni senza hardcoding.<\/p>\n<h2>Ciclo di Registrazione: Categorie e Ability<\/h2>\n<h3>Step 1: Registrazione della Categoria<\/h3>\n<p>Ogni ability appartiene a una categoria. La categoria organizza le abilit\u00e0 in spazi semantici (es. <code>content-management<\/code>, <code>analytics<\/code>, <code>media-processing<\/code>). <cite>Per aggiungere capacit\u00e0 personalizzate, \u00e8 necessario prima registrare una categoria di abilit\u00e0 collegandosi a <code>wp_abilities_api_categories_init<\/code>. La funzione di registrazione accetta uno slug di categoria univoco e un array di metadati.<\/cite><\/p>\n<p>Implementazione:<\/p>\n<pre><code>add_action( 'wp_abilities_api_categories_init', function () {\n    wp_register_ability_category(\n        'ai-content-ops',\n        array(\n            'label'       =&gt; __( 'AI Content Operations', 'my-publisher' ),\n            'description' =&gt; __( 'Generate, process, and orchestrate structured content via LLM providers.', 'my-publisher' ),\n        )\n    );\n} );<\/code><\/pre>\n<h3>Step 2: Registrazione dell&#8217;Ability con Schema<\/h3>\n<p><cite>Per registrare un&#8217;ability personalizzata, chiama <code>wp_register_ability()<\/code> all&#8217;interno dell&#8217;hook <code>wp_abilities_api_init<\/code>, passando un nome in formato <code>plugin-slug\/ability-name<\/code> e un array <code>$args<\/code> contenente almeno label, description, category, output_schema, execute_callback e permission_callback.<\/cite><\/p>\n<p>L&#8217;esempio seguente implementa un&#8217;ability per il <strong>restyling semantico di articoli<\/strong> tramite vision model Gemini:<\/p>\n<pre><code>add_action( 'wp_abilities_api_init', function () {\n    wp_register_ability(\n        'publisher\/restyle-article-semantic',\n        array(\n            'label'              =&gt; __( 'Restyle Article via Vision Model', 'publisher-plugin' ),\n            'description'        =&gt; __( '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' ),\n            'category'           =&gt; 'ai-content-ops',\n            'input_schema'       =&gt; array(\n                'type'       =&gt; 'object',\n                'properties' =&gt; array(\n                    'post_id' =&gt; array(\n                        'type'        =&gt; 'integer',\n                        'description' =&gt; 'The post ID to restyle.',\n                    ),\n                    'include_vision_analysis' =&gt; array(\n                        'type'        =&gt; 'boolean',\n                        'description' =&gt; 'Extract entities and visual semantics via Gemini 3.7.',\n                        'default'     =&gt; true,\n                    ),\n                    'target_schema_types' =&gt; array(\n                        'type'        =&gt; 'array',\n                        'items'       =&gt; array( 'type' =&gt; 'string' ),\n                        'description' =&gt; 'Desired schema.org types: e.g., [\"NewsArticle\", \"FAQPage\", \"BreadcrumbList\"].',\n                    ),\n                ),\n                'required' =&gt; array( 'post_id' ),\n            ),\n            'output_schema'      =&gt; array(\n                'type'       =&gt; 'object',\n                'properties' =&gt; array(\n                    'post_id'           =&gt; array(\n                        'type'        =&gt; 'integer',\n                        'description' =&gt; 'The processed post ID.',\n                    ),\n                    'semantic_sections' =&gt; array(\n                        'type'        =&gt; 'object',\n                        'description' =&gt; 'Identified semantic sections: title, summary, entities, faq, cta.',\n                    ),\n                    'json_ld_suggestions' =&gt; array(\n                        'type'        =&gt; 'array',\n                        'description' =&gt; 'Array of suggested JSON-LD blocks for AI readiness.',\n                    ),\n                    'execution_time_ms' =&gt; array(\n                        'type'        =&gt; 'integer',\n                        'description' =&gt; 'Latency in milliseconds.',\n                    ),\n                ),\n                'required' =&gt; array( 'post_id', 'semantic_sections', 'json_ld_suggestions' ),\n            ),\n            'execute_callback'   =&gt; 'publisher_restyle_article_execute',\n            'permission_callback' =&gt; 'publisher_restyle_article_permission',\n            'meta'               =&gt; array(\n                'show_in_rest'  =&gt; true,\n                'annotations'   =&gt; array(\n                    'readonly'      =&gt; false,\n                    'destructive'   =&gt; false,\n                    'idempotent'    =&gt; false,\n                    'instructions'  =&gt; 'Transforms article semantic structure and validates compliance with GEO schema standards.',\n                ),\n            ),\n        )\n    );\n} );\n\nfunction publisher_restyle_article_execute( $input ) {\n    $post_id = $input['post_id'] ?? 0;\n    $post = get_post( $post_id );\n\n    if ( ! $post ) {\n        return new WP_Error(\n            'ability_post_not_found',\n            sprintf( 'Post %d not found.', $post_id )\n        );\n    }\n\n    $start_time = microtime( true );\n\n    \/\/ Chiama Gemini Vision API per analisi strutturale\n    $vision_analysis = publisher_call_gemini_vision( $post );\n    $semantic_sections = publisher_extract_semantic_sections( $vision_analysis );\n    $json_ld_suggestions = publisher_generate_json_ld( $semantic_sections );\n\n    $end_time = microtime( true );\n\n    return array(\n        'post_id'               =&gt; $post_id,\n        'semantic_sections'     =&gt; $semantic_sections,\n        'json_ld_suggestions'   =&gt; $json_ld_suggestions,\n        'execution_time_ms'     =&gt; (int) ( ( $end_time - $start_time ) * 1000 ),\n    );\n}\n\nfunction publisher_restyle_article_permission( $input ) {\n    return current_user_can( 'edit_posts' ) ? true : new WP_Error(\n        'rest_forbidden',\n        __( 'You do not have permission to restyle articles.' ),\n        array( 'status' =&gt; 403 )\n    );\n}<\/code><\/pre>\n<h2>Schema Design per AI Readiness<\/h2>\n<p><cite>Lo schema fornito per le capacit\u00e0 non \u00e8 solo documentazione, ma il modo primario con cui gli agenti AI comprendono cosa fa la tua capacit\u00e0 e come usarla. Scrivilo come scriveresti documentazione per uno sviluppatore che non ha mai visto il tuo plugin.<\/cite><\/p>\n<h3>Best Practice per Input Schema<\/h3>\n<ul>\n<li><strong>Esplicita i tipi:<\/strong> Specifica <code>integer<\/code>, <code>string<\/code>, <code>boolean<\/code>, <code>array<\/code> per ogni parametro. Non affidarti al casting implicito.<\/li>\n<li><strong>Descrizioni su ogni propriet\u00e0:<\/strong> <cite>Includi descrizioni per ogni parametro. Gli agenti AI le usano per determinare quale parametro corrisponde a quale intento dell&#8217;utente. Un parametro denominato <code>id<\/code> senza descrizione \u00e8 ambiguo; uno con descrizione &#8220;The post ID of the item to update&#8221; non lo \u00e8.<\/cite><\/li>\n<li><strong>Marchia required vs optional:<\/strong> <cite>L&#8217;array <code>required<\/code> in JSON Schema \u00e8 utilizzato dal registro per la validazione automatica. I parametri opzionali dovrebbero avere default sensati definiti.<\/cite><\/li>\n<li><strong>Usa enum per valori vincolati:<\/strong> Se un parametro accetta solo un set fisso di valori (stati post, ordinamento), elencali.<\/li>\n<\/ul>\n<h3>Best Practice per Output Schema<\/h3>\n<ul>\n<li>Documenta la struttura di successo: quali chiavi sono garantite, quali sono opzionali.<\/li>\n<li>Includi side effect nella descrizione dell&#8217;ability (es. &#8220;Crea un post bozza e innesca l&#8217;hook <code>save_post<\/code>&#8220;).<\/li>\n<li><cite>Ogni propriet\u00e0 dello schema deve avere una <code>description<\/code>. Gli agenti AI leggono le descrizioni dello schema letteralmente \u2014 trattale come il contratto.<\/cite><\/li>\n<\/ul>\n<h2>REST Endpoint Exposure e Autenticazione<\/h2>\n<p><cite>L&#8217;esposizione REST \u00e8 disabilitata per impostazione predefinita. Un plugin accetta per ability con <code>meta.show_in_rest<\/code>. Una volta abilitata, i client autenticati possono elencare le ability sotto <code>\/wp-json\/wp-abilities\/v1\/abilities<\/code>, recuperarne una per namespace e nome, e chiamare il suo endpoint <code>\/run<\/code>.<\/cite><\/p>\n<pre><code>\/\/ Scopri tutte le ability disponibili\nGET \/wp-json\/wp-abilities\/v1\/abilities\nAuthorization: Bearer {token}\n\n\/\/ Scopri una ability specifica\nGET \/wp-json\/wp-abilities\/v1\/abilities\/publisher\/restyle-article-semantic\nAuthorization: Bearer {token}\n\n\/\/ Esegui l'ability\nPOST \/wp-json\/wp-abilities\/v1\/abilities\/publisher\/restyle-article-semantic\/run\nContent-Type: application\/json\nAuthorization: Bearer {token}\n\n{\n  \"post_id\": 42,\n  \"include_vision_analysis\": true,\n  \"target_schema_types\": [\"NewsArticle\", \"FAQPage\"]\n}<\/code><\/pre>\n<h3>Autenticazione: Application Passwords vs OAuth2<\/h3>\n<p><cite>Gli endpoint REST delle Abilities utilizzano l&#8217;autenticazione standard di WordPress. L&#8217;autenticazione tramite cookie \u00e8 disponibile per richieste same-origin. La documentazione ufficiale di REST consiglia le Application Passwords per accesso esterno e consente anche plugin di autenticazione personalizzati.<\/cite><\/p>\n<p>Per MCP bridge o agenti AI:<\/p>\n<ul>\n<li><strong>Application Passwords:<\/strong> Genera un token a lungo termine dall&#8217;admin di WordPress, con scope limitato. Adatto a service account persistenti.<\/li>\n<li><strong>OAuth 2.0:<\/strong> Se il publisher consente accesso delegato di terzi, implementa OAuth2 via plugin (<code>OAuth2 Provider<\/code> \u00e8 mantenuto attivamente nel 2026).<\/li>\n<li><strong>JWT:<\/strong> Token temporanei e stateless per architetture headless; <code>JWT Authentication for WP REST APIs<\/code> \u00e8 mantenuto nel 2026.<\/li>\n<\/ul>\n<h2>Plugin Integration Pattern: Interoperabilit\u00e0 Cross-Plugin<\/h2>\n<p><cite>I plugin possono chiamarsi reciprocamente le ability registrate in modo sicuro, senza accoppiamento profondo o hook nascosti.<\/cite> Questo \u00e8 il pattern fondamentale per workflow multi-stage in newsroom italiane.<\/p>\n<h3>Scenario: Content Triage Workflow<\/h3>\n<p>Supponiamo tre plugin:<\/p>\n<ul>\n<li><code>publisher-seo<\/code>: espone <code>publisher-seo\/analyze-keyphrases<\/code><\/li>\n<li><code>publisher-fact-check<\/code>: espone <code>publisher-fact-check\/validate-claims<\/code><\/li>\n<li><code>publisher-orchestrator<\/code>: chiama le due ability precedenti in sequenza<\/li>\n<\/ul>\n<pre><code>add_action( 'wp_abilities_api_init', function () {\n    wp_register_ability(\n        'publisher-orchestrator\/content-quality-gate',\n        array(\n            'label'       =&gt; __( 'Content Quality Gate', 'publisher-orchestrator' ),\n            'description' =&gt; __( 'Runs SEO analysis and fact-checking on a post draft. Halts if claims fail validation.', 'publisher-orchestrator' ),\n            'category'    =&gt; 'content-workflow',\n            'input_schema' =&gt; array(\n                'type'       =&gt; 'object',\n                'properties' =&gt; array(\n                    'post_id' =&gt; array(\n                        'type'        =&gt; 'integer',\n                        'description' =&gt; 'Draft post to validate.',\n                    ),\n                ),\n                'required' =&gt; array( 'post_id' ),\n            ),\n            'output_schema' =&gt; array(\n                'type'       =&gt; 'object',\n                'properties' =&gt; array(\n                    'post_id'        =&gt; array( 'type' =&gt; 'integer' ),\n                    'seo_analysis'   =&gt; array( 'type' =&gt; 'object' ),\n                    'fact_check'     =&gt; array( 'type' =&gt; 'object' ),\n                    'gate_status'    =&gt; array(\n                        'type'        =&gt; 'string',\n                        'enum'        =&gt; array( 'pass', 'fail', 'review' ),\n                        'description' =&gt; 'Quality gate outcome.',\n                    ),\n                ),\n            ),\n            'execute_callback'    =&gt; 'publisher_orchestrator_quality_gate',\n            'permission_callback' =&gt; function() {\n                return current_user_can( 'edit_posts' );\n            },\n        )\n    );\n} );\n\nfunction publisher_orchestrator_quality_gate( $input ) {\n    $post_id = $input['post_id'];\n\n    \/\/ Step 1: Chiama ability SEO\n    $seo_ability = wp_get_ability( 'publisher-seo\/analyze-keyphrases' );\n    $seo_result = $seo_ability-&gt;execute( array( 'post_id' =&gt; $post_id ) );\n    if ( is_wp_error( $seo_result ) ) {\n        return $seo_result;\n    }\n\n    \/\/ Step 2: Chiama ability fact-check\n    $fact_ability = wp_get_ability( 'publisher-fact-check\/validate-claims' );\n    $fact_result = $fact_ability-&gt;execute( array( 'post_id' =&gt; $post_id ) );\n    if ( is_wp_error( $fact_result ) ) {\n        return $fact_result;\n    }\n\n    \/\/ Step 3: Determina status gate\n    $gate_status = ( $fact_result['failed_claims'] &gt; 0 ) ? 'fail' : 'pass';\n\n    return array(\n        'post_id'      =&gt; $post_id,\n        'seo_analysis' =&gt; $seo_result,\n        'fact_check'   =&gt; $fact_result,\n        'gate_status'  =&gt; $gate_status,\n    );\n}<\/code><\/pre>\n<h2>Annotazioni: Controllo del Verbo HTTP e del Comportamento<\/h2>\n<p><cite>Le annotazioni <code>readonly<\/code>, <code>destructive<\/code>, <code>idempotent<\/code> guidano il verbo HTTP sull&#8217;endpoint REST.<\/cite> Questo \u00e8 critico per la sicurezza e per comunicare ai client il tipo di operazione.<\/p>\n<ul>\n<li><strong>readonly: true<\/strong> \u2192 GET (nessuna modifica di stato)<\/li>\n<li><strong>destructive: true<\/strong> \u2192 DELETE (rimuove dati permanentemente)<\/li>\n<li><strong>idempotent: true<\/strong> \u2192 PUT (esecuzioni ripetute = medesimo risultato)<\/li>\n<li><strong>Nessuna annotazione:<\/strong> POST (creazione o stato mutabile)<\/li>\n<\/ul>\n<pre><code>'meta' =&gt; array(\n    'annotations' =&gt; array(\n        'readonly'    =&gt; false,  \/\/ Modifica post\n        'destructive' =&gt; false,  \/\/ Non cancella\n        'idempotent'  =&gt; false,  \/\/ Pu\u00f2 produrre risultati diversi\n    ),\n),<\/code><\/pre>\n<h2>Schema Preparation per AI Client e MCP<\/h2>\n<p>WordPress 7.1 ha introdotto <code>wp_prepare_json_schema_for_client()<\/code>, una funzione che converte schema interni WordPress (con callback, required a livello di propriet\u00e0, etc.) in JSON Schema standard Draft 4 compatibile con AI tool, MCP adapter e frontend validator.<\/p>\n<p><cite>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.<\/cite><\/p>\n<pre><code>\/\/ Nel tuo REST endpoint o MCP bridge\n$ability = wp_get_ability( 'publisher\/restyle-article-semantic' );\n$input_schema = $ability-&gt;get_input_schema();\n\n\/\/ Prepara per AI client\n$prepared_schema = wp_prepare_json_schema_for_client(\n    $input_schema,\n    array( 'profile' =&gt; 'draft-04' )\n);\n\n\/\/ Ora compatibile con Gemini, Claude, o agenti MCP<\/cite><\/pre>\n<p><cite>Mantieni lo schema canonico di WordPress per uso lato server; prepara solo una copia per i client.<\/cite> Questo evita che la validazione lato server perda i callback di cui ha bisogno.<\/p>\n<h2>Testing e Validazione End-to-End<\/h2>\n<h3>Test di Autorizzazione<\/h3>\n<p>Testa che <code>permission_callback<\/code> nega correttamente accesso a utenti non autorizzati:<\/p>\n<pre><code>\/\/ Test: Utente subscriber non pu\u00f2 eseguire\n$user = wp_create_user( 'subscriber', 'pass', 'subscriber@test.local' );\nwp_update_user_meta( $user, 'wp_user_level', 0 );\n\nwp_set_current_user( $user );\n$ability = wp_get_ability( 'publisher\/restyle-article-semantic' );\n$result = $ability-&gt;execute( array( 'post_id' =&gt; 42 ) );\n\nassert( is_wp_error( $result ), 'Should deny subscriber.' );<\/code><\/pre>\n<h3>Test di Validazione Input<\/h3>\n<p>JSON Schema del plugin valida input prima dell'esecuzione:<\/p>\n<pre><code>\/\/ Input non valido: post_id \u00e8 string invece che integer\nwp_set_current_user( 1 );\n$ability = wp_get_ability( 'publisher\/restyle-article-semantic' );\n$result = $ability-&gt;execute( array( 'post_id' =&gt; '42' ) );\n\n\/\/ WordPress valida automaticamente contro input_schema\nassert( is_wp_error( $result ), 'Should fail type validation.' );<\/code><\/pre>\n<h3>Test REST Endpoint<\/h3>\n<pre><code>\/\/ Scopri ability via REST\n$response = wp_remote_get(\n    home_url( '\/wp-json\/wp-abilities\/v1\/abilities\/publisher\/restyle-article-semantic' ),\n    array(\n        'headers' =&gt; array(\n            'Authorization' =&gt; 'Bearer ' . wp_create_nonce( 'wp_rest' ),\n        ),\n    )\n);\n\nassert( 200 === wp_remote_retrieve_response_code( $response ) );\n$data = json_decode( wp_remote_retrieve_body( $response ), true );\nassert( 'publisher\/restyle-article-semantic' === $data['name'] );<\/code><\/pre>\n<h2>Integrazione con GEO e Content Enrichment<\/h2>\n<p>Secondo l'<a href=\"https:\/\/aipublisherwp.com\/blog\/geo-content-engineering-modular-sections-faq-semantic-clarity\/\">approccio GEO Content Engineering<\/a>, l'Abilities API abilita il <em>Semantic Content Enrichment<\/em> automatico. Le ability possono:<\/p>\n<ul>\n<li><strong>Generare FAQ strutturate<\/strong> tramite <code>publisher\/generate-faq<\/code> e <strong>JSON-LD FAQPage<\/strong><\/li>\n<li><strong>Estendere Entity Disambiguation<\/strong> via Vision Models (vedi <a href=\"https:\/\/aipublisherwp.com\/blog\/schema-markup-2-0-json-ld-entity-disambiguation-knowledge-graph-audit\/\">Schema Markup 2.0 per AI Readiness<\/a>)<\/li>\n<li><strong>Orchestrare Fact-Checking Real-Time<\/strong> (integra con <a href=\"https:\/\/aipublisherwp.com\/blog\/real-time-fact-checking-ai-newsroom-claims-tracking-gdpr\/\">Real-Time Fact-Checking per AI Newsroom<\/a>)<\/li>\n<\/ul>\n<p>Il risultato: articoli nativamente AI-ready, visibili in AI Overviews e schema STRUCTURED_DATA conforme GEO.<\/p>\n<h2>Compliance e Sicurezza<\/h2>\n<ul>\n<li><strong>Permission Callback Obbligatorio:<\/strong> Ogni ability richiede un callback di autorizzazione. Controlla il capability minimo sensato.<\/li>\n<li><strong>Input Validation:<\/strong> JSON Schema valida input automaticamente prima dell'esecuzione. Bad input non raggiunge mai il callback.<\/li>\n<li><strong>GDPR Compliance:<\/strong> Se un'ability accede a dati utente, documenta il trattamento nella descrizione e registra le esecuzioni per audit trail.<\/li>\n<li><strong>MCP Bridge Gating:<\/strong> <cite>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\u00f2 eseguire, non ogni ability scoperta.<\/cite><\/li>\n<\/ul>\n<h2>FAQ<\/h2>\n<h3>Qual \u00e8 la differenza tra un'Ability e un Custom Endpoint REST?<\/h3>\n<p>Un Custom Endpoint REST \u00e8 una singola rotta HTTP con logica proprietaria. Un'Ability \u00e8 una <em>unit\u00e0 semantica<\/em> di lavoro con schema, autorizzazione e annotatione strutturate. Un'Ability <em>pu\u00f2<\/em> essere esposta via REST, ma la sua vera forza \u00e8 la scoperta e orchestrazione machine-readable: agenti AI, plugin terzi e MCP client sanno come usarla senza hardcoding.<\/p>\n<h3>Posso registrare un'Ability senza esporre REST (show_in_rest: false)?<\/h3>\n<p><cite>Se nessun client esterno ha bisogno dell'ability, ometti <code>show_in_rest<\/code> e richiama l'ability internamente tramite <code>wp_get_ability()<\/code>.<\/cite> Questo \u00e8 utile per operazioni interne che solo il core del plugin orchestrate, non pubbliche.<\/p>\n<h3>Come gestisco le dipendenze tra ability? (es. SEO + Fact-Check in sequenza)<\/h3>\n<p><cite>Il Core fornisce registrazione, scoperta, validazione ed esecuzione. Non crea un planner di workflow da un campo <code>depends_on<\/code> personalizzato. Se pi\u00f9 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.<\/cite> Questo \u00e8 esattamente il pattern <code>publisher-orchestrator\/content-quality-gate<\/code> mostrato sopra.<\/p>\n<h3>Qual \u00e8 il modo migliore per versioning di un'Ability?<\/h3>\n<p>Non modificare direttamente un'ability registrata: crea una nuova ability con nome versioned (es. <code>publisher\/restyle-article-semantic-v2<\/code>). 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.<\/p>\n<h3>Come integro MCP (Model Context Protocol) con le mie Ability?<\/h3>\n<p>Crea un bridge MCP che:<\/p>\n<ol>\n<li>Si autentica a WordPress via Application Password<\/li>\n<li>Scopre le ability tramite <code>GET \/wp-json\/wp-abilities\/v1\/abilities<\/code><\/li>\n<li>Converti ogni schema tramite <code>wp_prepare_json_schema_for_client( schema, 'draft-04' )<\/code><\/li>\n<li>Esponi come MCP Tool (uno per ability)<\/li>\n<li>Quando un LLM invoca un MCP Tool, chiama l'endpoint REST <code>POST \/wp-json\/wp-abilities\/v1\/abilities\/{name}\/run<\/code><\/li>\n<\/ol>\n<p>Vedi <a href=\"https:\/\/aipublisherwp.com\/blog\/wordpress-7-2-ai-client-provider-agnostic-credential-management-plugin-interoperability\/\">WordPress 7.2 AI Client Deep Dive<\/a> per l'implementazione completa.<\/p>\n<h2>Conclusione<\/h2>\n<p>La <strong>Abilities API di WordPress 7.2<\/strong> trasforma il modo in cui i plugin si comunicano, agenti AI orchestrano editori e MCP bridge espongono capacit\u00e0 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.<\/p>\n<p>La chiave: <strong>tratta gli schemi come contratti pubblici<\/strong>. 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 <a href=\"https:\/\/aipublisherwp.com\/blog\/geo-content-engineering-modular-sections-faq-semantic-clarity\/\">GEO Content Engineering<\/a> per garantire che i contenuti arricchiti sono nativamente AI-ready.<\/p>\n<p>Le Ability API non sono un dettaglio tecnico \u2014 sono l'infrastruttura di base per il <em>Generative Engine Optimization<\/em>, l'automazione editoriale e il futuro decentralizzato di WordPress come application platform.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Guida tecnica completa alla registrazione di Custom AI Capabilities in WordPress 7.2: schema design, REST endpoint exposure, plugin interoperability e compliance.<\/p>\n","protected":false},"author":1,"featured_media":566,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"WordPress 7.2 Abilities API: Custom Capabilities & REST Endpoint | Guide","_seopress_titles_desc":"Registra custom AI capabilities in WordPress 7.2 con schemi JSON-LD, REST exposure e plugin integration. Developer blueprint per GEO e agentic workflows.","_seopress_robots_index":"","footnotes":""},"categories":[7],"tags":[60,441,298,878,877],"class_list":["post-565","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress","tag-ai-integration","tag-plugin-development","tag-rest-api","tag-schema-design","tag-wordpress-abilities-api"],"_links":{"self":[{"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/posts\/565","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/comments?post=565"}],"version-history":[{"count":0,"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/posts\/565\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/media\/566"}],"wp:attachment":[{"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/media?parent=565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/categories?post=565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aipublisherwp.com\/blog\/wp-json\/wp\/v2\/tags?post=565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}