Skip to content

Conversation

gziolo
Copy link
Member

@gziolo gziolo commented Oct 2, 2025

Closes #62.

What

Oftentimes we want to give the AI different instructions for when it's about to perform a destructive action, such as framing what's about to happen and requesting confirmation to the user. It would be helpful, therefore, to have a property of an Ability that marks it as a destructive ability.

I took some inspiration from ToolAnnotation in MCP. For starters, we will need read_only to replace the current logic that uses meta.tool to distinguish between HTTP method usage (i.e., GET and POST) in requests.

Why

The best explanation of the root problem that is being addressed comes from @galatanovidiu in WordPress/mcp-adapter#48 (comment)

It would be great to leverage the same metadata in MCP, but we need to address a fundamental terminology mismatch first.

The core issue: WordPress Abilities API and MCP use "tools" and "resources" to mean completely different things:

WordPress Abilities API:

Tools = callable functions that modify data
Resources = callable functions that read data

MCP:

Tools = callable functions that the AI invokes automatically when needed
Resources = static context that users manually attach to conversations

So WordPress's "tool vs resource" distinction doesn't map to MCP's "tool vs resource"

Concrete example: A site-info ability could be implemented as:

MCP tool: AI calls it when it needs current site data during conversation
MCP resource: User pre-attaches site info as reference context

The choice depends on the usage pattern (AI-driven vs. user-driven), not the type of action.

Here, we remove all references to tool and resource nomenclature. Instead, we perform detection of the GET vs POST method in the REST API calls based on annotations that describe what the ability does: read only vs updates data.

Fute considerations

With more properties, we could also start using DELETE HTTP method as I explore idempotent and destructive annotations. I'm also interested in including freeform instructions so devs could consist of usage examples for both the user and for consideration to pass to LLMs.

Testing

Run test:

npm run test:php
npm run test:client

Copy link

codecov bot commented Oct 2, 2025

Codecov Report

❌ Patch coverage is 88.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.60%. Comparing base (45cfa27) to head (47ef053).

Files with missing lines Patch % Lines
includes/abilities-api/class-wp-ability.php 70.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##              trunk      #99      +/-   ##
============================================
- Coverage     85.69%   85.60%   -0.09%     
- Complexity      103      105       +2     
============================================
  Files            16       16              
  Lines           776      792      +16     
  Branches         86       86              
============================================
+ Hits            665      678      +13     
- Misses          111      114       +3     
Flag Coverage Δ
javascript 92.62% <100.00%> (-0.04%) ⬇️
unit 82.95% <87.50%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gziolo gziolo force-pushed the update/add-ability-annotations branch from 0a65ff7 to 324d332 Compare October 2, 2025 13:27
@gziolo gziolo added [Status] In Progress Assigned work scheduled [Type] Enhancement New feature or request labels Oct 2, 2025
@gziolo gziolo force-pushed the update/add-ability-annotations branch from 1ca8dcb to 1708839 Compare October 3, 2025 10:59
@gziolo gziolo marked this pull request as ready for review October 3, 2025 10:59
@gziolo gziolo requested a review from emdashcodes October 3, 2025 10:59
Copy link

github-actions bot commented Oct 3, 2025

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: gziolo <[email protected]>
Co-authored-by: emdashcodes <[email protected]>
Co-authored-by: galatanovidiu <[email protected]>
Co-authored-by: swissspidy <[email protected]>
Co-authored-by: justlevine <[email protected]>
Co-authored-by: JasonTheAdams <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@gziolo gziolo removed the [Status] In Progress Assigned work scheduled label Oct 3, 2025
@gziolo gziolo requested a review from swissspidy October 3, 2025 10:59
@gziolo gziolo force-pushed the update/add-ability-annotations branch from 1708839 to 9306cd9 Compare October 3, 2025 11:01
@gziolo gziolo self-assigned this Oct 3, 2025
@gziolo gziolo force-pushed the update/add-ability-annotations branch from 9306cd9 to a84b388 Compare October 3, 2025 11:12
@gziolo gziolo force-pushed the update/add-ability-annotations branch from b0824a5 to 47ef053 Compare October 3, 2025 12:21
Copy link
Contributor

@emdashcodes emdashcodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this a lot. I prefer the annotations over the current tool/resource pattern.

The instructions will also be useful for providing tool instructions that various things like the MCP Adapter or Agents can adapt.

* @see WP_Abilities_Registry
*/
class WP_Ability {
/**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to suggest we align our internal naming conventions with the established MCP protocol standards to reduce developer cognitive load and maintain consistency across the systems.

Current approach:

  • Internally: read_only, destructive, idempotent
  • MCP: readOnlyHint, destructiveHint, idempotentHint

Suggested approach:
Since MCP is a well-established protocol with defined conventions, I think we should adopt the MCP naming directly in our abilities API:

  • Use: readOnlyHint, destructiveHint, idempotentHint internally
  • This eliminates the need for translation in the MCP adapter
  • Developers working with both our API and MCP won't need to context-switch between naming conventions
  • Minimizes developer confusion when working across both systems

Additional consideration - Instructions handling:
For the instructions field, since MCP uses the tool description as instructions, we can handle this in the MCP adapter by appending our instructions content to the description field.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The counterpoint would be that WordPress uses snake case convention for naming properties. REST API is a good reflection of that. It's also inconvenient with JavaScript that uses camel case similarly to the MCP protocol. Sometimes, we even mix the two when functionality spans all layers, as with block types that also support the JSON format, which again uses camel case.

@felixarntz, and @swissspidy, what are your thoughts on that aspect?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add property for marking Ability hints like destructive, read-only, idempotent
3 participants