From c8665e978d94bbea267bb7d39f163593fe449637 Mon Sep 17 00:00:00 2001 From: Prafulla Purohit <165504739+prafulla2121@users.noreply.github.com> Date: Sun, 1 Nov 2026 19:28:52 +0530 Subject: [PATCH] docs(examples): show ToolAnnotations where they carry information --- examples/mcpserver/screenshot.py | 5 ++++- examples/mcpserver/text_me.py | 4 ++++ tests/test_examples.py | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/examples/mcpserver/screenshot.py b/examples/mcpserver/screenshot.py index e7b3ee6fbd..104013bda4 100644 --- a/examples/mcpserver/screenshot.py +++ b/examples/mcpserver/screenshot.py @@ -7,12 +7,15 @@ from mcp.server.mcpserver import MCPServer from mcp.server.mcpserver.utilities.types import Image +from mcp.types import ToolAnnotations # Create server mcp = MCPServer("Screenshot Demo") -@mcp.tool() +# Both hints differ from the spec defaults, so they tell a client something: +# the tool only reads the local display and never reaches an external system. +@mcp.tool(annotations=ToolAnnotations(read_only_hint=True, open_world_hint=False)) def take_screenshot() -> Image: """Take a screenshot of the user's screen and return it as an image. Use this tool anytime the user wants you to look at something they're doing. diff --git a/examples/mcpserver/text_me.py b/examples/mcpserver/text_me.py index f6da331ec4..9dbb6c9ac5 100644 --- a/examples/mcpserver/text_me.py +++ b/examples/mcpserver/text_me.py @@ -41,6 +41,10 @@ class SurgeSettings(BaseSettings): surge_settings = SurgeSettings() # type: ignore +# No ToolAnnotations on purpose. This tool sends a real SMS, and the spec defaults +# (read_only_hint=False, destructive_hint=True, open_world_hint=True) already make a +# client treat it with the most caution. Declaring destructive_hint=False would be +# accurate but would only relax that, so leave the defaults in place. @mcp.tool(name="textme", description="Send a text message to me") def text_me(text_content: str) -> str: """Send a text message to a phone number via https://surgemsg.com/""" diff --git a/tests/test_examples.py b/tests/test_examples.py index ffc0c448d0..59755c1bfe 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -142,3 +142,15 @@ def test_docs_examples(example: CodeExample, eval_example: EvalExample): eval_example.format_ruff(example) else: eval_example.lint_ruff(example) + + +@pytest.mark.anyio +async def test_screenshot_declares_tool_annotations(): + """The screenshot example shows annotations that differ from the spec defaults.""" + from examples.mcpserver.screenshot import mcp + + async with Client(mcp) as client: + (tool,) = (await client.list_tools()).tools + assert tool.annotations is not None + assert tool.annotations.read_only_hint is True + assert tool.annotations.open_world_hint is False