MCP support for Foundry (#652)

Co-authored-by: Giles Odigwe <gilesodigwe@microsoft.com>
This commit is contained in:
Giles Odigwe
2025-09-09 13:07:20 -07:00
committed by GitHub
Unverified
parent 745a05d43c
commit 9f8823192e
5 changed files with 163 additions and 0 deletions
@@ -18,6 +18,7 @@ from agent_framework import (
FunctionCallContent,
FunctionResultContent,
HostedCodeInterpreterTool,
MCPStreamableHTTPTool,
Role,
TextContent,
UriContent,
@@ -880,6 +881,27 @@ async def test_foundry_chat_client_agent_code_interpreter():
assert "120" in response.text or "factorial" in response.text.lower()
@skip_if_foundry_integration_tests_disabled
async def test_foundry_chat_client_agent_with_mcp_tools() -> None:
"""Test MCP tools defined at agent creation with FoundryChatClient."""
async with ChatAgent(
chat_client=FoundryChatClient(async_credential=AzureCliCredential()),
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
),
) as agent:
# Test that the agent can use MCP tools to answer questions
response = await agent.run("What is Azure App Service?")
assert isinstance(response, AgentRunResponse)
assert response.text is not None
# Verify the response contains relevant information about Azure App Service
assert any(term in response.text.lower() for term in ["app service", "azure", "web", "application"])
@skip_if_foundry_integration_tests_disabled
async def test_foundry_chat_client_agent_level_tool_persistence():
"""Test that agent-level tools persist across multiple runs with FoundryChatClient."""
@@ -11,6 +11,7 @@ This folder contains examples demonstrating different ways to create and use age
| [`foundry_with_existing_agent.py`](foundry_with_existing_agent.py) | Shows how to work with a pre-existing agent by providing the agent ID to the Foundry chat client. This example also demonstrates proper cleanup of manually created agents. |
| [`foundry_with_function_tools.py`](foundry_with_function_tools.py) | Demonstrates how to use function tools with agents. Shows both agent-level tools (defined when creating the agent) and query-level tools (provided with specific queries). |
| [`foundry_with_code_interpreter.py`](foundry_with_code_interpreter.py) | Shows how to use the HostedCodeInterpreterTool with Foundry agents to write and execute Python code. Includes helper methods for accessing code interpreter data from response chunks. |
| [`foundry_with_local_mcp.py`](foundry_with_local_mcp.py) | Shows how to integrate Foundry agents with Model Context Protocol (MCP) servers for enhanced functionality and tool integration. Demonstrates both agent-level and run-level tool configuration. |
| [`foundry_with_thread.py`](foundry_with_thread.py) | Demonstrates thread management with Foundry agents, including automatic thread creation for stateless conversations and explicit thread management for maintaining conversation context across multiple interactions. |
## Environment Variables
@@ -0,0 +1,81 @@
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from agent_framework import ChatAgent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient
from azure.identity.aio import AzureCliCredential
async def mcp_tools_on_run_level() -> None:
"""Example showing MCP tools defined when running the agent."""
print("=== Tools Defined on Run Level ===")
# Tools are provided when running the agent
# This means we have to ensure we connect to the MCP server before running the agent
# and pass the tools to the run method.
async with (
AzureCliCredential() as credential,
MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
) as mcp_server,
ChatAgent(
chat_client=FoundryChatClient(async_credential=credential),
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
) as agent,
):
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await agent.run(query1, tools=mcp_server)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Semantic Kernel?"
print(f"User: {query2}")
result2 = await agent.run(query2, tools=mcp_server)
print(f"{agent.name}: {result2}\n")
async def mcp_tools_on_agent_level() -> None:
"""Example showing tools defined when creating the agent."""
print("=== Tools Defined on Agent Level ===")
# Tools are provided when creating the agent
# The agent can use these tools for any query during its lifetime
# The agent will connect to the MCP server through its context manager.
async with (
AzureCliCredential() as credential,
FoundryChatClient(async_credential=credential).create_agent(
name="DocsAgent",
instructions="You are a helpful assistant that can help with microsoft documentation questions.",
tools=MCPStreamableHTTPTool( # Tools defined at agent creation
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
),
) as agent,
):
# First query
query1 = "How to create an Azure storage account using az cli?"
print(f"User: {query1}")
result1 = await agent.run(query1)
print(f"{agent.name}: {result1}\n")
print("\n=======================================\n")
# Second query
query2 = "What is Microsoft Semantic Kernel?"
print(f"User: {query2}")
result2 = await agent.run(query2)
print(f"{agent.name}: {result2}\n")
async def main() -> None:
print("=== Foundry Chat Client Agent with MCP Tools Examples ===\n")
await mcp_tools_on_agent_level()
await mcp_tools_on_run_level()
if __name__ == "__main__":
asyncio.run(main())
@@ -68,6 +68,9 @@ from samples.getting_started.agents.foundry.foundry_with_explicit_settings impor
from samples.getting_started.agents.foundry.foundry_with_function_tools import (
main as foundry_with_function_tools,
)
from samples.getting_started.agents.foundry.foundry_with_local_mcp import (
main as foundry_with_local_mcp,
)
from samples.getting_started.agents.foundry.foundry_with_thread import (
main as foundry_with_thread,
)
@@ -337,6 +340,15 @@ agent_samples = [
pytest.mark.skipif(os.getenv(RUN_SAMPLES_TESTS, None) is None, reason="Not running sample tests."),
],
),
param(
foundry_with_local_mcp,
[], # Non-interactive sample
id="foundry_with_local_mcp",
marks=[
pytest.mark.foundry,
pytest.mark.skipif(os.getenv(RUN_SAMPLES_TESTS, None) is None, reason="Not running sample tests."),
],
),
# OpenAI Assistants Agent samples
param(
openai_assistants_basic,