Skip to content

Commit c8665e9

Browse files
committed
docs(examples): show ToolAnnotations where they carry information
1 parent d7845c0 commit c8665e9

3 files changed

Lines changed: 20 additions & 1 deletion

File tree

‎examples/mcpserver/screenshot.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77

88
from mcp.server.mcpserver import MCPServer
99
from mcp.server.mcpserver.utilities.types import Image
10+
from mcp.types import ToolAnnotations
1011

1112
# Create server
1213
mcp = MCPServer("Screenshot Demo")
1314

1415

15-
@mcp.tool()
16+
# Both hints differ from the spec defaults, so they tell a client something:
17+
# the tool only reads the local display and never reaches an external system.
18+
@mcp.tool(annotations=ToolAnnotations(read_only_hint=True, open_world_hint=False))
1619
def take_screenshot() -> Image:
1720
"""Take a screenshot of the user's screen and return it as an image. Use
1821
this tool anytime the user wants you to look at something they're doing.

‎examples/mcpserver/text_me.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class SurgeSettings(BaseSettings):
4141
surge_settings = SurgeSettings() # type: ignore
4242

4343

44+
# No ToolAnnotations on purpose. This tool sends a real SMS, and the spec defaults
45+
# (read_only_hint=False, destructive_hint=True, open_world_hint=True) already make a
46+
# client treat it with the most caution. Declaring destructive_hint=False would be
47+
# accurate but would only relax that, so leave the defaults in place.
4448
@mcp.tool(name="textme", description="Send a text message to me")
4549
def text_me(text_content: str) -> str:
4650
"""Send a text message to a phone number via https://surgemsg.com/"""

‎tests/test_examples.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,15 @@ def test_docs_examples(example: CodeExample, eval_example: EvalExample):
142142
eval_example.format_ruff(example)
143143
else:
144144
eval_example.lint_ruff(example)
145+
146+
147+
@pytest.mark.anyio
148+
async def test_screenshot_declares_tool_annotations():
149+
"""The screenshot example shows annotations that differ from the spec defaults."""
150+
from examples.mcpserver.screenshot import mcp
151+
152+
async with Client(mcp) as client:
153+
(tool,) = (await client.list_tools()).tools
154+
assert tool.annotations is not None
155+
assert tool.annotations.read_only_hint is True
156+
assert tool.annotations.open_world_hint is False

0 commit comments

Comments
 (0)