- name
- foundry-toolbox
- description
- Use Microsoft Foundry Toolbox GA to manage versioned multi-tool bundles behind a single MCP endpoint and connect them to hosted agents. Covers stable AIProjectClient.toolboxes CRUD, SDK models, agent_framework_foundry_hosting.FoundryToolbox, authentication, immutable-version promotion and rollback, the azd ai toolbox declarative path, A2A 1.0 GA and stable Tool Search. Distinguishes these from preview A2A 0.3, Work IQ, Fabric IQ, Browser Automation, Reminder, and skills in Toolboxes; explains that azure_ai_search wraps an index, not a Foundry IQ knowledge base. USE FOR: foundry toolbox, toolbox MCP endpoint, AIProjectClient toolboxes, FoundryToolbox, toolbox version promote, multi-tool MCP endpoint, ToolboxSearchPreviewToolboxTool, ToolSearchToolboxTool, kind toolbox, host azure.ai.toolbox, toolbox.yaml. DO NOT USE FOR: building MCP servers (use foundry-mcp-aca), KB-only RAG (use foundry-iq), generic hosted-agent runtime (use foundry-hosted-agents), cross-resource models (use foundry-cross-resource).
- metadata
- {"version":"2.3.0","validated":"2026-08-04T00:00:00.000Z"}
# Microsoft Foundry Toolbox GA - Reference Guide
The [Foundry Toolbox](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/toolbox)
is a GA managed resource that bundles versioned tools behind one MCP endpoint.
The platform centralizes connection references, credentials, token refresh,
policy, and immutable-version promotion while the agent connects to one URL.
Use a Toolbox when an agent needs several managed tools, when tool composition
must change without redeploying agent code, or when credentials belong in the
Foundry project rather than the agent container. Stable management uses
`AIProjectClient.toolboxes`. Stable
[Tool Search](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/tool-search)
uses `ToolSearchToolboxTool`; skills in Toolboxes retain their preview support
terms even though the parent Toolbox resource is GA.
## Status boundary
| Surface | Status | Canonical contract |
|---|---|---|
| Toolbox resource, versions, promotion, CRUD, and MCP `v1` endpoints | **GA** | `AIProjectClient.toolboxes`; no preview feature header |
| MCP, Web Search, Azure AI Search, Code Interpreter, File Search, OpenAPI | **GA Toolbox tool types** | Toolbox-specific SDK model classes |
| A2A protocol 1.0 | **GA** | `A2AToolboxTool`, wire type `a2a`, required `a2a_version` |
| A2A protocol 0.3, Work IQ, Fabric IQ, Browser Automation, Reminder | **Preview** | Classes retain `Preview` in their names |
| Tool Search | **Stable Toolbox capability** | `ToolSearchToolboxTool`; returns `tool_search` + `call_tool` |
| Skills in Toolboxes | **Preview** | Opt in explicitly; no SLA |
| Prompt Agent consumption of a Toolbox | **Preview integration** | MCP bridge; GA management and Tool Search do not make this integration GA |
| `agent_framework_foundry_hosting.FoundryToolbox` | **Prerelease client package** | High-level consumer for the GA Toolbox MCP endpoint |
| `microsoft.foundry` azd bundle `1.0.0-beta.1` | **Beta client bundle** | Recommended CLI install; currently bundles Toolbox component `azure.ai.toolboxes` `1.0.0-beta.2` |
Do not infer a subfeature's status from the Toolbox resource's GA status. A
GA Toolbox can contain stable Tool Search and a preview skill at the same time;
each subfeature keeps its own support and SLA boundary.
```
Foundry project
└── Toolbox: agent-tools
├── default_version -> 3
├── immutable versions: 1, 2, 3
├── GA tool models
│ ├── MCPToolboxTool
│ ├── WebSearchToolboxTool
│ ├── AzureAISearchToolboxTool
│ ├── CodeInterpreterToolboxTool
│ ├── FileSearchToolboxTool
│ ├── ToolSearchToolboxTool
│ ├── OpenApiToolboxTool
│ └── A2AToolboxTool (protocol 1.0)
└── preview tool models
├── A2APreviewToolboxTool
├── WorkIQPreviewToolboxTool
├── FabricIQPreviewToolboxTool
├── BrowserAutomationPreviewToolboxTool
└── ReminderPreviewToolboxTool
Version-specific MCP endpoint:
{project}/toolboxes/agent-tools/versions/3/mcp?api-version=v1
Default-version MCP endpoint:
{project}/toolboxes/agent-tools/mcp?api-version=v1
Every request:
Entra bearer token scoped to https://ai.azure.com/.default
No preview feature header
Consumers:
Hosted MAF -> FoundryToolbox
Direct non-Toolbox MCP -> MCPStreamableHTTPTool
LangGraph / other frameworks -> authenticated Streamable HTTP MCP client
Prompt Agent Tool Search -> MCPTool bridge
```
## Consumption boundary
The GA Toolbox resource exposes authenticated Streamable HTTP MCP endpoints; it
is not itself an Agent `tools[].type`. Use the consumer that matches the host:
| Host | Toolbox consumer | Status |
|---|---|---|
| Hosted Microsoft Agent Framework code | `FoundryToolbox` in the Agent `tools` list | GA Toolbox path through a prerelease hosting wrapper |
| LangGraph or another code framework | Its authenticated Streamable HTTP MCP client | Framework-specific |
| Prompt Agent | `MCPTool` pointing at the Toolbox endpoint with Tool Search enabled | Preview integration of GA Tool Search |
Do not invent `tools=[{"type": "toolbox"}]`; that Agent tool type does not
exist. A Prompt Agent can use the documented Tool Search bridge, where the
Toolbox endpoint exposes `tool_search`, `call_tool` and pinned tools. For existing hosted
production composition, use `FoundryToolbox` in code.
## When to use Toolbox vs alternatives
| Need | Use | Why |
|---|---|---|
| **Multiple managed tools behind one endpoint** | **Toolbox** | Centralized creds, swap tools without agent redeploy, versioning |
| **Single hosted MCP with static API key** | `client.get_mcp_tool()` (`foundry-hosted-agents` § MCP) | Simpler — no toolbox abstraction layer |
| **MCP with short-lived AAD bearer (KB MCP, Storage behind PMI)** | `MCPStreamableHTTPTool` + `header_provider` (`foundry-hosted-agents`) | Toolbox MCP endpoint can wrap it, but direct `header_provider` is one less hop |
| **KB-only RAG with agentic retrieval / multi-hop / citations** | `foundry-iq` (Knowledge Base, NOT Toolbox `azure_ai_search`) | Toolbox `azure_ai_search` wraps an INDEX, not a KB — no query planning or answer synthesis |
| **Custom MCP server you build + deploy** | `foundry-mcp-aca` to build the server, **then wire it INTO a Toolbox** | These compose: build with one skill, manage centrally with this one |
| **Cross-resource model invocation** | `foundry-cross-resource` | Toolbox is for *tools*, not models |
| **Vision / DocIntel / Speech tools** | `foundry-doc-vision-speech` patterns wrapped via Toolbox `openapi` or `mcp` | Toolbox is the consumption layer |
---
## Tool type reference
`ToolboxTool` is the abstract base. Use the concrete subclasses below for
Toolbox versions. Generic Agent models such as `MCPTool` and `WebSearchTool`
belong to Agent definitions and are not Toolbox models. The existing consumer
stack remains on SDK 2.4; the additive A2A management path below is isolated.
| SDK model | Wire type | Status | Required configuration |
|---|---|---|---|
| `MCPToolboxTool` | `mcp` | GA | `server_label` plus `server_url` or `connector_id`; optional project connection |
| `WebSearchToolboxTool` | `web_search` | GA | No required fields; optional filters and search context |
| `AzureAISearchToolboxTool` | `azure_ai_search` | GA | `azure_ai_search=AzureAISearchToolResource(...)` |
| `CodeInterpreterToolboxTool` | `code_interpreter` | GA | No required fields; optional container/files |
| `FileSearchToolboxTool` | `file_search` | GA | Vector-store configuration |
| `OpenApiToolboxTool` | `openapi` | GA | `openapi=OpenApiFunctionDefinition(...)` |
| `ToolSearchToolboxTool` | `toolbox_search` | GA | No required fields; activates `tool_search` and `call_tool` |
| `A2AToolboxTool` | `a2a` | GA, protocol 1.0 | Required `a2a_version=A2AProtocolVersion.V1_0`; remote agent connection |
| `A2APreviewToolboxTool` | `a2a_preview` | Preview | Remote agent URL and project connection as needed |
| `WorkIQPreviewToolboxTool` | `work_iq_preview` | Preview | Work IQ project connection |
| `FabricIQPreviewToolboxTool` | `fabric_iq_preview` | Preview | Fabric IQ project connection and target server details |
| `BrowserAutomationPreviewToolboxTool` | `browser_automation_preview` | Preview | Browser Automation connection parameters |
| `ReminderPreviewToolboxTool` | `reminder_preview` | Preview | No required fields |
> **Identifier requirement (live invariant):** the per-tool `name` above is
> otherwise optional, but a Toolbox version may contain **at most one** tool
> without an identifier. As soon as a version bundles two or more tools, every
> tool beyond that single unnamed allowance **must** carry a unique identifier —
> `name` for built-in tools, or `server_label` for `MCPToolboxTool`. Omitting it
> makes `create_version` fail with `400 invalid_payload: Multiple tools without
> identifiers found`. This is not limited to duplicate instances of the same
> tool type — two unnamed tools of any types collide.
The `toolbox_search` configuration directive is not a callable tool and does
not consume this unnamed-tool allowance.
### Per-tool anti-patterns
- **`azure_ai_search` tool:** wraps an index, not a Knowledge Base. Private endpoint support does not turn index retrieval into agentic KB retrieval.
- **`file_search` tool:** private networking is supported. Validate the project's data-resource private endpoints, DNS and intended caller; do not disable isolation to work around a failed probe.
- **`code_interpreter` tool:** DO NOT use for long-running computations (>5 min wall-clock) — the container will timeout and fail silently. DO use ACA Jobs via `azd-patterns` for batch work.
- **`web_search` tool:** DO NOT enable in regulated-data contexts without explicit allow-listing of source domains. DO use the `allowed_domains` parameter when you need to scope results to a restricted set of trusted sources.
---
## Stable Toolbox request contract
The GA request shape is:
| Element | Value |
|---|---|
| AAD token scope | `https://ai.azure.com/.default` |
| Authorization | OAuth 2.0 bearer token minted for the Toolbox scope |
| MCP API version | `?api-version=v1` |
| Preview feature header | **None** |
`azure-ai-projects` 2.4.0 and `FoundryToolbox` apply this contract without
`Foundry-Features: Toolboxes=V1Preview`. Remove that header when migrating
preview-era clients; do not make correctness depend on a retired feature gate.
### Preview-to-GA migration
| Preview-era contract | GA contract |
|---|---|
| `project.beta.toolboxes` | `project.toolboxes` |
| `client.get_toolbox(...)` | `project.toolboxes.get(name)` for the latest version, or `project.toolboxes.get_version(name, version)` for an explicit immutable version |
| `select_toolbox_tools(...)` | Define the exact `tools=[...]` set in a Toolbox version, then consume that version through `FoundryToolbox` |
| Generic `MCPTool`, `WebSearchTool`, `AzureAISearchTool` | `MCPToolboxTool`, `WebSearchToolboxTool`, `AzureAISearchToolboxTool` |
| `Foundry-Features: Toolboxes=V1Preview` | Remove the feature header |
| `AzureAIToolbox` | `agent_framework_foundry_hosting.FoundryToolbox` |
| `create_toolbox_version(...)` in stale examples | `create_version(...)` in SDK 2.4.0 |
This table is the only place presenting obsolete APIs as migration mapping;
status/troubleshooting may name retired header, but fenced canonical code must
not contain preview-era API.
---
## Two endpoint shapes
| Role | Endpoint | When |
|---|---|---|
| **Toolbox developer** | `{project}/toolboxes/{name}/versions/{version}/mcp?api-version=v1` | Test or validate a specific version before promoting it |
| **Toolbox consumer** | `{project}/toolboxes/{name}/mcp?api-version=v1` | Production agents — always serves `default_version` |
The first version of a new toolbox is auto-promoted to `default_version`
(`v1`). Subsequent versions stay un-promoted until you explicitly update
the toolbox's `default_version`.
---
## Auth & RBAC
Use **Foundry User** (formerly **Azure AI User**) for developer/Toolbox runtime
access where a role assignment is required. For end users consuming an agent
with OAuth passthrough, prefer **Foundry Agent Consumer** where the surface
supports it; Playground authoring/editing requires Foundry User.
| Identity | Required for | Why |
|---|---|---|
| **Developer** | Always | Create / update / promote / delete toolbox versions |
| **Agent identity (UAMI / agent MI)** | Hosted agents calling tools | Agent calls `tools/call` at runtime |
| **End user** | OAuth-based MCP or supported `UserEntraToken` connections | Per-user credentials for the downstream audience; native OAuth is not by itself proof of an Entra OBO exchange |
For custom delegated MCP authentication, use the
[foundry-mcp-auth candidate](../foundry-mcp-auth/SKILL.md). It distinguishes
platform identity from downstream user identity. Single-user live execution
passed for Hosted/Toolbox and the native Prompt/Toolbox bridge; remaining
Playground, multi-user and lifecycle acceptance gaps are documented separately.
> **Hosted MAF / GHCP agent identity:** the calling identity at runtime
> is `instance_identity.principal_id`, not the project / account MIs. See
> `foundry-iq` § Hosted-agent runtime identity for the full breakdown
> (same identity model applies to Toolbox tool calls).
---
## Low-level MCP compatibility notes
`FoundryToolbox` is the canonical MAF consumer. On MAF 1.13 it handles
per-request Entra authorization, defaults `load_prompts=False`, treats MCP
method-not-found from `ping` as a supported server capability boundary, and
owns connection cleanup.
Custom MCP clients still need these protocol rules:
- do not require `prompts/list`; Toolboxes expose tools;
- keep Streamable HTTP tool calls in streaming mode;
- request tokens for `https://ai.azure.com/.default`; and
- do not add the removed preview feature header.
The hosted platform reserves `FOUNDRY_*` environment variables. Use the
platform-provided `FOUNDRY_PROJECT_ENDPOINT`, and use `TOOLBOX_ENDPOINT` plus
`TOOLBOX_NAME` only when overriding `FoundryToolbox` endpoint discovery.
## Tool-authoring failure modes
When integrating tools into a toolbox or wiring them to an agent, watch for these common authoring mistakes. This table documents how they manifest, root causes, and defensive patterns.
| Symptom | Root cause | DO NOT do | DO instead |
|---|---|---|---|
| Tool not invoked when expected | Tool description too vague or contradicts agent instructions | Write generic tool descriptions like "search for things" | Write specific descriptions naming inputs/outputs/preconditions — e.g. "Search product catalog by name or SKU; returns title + price + stock" |
| Tool invoked too aggressively | Tool description too tempting OR no scoping in agent system prompt | Rely solely on description to control invocation | Add explicit tool-use scope rules in the agent's `instructions=` parameter; e.g. "Only call product_search after confirming the user requested a search" |
| Malformed JSON returned by tool | Tool returns Python object via plain `print()` or `return` | Return non-JSON-serializable objects (dicts, tuples, custom classes without serialization) | Use Pydantic models with `.model_dump()` or explicit `json.dumps()` serialization before returning |
| Tool exception bubbles up as `session_not_ready` (424) | Tool raises unhandled exception → container crashes → no error trace surfaced | Let tool exceptions propagate to the framework | Wrap tool body in `try/except` and return a structured error dict the model can reason about — e.g. `{"error": "...reason...", "retry_in_seconds": 30}` |
| Tool description doesn't match agent intent | Spec says "summarize PDFs" but tool description says "extract text" | Let tool descriptions drift from the agent's stated capabilities | Sync tool descriptions against spec.md § Agent Tools during every spec review — re-check before each promotion |
---
## Step 1 — Create a toolbox version
Python SDK (azure-ai-projects):
```python
import os
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
AISearchIndexResource,
AzureAISearchToolResource,
AzureAISearchToolboxTool,
MCPToolboxTool,
WebSearchToolboxTool,
)
from azure.identity import DefaultAzureCredential
with (
DefaultAzureCredential() as credential,
AIProjectClient(
endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
credential=credential,
) as project,
):
toolbox_version = project.toolboxes.create_version(
name="agent-tools",
description="Web search + product index + Microsoft Learn MCP",
tools=[
WebSearchToolboxTool(name="web-search"),
AzureAISearchToolboxTool(
name="product-index",
azure_ai_search=AzureAISearchToolResource(
indexes=[
AISearchIndexResource(
index_name="products",
project_connection_id="aisearch-conn",
),
],
),
),
MCPToolboxTool(
server_label="mslearn",
server_url="https://learn.microsoft.com/api/mcp",
require_approval="never",
),
],
)
print(
f"Created {toolbox_version.name} "
f"version {toolbox_version.version}"
)
```
`project.toolboxes` exposes `create_version`, `get`, `list`, `delete`,
`update`, `get_version`, `list_versions`, `delete_version`; stable management
does not require `allow_preview=True`.
> **Current API matrix (validated 2026-08-04):**
>
> | Package | Supported line |
Auf GitHub ansehen