Generated banner for Wp Abilities API
Generated logo for Wp Abilities API

Wp Abilities API

WordPressOfficialPublished by WordPress

  • Skill
  • Tool integration
  • Software development
  • GPL-2.0-or-later
  • No issues found

From the author

Use when working with the WordPress Abilities API (wp_register_ability, wp_register_ability_category, /wp-json/wp-abilities/v1/*, @wordpress/abilities) including defining abilities, categories, meta, REST exposure, and permissions checks for clients.
— the description by WordPress

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to working with the WordPress Abilities API. It covers the registration of abilities and categories in PHP, exposing them via the REST API, and consuming them in JavaScript using @wordpress/abilities. The documentation emphasizes a layered architecture—distinguishing between domain capabilities and their projections—to ensure stable, transport-neutral plugin contracts that remain maintainable as consumer requirements evolve.

What it does

  • Registers abilities and categories using the WordPress Abilities API.
  • Exposes domain capabilities through the REST API for client consumption.
  • Provides patterns for delegating ability execution to existing REST controllers.
  • Offers guidance on grouping heuristics to avoid atomic-ability bloat.
  • Defines standard error vocabulary for consistent agent-based error handling.
  • Facilitates client-side ability consumption via @wordpress/abilities.

When to use it

  • When adding new capabilities that should be discoverable by agents or external clients.
  • When refactoring existing REST endpoints into a more stable, action-oriented ability contract.
  • When building features that require consistent permission checks across different transport layers.
  • When debugging issues where abilities are not appearing in REST responses or client-side registries.

Advantages

  • Promotes a stable, transport-neutral domain layer that survives UI or consumer changes.
  • Reduces boilerplate by providing patterns for delegating to existing controller logic.
  • Ensures consistent error handling and input validation across the plugin ecosystem.
  • Improves discoverability of plugin actions for AI agents and automated workflows.

Usage examples

“Register a new ability for listing user orders in my plugin.”
The agent will guide you through defining the ability ID, category, and meta, ensuring it is registered via the correct hooks and exposed in the REST API.
“My ability is not showing up in the REST API; how do I debug this?”
The agent will help you verify the registration hook, check for the show_in_rest meta flag, and confirm the namespace and route configuration.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/wordpress/wp-abilities-api/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip wp-abilities-api.zip -d .agents/skills

Documentation by WordPress

WP Abilities API

When to use

Use this skill when the task involves:

  • registering abilities or ability categories in PHP,

  • exposing abilities to clients via REST (wp-abilities/v1),

  • consuming abilities in JS (notably @wordpress/abilities),

  • diagnosing “ability doesn’t show up” / “client can’t see ability” / “REST returns empty”.

Inputs required

  • Repo root (run wp-project-triage first if you haven’t).

  • Target WordPress version(s) and whether this is WP core or a plugin/theme.

  • Where the change should live (plugin vs theme vs mu-plugin).

Procedure

Before deciding what to register, read references/domain-vs-projection.md — abilities live at the domain capability layer; MCP / Command Palette / REST exposure is a projection. Registration shape and exposure shape are different decisions, and conflating them forces re-registration every time a consumer's constraints change.

1) Confirm availability and version constraints
  • If this is WP core work, check signals.isWpCoreCheckout and versions.wordpress.core.

  • If the project targets WP < 6.9, you may need the Abilities API plugin/package rather than relying on core.

2) Find existing Abilities usage

Search for these in the repo:

  • wp_register_ability(

  • wp_register_ability_category(

  • wp_abilities_api_init

  • wp_abilities_api_categories_init

  • wp-abilities/v1

  • @wordpress/abilities

If none exist, decide whether you’re introducing Abilities API fresh (new registrations + client consumption) or only consuming.

3) Register categories (optional)

If you need a logical grouping, register an ability category early (see references/php-registration.md).

4) Register abilities (PHP)

For grouping decisions (how many abilities to register, and where to put filters vs. new ability names), read references/grouping-heuristic.md first — it keeps you from shipping one atomic ability per REST operation.

To avoid drift between the ability and the existing UI / REST code path, see references/shared-core-service.md — abilities, REST handlers, CLI commands, and UI controllers should be thin adapters over a shared service. The reference also covers the metric trap (REST handlers that emit usage telemetry) and the AGENTS.md rule for keeping registrations in sync when underlying code paths change.

For shared helper patterns when multiple execute callbacks delegate to existing REST controllers, see references/plugin-family-patterns.md (identify the shared-API-client vs zero-arg-controllers shape) and references/delegate-helper-pattern.md (one helper shape that works, and when not to use it).

For standardized WP_Error codes that let agents reason about retry vs. escalation, see references/error-code-vocabulary.md.

Implement the ability in PHP registration with:

  • stable id (namespaced),

  • label/description,

  • category,

  • meta:

    • add readonly: true when the ability is informational,

    • set show_in_rest: true for abilities you want visible to clients.

Use the documented init hooks for Abilities API registration so they load at the right time (see references/php-registration.md).

5) Confirm REST exposure
  • Verify the REST endpoints exist and return expected results (see references/rest-api.md).

  • If the client still can’t see the ability, confirm meta.show_in_rest is enabled and you’re querying the right endpoint.

6) Consume from JS (if needed)
  • Prefer @wordpress/abilities APIs for client-side access and checks.

  • Ensure build tooling includes the dependency and the project’s build pipeline bundles it.

Verification

  • wp-project-triage indicates signals.usesAbilitiesApi: true after your change (if applicable).

  • REST check (in a WP environment): endpoints under wp-abilities/v1 return your ability and category when expected.

  • If the repo has tests, add/update coverage near:

    • PHP: ability registration and meta exposure

    • JS: ability consumption and UI gating

Failure modes / debugging

  • Ability never appears:

    • registration code not running (wrong hook / file not loaded),

    • missing meta.show_in_rest,

    • incorrect category/ID mismatch.

  • REST shows ability but JS doesn’t:

    • wrong REST base/namespace,

    • JS dependency not bundled,

    • caching (object/page caches) masking changes.

  • Execute callback returns unexpected errors or silently ignores input:

    • input_schema defaults aren't being applied, pagination key drift between the ability and the backing, or empty()-based ID validation — see references/input-schema-gotchas.md.

Escalation

  • If you’re uncertain about version support, confirm target WP core versions and whether Abilities API is expected from core or as a plugin.

  • For canonical details, consult:

    • references/rest-api.md

    • references/php-registration.md

Files

references/domain-vs-projection.md

Domain capability vs projection — picking the layer to register at

Three layers in this model: domain, projection, and an optional workflow layer that composes abilities into multi-step tasks. The title names the two primary decisions; workflow is introduced where it earns its keep.

The Abilities API can be used at two heights. You can register abilities as the surface an MCP/REST/Command-Palette client will consume directly. Or you can register abilities at the domain layer — "what can this plugin do, transport-neutrally?" — and let each consumer see a projection of that surface that suits its constraints. This reference covers why the second framing pays off, the three-layer model that operationalizes it, and how to use it when deciding what to register.

Why this matters

Treating MCP exposure as the registration target conflates two decisions:

  1. What capabilities does this plugin offer?

  2. How should each consumer see them?

The first decision is stable. The second is volatile — token budgets shift, MCP clients improve, Command Palette gains new conventions, large plugins outgrow flat tool lists and adopt nested-discovery patterns. Coupling the two means re-registering abilities every time the projection question is reopened.

Decoupling them means registrations stay where they are while projections evolve underneath.

The three layers

LayerPurposeExamples
Domain capabilityStable, transport-neutral, permission-checked. The plugin's contract for "what can this do."myplugin/list-things, myplugin/update-thing, myplugin/get-overview
Workflow (optional)Compositions of one or more abilities into a human- or agent-friendly task."Onboard a new merchant" = verify-account → enable-feature → send-welcome
ProjectionConsumer-specific view of the domain layer. Token-efficient compression for MCP, curated workflows for Command Palette, discoverable execution surface for REST, forms for admin UI, chainable commands for CLI.The bundled WordPress MCP adapter projects every published ability through three meta-abilities (mcp-adapter/discover-abilities, mcp-adapter/execute-ability, mcp-adapter/get-ability-info) — agents traverse those three rather than seeing the full registry flat. Command Palette, by contrast, can show the same domain abilities flat because token budget is not a constraint.

The domain layer is what the registry holds. The projection layer is what each consumer sees. The workflow layer is optional and exists when a user-or-agent-meaningful task needs more than one ability.

The use-case-contract test

A registered ability is a use-case contract — a natural-language shortcut to an action a human can already perform in the UI. REST endpoints and CLI commands are transport contracts; they expose plumbing. Abilities expose actions.

Two consequences fall out of that framing:

1. Inclusion test — "would a human intentionally do this through a supported UI or workflow?"

If yes, the operation is a candidate for an ability. The lens is broader than wp-admin alone: a "supported UI or workflow" covers admin screens, public-facing UIs (storefront, account dashboard, course viewer, appointment booker), end-user self-service flows on the site front-end, and supported workflows in which another plugin or an agent calls the operation as part of a chain of actions. Abilities like store/get-my-orders, events/list-available-tickets, or profile/update-public-profile qualify just as much as admin-side abilities like myplugin/list-pending-orders or myplugin/approve-submission.

If no, the operation stays a REST endpoint, a CLI command, or an internal hook. Internal-only plumbing — cache invalidation, scheduler ticks, debug snapshots, lifecycle bookkeeping — does not belong as an ability even when it has a clean schema. There is no meaningful human invocation point, so there is no use-case contract to register.

The test is asymmetric: not everything a UI exposes should be an ability either (rule 1 in grouping-heuristic.md covers grouping). But anything that has no human-meaningful invocation surface almost certainly is not ability-meaningful.

2. Same code path as the UI

If the ability mirrors a UI action, it must share the UI's permissions, validation, and business rules. The mechanism for keeping that promise is in shared-core-service.md. The framing is here: the ability is the use-case; UI / REST / CLI / MCP are thin adapters over it.

Implications

You may register abilities you do NOT expose via MCP

The Abilities API is a WordPress core primitive. It establishes a formal contract for "run this code with these inputs under this permission check." MCP, REST, and Command Palette are exposure layers on top. You opt in.

This means a plugin can register abilities that the Command Palette uses but MCP does not see, or vice versa. The registration is transport-neutral; exposure is per-consumer.

The same domain ability can appear in multiple projections with different shapes

A small plugin might expose its three abilities flat in MCP and flat in Command Palette. A larger plugin might keep the same three domain abilities but project them through a nested-discovery facade for MCP (three meta-tools that traverse to the underlying registrations) while showing them flat in the Command Palette where token budget is not a constraint.

The domain layer does not change. The projection layer does the consumer-specific work.

Token-efficiency tradeoffs live at the projection layer

The choice between flat-with-full-schemas, semantic-grouping, single-tool-facade, and nested-discovery is a projection decision. Different shapes serve different consumer constraints. None of those shapes require changing what abilities are registered at the domain layer; they change how a consumer sees the registered set.

This is what "pattern-agnostic" means in practice: the registration is one decision, the projection is another, and a redesign of the second does not invalidate the first.

Decision order

When designing a plugin's ability surface, work in this order:

  1. Domain first. What can this plugin do, transport-neutrally? Use the inclusion test. Apply grouping-heuristic.md to pick the right granularity (semantic-intent over REST-atomization).

  2. Projection second. Which surfaces does each capability appear on, and in what shape? For most plugins under ~10 abilities, flat-in-every-projection works. For larger plugins, consider nested-discovery for MCP while keeping flat for Command Palette and REST.

  3. Workflow third (only if needed). Are there multi-ability tasks worth composing into a single user-or-agent-facing entry point? If yes, the workflow lives above the domain layer and references multiple abilities.

Most plugins never need step 3.

Worked example — generic Notifications plugin

A "Notifications" plugin manages a per-user notification feed. It supports listing, marking read, and dismissing all.

Domain layer

Three abilities, registered once:

  • notifications/list — read; filter by unread_only, since, category.

  • notifications/mark-read — write; takes a notification_id.

  • notifications/dismiss-all — write; zero-arg.

These are use-case contracts. They are transport-neutral. They do not assume MCP or Command Palette or REST.

Projection — MCP

Small surface, flat works. The MCP projection exposes the three abilities as-is. No nested-discovery needed.

Projection — Command Palette

The Command Palette projection adds a small workflow that wraps notifications/list with default filters (unread_only=true) and opens the admin notifications page on selection. The other two abilities remain visible as flat commands. The domain registration did not change; the Command Palette layer added the workflow on top.

Projection — REST

The REST projection exposes only the read ability. Writes go through admin UI for security-review reasons. The domain registration is unchanged; the REST layer just doesn't expose two of the three.

Same three registrations, three different projections, no re-registration as projection decisions evolve.

Escape hatch — tiny plugins

For plugins with one to three admin-only abilities and no other surfaces, the projection layer is trivially the identity function. You don't need to implement layers; you need to think in layers so you don't paint yourself into a corner when the plugin grows or when MCP token budgets become a constraint.

Concretely: name the abilities at the domain level (myplugin/get-thing, not myplugin-mcp/get-thing), keep the registration permission-checked and transport-neutral, and skip the projection layer until something needs it.

  • grouping-heuristic.md — within-domain decisions: how many abilities, where to put filters.

  • shared-core-service.md — the implementation mechanism for "same code path as the UI."

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

The author says: Targets WordPress 7.0+ (PHP 7.4.0+). Filesystem-based agent with bash + node. Some workflows require WP-CLI.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
WordPress
Publisher
WordPress (Official)
Source
WordPress/agent-skills · skills/wp-abilities-api · commit 7374e6f
Licence
GNU General Public License v2.0 or later (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by WordPress or WordPress.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download wp-abilities-api.zip