From fde2efed241983b573192341942e0455ddf534a2 Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Thu, 16 Apr 2026 11:12:29 +0900 Subject: [PATCH 1/2] Python: use local MCP server for hosted tools test and broaden image assertion The hosted tools integration test was hitting rate limits on the external learn.microsoft.com MCP server, causing persistent failures that retries couldn't recover from. Switch to the local MCP server already spun up in CI via LOCAL_MCP_URL, skipping when the env var isn't set. Also broaden the image description assertion to accept common synonyms (cottage, mansion, villa, etc.) instead of just "house", since the model legitimately uses varied vocabulary for the same image. --- .../packages/anthropic/tests/test_anthropic_client.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/python/packages/anthropic/tests/test_anthropic_client.py b/python/packages/anthropic/tests/test_anthropic_client.py index 52bb4c3a49..3131468806 100644 --- a/python/packages/anthropic/tests/test_anthropic_client.py +++ b/python/packages/anthropic/tests/test_anthropic_client.py @@ -1503,6 +1503,10 @@ async def test_anthropic_client_integration_function_calling() -> None: @skip_if_anthropic_integration_tests_disabled async def test_anthropic_client_integration_hosted_tools() -> None: """Integration test for hosted tools.""" + local_mcp_url = os.environ.get("LOCAL_MCP_URL", "") + if not local_mcp_url: + pytest.skip("LOCAL_MCP_URL not set; skipping hosted tools test") + client = AnthropicClient() messages = [Message(role="user", contents=["What tools do you have available?"])] @@ -1510,8 +1514,8 @@ async def test_anthropic_client_integration_hosted_tools() -> None: AnthropicClient.get_web_search_tool(), AnthropicClient.get_code_interpreter_tool(), AnthropicClient.get_mcp_tool( - name="example-mcp", - url="https://learn.microsoft.com/api/mcp", + name="local-mcp", + url=local_mcp_url, ), ] @@ -1607,7 +1611,8 @@ async def test_anthropic_client_integration_images() -> None: assert response is not None assert response.messages[0].text is not None - assert "house" in response.messages[0].text.lower() + text = response.messages[0].text.lower() + assert any(word in text for word in ("house", "home", "building", "cottage", "mansion", "villa")) # Response Format Tests From 7555b85fa1972629d33f00a0090411af92776f9d Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Thu, 16 Apr 2026 11:23:42 +0900 Subject: [PATCH 2/2] Address review feedback: validate LOCAL_MCP_URL scheme and use word boundaries - Skip hosted tools test when LOCAL_MCP_URL lacks http/https scheme, matching the pattern used in test_mcp.py. - Use regex word boundaries for image assertion to avoid false matches like "villain" matching "villa". --- python/packages/anthropic/tests/test_anthropic_client.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/python/packages/anthropic/tests/test_anthropic_client.py b/python/packages/anthropic/tests/test_anthropic_client.py index 3131468806..a10a8830b4 100644 --- a/python/packages/anthropic/tests/test_anthropic_client.py +++ b/python/packages/anthropic/tests/test_anthropic_client.py @@ -1,5 +1,6 @@ # Copyright (c) Microsoft. All rights reserved. import os +import re from pathlib import Path from typing import Annotated, Any from unittest.mock import MagicMock, patch @@ -1504,8 +1505,8 @@ async def test_anthropic_client_integration_function_calling() -> None: async def test_anthropic_client_integration_hosted_tools() -> None: """Integration test for hosted tools.""" local_mcp_url = os.environ.get("LOCAL_MCP_URL", "") - if not local_mcp_url: - pytest.skip("LOCAL_MCP_URL not set; skipping hosted tools test") + if not local_mcp_url or not local_mcp_url.startswith(("http://", "https://")): + pytest.skip("LOCAL_MCP_URL not set or not an HTTP URL; skipping hosted tools test") client = AnthropicClient() @@ -1612,7 +1613,7 @@ async def test_anthropic_client_integration_images() -> None: assert response is not None assert response.messages[0].text is not None text = response.messages[0].text.lower() - assert any(word in text for word in ("house", "home", "building", "cottage", "mansion", "villa")) + assert re.search(r"\b(house|home|building|cottage|mansion|villa)\b", text) # Response Format Tests