Repository navigation
Add remove_prompt() and remove_resource() for parity with remove_tool() #2331
Description
Activity
- added a commit that references this issue
on Mar 22, 2026 - added a commit that references this issue
on Mar 22, 2026 Submitted PR #2335 as an alternative to #2333. It covers the same implementation scope but adds:
- Tests — 11 tests mirroring the existing
remove_toolpatterns (remove existing, remove nonexistent, remove-and-list via client, remove-and-access via client) for all three primitives. Required to pass CI's 100% coverage gate. AnyUrl | strtype onremove_resource— normalizes withstr(uri)before lookup, matching howget_resource()handles it.
- Tests — 11 tests mirroring the existing
I don't think this is the way the specification wants us to go.
I believe we should offer an API that should depend on the client i.e. I would like to remove a tool for a single client, not all of them.
I don't think we should merge this without clarifying that first.
I don't think this is the way the specification wants us to go.
I believe we should offer an API that should depend on the client i.e. I would like to remove a tool for a single client, not all of them.
I don't think we should merge this without clarifying that first.
I'm not sure im following you, like remove a tool depending on the client that is connecting?
- addedenhancementRequest for a new feature that's not currently supportedRequest for a new feature that's not currently supportedP3Nice to haves, rare edge casesNice to haves, rare edge casesneeds decisionIssue is actionable, needs maintainer decision on whether to implementIssue is actionable, needs maintainer decision on whether to implement
on Aug 14, 2026 Still relevant on v2, but the ask is smaller than when I opened this.
remove_prompt()landed in v2 — thanks for that. Resources are the remaining gap:add remove tools add_toolremove_toolprompts add_promptremove_prompt✅ v2resources add_resource— resource templates add_template— MCPServer.remove_prompt()delegates toPromptManager.remove_prompt().ResourceManagerkeeps_resourcesand_templatesas plain dicts withadd_resource()/add_template()and no removal for either, so the same shape would apply.Repro (v2,
main)from mcp.server import MCPServer mcp = MCPServer("demo") @mcp.resource("config://settings") def settings() -> str: return "..." mcp.remove_tool("some_tool") # ok mcp.remove_prompt("some_prompt") # ok, new in v2 mcp.remove_resource("config://settings") # AttributeError: 'MCPServer' object has no attribute 'remove_resource'
Use case
We run one server image as nine Azure Container Apps. Each deployment serves a different surface, selected at startup from an environment variable naming the tools that deployment should expose — a customer-facing endpoint gets three tools, an internal one gets thirty-four, and so on.
Tools are filtered with
remove_tool(), and prompts can now be filtered withremove_prompt(). Resources cannot, so a deployment that deliberately excludes a feature still publishes that feature's resources. Concretely: we recently moved one integration's tools onto a dedicated endpoint and removed them from the shared one, and its resources stayed behind on both — the split is complete for tools and prompts and incomplete for resources, purely because there is no public API for it.The workaround is reaching into
_resource_manager._resources, which is the same shape as the one noted earlier in this thread.remove_resource(uri)andremove_template(uri_template), mirroring the prompt implementation, would close it.
For anyone following the history: #2335 was closed as part of the v2 backlog sweep, not on the merits. Happy to open a PR against v2 for just the resource side if that would help.
Description
MCPServerexposesremove_tool(name)(added in #1322) but has no equivalent for prompts or resources. This was part of the original ask in #711 ("removing a tool or resource dynamically"), which was closed whenremove_tool()landed — but the resource and prompt sides were never addressed.Use case
Multi-tenant / multi-instance deployments where the same server image serves different clients. Today users can filter tools per-instance via
remove_tool(), but for prompts and resources they're forced to reach into private internals:(This is the same pattern @lukehsiao described in #711 (comment) for tools, before
remove_tool()existed.)Current state
add_*remove_*add_tool()/@tool()remove_tool()✅add_prompt()/@prompt()add_resource()/@resource()add_template()Proposed API
Add these methods, mirroring the existing
remove_tool()pattern exactly:PromptManager.remove_prompt(name: str)— raisesPromptErrorif not foundResourceManager.remove_resource(uri: str)— raisesResourceErrorif not foundResourceManager.remove_template(uri_template: str)— raisesResourceErrorif not foundMCPServer.remove_prompt(name)— thin wrapper delegating to the managerMCPServer.remove_resource(uri)— thin wrapper delegating to the managerMCPServer.remove_resource_template(uri_template)— thin wrapper delegating to the managerPromptErrorexception class inexceptions.py(for symmetry withToolErrorandResourceError)This is ~15 lines of implementation across 4 source files, plus tests. Purely additive, no breaking changes.
References
remove_tool()(the pattern this proposal follows)