From db7f7671801079fa69e7fa199a769af5906d74d6 Mon Sep 17 00:00:00 2001 From: Giles Odigwe <79032838+giles17@users.noreply.github.com> Date: Wed, 15 Oct 2025 22:42:45 -0700 Subject: [PATCH] Python: Added MCP headers for AzureAI (#1506) * add mcp headers * small fix --- .../agent_framework_azure_ai/_chat_client.py | 4 +++ .../tests/test_azure_ai_agent_client.py | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py index 682dcb8d3d..23db4894c6 100644 --- a/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py +++ b/python/packages/azure-ai/agent_framework_azure_ai/_chat_client.py @@ -786,6 +786,10 @@ class AzureAIAgentClient(BaseChatClient): server_label = mcp_tool.name.replace(" ", "_") mcp_resource: dict[str, Any] = {"server_label": server_label} + # Add headers if they exist + if mcp_tool.headers: + mcp_resource["headers"] = mcp_tool.headers + if mcp_tool.approval_mode is not None: match mcp_tool.approval_mode: case str(): diff --git a/python/packages/azure-ai/tests/test_azure_ai_agent_client.py b/python/packages/azure-ai/tests/test_azure_ai_agent_client.py index b713f4cec2..b590557224 100644 --- a/python/packages/azure-ai/tests/test_azure_ai_agent_client.py +++ b/python/packages/azure-ai/tests/test_azure_ai_agent_client.py @@ -831,6 +831,38 @@ async def test_azure_ai_chat_client_create_run_options_mcp_never_require(mock_ai assert mcp_resource["require_approval"] == "never" +async def test_azure_ai_chat_client_create_run_options_mcp_with_headers(mock_ai_project_client: MagicMock) -> None: + """Test _create_run_options with HostedMCPTool having headers.""" + chat_client = create_test_azure_ai_chat_client(mock_ai_project_client) + + # Test with headers + headers = {"Authorization": "Bearer DUMMY_TOKEN", "X-API-Key": "DUMMY_KEY"} + mcp_tool = HostedMCPTool( + name="Test MCP Tool", url="https://example.com/mcp", headers=headers, approval_mode="never_require" + ) + + messages = [ChatMessage(role=Role.USER, text="Hello")] + chat_options = ChatOptions(tools=[mcp_tool], tool_choice="auto") + + with patch("agent_framework_azure_ai._chat_client.McpTool") as mock_mcp_tool_class: + # Mock _prep_tools to avoid actual tool preparation + mock_mcp_tool_instance = MagicMock() + mock_mcp_tool_instance.definitions = [{"type": "mcp", "name": "test_mcp"}] + mock_mcp_tool_class.return_value = mock_mcp_tool_instance + + run_options, _ = await chat_client._create_run_options(messages, chat_options) # type: ignore + + # Verify tool_resources is created with headers + assert "tool_resources" in run_options + assert "mcp" in run_options["tool_resources"] + assert len(run_options["tool_resources"]["mcp"]) == 1 + + mcp_resource = run_options["tool_resources"]["mcp"][0] + assert mcp_resource["server_label"] == "Test_MCP_Tool" + assert mcp_resource["require_approval"] == "never" + assert mcp_resource["headers"] == headers + + async def test_azure_ai_chat_client_prep_tools_web_search_bing_grounding(mock_ai_project_client: MagicMock) -> None: """Test _prep_tools with HostedWebSearchTool using Bing Grounding."""