diff --git a/python/samples/02-agents/providers/foundry/README.md b/python/samples/02-agents/providers/foundry/README.md index f4253d98861..812e7532374 100644 --- a/python/samples/02-agents/providers/foundry/README.md +++ b/python/samples/02-agents/providers/foundry/README.md @@ -27,7 +27,7 @@ This folder contains Microsoft Foundry and Foundry Local samples for Agent Frame | [`foundry_chat_client_with_hosted_mcp.py`](foundry_chat_client_with_hosted_mcp.py) | Foundry Chat Client with hosted MCP | | [`foundry_chat_client_with_local_mcp.py`](foundry_chat_client_with_local_mcp.py) | Foundry Chat Client with local MCP | | [`foundry_chat_client_with_session.py`](foundry_chat_client_with_session.py) | Foundry Chat Client with session management | -| [`foundry_chat_client_with_toolbox.py`](foundry_chat_client_with_toolbox.py) | Foundry Chat Client connected to a toolbox via its MCP endpoint using `MCPStreamableHTTPTool` | +| [`foundry_chat_client_with_toolbox.py`](foundry_chat_client_with_toolbox.py) | Discover and invoke Foundry toolbox tools on demand with `tool_search` and `call_tool` over MCP | | [`foundry_chat_client_with_toolbox_skills.py`](foundry_chat_client_with_toolbox_skills.py) | Foundry Chat Client that discovers MCP-based skills from a Foundry Toolbox endpoint via `MCPSkillsSource` (uses an Azure AD bearer token and the toolbox preview header) | ## FoundryLocalClient Samples diff --git a/python/samples/02-agents/providers/foundry/foundry_chat_client_with_toolbox.py b/python/samples/02-agents/providers/foundry/foundry_chat_client_with_toolbox.py index 7d15cfb49ca..16bc82ad17a 100644 --- a/python/samples/02-agents/providers/foundry/foundry_chat_client_with_toolbox.py +++ b/python/samples/02-agents/providers/foundry/foundry_chat_client_with_toolbox.py @@ -24,27 +24,36 @@ Prerequisites: - A Microsoft Foundry project with a toolbox configured - FOUNDRY_PROJECT_ENDPOINT and FOUNDRY_MODEL environment variables set -- FOUNDRY_TOOLBOX_ENDPOINT: the toolbox's MCP endpoint URL, e.g. - ``https://.services.ai.azure.com/api/projects//toolsets//mcp?api-version=v1`` - Azure CLI authentication (``az login``) +- azure-ai-projects >= 2.4.0 for toolbox tool search + +The helper publishes a version with tool search enabled and connects to that exact +version. The model initially sees tool_search and call_tool, then discovers the +underlying MCP tools as needed. Each run creates a version; existing versions are +not deleted. Remove ToolSearchToolboxTool() to compare the full initial tool list. """ -# Must match the ```` segment of FOUNDRY_TOOLBOX_ENDPOINT. TOOLBOX_NAME = "research_toolbox" def create_sample_toolbox(name: str) -> str: - """Create (or replace) a toolbox version in the Foundry project. + """Create a toolbox version with tool search in the Foundry project. Toolboxes are normally configured in the Foundry portal or a deployment script, not the application itself. This helper exists so the sample can - be run end-to-end without first setting a toolbox up by hand — delete any - existing toolbox under ``name``, then create a fresh version containing a - single MCP tool. Returns the created version identifier. + be run end-to-end without first setting a toolbox up by hand. Returns the + created version identifier without deleting existing versions. """ from azure.ai.projects import AIProjectClient - from azure.ai.projects.models import MCPTool, Tool - from azure.core.exceptions import ResourceNotFoundError + from azure.ai.projects.models import MCPToolboxTool, ToolboxTool + + try: + from azure.ai.projects.models import ToolSearchToolboxTool + except ImportError as exc: + raise ImportError( + "This sample requires azure-ai-projects>=2.4.0 for toolbox tool search. " + "Upgrade with: pip install --upgrade 'azure-ai-projects>=2.4.0'" + ) from exc with ( AzureCliCredential() as credential, @@ -54,23 +63,18 @@ def create_sample_toolbox(name: str) -> str: if toolboxes is None: toolboxes = cast(Any, project_client.beta).toolboxes - try: - toolboxes.delete(name) - print(f"Toolbox `{name}` deleted") - except ResourceNotFoundError: - pass - - tools: list[Tool] = [ - MCPTool( + tools: list[ToolboxTool] = [ + MCPToolboxTool( server_label="api_specs", server_url="https://gitmcp.io/Azure/azure-rest-api-specs", require_approval="never", - ) + ), + ToolSearchToolboxTool(), ] created = toolboxes.create_version( name=name, - description="Toolbox version with MCP require_approval set to 'never'.", + description="Toolbox version with MCP tools discovered through tool search.", tools=tools, ) print(f"Created toolbox {created.name}@{created.version} ({len(created.tools)} tool(s))") @@ -92,13 +96,14 @@ def provide(_kwargs: dict[str, Any]) -> dict[str, str]: async def main() -> None: credential = DefaultAzureCredential() - # Comment out if the toolbox already exists in your Foundry project. - create_sample_toolbox(TOOLBOX_NAME) + # Connect to the new version so the tool-search configuration is unambiguous. + version = create_sample_toolbox(TOOLBOX_NAME) + project_endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"].rstrip("/") toolbox_tool = MCPStreamableHTTPTool( name="foundry_toolbox", description="Tools exposed by the configured Foundry toolbox", - url=os.environ["FOUNDRY_TOOLBOX_ENDPOINT"], + url=f"{project_endpoint}/toolboxes/{TOOLBOX_NAME}/versions/{version}/mcp?api-version=v1", header_provider=make_toolbox_header_provider(credential), load_prompts=False, ) @@ -112,7 +117,7 @@ async def main() -> None: instructions="You are a helpful assistant. Use the available toolbox tools to answer the user.", tools=toolbox_tool, ) as agent: - query = "What tools do you have access to?" + query = "Find the REST API documentation for Azure Container Apps session pools." print(f"User: {query}") result = await agent.run(query) print(f"Assistant: {result}")