From 3bd7df8d07d72ce5c7b2c4d6561793e9fc41f56c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 18 Apr 2026 00:28:25 +0530 Subject: [PATCH] docs: add prompt client/server example to address issue #498 --- examples/snippets/clients/prompt_client.py | 61 ++++++++++++++++++++++ examples/snippets/pyproject.toml | 1 + examples/snippets/servers/__init__.py | 4 +- examples/snippets/servers/prompt_server.py | 30 +++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 examples/snippets/clients/prompt_client.py create mode 100644 examples/snippets/servers/prompt_server.py diff --git a/examples/snippets/clients/prompt_client.py b/examples/snippets/clients/prompt_client.py new file mode 100644 index 000000000..9fa9b9109 --- /dev/null +++ b/examples/snippets/clients/prompt_client.py @@ -0,0 +1,61 @@ +"""Prompt client example: list, inspect, and get prompts from a server. + +cd to the `examples/snippets` directory and run: + uv run prompt-client +""" + +import asyncio +import os + +from mcp import ClientSession, StdioServerParameters +from mcp.client.stdio import stdio_client +from mcp.types import TextContent + +server_params = StdioServerParameters( + command="uv", + args=["run", "server", "prompt_server", "stdio"], + env={"UV_INDEX": os.environ.get("UV_INDEX", "")}, +) + + +async def run(): + """Connect to the prompt server and exercise the prompts API.""" + async with stdio_client(server_params) as (read, write): + async with ClientSession(read, write) as session: + await session.initialize() + + # 1. Discover which prompts the server exposes + result = await session.list_prompts() + print("Available prompts:") + for prompt in result.prompts: + args = ", ".join(f"{a.name}{'?' if not a.required else ''}" for a in (prompt.arguments or [])) + print(f" - {prompt.name}({args}): {prompt.description}") + + # 2. Fetch the single-string prompt and print its message + review = await session.get_prompt( + "review_code", + arguments={"code": "def add(a, b):\n return a + b"}, + ) + print("\nreview_code prompt messages:") + for msg in review.messages: + text = msg.content.text if isinstance(msg.content, TextContent) else str(msg.content) + print(f" [{msg.role}] {text}") + + # 3. Fetch the multi-turn prompt and print each message in the thread + debug = await session.get_prompt( + "debug_error", + arguments={"error": "NameError: name 'x' is not defined"}, + ) + print("\ndebug_error prompt messages:") + for msg in debug.messages: + text = msg.content.text if isinstance(msg.content, TextContent) else str(msg.content) + print(f" [{msg.role}] {text}") + + +def main(): + """Entry point for the prompt client.""" + asyncio.run(run()) + + +if __name__ == "__main__": + main() diff --git a/examples/snippets/pyproject.toml b/examples/snippets/pyproject.toml index 4e68846a0..1e2ceb6ed 100644 --- a/examples/snippets/pyproject.toml +++ b/examples/snippets/pyproject.toml @@ -22,3 +22,4 @@ direct-execution-server = "servers.direct_execution:main" display-utilities-client = "clients.display_utilities:main" oauth-client = "clients.oauth_client:run" elicitation-client = "clients.url_elicitation_client:run" +prompt-client = "clients.prompt_client:main" diff --git a/examples/snippets/servers/__init__.py b/examples/snippets/servers/__init__.py index f132f875f..afac75432 100644 --- a/examples/snippets/servers/__init__.py +++ b/examples/snippets/servers/__init__.py @@ -20,8 +20,8 @@ def run_server(): """ if len(sys.argv) < 2: print("Usage: server [transport]") - print("Available servers: basic_tool, basic_resource, basic_prompt, tool_progress,") - print(" sampling, elicitation, completion, notifications,") + print("Available servers: basic_tool, basic_resource, basic_prompt, prompt_server,") + print(" tool_progress, sampling, elicitation, completion, notifications,") print(" mcpserver_quickstart, structured_output, images") print("Available transports: stdio (default), sse, streamable-http") sys.exit(1) diff --git a/examples/snippets/servers/prompt_server.py b/examples/snippets/servers/prompt_server.py new file mode 100644 index 000000000..377f25bf0 --- /dev/null +++ b/examples/snippets/servers/prompt_server.py @@ -0,0 +1,30 @@ +"""Prompt server example showing both return styles. + +Run from the repository root: + uv run examples/snippets/servers/prompt_server.py +""" + +from mcp.server.mcpserver import MCPServer +from mcp.server.mcpserver.prompts import base + +mcp = MCPServer(name="Prompt Server") + + +@mcp.prompt(title="Code Review") +def review_code(code: str) -> str: + """Return a single string prompt asking the model to review code.""" + return f"Please review this code and suggest improvements:\n\n{code}" + + +@mcp.prompt(title="Debug Assistant") +def debug_error(error: str) -> list[base.Message]: + """Return a multi-turn conversation as a list of messages.""" + return [ + base.UserMessage("I'm seeing this error:"), + base.UserMessage(error), + base.AssistantMessage("I'll help debug that. What have you tried so far?"), + ] + + +if __name__ == "__main__": + mcp.run(transport="stdio")