-
Notifications
You must be signed in to change notification settings - Fork 48
Fix/tool annotations mapping #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Simplifies annotation field validation logic by removing unnecessary conditional checks for specific field names after earlier validation has already filtered them out.
Inverts the conditional logic in priority validation to use early returns for valid cases instead of checking for invalid ranges.
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## trunk #91 +/- ##
============================================
+ Coverage 79.74% 81.46% +1.72%
- Complexity 858 917 +59
============================================
Files 46 48 +2
Lines 3080 3162 +82
============================================
+ Hits 2456 2576 +120
+ Misses 624 586 -38
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request implements MCP-compliant annotation handling for WordPress abilities, adding support for converting WordPress-format annotations to MCP specification format and validating them according to their respective schemas (ToolAnnotations for Tools, Annotations for Resources and Prompts).
Key Changes
- Implements annotation mapping from WordPress format (e.g.,
readonly) to MCP format (e.g.,readOnlyHint) for Tools - Adds validation and filtering for MCP-specific annotations (
audience,lastModified,priority) for Resources and Prompts - Introduces comprehensive annotation validation in validators to enforce MCP specification compliance
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
includes/Domain/Tools/RegisterAbilityAsMcpTool.php |
Adds map_annotations_to_mcp() method to convert WordPress format Tool annotations to MCP ToolAnnotations format |
includes/Domain/Tools/McpToolValidator.php |
Adds strict validation for MCP ToolAnnotations fields (readOnlyHint, destructiveHint, idempotentHint, openWorldHint, title) |
includes/Domain/Resources/RegisterAbilityAsMcpResource.php |
Adds map_annotations_to_mcp() and ISO 8601 timestamp validation for Resource annotations |
includes/Domain/Resources/McpResourceValidator.php |
Adds validation for Resource-specific MCP Annotations (audience, lastModified, priority) |
includes/Domain/Prompts/RegisterAbilityAsMcpPrompt.php |
Adds map_annotations_to_mcp() and ISO 8601 timestamp validation for Prompt annotations |
includes/Domain/Prompts/McpPromptValidator.php |
Adds validation for Prompt-specific MCP Annotations (audience, lastModified, priority) |
tests/Unit/Tools/RegisterAbilityAsMcpToolTest.php |
Adds comprehensive test coverage for Tool annotation mapping and filtering |
tests/Unit/Resources/RegisterAbilityAsMcpResourceTest.php |
Adds test coverage for Resource annotation handling and validation |
tests/Unit/Prompts/RegisterAbilityAsMcpPromptTest.php |
Adds test coverage for Prompt annotation handling and validation |
tests/Unit/Domain/Tools/McpToolValidatorTest.php |
Adds tests for MCP ToolAnnotations validation |
tests/Unit/Domain/Resources/McpResourceValidatorTest.php |
Adds tests for MCP Resource Annotations validation |
tests/Unit/Domain/Prompts/McpPromptValidatorTest.php |
Adds tests for MCP Prompt Annotations validation |
tests/Unit/Core/McpAdapterConfigTest.php |
Updates expected resource/prompt lists to include new annotation test fixtures |
tests/Fixtures/DummyAbility.php |
Adds test fixtures for various annotation scenarios (valid, invalid, partial, null values) |
docs/guides/creating-abilities.md |
Extensively updates documentation to explain WordPress vs MCP annotation formats and usage patterns |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Eliminates duplicate annotation mapping code by creating a centralized utility class. The identical mapping logic was previously duplicated across prompt and resource registration classes, violating DRY principles and making maintenance more difficult. Creates a new static utility class that handles the conversion of WordPress ability annotations to MCP-compliant format, including validation and normalization of audience, lastModified, and priority fields. Improves code maintainability by providing a single source of truth for annotation transformation logic.
…to fix/tool-annotations-mapping Resolved conflicts by keeping local refactored code that uses shared utility classes (McpAnnotationMapper and McpValidator) instead of inline methods.
Add is_null() check in annotation field conversion to prevent null values from being cast to false. Null annotations are now properly filtered out as expected.
Remove no-op assertion when no annotations are present. The test already has assertions and the early return is a valid pass condition.
Replace conditional checks with required assertions to prevent false positives. Verify annotations and audience are present, priority is clamped to 0.0, and invalid values are filtered. Update fixture to include mixed valid/invalid audience values.
Removed the explicit check for the 'priority' field in the validation logic, allowing all numeric values to be processed. This change simplifies the validation flow and enhances maintainability by ensuring that only numeric values are validated without restricting to a specific field.
JasonTheAdams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, @galatanovidiu! Left some comments and questions.
…ed validation methods in McpValidator Updated validation logic to call static methods from McpValidator for base64 and MIME type checks. Removed redundant validation methods from McpPromptValidator and McpResourceValidator. Updated unit tests to reflect these changes and ensure proper validation behavior.
- centralize ability→MCP annotation mapping so MCP-native values are preserved and WP-format overrides take precedence - trim ability metadata, normalize resource URIs, and enforce server guards before validating prompts/resources/tools - reuse shared annotation validator logic in tool validator + tests, and add coverage for whitespace URIs and missing MCP server cases
- Trimmed the ability label before assigning it to the tool data title to ensure consistent formatting. - Updated DummyAbility test fixture to include a new test case for handling whitespace in resource URIs.
- Updated annotation keys from 'readOnlyHint', 'destructiveHint', and 'idempotentHint' to 'readonly', 'destructive', and 'idempotent' across multiple ability classes for uniformity. - Ensured that the metadata structure aligns with the new naming conventions.
- Implemented logic to set the annotations.title from the label if annotations exist but the title is not set, ensuring better metadata completeness.
- Replaced 'readOnlyHint', 'destructiveHint', and 'idempotentHint' with 'readonly', 'destructive', and 'idempotent' in the DiscoverAbilitiesAbilityTest, ExecuteAbilityAbilityTest, and GetAbilityInfoAbilityTest for consistency with the updated metadata structure.
…a handling - Adjusted the validation flow for the 'title' field to streamline error handling and ensure non-empty string requirements are enforced. - Cleaned up whitespace handling in the RegisterAbilityAsMcpResource class to enhance URI normalization. - Made minor formatting adjustments in ExecuteAbilityAbility for consistency.
JasonTheAdams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good improvements, @galatanovidiu! I left some more feedback. 😄
Update McpAnnotationMapper to use null for ability_property when annotations map directly to MCP field names, improving type safety and code clarity.
Replace if statements with switch...case in get_annotation_validation_errors() and fix priority validation logic.
Replace if statements with switch...case in annotation validation methods and fix priority validation logic.
Return value directly instead of array structure with has_value flag
JasonTheAdams
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, @galatanovidiu! We have a couple discussions going on, but to your point I believe anything remaining can/should be resolved in a subsequent PR.
LGTM! 🚀
Why
The adapter was passing annotations through unchanged, causing field name mismatches between WordPress Abilities API format and MCP specification. WordPress uses
readonly,destructive, andidempotent, while MCP requiresreadOnlyHint,destructiveHint, andidempotentHint. This caused protocol compliance issues and could break MCP clients expecting the correct field names.Additionally null annotation values should not be included in MCP responses.
What
Adapts abilities-api annotations format to comply with the MCP ToolAnnotations specification. Adds annotation mapping functions that convert WordPress annotation field names to MCP-compliant format:
readonly→readOnlyHint,destructive→destructiveHint,idempotent→idempotentHintaudience,lastModified, andpriorityfields according to MCP specificationThe implementation includes:
RegisterAbilityAsMcpTool,RegisterAbilityAsMcpResource, andRegisterAbilityAsMcpPromptMcpToolValidator,McpResourceValidator, andMcpPromptValidatorto ensure MCP complianceopenWorldHint,titlefor tools)This change ensures full compliance with the MCP ToolAnnotations specification while maintaining backward compatibility by accepting both WordPress-format and MCP-native annotation fields.
Closes #70