Repository navigation
Add remove_prompt() and remove_resource() for parity with remove_tool() #2331
Description
Description
MCPServer exposes remove_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 when remove_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:
# Current workaround — fragile, undocumented
del mcp._prompt_manager._prompts["some_prompt"]
del mcp._resource_manager._resources[str(uri)](This is the same pattern @lukehsiao described in #711 (comment) for tools, before remove_tool() existed.)
Current state
| Primitive | add_* |
remove_* |
|---|---|---|
| Tool | add_tool() / @tool() |
remove_tool() ✅ |
| Prompt | add_prompt() / @prompt() |
missing |
| Resource | add_resource() / @resource() |
missing |
| Resource Template | add_template() |
missing |
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
- removing a tool or resource dynamically #711 — Original issue requesting dynamic tool/resource removal (closed, only tools were addressed)
- feat: add ability to remove tools #1322 — PR that added
remove_tool()(the pattern this proposal follows)
Activity
feat: add remove_prompt() and remove_resource() for parity with remov…
goingforstudying-ctrl commentedon Mar 22, 2026
Submitted PR #2333 to implement this: #2333
This adds remove_prompt(), remove_resource(), and remove_resource_template()
following the same pattern as remove_tool(). Please review when you have time. Thanks!
feat: add remove_prompt(), remove_resource(), and remove_resource_tem…
rgoldstein1989 commentedon Mar 22, 2026
Submitted PR #2335 as an alternative to #2333. It covers the same implementation scope but adds:
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.Kludex commentedon Apr 5, 2026
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.
rgoldstein1989 commentedon Apr 6, 2026
I'm not sure im following you, like remove a tool depending on the client that is connecting?
rgoldstein1989 commentedon Oct 9, 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_toolremove_tooladd_promptremove_prompt✅ v2add_resourceadd_templateMCPServer.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)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.