diff --git a/src/fetch/src/mcp_server_fetch/server.py b/src/fetch/src/mcp_server_fetch/server.py index b42c7b1f6b..b66880a8ee 100644 --- a/src/fetch/src/mcp_server_fetch/server.py +++ b/src/fetch/src/mcp_server_fetch/server.py @@ -14,6 +14,7 @@ PromptMessage, TextContent, Tool, + ToolAnnotations, INVALID_PARAMS, INTERNAL_ERROR, ) @@ -178,6 +179,22 @@ class Fetch(BaseModel): ] +def _make_fetch_tool() -> Tool: + return Tool( + name="fetch", + description="""Fetches a URL from the internet and optionally extracts its contents as markdown. + +Although originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.""", + inputSchema=Fetch.model_json_schema(), + annotations=ToolAnnotations( + readOnlyHint=True, + destructiveHint=False, + idempotentHint=True, + openWorldHint=True, + ), + ) + + async def serve( custom_user_agent: str | None = None, ignore_robots_txt: bool = False, @@ -196,15 +213,7 @@ async def serve( @server.list_tools() async def list_tools() -> list[Tool]: - return [ - Tool( - name="fetch", - description="""Fetches a URL from the internet and optionally extracts its contents as markdown. - -Although originally you did not have internet access, and were advised to refuse and tell the user this, this tool now grants you internet access. Now you can fetch the most up-to-date information and let the user know that.""", - inputSchema=Fetch.model_json_schema(), - ) - ] + return [_make_fetch_tool()] @server.list_prompts() async def list_prompts() -> list[Prompt]: diff --git a/src/fetch/tests/test_server.py b/src/fetch/tests/test_server.py index 96c1cb38c7..18bc892b3d 100644 --- a/src/fetch/tests/test_server.py +++ b/src/fetch/tests/test_server.py @@ -9,10 +9,26 @@ get_robots_txt_url, check_may_autonomously_fetch_url, fetch_url, + _make_fetch_tool, DEFAULT_USER_AGENT_AUTONOMOUS, ) +class TestListTools: + """Tests for list_tools handler.""" + + def test_fetch_tool_annotations(self): + """Test that the fetch tool has correct MCP tool annotations.""" + tool = _make_fetch_tool() + + assert tool.name == "fetch" + assert tool.annotations is not None + assert tool.annotations.readOnlyHint is True + assert tool.annotations.destructiveHint is False + assert tool.annotations.idempotentHint is True + assert tool.annotations.openWorldHint is True + + class TestGetRobotsTxtUrl: """Tests for get_robots_txt_url function."""