Skip to content

Commit c1053d5

Browse files
author
PR-Contributor
committed
feat: add remove_prompt() and remove_resource() for parity with remove_tool()
Add methods to dynamically remove prompts and resources, matching the existing remove_tool() functionality: - Add PromptError exception class for prompt operation errors - Add PromptManager.remove_prompt(name) - raises PromptError if not found - Add ResourceManager.remove_resource(uri) - raises ResourceError if not found - Add ResourceManager.remove_template(uri_template) - raises ResourceError - Add MCPServer.remove_prompt(name) - thin wrapper to prompt manager - Add MCPServer.remove_resource(uri) - thin wrapper to resource manager - Add MCPServer.remove_resource_template(uri_template) - thin wrapper This enables multi-tenant/multi-instance deployments where servers need to dynamically manage their registered primitives. Fixes #2331
1 parent 92c693b commit c1053d5

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

src/mcp/server/mcpserver/exceptions.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ class ResourceError(MCPServerError):
1313
"""Error in resource operations."""
1414

1515

16+
class PromptError(MCPServerError):
17+
"""Error in prompt operations."""
18+
19+
1620
class ToolError(MCPServerError):
1721
"""Error in tool operations."""
1822

src/mcp/server/mcpserver/prompts/manager.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from typing import TYPE_CHECKING, Any
66

7+
from mcp.server.mcpserver.exceptions import PromptError
78
from mcp.server.mcpserver.prompts.base import Message, Prompt
89
from mcp.server.mcpserver.utilities.logging import get_logger
910

@@ -45,6 +46,19 @@ def add_prompt(
4546
self._prompts[prompt.name] = prompt
4647
return prompt
4748

49+
def remove_prompt(self, name: str) -> None:
50+
"""Remove a prompt by name.
51+
52+
Args:
53+
name: The name of the prompt to remove
54+
55+
Raises:
56+
PromptError: If the prompt does not exist
57+
"""
58+
if name not in self._prompts:
59+
raise PromptError(f"Unknown prompt: {name}")
60+
del self._prompts[name]
61+
4862
async def render_prompt(
4963
self,
5064
name: str,

src/mcp/server/mcpserver/resources/resource_manager.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from pydantic import AnyUrl
99

10+
from mcp.server.mcpserver.exceptions import ResourceError
1011
from mcp.server.mcpserver.resources.base import Resource
1112
from mcp.server.mcpserver.resources.templates import ResourceTemplate
1213
from mcp.server.mcpserver.utilities.logging import get_logger
@@ -108,3 +109,29 @@ def list_templates(self) -> list[ResourceTemplate]:
108109
"""List all registered templates."""
109110
logger.debug("Listing templates", extra={"count": len(self._templates)})
110111
return list(self._templates.values())
112+
113+
def remove_resource(self, uri: str) -> None:
114+
"""Remove a resource by URI.
115+
116+
Args:
117+
uri: The URI of the resource to remove
118+
119+
Raises:
120+
ResourceError: If the resource does not exist
121+
"""
122+
if uri not in self._resources:
123+
raise ResourceError(f"Unknown resource: {uri}")
124+
del self._resources[uri]
125+
126+
def remove_template(self, uri_template: str) -> None:
127+
"""Remove a resource template by URI template.
128+
129+
Args:
130+
uri_template: The URI template of the template to remove
131+
132+
Raises:
133+
ResourceError: If the template does not exist
134+
"""
135+
if uri_template not in self._templates:
136+
raise ResourceError(f"Unknown template: {uri_template}")
137+
del self._templates[uri_template]

src/mcp/server/mcpserver/server.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,39 @@ def remove_tool(self, name: str) -> None:
500500
"""
501501
self._tool_manager.remove_tool(name)
502502

503+
def remove_prompt(self, name: str) -> None:
504+
"""Remove a prompt from the server by name.
505+
506+
Args:
507+
name: The name of the prompt to remove
508+
509+
Raises:
510+
PromptError: If the prompt does not exist
511+
"""
512+
self._prompt_manager.remove_prompt(name)
513+
514+
def remove_resource(self, uri: str) -> None:
515+
"""Remove a resource from the server by URI.
516+
517+
Args:
518+
uri: The URI of the resource to remove
519+
520+
Raises:
521+
ResourceError: If the resource does not exist
522+
"""
523+
self._resource_manager.remove_resource(uri)
524+
525+
def remove_resource_template(self, uri_template: str) -> None:
526+
"""Remove a resource template from the server by URI template.
527+
528+
Args:
529+
uri_template: The URI template of the template to remove
530+
531+
Raises:
532+
ResourceError: If the template does not exist
533+
"""
534+
self._resource_manager.remove_template(uri_template)
535+
503536
def tool(
504537
self,
505538
name: str | None = None,

0 commit comments

Comments
 (0)