Add 11 handler filter hooks for extensibility#151
Add 11 handler filter hooks for extensibility#151galatanovidiu wants to merge 7 commits intorelease/v0.5.0from
Conversation
Add resolve_prompt_name() method following the same pattern as resolve_tool_name() in RegisterAbilityAsMcpTool. Uses McpNameSanitizer for normalization and McpValidator for post-filter validation. Closes the naming parity gap — tools and resources already had naming filters but prompts did not. Ref #130
Add mcp_adapter_tools_list, mcp_adapter_resources_list, and mcp_adapter_prompts_list filters. These fire after retrieving components from the registry and before assembling the list result DTO. Enables hiding components per user/role, adding dynamic components, or reordering. Ref #130
Filter fires after constructing InitializeResult and before returning. Enables dynamic capabilities, custom instructions, and server info modifications. Ref #130
Pre-filter fires after permission check, before execution. Enables argument transformation, context injection, and rate limiting. Post-filter fires after execution, before DTO assembly. Enables result transformation, PII redaction, and audit logging. Ref #130
Pre-filter fires after permission check, before resource execution. Post-filter fires after execution, before DTO conversion. Enables access control, caching, content transformation, and audit logging. Ref #130
Pre-filter fires after permission check, before prompt execution. Post-filter fires after execution, before normalization. Enables argument normalization, context injection, and message transformation. Ref #130
Rename pre/post execution hooks to follow WordPress pre_* convention: - mcp_adapter_tool_call_pre → mcp_adapter_pre_tool_call - mcp_adapter_tool_call_post → mcp_adapter_tool_call_result - mcp_adapter_resource_read_pre → mcp_adapter_pre_resource_read - mcp_adapter_resource_read_post → mcp_adapter_resource_read_result - mcp_adapter_prompt_get_pre → mcp_adapter_pre_prompt_get - mcp_adapter_prompt_get_post → mcp_adapter_prompt_get_result The pre_* filters now support WP_Error returns to short-circuit execution, following the WordPress pre_delete_post pattern. This enables rate limiting, circuit breakers, and custom permission checks from filter callbacks. Ref #130
|
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 @@
## release/v0.5.0 #151 +/- ##
====================================================
+ Coverage 87.62% 87.71% +0.08%
- Complexity 1218 1227 +9
====================================================
Files 54 54
Lines 3944 3980 +36
====================================================
+ Hits 3456 3491 +35
- Misses 488 489 +1
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:
|
Summary
11 new
apply_filtershooks across the MCP handler lifecycle. Covers execution gates, argument/result transformation, list operations, initialization, and component naming.Motivation
The plugin had 20 hooks but none in the request/response lifecycle. Once a request entered
RequestRouter, there were zero extension points until the JSON-RPC response left. No way to modify arguments, filter results, block execution, or dynamically adjust component lists.Hooks added
Pre-execution (can short-circuit with
WP_Error)mcp_adapter_pre_tool_call(array $args, string $tool_name, McpTool $mcp_tool, McpServer $server) => array|WP_Errormcp_adapter_pre_resource_read(array $params, string $uri, McpResource $mcp_resource, McpServer $server) => array|WP_Errormcp_adapter_pre_prompt_get(array $arguments, string $prompt_name, McpPrompt $mcp_prompt, McpServer $server) => array|WP_ErrorResult filters
mcp_adapter_tool_call_result(mixed $result, array $args, string $tool_name, McpTool $mcp_tool, McpServer $server) => mixedmcp_adapter_resource_read_result(mixed $contents, array $params, string $uri, McpResource $mcp_resource, McpServer $server) => mixedmcp_adapter_prompt_get_result(mixed $result, array $arguments, string $prompt_name, McpPrompt $mcp_prompt, McpServer $server) => mixedList filters
mcp_adapter_tools_list(array $tools, McpServer $server) => arraymcp_adapter_resources_list(array $resources, McpServer $server) => arraymcp_adapter_prompts_list(array $prompts, McpServer $server) => arrayInitialize
mcp_adapter_initialize_response(InitializeResult $result, McpServer $server) => InitializeResultNaming
mcp_adapter_prompt_name(string $name, WP_Ability $ability) => stringmcp_adapter_tool_nameandmcp_adapter_resource_nameWhy the names differ from #130
The names differ from the ones proposed in the #130 investigation. During implementation I found two problems with the
_pre/_postnaming from the issue:_prewas ambiguous. It could mean "modify arguments" or "gate execution" but couldn't do both. I need to block execution (rate limiting, circuit breakers) from the same hook that modifies arguments, not from a separate one._postdidn't say what you're filtering._resultis explicit.I went with the WordPress core
pre_*short-circuit pattern instead (pre_delete_post,pre_update_option,pre_get_shortlink). The filter returns the modified value to proceed orWP_Errorto block. This is a pattern WordPress developers already know.Test plan
npm run test:php)npm run lint:php)npm run lint:php:stan)pre_tool_callfilter can modify argumentspre_tool_callfilter can block execution with WP_Errortool_call_resultfilter can modify resultinitialize_responsefilter can modify instructionsprompt_namefilter can customize namenpx @modelcontextprotocol/inspector --cli --config .mcp.json --server mcp-adapter-default-npx --method tools/listRef #130