Spørsmålet et norsk utviklingsteam faktisk står i, er ikke om en språkmodell kan skrive WordPress-kode. Det er hvem som får utføre en handling på nettstedet, og hvordan tillatelsen lar seg gjennomgå av en kollega som ikke skrev koden. Abilities API svarer på nettopp det, og bare det: en plugin erklærer navngitte operasjoner med skjemaer, kjørecallback og tillatelsessjekk, og WordPress holder registeret.
Et register er ingen agentplattform. Kjernen leverer ingen MCP-server, ingen egne agenttokener, ingen hastighetsbegrensning og ingen revisjonslogg.
Til gjengjeld er dette ikke lenger et forslag på en veikart-side. Serversiden har vært en del av kjernen siden WordPress 6.9, og WordPress 7.0 la til abilities på klientsiden slik at JavaScript og blokkredigeringen leser det samme registeret. Klientsiden erstatter verken PHP-registeret eller tillatelsesmodellen bak det. Hooks, filtre, REST API og GraphQL fungerer som før. Det nye laget beskriver hva installasjonen kan gjøre, ikke hvilke data den har.
Hva er WordPress Abilities API?
Problemet med nåværende tilnærminger
WordPress REST API er kraftig, men ressursorientert. Det eksponerer endepunkter som /wp/v2/posts og /wc/v3/products, altså CRUD-operasjoner på dataobjekter. En KI-agent kan bruke disse endepunktene, men den må være forhåndsprogrammert til å vite hva hvert endepunkt gjør, hvilke parametere det aksepterer og hvordan flere kall skal kjedes sammen.
WPGraphQL forbedrer dette med fleksible spørringer, men deler den samme grunnleggende begrensningen: det beskriver data, ikke evner.
Vurder dette scenariet: du vil at en agent skal «skrive et blogginnlegg om vårens hagearbeid, optimalisere det for SEO, legge til et utvalgt bilde og planlegge publisering til neste tirsdag.» Med REST API må agenten:
- Kjenne
/wp/v2/posts-endepunktet og dets parametere - Vite at SEO-data ligger i et metafelt kontrollert av Yoast eller RankMath
- Vite hvordan media lastes opp via
/wp/v2/media - Kjenne datoformatet for planlegging
- Kjede disse kallene i riktig rekkefølge
Med Abilities API kan en plugin i stedet registrere smale operasjoner som content/create-draft eller media/attach-image. En autentisert integrasjon kan liste de abilities som faktisk er eksponert over REST, lese skjemaene deres og kalle riktig /run-endepunkt. Selve planleggingen og rekkefølgen mellom kallene er fortsatt kallerens ansvar, med mindre pluginen tilbyr én operasjon på høyere nivå som eier hele jobben.
Arkitekturoversikt
APIet består av fire deler. En kategori grupperer beslektede operasjoner. En ability bærer et unikt navnerom/ability-navn, en etikett, en beskrivelse, skjemaer og callbacks. Registeret lar WordPress-kode finne fram til abilities. REST-eksponering er en valgfri transport for autentiserte eksterne systemer.
Registreringen skjer på egne hooks, og tidspunktet er ikke likegyldig. Kategorier registreres på wp_abilities_api_categories_init med wp_register_ability_category(), abilities på wp_abilities_api_init med wp_register_ability(). Kjører du registreringen på en generisk plugin-hook i stedet, risikerer du å treffe før registrene er klare, og da forsvinner abilityen stille.
Den offisielle håndboken dokumenterer serversidens API for WordPress 6.9 og nyere.
Oppdagelse og kjøring over REST
REST-eksponering er avslått som standard. En plugin melder seg på per ability med meta.show_in_rest. Når det er gjort, kan autentiserte klienter liste abilities under /wp-json/wp-abilities/v1/abilities, hente én enkelt etter navnerom og navn, og kalle dens /run-endepunkt. Metoden følger av annotasjonene og oppførselen til den enkelte abilityen.
Det finnes ikke noe samlet manifestendepunkt som beskriver hele nettstedet i ett kall, og APIet deler ikke ut egne tokener til agenter. Autentiseringen er den vanlige for WordPress REST.
Å se en ability i listen er dessuten ikke det samme som å ha lov til å kjøre den. WordPress evaluerer permission_callback for den innloggede brukeren ved hvert kall. En intern ability som bare annen PHP-kode bruker, kan la show_in_rest stå usann. En destruktiv operasjon bør ha en snevrere tillatelsescallback og kontroller i tillegg.
Hvordan et KI- eller MCP-lag kobles på
MCP-broen er integrasjonsarbeid
Anthropics Model Context Protocol definerer hvordan agenter oppdager og bruker verktøy. Abilities API leverer råmaterialet en slik oversettelse trenger: navn, beskrivelse og JSON Schema for inn- og utdata. Det er nyttig, men kjernen gjør ikke nettstedet ditt til en MCP-server av seg selv.
En bro må autentisere seg mot WordPress, velge ut hvilke abilities som skal videreformidles, oversette skjemaene, håndheve sine egne grenser og oversette feil tilbake til klienten. Tommelfingerregelen er å eksponere færre operasjoner enn WordPress-brukeren teknisk kan utføre, ikke alle som blir oppdaget. En supportassistent kan for eksempel få ett skrivebeskyttet produktoppslag og én operasjon som oppretter et saksutkast, mens refusjoner, sletting av brukere og innstillingsendringer holdes utenfor. Den avgrensningen er langt lettere å gjennomgå enn å gi én generell agent en administratorkonto.
Verktøyskjemaer for ChatGPT og Claude
Det samme gjelder leverandørspesifikke formater. input_schema lar seg mappe rimelig direkte til parameterdefinisjonen i et verktøykall, men oversettelsen skjer i integrasjonslaget ditt. Kjernen publiserer verken en plugin-spesifikasjon for OpenAI eller en ferdig verktøyliste for Claude, og et nettsted blir ikke automatisk oppdagbart bare fordi noen abilities er registrert.
Praktiske bruksområder
Arbeidsflyter for innholdsoppretting
Det mest umiddelbare bruksområdet er intelligent innholdsoppretting. I stedet for at en modell genererer rå tekst som et menneske limer inn i WordPress, kjører orkestreringslaget hele kjeden. Hvert trinn nedenfor er et separat kall som kalleren selv setter i rekkefølge:
Bruker: "Lag en omfattende guide om biologisk skadedyrbekjempelse for hagebloggen vår"
Orkestrering:
1. kall: research_topics → finner trendende undertemaer og konkurransehuller
2. kall: generate_content → lager artikkel med overskrifter og bildereferanser
3. kall: optimize_seo → legger til metabeskrivelse, fokusnøkkelord, interne lenker
4. kall: generate_featured_image → oppretter hero-bilde
5. kall: create_draft → lagrer som utkast med alle metadata
6. kall: notify_editor → sender gjennomgangsvarsel til redaksjonen
Navnene her er ikke noe kjernen leverer. Hver operasjon må registreres av en plugin med eget skjema og egen tillatelsescallback, og de kan godt komme fra ulike plugins. Det Abilities API bidrar med, er at alle seks beskriver seg selv på samme måte.
WooCommerce-butikkadministrasjon
For e-handelssider er listen over operasjoner som er verdt å pakke inn som abilities, ganske lang:
- Lagerstyring: overvåke lagernivåer, generere bestillingsforslag, oppdatere mengder
- Prisoptimalisering: analysere konkurrentpriser, foreslå justeringer, anvende masseendringer
- Produktbeskrivelser: generere og oppdatere beskrivelser basert på produktattributter og SEO-mål
- Kundeservice: behandle refusjoner, oppdatere ordrestatus, generere fraktetiketter
- Salgsanalyse: generere rapporter, identifisere trender, foreslå kampanjer
Legg merke til at punktene har svært ulik risikoprofil. Et salgssammendrag kan trygt eksponeres for en tjenestekonto. En refusjon bør ikke ha show_in_rest slått på før prosjektet har bestemt hvordan godkjenning skal fungere.
SEO-automatisering
SEO-oppgaver som tidligere krevde manuelt arbeid eller separate verktøy, egner seg godt som navngitte operasjoner:
analyze_page_seo, returnerer poengsum, manglende metatagger og nøkkelordtetthetsuggest_internal_links, finner relatert innhold for krysslenkingcheck_broken_links, skanner etter 404-er og foreslår erstatningergenerate_schema_markup, oppretter JSON-LD strukturerte dataoptimize_images, komprimerer og legger til alt-tekstaudit_content_freshness, markerer utdatert innhold for gjennomgang
Alle seks er lesende eller lett reverserbare, og det er nettopp derfor de er et godt startpunkt: en revisjon som bare rapporterer, trenger ingen godkjenningsflyt.
Implementere egendefinerte abilities i pluginen din
Grunnleggende registrering
En ability trenger et unikt navn, en kategori, lesbar metadata, skjemaer, en kjørecallback og en tillatelsescallback. Registrer kategorien først.
add_action( 'wp_abilities_api_categories_init', function () {
wp_register_ability_category(
'redaksjon',
array(
'label' => __( 'Redaksjon', 'wppoland' ),
'description' => __( 'Operasjoner for redaksjonelt arbeid.', 'wppoland' ),
)
);
} );
add_action( 'wp_abilities_api_init', function () {
wp_register_ability(
'wppoland/finn-utdaterte-artikler',
array(
'label' => __( 'Finn utdaterte artikler', 'wppoland' ),
'description' => __( 'Lister publiserte innlegg uendret siden en gitt tidsgrense.', 'wppoland' ),
'category' => 'redaksjon',
'input_schema' => array(
'type' => 'object',
'required' => array( 'eldre_enn_dager' ),
'properties' => array(
'eldre_enn_dager' => array(
'type' => 'integer',
'minimum' => 30,
'description' => 'Dager siden siste endring.',
),
'kategori_slug' => array(
'type' => 'string',
'description' => 'Begrens til én kategori.',
),
),
),
'output_schema' => array(
'type' => 'object',
'properties' => array(
'artikler' => array(
'type' => 'array',
'items' => array(
'type' => 'object',
'properties' => array(
'id' => array( 'type' => 'integer' ),
'tittel' => array( 'type' => 'string' ),
'sist_endret' => array( 'type' => 'string', 'format' => 'date-time' ),
),
),
),
'antall_treff' => array( 'type' => 'integer' ),
),
),
'execute_callback' => 'wppoland_finn_utdaterte_artikler',
'permission_callback' => function () {
return current_user_can( 'edit_others_posts' );
},
'meta' => array(
'show_in_rest' => false,
),
)
);
} );
To valg er verdt å stoppe ved. show_in_rest står usann, så lenge ingen ekstern klient trenger operasjonen kalles den fra PHP med wp_get_ability(). Og tillatelsen er edit_others_posts, ikke edit_posts, fordi svaret krysser forfattergrenser: en skribent som bare kan redigere egne innlegg, trenger ikke et kart over hele arkivet.
Komposisjon er kallerens ansvar
Kjernen tilbyr registrering, oppdagelse, validering og kjøring. Den tolker ikke et depends_on-felt og bygger ingen arbeidsflytplanlegger. Skal flere operasjoner kjøres i fast rekkefølge, har du to reelle valg: én ability på serversiden som eier hele transaksjonen, eller et orkestreringslag du selv har gjennomgått.
Serversidevarianten er tryggest når endringene henger sammen. Én callback kan validere hele inputen, stoppe ved første feil og returnere ett strukturert resultat. Komposisjon i kallerleddet fungerer greit for uavhengige leseoperasjoner, men da må kalleren håndtere delvis feil og nye forsøk på egen hånd.
Legg driftskontrollene inn eksplisitt
Ikke bygg sikkerheten på en mellomvare-hook som ikke finnes. Domenevalidering hører hjemme i selve kjørecallbacken. Hastighetsbegrensning legges i gateway, omvendt proxy eller applikasjonslaget. Revisjonsdata skrives der prosjektet faktisk har lov til å oppbevare dem.
Hva WordPress 7.1 legger til
WordPress 7.1 kommer 19. august 2026, og for dette APIet handler endringene om to spørsmål: hvordan en ability erklærer at den er ment for omverdenen, og hvordan kode henter ut et utvalg fra registeret.
Erklæringen er en ny nøkkel, public, i meta-arrayen ved registrering. Den erstatter ingenting. Utviklernotatet fra 4. august sier det rett ut: «Channel-specific settings take precedence over the general public setting.» Kanalspesifikke innstillinger går altså foran den generelle, show_in_rest består uendret og vinner ved konflikt, og oppslaget i kjernen er nøyaktig dette:
$show_in_rest = $meta['show_in_rest'] ?? $meta['public'] ?? false;
En registrering med det nye flagget ser slik ut:
wp_register_ability(
'my-plugin/export-users',
array(
'label' => __( 'Export users', 'my-plugin' ),
'description' => __( 'Exports user data as CSV.', 'my-plugin' ),
'category' => 'data-export',
'execute_callback' => 'my_plugin_export_users',
'permission_callback' => function (): bool {
return current_user_can( 'export' );
},
'meta' => array(
'public' => true,
),
)
);
Les public som en hensiktserklæring og ingenting mer. Den sier at abilityen er ment å kunne nås av eksterne klienter, enten det er REST API, en MCP-adapter eller en KI-agent, ikke at kjernen nå leverer noen av dem. Kjernen har fortsatt ingen MCP-server, ingen agentspesifikke OAuth-scopes, ingen hastighetsbegrensning, ingen revisjonslogg og ingen godkjenningskø. Flagget flytter ikke en eneste av de postene fra prosjektets ansvar til kjernens.
Den andre endringen er at wp_get_abilities() tar imot et valgfritt $args-array med category, namespace, meta, item_include_callback og result_callback. Før 7.1 måtte den som trengte et utvalg, hente hele registeret og sile det selv med array_filter(). Vilkårene kombineres strengt: «Conditions are combined using AND logic. An ability must satisfy every supplied argument to be included.» Alle oppgitte argumenter må være oppfylt samtidig.
Notatet fra 5. august presiserer også at filtrering styrer hva som kommer tilbake ved oppdagelse, ikke hvem som får kjøre en ability. Det avgjør permission_callback som før. To nye filtre, wp_get_abilities_item_include og wp_get_abilities_result, lar annen kode gripe inn i henholdsvis utvalget og resultatet, og rest_abilities_collection_params utvider skjemaet for kolleksjonsargumentene i REST.
Sikkerhetshensyn for ekstern tilgang
Autentisering og autorisasjon
REST-endepunktene for abilities bruker WordPress sin egen REST-autentisering: informasjonskapsler for kall fra samme opphav, applikasjonspassord for eksterne systemer, eventuelt en egen autentiseringsplugin.
Autentisering svarer på hvem kalleren er. permission_callback svarer på om nettopp den brukeren får kjøre nettopp den operasjonen. Begge sjekkene må stå. Et delt administratorpassord river ned hele poenget med en smal kontrakt.
REST-synlighet er den tredje grensen. En registrert ability forblir intern så lenge show_in_rest er usann, så behandle det flagget som et bevisst valg i kodegjennomgangen.
Godkjenning for risikofylte endringer
Kjernen har ingen generell godkjenningskø for abilities. Skal en refusjon, en sletting eller en innstillingsendring bekreftes av et menneske, bygges den køen i domenelogikken. Et vanlig mønster er at abilityen oppretter en ventende forespørsel som en autorisert bruker godkjenner gjennom en egen adminhandling.
Hold godkjenning og kjøring adskilt. Godkjenningsposten bør identifisere den foreslåtte endringen, hvem som godkjente, når godkjenningen utløper og en sjekksum av nøyaktig den inputen som ble godkjent. Gjenbruk på endret input åpner akkurat det hullet ordningen skulle lukke.
Revisjonsspor
APIet fører ingen fullstendig revisjonslogg for deg. Bestem selv hva som må registreres for operasjoner som er åpne for eksterne systemer:
- autentisert WordPress-bruker eller tjenestekonto
- ability-navn og korrelasjons-ID for forespørselen
- resultatkategori og varighet
- referanse til godkjenning ved følsomme endringer
- tidsstempel og relevant applikasjonsversjon
Unngå å logge hemmeligheter, hele prompter eller personopplysninger du ikke trenger. Oppbevaringstid og tilgang trenger en eier, ikke bare en databasetabell.
Inputsanitisering
Abilities API validerer input mot det deklarerte JSON-skjemaet før kjøring. Skjemavalidering sjekker form, ikke trygghet: en streng kan bestå valideringen og likevel være farlig i en SQL-spørring, i HTML eller i et filnavn. Bruk WordPress sine sanitiserings- og escaping-funksjoner for den faktiske konteksten (sanitize_text_field(), wp_kses_post()), og forberedte spørringer der de hører hjemme.
Sammenligning med eksisterende tilnærminger
REST API vs. Abilities API
| Egenskap | REST API | Abilities API |
|---|---|---|
| Fokus | Dataressurser (CRUD) | Navngitte operasjoner |
| Oppdagelse | Ruteindeks og endepunktskjemaer | Ability-liste med etiketter og JSON Schema |
| Ekstern tilgang | Følger av ruteregistrering | Opt-in med show_in_rest |
| Autorisasjon | Tillatelsescallback per rute | Tillatelsescallback per ability |
| Autentisering | WordPress REST-metoder | De samme WordPress REST-metodene |
| Hastighetsbegrensning | Prosjekt eller infrastruktur | Prosjekt eller infrastruktur |
| Revisjon | Egen implementering | Egen implementering |
WPGraphQL vs. Abilities API
WPGraphQL utmerker seg i fleksibel dataspørring, der klienter ber om nøyaktig de dataene de trenger i én forespørsel. Abilities API er ikke en erstatning. Abilities kan bruke GraphQL internt for datahenting mens de eksponerer et grensesnitt på høyere nivå.
Enkelt sagt: GraphQL svarer på «hvilke data har du?» mens Abilities API svarer på «hva kan du gjøre?»
Når bruke hva
- REST API: server-til-server-integrasjoner, mobilapper, tradisjonell frontend-konsumering
- WPGraphQL: kompleks datahenting, headless frontender, Jamstack-arkitekturer
- Abilities API: agentintegrasjon, automatiserte arbeidsflyter, oppdagelse av operasjoner
Fremtiden for KI-drevne WordPress-arbeidsflyter
Avsnittene under er forventninger om retning, ikke funksjonalitet som finnes i kjernen i dag.
Multi-agentorkestrering og ability-bundles
Det er rimelig å vente at flere spesialiserte agenter etter hvert samarbeider om WordPress-oppgaver: én for innhold, én for SEO, én for gjennomgang. Abilities API kan bli den delte kontrakten de koordinerer gjennom, men selve koordineringen ligger utenfor APIet.
Parallelt kan plugin-økosystemet få ability-bundles, altså plugins som primært eksisterer for å eksponere operasjoner. En plugin uten synlig grensesnitt, men med et tyvetalls godt beskrevne SEO-abilities, gir mening i en slik verden. Verdien flytter seg fra menneskerettede skjermbilder til maskinlesbare kontrakter. Forutsetningen er at hver operasjon er smal nok til at noen faktisk klarer å gjennomgå den.
Integrasjon med eksterne KI-tjenester
Det finnes ingen invoke_external_ability() i APIet. WordPress kan selvsagt kalle en ekstern tjeneste med HTTP API og pakke det kallet inn i sin egen ability, men da eier pluginen alt det vanskelige: nøkler, tidsavbrudd, nye forsøk, kostnadskontroll og validering av svaret.
Hold det eksterne kallet bak en smal domeneoperasjon. En ability som heter media/opprett-godkjent-variant er lettere å gjennomgå enn et generelt promptrelé som tar imot vilkårlige instruksjoner og skriver resultatet rett inn i postmeta.
Slik tester du en ability mot ekte innhold
Skjemavalideringen er allerede WordPress sitt ansvar, og det stryker den mest fristende testen fra listen: at ugyldig input blir avvist. Operasjoner velter sjelden på ugyldig input. De velter på innhold som er gyldig og likevel uventet.
Ta et redaksjonelt arkiv av typen mange norske nettsteder sitter på etter et tiår eller to: forfattere som har sluttet og fått kontoen deaktivert, kategorier slått sammen under en migrering, tidsstempler fra begge sider av omstillingen mellom sommertid og vintertid i Europe/Oslo. En handler skrevet mot tjue testinnlegg møter her tre situasjoner den aldri har sett: tomt resultatsett, innlegg uten gyldig forfatter-ID, og et datofilter som forskyver seg en time.
Den første testen verdt å skrive er derfor ikke en feiltest, men en tomtest. Et tomt treff må se ut som et tomt treff i output_schema. Ikke null, ikke false, ikke en WP_Error mottakeren må gjette betydningen av:
public function test_tomt_arkiv_gir_gyldig_struktur(): void {
$ability = wp_get_ability( 'wppoland/finn-utdaterte-artikler' );
$resultat = $ability->execute( array( 'eldre_enn_dager' => 3650 ) );
$this->assertSame( array(), $resultat['artikler'] );
$this->assertSame( 0, $resultat['antall_treff'] );
}
Den andre testen gjelder hvem som spør. Sett gjeldende bruker til en rolle som bare eier egne innlegg, og bekreft at kravet om edit_others_posts stopper kallet før kjørecallbacken kjører i det hele tatt. På et nettsted med eksterne bidragsytere er skillet hele forskjellen mellom oversikt og lekkasje.
Kjør så handleren mot en kopi av produksjonsinnholdet før du vurderer show_in_rest. Æ, ø og å i titler og slugger, bokmål og nynorsk om hverandre i samme arkiv, og innlegg med tomme metafelt avdekker flere kontraktbrudd på en formiddag enn en syntetisk testdatabase gjør på en uke.
Kom i gang
Kjører du WordPress 6.9 eller nyere, har du APIet allerede:
- Velg én operasjon. Start med en liten, skrivebeskyttet ability
- Registrer kategorien. Bruk
wp_abilities_api_categories_init - Registrer abilityen. Bruk
wp_register_ability()påwp_abilities_api_init - Beskriv skjemaene. Definer inn- og utdata med JSON Schema
- Test tillatelsene. Prøv med både autorisert og uautorisert WordPress-bruker
- Hold REST privat som standard. Slå på
show_in_restførst når en reell ekstern konsument finnes - Bygg det som mangler. Hastighetsbegrensning, revisjonsdata og godkjenning tilhører prosjektarkitekturen
Den praktiske gevinsten er en ensartet kontrakt mellom WordPress-komponenter og ekstern automatisering, og den er nyttig selv uten en agent i bildet: plugins kan finne navngitte operasjoner, lese skjemaene og kalle dem gjennom det samme registeret. Følg gjerne WordPress-utviklingspraksisene vi bruker på wppoland.com.
For WordPress-vedlikehold og utviklingshjelp: send WordPress-versjon, pluginliste, ønsket operasjon og hvem kalleren er via kontaktsiden.
Kontrollert mot den offisielle håndboken for WordPress Abilities API og utviklernotatene for WordPress 7.0 og 7.1, 9. august 2026.





