From the v0.12.0 MCP endpoint security review (PR #216, finding [Low #3]).
`Ability_Registry::resolve_tool_name()` calls `get_exposed_abilities()` on every `tools/call`, which re-walks `wp_get_abilities()` and re-reads settings. An authenticated client could spam bogus tool names and force repeated full-registry walks.
Fix: memoize `get_exposed_abilities()` for the lifetime of one `JsonRpc_Server::handle()` invocation. Either via an instance-level cache on `Ability_Registry` (cleared at the start of each `handle()` call) or by passing the resolved map down from `JsonRpc_Server`.
Acceptance:
- A single MCP request that triggers `tools/list` followed by `tools/call` walks the abilities registry once.
- No behavior change for the consumer.
Not security-critical — defense-in-depth + perf hardening.
From the v0.12.0 MCP endpoint security review (PR #216, finding [Low #3]).
`Ability_Registry::resolve_tool_name()` calls `get_exposed_abilities()` on every `tools/call`, which re-walks `wp_get_abilities()` and re-reads settings. An authenticated client could spam bogus tool names and force repeated full-registry walks.
Fix: memoize `get_exposed_abilities()` for the lifetime of one `JsonRpc_Server::handle()` invocation. Either via an instance-level cache on `Ability_Registry` (cleared at the start of each `handle()` call) or by passing the resolved map down from `JsonRpc_Server`.
Acceptance:
Not security-critical — defense-in-depth + perf hardening.