diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-connect.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-connect.mdx index 1d41612f2..e66be8a20 100644 --- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-connect.mdx +++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-connect.mdx @@ -73,6 +73,28 @@ The Foundry project resource (`FoundryProjectResource`) exposes: Endpoint=https://my-foundry.services.ai.azure.com/;Project=my-project ``` +### Foundry Toolbox resource + +The Foundry Toolbox resource (`FoundryToolboxResource`) exposes: + +| Property Name | Description | +| -------------- | ----------- | +| `Uri` | The default consumer MCP endpoint, or a version-specific endpoint when the Toolbox pins a `Version` | +| `ProjectEndpoint` | The parent Foundry project endpoint | +| `Name` | The Toolbox name | +| `ApiVersion` | The Toolbox data-plane API version | +| `Version` | The pinned immutable version, when configured | +| `FoundryFeatures` | The required `Foundry-Features` request-header value | +| `AuthorizationScope` | The Microsoft Entra authorization scope for Toolbox requests | + +**Example connection string:** + +``` +Uri=https://my-foundry.services.ai.azure.com/api/projects/my-project/toolboxes/field-tools/mcp +``` + +Consuming apps call the Toolbox as a standard MCP server: authenticate with Microsoft Entra ID using the `AuthorizationScope` value, then send the `Foundry-Features` header on requests, and perform the MCP `initialize` / `tools/list` handshake against `Uri`. See [Add a Toolbox](../azure-ai-foundry-host/#add-a-toolbox) for how the Toolbox and its tools are modeled in the AppHost. + ## Connect from your app Pick the language your consuming app is written in. Each example assumes your AppHost adds a Foundry deployment resource named `chat` and references it from the consuming app. diff --git a/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-host.mdx b/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-host.mdx index f414a1bb6..2f8f86a32 100644 --- a/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-host.mdx +++ b/src/frontend/src/content/docs/integrations/cloud/azure/azure-ai-foundry/azure-ai-foundry-host.mdx @@ -349,6 +349,115 @@ await foundry `AddProject` creates a default Azure Container Registry for hosted agents only in publish mode (when deploying to Azure). In local run mode, no default registry is created. Use `WithContainerRegistry` when you want to point the project at a specific registry. +## Add a Toolbox + +A [Toolbox](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/toolbox) is a Foundry data-plane resource that bundles reusable tools behind a single MCP endpoint. Toolboxes don't have an ARM or Bicep representation — Aspire manages them directly through the Foundry data-plane API. Use `AddToolbox` on a Foundry project to declare one: + + + + +```csharp title="AppHost.cs" +var builder = DistributedApplication.CreateBuilder(args); + +var foundry = builder.AddFoundry("foundry"); +var project = foundry.AddProject("project"); +var search = builder.AddAzureSearch("search"); + +var toolbox = project.AddToolbox("field-tools") + .WithDescription("Tools for field technicians.") + .WithWebSearchTool("web-search", "Search the public web.") + .WithMcpTool( + "inventory", + "https://inventory.example.com/mcp", + new FoundryToolboxMcpToolOptions + { + ServerDescription = "Inventory MCP server.", + ApprovalPolicy = new() + { + Global = FoundryToolboxMcpGlobalApprovalMode.Always + } + }) + .WithAISearchTool("knowledge-base", search, "docs"); + +builder.AddProject("api") + .WithReference(toolbox) + .WaitFor(toolbox); + +builder.Build().Run(); +``` + + + + +```typescript title="apphost.mts" +import { createBuilder } from './.aspire/modules/aspire.mjs'; +import { FoundryToolboxMcpGlobalApprovalMode } from './.aspire/modules/aspire.mjs'; + +const builder = await createBuilder(); + +const foundry = await builder.addFoundry('foundry'); +const project = await foundry.addProject('project'); +const search = await builder.addAzureSearch('search'); + +const toolbox = await project.addToolbox('field-tools'); +await toolbox.withDescription('Tools for field technicians.'); +await toolbox.withWebSearchTool({ + name: 'web-search', + description: 'Search the public web.', +}); +await toolbox.withMcpTool('inventory', 'https://inventory.example.com/mcp', { + serverDescription: 'Inventory MCP server.', + approvalPolicy: { + global: FoundryToolboxMcpGlobalApprovalMode.Always, + }, +}); +await toolbox.withAISearchTool('knowledge-base', search, 'docs'); + +const api = await builder.addProject('api', '../Api/Api.csproj'); +await api.withReference(toolbox); +await api.waitFor(toolbox); + +await builder.build().run(); +``` + + + + +Parameter details: + +| API | Parameter | Description | +| --- | --- | --- | +| `AddToolbox(...)` | `name` | The Aspire resource name and the Toolbox name. | +| `WithDescription(...)` | `description` | A description persisted with each Toolbox version. | +| `WithWebSearchTool(...)` | `name`, `description` | Adds a web search tool definition to the Toolbox. | +| `WithMcpTool(...)` | `name`, `endpoint`, `options` | Adds an MCP tool definition. `endpoint` accepts a string URI, an `EndpointReference`, or a `ReferenceExpression` for composed URLs. `options` configures the MCP server label, description, and approval policy. | +| `WithAISearchTool(...)` | `name`, `search`, `indexName`, `description` | Adds an Azure AI Search tool backed by an `AddAzureSearch` resource and an existing search index. | + + + + + +Aspire reuses the current default Toolbox version when its configuration matches. Otherwise, it creates and promotes a new immutable version, using a deterministic configuration fingerprint to detect changes. The default consumer endpoint always serves the promoted version; set `Version` on the Toolbox options only when a consumer must pin a specific immutable version. + +### Use an existing Toolbox + +Use the existing-resource methods to validate a remote Toolbox without resolving modeled tools, creating versions, or changing the default: + +| Method | `aspire run` | `aspire deploy` | +| --- | --- | --- | +| `RunAsExisting()` | Validate existing | Reconcile managed | +| `PublishAsExisting()` | Reconcile managed | Validate existing | +| `AsExisting()` | Validate existing | Validate existing | + +```csharp title="AppHost.cs" +var toolbox = project.AddToolbox("field-tools") + .AsExisting(); +``` + ## Add a hosted agent to Azure AI Foundry Use `AsHostedAgent` in C# or `asHostedAgent` in TypeScript to configure an executable or containerized app as a hosted agent in a Foundry project: