Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// Point an `McpClient` at a Foundry Toolbox's MCP endpoint. The agent
// discovers the toolbox's tools at runtime and invokes them locally.

using System.ClientModel;
using System.Net.Http.Headers;
using Azure.AI.Projects;
using Azure.AI.Projects.Agents;
Expand All @@ -21,15 +20,15 @@

// Name of the toolbox to create and connect to.
const string ToolboxName = "research_toolbox";
const string Query = "What tools do you have access to?";
const string Query = "Find the REST API documentation for Azure Container Apps session pools.";

string endpoint = Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("FOUNDRY_MODEL") ?? "gpt-5.4-mini";

TokenCredential credential = new DefaultAzureCredential();

// Comment out if the toolbox already exists in your Foundry project.
// Connect to the new version so the tool-search configuration is unambiguous.
var toolboxEndpoint = await CreateSampleToolboxAsync(ToolboxName, endpoint, credential);

// Inject a fresh Azure AI bearer token on every MCP request.
Expand Down Expand Up @@ -72,7 +71,7 @@
Console.WriteLine($"Assistant: {await agent.RunAsync(Query)}");

// ---------------------------------------------------------------------------
// Helper: create (or replace) a sample toolbox so the sample runs end-to-end
// Helper: create a sample toolbox version so the sample runs end-to-end
// ---------------------------------------------------------------------------
static async Task<string> CreateSampleToolboxAsync(string name, string endpoint, TokenCredential credential)
{
Expand All @@ -83,18 +82,8 @@ static async Task<string> CreateSampleToolboxAsync(string name, string endpoint,
var adminClient = new AgentAdministrationClient(new Uri(endpoint), credential);
var toolboxClient = adminClient.GetAgentToolboxes();

// Delete existing toolbox if present (ignore 404).
try
{
await toolboxClient.DeleteAsync(name);
Console.WriteLine($"Deleted existing toolbox '{name}'");
}
catch (ClientResultException ex) when (ex.Status == 404)
{
// Toolbox does not exist — nothing to delete.
}

// Create a fresh version with a single MCP tool.
// Enable discovery through tool_search and invocation through call_tool.
// The underlying MCP tools are not all placed in the model's initial context.
MCPToolboxTool mcpTool = new("api-specs")
{
ServerUri = new Uri("https://gitmcp.io/Azure/azure-rest-api-specs"),
Expand All @@ -103,11 +92,11 @@ static async Task<string> CreateSampleToolboxAsync(string name, string endpoint,

ToolboxVersion created = (await toolboxClient.CreateVersionAsync(
name: name,
tools: [mcpTool],
description: "Sample toolbox with an MCP tool — created by Agent_Step25 sample.")).Value;
tools: [mcpTool, new ToolSearchToolboxTool()],
description: "Sample toolbox with tool search — created by Agent_Step25 sample.")).Value;

Console.WriteLine($"Created toolbox '{created.Name}' v{created.Version} ({created.Tools.Count} tool(s))");
return $"{endpoint}/toolboxes/{created.Name}/mcp?api-version=v{created.Version}";
return $"{endpoint.TrimEnd('/')}/toolboxes/{created.Name}/versions/{created.Version}/mcp?api-version=v1";
}

// ---------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This sample shows how to use a Foundry Toolbox by pointing an `McpClient` at the
- Connecting to a Foundry toolbox's MCP endpoint via Streamable HTTP transport
- Injecting a fresh Azure AI bearer token (`https://ai.azure.com/.default`) on every MCP request
- Passing the discovered MCP tools to `AIProjectClient.AsAIAgent(...)`
- Optional helper to create (or replace) a sample toolbox in the project so the sample is runnable end-to-end
- Creating a toolbox version with tool search enabled and connecting to that version

## Prerequisites

Expand All @@ -21,9 +21,24 @@ $env:FOUNDRY_PROJECT_ENDPOINT="https://your-foundry-service.services.ai.azure.co
$env:FOUNDRY_MODEL="gpt-5.4-mini"
```

The sample creates a toolbox named `research_toolbox` in your Foundry project on
startup, then connects to its MCP endpoint at
`{FOUNDRY_PROJECT_ENDPOINT}/toolboxes/research_toolbox/mcp?api-version=v{version}`.
The sample creates a version of `research_toolbox` on startup, then connects to
`{FOUNDRY_PROJECT_ENDPOINT}/toolboxes/research_toolbox/versions/{version}/mcp?api-version=v1`.
Existing versions are not deleted. Review and remove sample versions in your
Foundry project when you no longer need them.

## Tool search

`ToolSearchToolboxTool` enables the toolbox's `tool_search` and `call_tool`
meta-tools. The agent searches for relevant capabilities before invoking a
discovered tool, rather than receiving all underlying tool definitions initially.
The sample prints the initial MCP tool names; expect those two meta-tools.
Remove `new ToolSearchToolboxTool()` from the creation helper to compare ordinary
toolbox discovery.

This demonstrates [Foundry toolbox tool search](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/tool-search),
not the separate request-scoped deferred-tool feature of the OpenAI Responses API.
The existing MCP integration handles discovery and invocation without adding an
Agent Framework tool-search API.

## Run the sample

Expand Down
Loading