Skip to content

Commit b1f7a29

Browse files
committed
Drop the add_prompt(fn) overload; keep only the Message re-exports
add_tool takes a function while add_resource and add_prompt take built objects; letting add_prompt accept both would be a third shape rather than consistency, and changing the imperative registration API deserves its own design pass across all three primitives. mcp.add_prompt(Prompt.from_function(fn, ...)) remains the spelling for runtime registration.
1 parent 988fbbf commit b1f7a29

2 files changed

Lines changed: 2 additions & 78 deletions

File tree

src/mcp/server/mcpserver/server.py

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -890,47 +890,12 @@ def decorator(fn: _CallableT) -> _CallableT:
890890

891891
return decorator
892892

893-
@overload
894-
def add_prompt(self, prompt: Prompt) -> None: ...
895-
896-
@overload
897-
def add_prompt(
898-
self,
899-
fn: Callable[..., Any],
900-
/,
901-
*,
902-
name: str | None = None,
903-
title: str | None = None,
904-
description: str | None = None,
905-
icons: list[Icon] | None = None,
906-
) -> None: ...
907-
908-
def add_prompt(
909-
self,
910-
prompt: Prompt | Callable[..., Any],
911-
*,
912-
name: str | None = None,
913-
title: str | None = None,
914-
description: str | None = None,
915-
icons: list[Icon] | None = None,
916-
) -> None:
893+
def add_prompt(self, prompt: Prompt) -> None:
917894
"""Add a prompt to the server.
918895
919-
Pass the function that renders the prompt: its name, docstring and parameters become
920-
the prompt's name, description and arguments, exactly as with `@prompt()`. A ready-made
921-
`Prompt` instance is registered as-is.
922-
923896
Args:
924-
prompt: The function to register as a prompt, or a `Prompt` instance
925-
name: Optional name for the prompt (defaults to the function name)
926-
title: Optional human-readable title for the prompt
927-
description: Optional description (defaults to the function's docstring)
928-
icons: Optional list of icons for the prompt
897+
prompt: A Prompt instance to add
929898
"""
930-
if not isinstance(prompt, Prompt):
931-
prompt = Prompt.from_function(prompt, name=name, title=title, description=description, icons=icons)
932-
elif any(arg is not None for arg in (name, title, description, icons)):
933-
raise TypeError("name, title, description and icons can only be set when registering a function")
934899
self._prompt_manager.add_prompt(prompt)
935900

936901
def remove_prompt(self, name: str) -> None:

tests/server/mcpserver/test_server.py

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
from mcp.server.mcpserver import Context, MCPServer, ResourceSecurity
5151
from mcp.server.mcpserver.exceptions import ResourceNotFoundError, ToolError
5252
from mcp.server.mcpserver.prompts.base import Message, UserMessage
53-
from mcp.server.mcpserver.prompts.base import Prompt as PromptTemplate # `Prompt` here is the mcp_types wire model
5453
from mcp.server.mcpserver.resources import FileResource, FunctionResource
5554
from mcp.server.mcpserver.utilities.types import Audio, Image
5655
from mcp.server.subscriptions import (
@@ -2321,46 +2320,6 @@ def test_context_exposes_its_mcp_server() -> None:
23212320
assert Context(mcp_server=mcp).mcp_server is mcp
23222321

23232322

2324-
def _greet(who: str) -> str:
2325-
"""Say hi."""
2326-
return f"hi {who}"
2327-
2328-
2329-
async def test_add_prompt_registers_a_function_like_the_decorator() -> None:
2330-
"""SDK-defined: `add_prompt(fn, ...)` derives name, description and arguments as `@prompt()` does."""
2331-
mcp = MCPServer()
2332-
mcp.add_prompt(_greet, title="Greeter")
2333-
2334-
async with Client(mcp) as client:
2335-
[listed] = (await client.list_prompts()).prompts
2336-
result = await client.get_prompt("_greet", {"who": "max"})
2337-
2338-
assert (listed.name, listed.title, listed.description) == ("_greet", "Greeter", "Say hi.")
2339-
assert [arg.name for arg in listed.arguments or []] == ["who"]
2340-
assert result.messages[0].content == TextContent(type="text", text="hi max")
2341-
2342-
2343-
async def test_add_prompt_registers_a_prompt_instance_as_is() -> None:
2344-
"""SDK-defined: a ready-made prompt handed to `add_prompt` (the 2.0 form) is registered exactly as built."""
2345-
mcp = MCPServer()
2346-
mcp.add_prompt(prompt=PromptTemplate.from_function(_greet, name="custom"))
2347-
[listed] = await mcp.list_prompts()
2348-
assert listed.name == "custom"
2349-
2350-
2351-
async def test_add_prompt_rejects_overrides_alongside_a_prompt_instance() -> None:
2352-
"""SDK-defined: the keyword overrides only apply to the function form; passing them alongside a
2353-
ready-made prompt is rejected rather than silently ignored."""
2354-
mcp = MCPServer()
2355-
prompt: Any = PromptTemplate.from_function(_greet) # Any: the overloads already reject this call statically
2356-
with pytest.raises(TypeError) as exc_info:
2357-
mcp.add_prompt(prompt, name="renamed")
2358-
assert str(exc_info.value) == snapshot(
2359-
"name, title, description and icons can only be set when registering a function"
2360-
)
2361-
assert await mcp.list_prompts() == []
2362-
2363-
23642323
def test_remove_prompt_removes_and_unknown_name_raises() -> None:
23652324
mcp = MCPServer()
23662325

0 commit comments

Comments
 (0)