[wp-trac] [WordPress Trac] #64990: Abilities API: Add filtering support to `wp_get_abilities()`
WordPress Trac
noreply at wordpress.org
Mon Mar 30 08:41:11 UTC 2026
#64990: Abilities API: Add filtering support to `wp_get_abilities()`
-------------------------+----------------------------
Reporter: gziolo | Owner: (none)
Type: enhancement | Status: new
Priority: normal | Milestone: Future Release
Component: AI | Version: 6.9
Severity: normal | Keywords: abilities
Focuses: |
-------------------------+----------------------------
== Background
The Abilities API landed in WordPress 6.9
([https://make.wordpress.org/core/2025/11/10/abilities-api-in-
wordpress-6-9/ dev note]) with registration, retrieval, and REST API
exposure for abilities. The PHP API currently offers two retrieval paths:
{{{#!php
// All registered abilities.
$abilities = wp_get_abilities();
// A single ability by name.
$ability = wp_get_ability( 'core/create-post' );
}}}
The REST API mirrors this with {{{GET /wp-json/wp/v2/abilities}}} (list
all) and {{{GET /wp-json/wp/v2/abilities/{name}}}} (single), plus a
{{{?category}}} query parameter for filtering by category slug.
There is no server-side filtering support in the PHP API. Callers who need
a subset — by category, namespace, meta properties, or any combination —
must retrieve all abilities and filter manually.
=== Observed need
As the number of registered abilities grows (core, plugins, themes),
several consumers have independently built ad-hoc filtering to work around
this gap:
* '''MCP Adapter''' checks {{{meta.mcp.public}}} and
{{{meta.show_in_rest}}} to determine which abilities to expose, using its
own {{{array_filter}}} pass.
* '''WooCommerce''' (v10.3+) introduced a
{{{woocommerce_mcp_include_ability}}} filter that performs namespace-
prefix matching ({{{str_starts_with( $ability_id, 'woocommerce/' )}}}) to
scope its custom MCP server.
* '''WebMCP adapter experiment'''
([https://github.com/WordPress/ai/pull/224 WordPress/ai#224]) hardcoded
{{{isAbilityPublicForAgents}}} to return {{{true}}} because core abilities
lack protocol-specific metadata, with a comment noting this needs a proper
{{{public}}} flag that cascades into {{{show_in_rest}}},
{{{show_in_mcp}}}, {{{show_in_webmcp}}}.
* The REST API controller for abilities already supports
{{{?category=slug}}}, but the underlying PHP function it delegates to
({{{wp_get_abilities()}}}) has no filtering — the controller does its own
post-retrieval filtering.
This duplication signals a missing primitive. Each consumer reimplements
the same patterns (namespace matching, meta checks, category scoping) with
slightly different semantics.
=== Prior exploration
This was tracked as [https://github.com/WordPress/abilities-api/issues/38
WordPress/abilities-api#38] ("Proposal: Add a convenient way to filter the
list of all registered abilities"). Two competing implementations were
explored before the repo was archived:
* '''[https://github.com/WordPress/abilities-api/pull/115 PR #115]''' —
{{{WP_Abilities_Query}}} class modeled after {{{WP_Query}}}, with array-
based {{{$args}}} (category, namespace, search, meta, orderby, order,
limit, offset). Reviewed by @jason_the_adams, @justlevine,
@jorgefilipecosta, @swissspidy.
* '''[https://github.com/WordPress/abilities-api/pull/119 PR #119]''' —
{{{WP_Abilities_Collection}}} class with fluent chainable methods
({{{->where_category()}}}, {{{->where_namespace()}}}, {{{->filter()}}},
{{{->sort_by()}}}), inspired by Laravel Collections.
Both draft POC by @ovidiu-galatan. Key review feedback that emerged:
1. '''{{{WP_*_Query}}} implies DB-backed storage''' (@justlevine):
abilities are an in-memory registry, not a database. The Query pattern
sets wrong expectations and adds unnecessary complexity (pagination, query
vars, getters) for what is essentially {{{array_filter}}} over a PHP
array.
2. '''Collections introduce a new paradigm''' (@jorgefilipecosta):
WordPress has no {{{*_Collection}}} pattern anywhere. Blocks, patterns,
and other registries don't use it. Introducing it for abilities alone
raises consistency questions across the project.
3. '''Return type BC break''' (@gziolo): {{{wp_get_abilities()}}} returns
{{{WP_Ability[]}}} today. Changing it to return a Collection object would
break every {{{array_*}}} call site and type expectation downstream.
4. '''REST API is query-style''' (@jorgefilipecosta): REST filtering is
inherently {{{?category=x&namespace=y}}}, so a Collection approach would
require translation back to query-style args anyway.
5. '''Extensibility''' (@gziolo, @swissspidy): Some mechanism for custom
filtering logic (e.g., OR across meta conditions) is needed beyond what
declarative args can express.
The team deferred the feature from 6.9, agreeing it needed more time to
settle on the right API shape. The {{{WordPress/abilities-api}}} repo was
archived on February 5, 2026 with this issue still open.
=== Current limitations
* {{{wp_get_abilities()}}} accepts no arguments and always returns the
full registry.
* The REST API supports {{{?category}}} filtering, but this is
implemented in the controller rather than the underlying PHP function,
creating a mismatch between PHP and REST capabilities.
* There is no {{{namespace}}} filtering at any layer.
* There is no {{{meta}}} filtering at any layer — consumers who need
{{{show_in_rest === true}}} or {{{mcp.public === true}}} abilities must
filter manually.
* There is no extensibility hook for custom filtering logic (e.g., role-
based visibility, protocol-specific gates).
== Related
* [https://github.com/WordPress/abilities-api/issues/38 WordPress
/abilities-api#38] — Original tracking issue (archived repo)
* [https://github.com/WordPress/abilities-api/pull/115 WordPress
/abilities-api#115] — {{{WP_Abilities_Query}}} approach (archived repo)
* [https://github.com/WordPress/abilities-api/pull/119 WordPress
/abilities-api#119] — {{{WP_Abilities_Collection}}} approach (archived
repo)
* [https://github.com/WordPress/abilities-api/pull/85 WordPress
/abilities-api#85] — {{{wp_query_abilities}}} function approach (archived
repo)
* [https://github.com/WordPress/ai/pull/224 WordPress/ai#224] — WebMCP
adapter experiment (visibility workaround)
--
Ticket URL: <https://core.trac.wordpress.org/ticket/64990>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list