Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Deploy, evaluate, and manage AI agents end-to-end on Microsoft Azure AI Foundry
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
foundry-agent/create/references/use-toolbox-in-hosted-agent.md
1# Use Toolbox in a Hosted Agent23Hosted agents access Foundry-managed tools through a **Toolbox MCP endpoint**. Unlike prompt agents that wire tools directly, hosted agents connect to a single MCP-compatible endpoint that exposes all configured tools. The platform handles credential injection, token refresh, and policy enforcement.45> ๐ฆ **Toolbox creation gate:** before creating a toolbox/connection, you MUST read the boundary rules in [create-hosted.md โ Toolbox creation boundary](../create-hosted.md#toolbox-creation-boundary) and follow them, then continue with the rest of this file.67> ๐ For endpoint format, MCP protocol details, auth, OAuth consent handling, testing, citation pattern, and troubleshooting, see [toolbox-reference.md](toolbox-reference.md).8>9> ๐ For wiring a remote tool (catalog tile or generic MCP server) into a project connection that a toolbox can attach to, see [foundry-tool-catalog.md](foundry-tool-catalog.md).10>11> ๐ For the full list of supported tool types and their per-type fields, see [agent-tools.md](agent-tools.md) and the per-tool `tool-*.md` files.1213> ๐ก **This skill is scoped to *consuming* an existing toolbox from agent code** โ endpoint resolution, env-var contract, payload shape gathered before agent runtime, verification, and tracing. **Toolbox and connection CRUD belongs in [Foundry Toolkit (VS Code)](https://code.visualstudio.com/docs/intelligentapps/tool-catalog) or the [Foundry Portal](https://ai.azure.com/)** โ those surfaces give you tool browsing, metadata, connection wizards, and validation. Use the imperative `azd ai` CLI only for *operational* tasks (retarget the default version, smoke-test an endpoint).1415## โจ Recommendation: enable Tool Search1617**Before adding more than ~5 tools to a toolbox, add `{ "type": "toolbox_search_preview" }` to the toolbox.** This replaces the full `tools/list` shown to the model with two meta-tools โ `tool_search` (natural-language discovery) and `call_tool` (invoke a discovered tool) โ so context cost stays flat as the toolbox grows.1819- The `toolbox_search_preview` entry **doesn't count** toward the unnamed-tool-per-type limit.20- All other tools in the toolbox are hidden from the initial `tools/list` and surfaced only by `tool_search` (or by per-user auto-pinning of hot tools).21- Pin specific high-traffic tools or add ranking-only keywords via `tool_configs.{tool_name}` (with `pin: true` and `additional_search_text`).22- In the agent's system prompt, instruct the model to call `tool_search` whenever a needed capability isn't already visible.2324Full configuration recipe in [tool-tool-search.md](tool-tool-search.md) and the public [Tool Search (preview) docs](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/tool-search).2526## Quick Reference2728| Property | Value |29|----------|-------|30| **Toolbox Docs** | https://learn.microsoft.com/azure/foundry/agents/how-to/tools/toolbox |31| **Tool Catalog Docs** | https://learn.microsoft.com/azure/foundry/agents/concepts/tool-catalog |32| **Tool Search Docs** | https://learn.microsoft.com/azure/foundry/agents/how-to/tools/tool-search |33| **Foundry Toolkit (VS Code) โ set up tools/toolboxes** | https://code.visualstudio.com/docs/intelligentapps/tool-catalog |34| **Foundry Portal** | https://ai.azure.com/ |35| **Default Sample (Python, Agent Framework + toolbox)** | https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/agent-framework/responses/04-foundry-toolbox |36| **Python Hosted Agent โ `responses` (BYO)** | https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/bring-your-own/responses |37| **Python Hosted Agent โ `invocations` (BYO)** | https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/bring-your-own/invocations |38| **C# (.NET) Hosted Agent + toolbox** | https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/csharp/hosted-agents/agent-framework/foundry-toolbox-server-side |39| **Supported Toolbox Scenarios (sample-side reference)** | https://github.com/microsoft-foundry/foundry-samples/blob/main/samples/python/hosted-agents/SUPPORTED_TOOLBOX_SCENARIOS.md |4041## Resolve Toolbox Endpoint4243If the user provides a toolbox name or endpoint URL, or the project already references a toolbox (e.g., in `.env` or `agent.manifest.yaml`) โ use it directly.4445Otherwise, ask one question:4647> _"Would you like to provide your toolbox endpoint? (you can create one with the [Foundry Toolkit in VS Code](https://code.visualstudio.com/docs/intelligentapps/tool-catalog) or the [Foundry Portal](https://ai.azure.com/))"_4849Once the user supplies the toolbox name/endpoint โ either an existing one or a new one they create via the Foundry Toolkit or Foundry Portal โ set it on the agent (e.g., `TOOLBOX_ENDPOINT` in `.env`) and continue with verification.5051> Use the env var name **`TOOLBOX_ENDPOINT`** (no `FOUNDRY_` prefix). The Foundry platform reserves `FOUNDRY_`-prefixed env vars and may silently overwrite them at runtime โ see [toolbox-reference.md ยง Agent env contract](toolbox-reference.md#agent-env-contract).5253> **When asking the question, always include the doc links inline** for the manual options โ the [Foundry Toolkit in VS Code](https://code.visualstudio.com/docs/intelligentapps/tool-catalog) and the [Foundry Portal](https://ai.azure.com/) โ so the user knows where to go to create a tool/toolbox themselves. Don't just name the options; render them as clickable links every time.5455> **Before printing out any step-by-step guidance** for the Foundry Toolkit (VS Code) path, fetch and read [Use Tool Catalog to connect tools and Toolboxes in Foundry Toolkit](https://code.visualstudio.com/docs/intelligentapps/tool-catalog) first, then summarize the relevant steps for them. Don't paraphrase from memory โ the Toolkit UI changes; quote the current doc.5657## Available tool types5859The full set is documented in [agent-tools.md](agent-tools.md) and โ authoritatively โ in the public [Toolbox docs (Configure tools)](https://learn.microsoft.com/azure/foundry/agents/how-to/tools/toolbox#configure-tools). At time of writing the supported `type` values are:6061| `type` | Tool | Connection required? | Detail |62|---|---|---|---|63| `mcp` | Remote MCP server (third-party via catalog, BYO OAuth, or generic) | Optional (none / static key / project MI / OAuth) | [tool-mcp.md](tool-mcp.md) |64| `web_search` | Web search (basic Bing; optional `web_search.custom_search_configuration` for Bing Custom Search to scope grounding to specific domains) | No (basic); Yes for Custom Search | [tool-web-search.md](tool-web-search.md) |65| `azure_ai_search` | Azure AI Search index | Yes (Search service connection) | [tool-azure-ai-search.md](tool-azure-ai-search.md) |66| `code_interpreter` | Sandboxed Python execution | No | [tool-code-interpreter.md](tool-code-interpreter.md) |67| `file_search` | Vector-store-backed retrieval over uploaded files | No (vector store is part of the toolbox) | [tool-file-search.md](tool-file-search.md) |68| `openapi` | REST API exposed via an OpenAPI 3.x spec | Conditional (`connection` requires `project_connection_id`; `managed_identity` does not โ uses project MI + `audience`) | [tool-openapi.md](tool-openapi.md) |69| `a2a_preview` | Call another Foundry agent as a tool | Optional | [tool-a2a.md](tool-a2a.md) |70| `work_iq_preview` | Microsoft 365 work context (mail / meetings / files / chats) via Work IQ | Yes (Work IQ `RemoteA2A` OAuth connection; BYO Entra app; M365 Copilot license per user) | [tool-work-iq.md](tool-work-iq.md) |71| `fabric_iq_preview` | Microsoft Fabric data (Ontology / Fabric data agent / Power BI semantic model) | Yes (Fabric IQ OAuth connection; tenant admin consent) | [tool-fabric-iq.md](tool-fabric-iq.md) |72| `toolbox_search_preview` | **Tool Search** โ a directive (not a tool) that swaps `tools/list` for `tool_search` + `call_tool` meta-tools | No | [tool-tool-search.md](tool-tool-search.md) |7374**Adjacent (not a `type` in a toolbox version):**7576- **Agent Memory** โ use the `MemorySearchTool` SDK class on prompt agents; for hosted agents, configure the memory store via the project (separate from the toolbox). See [tool-memory.md](tool-memory.md).77- **Skills** โ reusable behavioral guidelines (`SKILL.md`) attached via the `skills[]` array, exposed as MCP resources (`skill://` URIs); the Agent Framework SDK wraps these into a `load_skill` tool for progressive disclosure. See [skill-toolbox.md](skill-toolbox.md).78- **Routines (preview)** โ not a tool; an agent **trigger** (`schedule` / `timer` / `github_issue` / `custom`) that invokes an existing agent. See the [public Routines docs](https://learn.microsoft.com/azure/foundry/agents/how-to/use-routines).7980## Information to Gather Before Building a Toolbox Payload8182When the user asks to "add an MCP tool" or similar, **never guess**. Confirm each field before generating any JSON or `azure.yaml` snippet:8384| # | Question | Why needed |85|---|----------|------------|86| 1 | **MCP server URL?** | The `server_url` field on the `mcp` tool entry |87| 2 | **Auth type?** `none` / `key` / `mi` / `oauth` | Determines whether a project connection is required and which shape to create (see [foundry-tool-catalog.md](foundry-tool-catalog.md)) |88| 3 | **Project connection name** (if auth โ `none`) | The `project_connection_id` field; must already exist in the Foundry project |89| 4 | **`server_label`** | Short prefix for the tool names exposed by this server (e.g. `myserver`) |90| 5 | **Toolbox name** | The container that will hold the tool entries |91| 6 | **Foundry project endpoint** | Where the toolbox is created โ read from `PROJECT_ENDPOINT` / `AZURE_AI_PROJECT_ENDPOINT` (avoid `FOUNDRY_`-prefixed names) |92| 7 | **Many tools planned?** (> ~5) | If yes, also add `{ "type": "toolbox_search_preview" }` so the model uses [Tool Search](#-recommendation-enable-tool-search) instead of seeing the full list. |9394### Toolbox payload โ MCP with a project connection9596```json97{98"name": "<TOOLBOX_NAME>",99"description": "MCP server with key or OAuth auth",100"tools": [101{102"type": "mcp",103"server_label": "<LABEL>",104"server_url": "<SERVER_URL>",105"require_approval": "never",106"project_connection_id": "<CONNECTION_NAME>"107}108]109}110```111112### Toolbox payload โ public MCP (no auth)113114```json115{116"name": "api-specs",117"description": "Public MCP server, no connection needed",118"tools": [119{120"type": "mcp",121"server_label": "api_specs",122"server_url": "https://gitmcp.io/Azure/azure-rest-api-specs",123"require_approval": "never"124}125]126}127```128129### Toolbox payload โ large toolbox with Tool Search130131```json132{133"name": "big-toolbox",134"description": "Many tools โ model uses tool_search to discover",135"tools": [136{ "type": "toolbox_search_preview" },137{ "type": "web_search" },138{ "type": "azure_ai_search", "name": "docs_index", "project_connection_id": "search-conn", "index_name": "docs" },139{140"type": "mcp", "server_label": "github", "server_url": "<github-mcp-url>",141"project_connection_id": "gh-conn",142"tool_configs": {143"search_issues": { "pin": true, "additional_search_text": "GitHub issues bug tracking" },144"*": { "additional_search_text": "GitHub repositories code" }145}146}147]148}149```150151### Declarative path via `azd`152153If the project already uses `azd ai agent init`, prefer declaring the toolbox in `azure.yaml` so `azd deploy` provisions it and injects `TOOLBOX_ENDPOINT` automatically:154155```yaml156# Declare secret parameters first; azd will prompt for the value on `azd up`157# (or read it from `AZURE_<NAME>` env vars) and never store it in plaintext.158params:159- name: github_pat160type: securestring161162resources:163- kind: connection164name: <CONNECTION_NAME>165target: <MCP_SERVER_URL>166category: remoteTool167credentials:168type: CustomKeys169keys:170# Header name comes from the catalog entry's x-ms-connection-parameters.171# {{ github_pat }} is resolved from the `params` block above.172Authorization: "Bearer {{ github_pat }}"173174- kind: toolbox175name: agent-tools176tools:177- type: toolbox_search_preview # recommended for any toolbox > ~5 tools178- type: web_search179- type: mcp180server_label: <LABEL>181server_url: <MCP_SERVER_URL>182project_connection_id: <CONNECTION_NAME>183```184185See [azd `params` reference](https://learn.microsoft.com/azure/developer/azure-developer-cli/azd-schema#params) for the full parameter syntax.186187## Operational helpers via `azd ai` CLI188189> The `azd ai` CLI also exposes `agent connection create`, `toolbox create`, `toolbox list`, and `toolbox delete`. Prefer **Foundry Toolkit (VS Code)** or the **Foundry Portal** for those โ the UI gives you tool browsing, connection wizards, and validation. The two commands below are the ones the skill should still drive directly because they're *operational*, not setup.190191> All commands require `--project-endpoint <PROJECT_ENDPOINT>` (the value of `PROJECT_ENDPOINT`, e.g. `https://<account>.services.ai.azure.com/api/projects/<project>`). To avoid repeating it, export it once:192>193> ```pwsh194> $PE = "https://<account>.services.ai.azure.com/api/projects/<project>"195> ```196197### Retarget the default version โ `azd ai toolbox update`198199Each toolbox version is **immutable**. The version an agent actually hits is the one marked `*` in `version list` โ i.e. the **default version**. Use `update` to point that pointer at any existing version (e.g. rollback to a known-good version after a bad publish).200201```pwsh202# Inspect first โ current default is marked with '*'203azd ai toolbox version list my-toolbox --project-endpoint $PE204205# Retarget the default206azd ai toolbox update my-toolbox --default-version 20 --project-endpoint $PE --no-prompt207208# Verify (Default version / Shown version / Endpoint all reflect the new value)209azd ai toolbox show my-toolbox --project-endpoint $PE210```211212- `--default-version` is the only field `update` accepts today.213- Validated: switched `default-tb` from version 21 โ 20 โ 21; both `show` and the computed MCP endpoint (`.../toolboxes/<name>/versions/<n>/mcp?api-version=v1`) tracked the change immediately.214215### End-to-end smoke test216217After the toolbox is created (via Toolkit / Portal / `azd`), hit the MCP endpoint directly to confirm the tool is reachable before pointing an agent at it:218219```pwsh220$TOK = az account get-access-token --resource "https://ai.azure.com" --query accessToken -o tsv221$H = @{222Authorization = "Bearer $TOK"223"Content-Type" = "application/json"224"Foundry-Features" = "Toolboxes=V1Preview"225}226$URL = "$PE/toolboxes/my-toolbox/mcp?api-version=v1"227$body = @{ jsonrpc = "2.0"; id = 1; method = "tools/list"; params = @{} } | ConvertTo-Json228(Invoke-RestMethod -Method POST -Uri $URL -Headers $H -Body $body).result.tools | Select-Object name229```230231`?api-version=v1` and the `Foundry-Features: Toolboxes=V1Preview` header are both required.232233## Code Integration Patterns234235The sample repo provides integration patterns for both Python and C#. Read the sample code and adapt it to the user's project.236237**Python samples:**238239| Sample | Framework | Protocol | When to use |240|--------|-----------|----------|-------------|241| [`agent-framework/responses/04-foundry-toolbox/`](https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/agent-framework/responses/04-foundry-toolbox) โ recommended | Agent Framework (MAF) | Responses | **Default choice** |242| [`bring-your-own/responses/langgraph-toolbox/`](https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/bring-your-own/responses/langgraph-toolbox) | LangGraph (BYO) | Responses | LangGraph hosted agent with toolbox |243| [`bring-your-own/responses/bring-your-own-toolbox/`](https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/bring-your-own/responses/bring-your-own-toolbox) | Generic MCP (BYO) | Responses | Raw `httpx` MCP client โ works with any framework |244| [`bring-your-own/invocations/toolbox/`](https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents/bring-your-own/invocations/toolbox) | Generic MCP (BYO) | Invocations | Toolbox via Invocations protocol |245246**C# (.NET) samples:**247248| Sample | Description |249|--------|-------------|250| [`csharp/hosted-agents/agent-framework/foundry-toolbox-server-side/`](https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/csharp/hosted-agents/agent-framework/foundry-toolbox-server-side) โ recommended | Agent Framework agent with toolbox MCP (Responses protocol) |251252**Notes** (apply to all patterns, both Python and C#):253254- Auth: Inject a bearer token with scope `https://ai.azure.com/.default` on every request (Python: `httpx.Auth` subclass; C#: `DefaultAzureCredential` + `BearerTokenAuthenticationPolicy`).255- Header: Always include `Foundry-Features: Toolboxes=V1Preview`.256- MCP client: Pass `load_prompts=False` โ the toolbox endpoint does not support `prompts/list`.257- Endpoint: Construct from `{project_endpoint}/toolboxes/{toolbox_name}/mcp?api-version=v1`.258- Multi-tool toolboxes: at most one tool per unnamed type, and unique `server_label` per MCP tool (see [toolbox-reference.md](toolbox-reference.md#multi-tool-toolbox-constraint)). `toolbox_search_preview` doesn't count toward this limit.259- Tool naming: MCP-sourced tools are prefixed `{server_label}.{tool_name}`; **all other tool types** use the entry's `name` field value (or the default tool name).260261> ๐ก **Tip:** If MCP tools have `require_approval: "always"` in `_meta.tool_configuration`, the agent runtime must ask the user for confirmation before invoking. The toolbox endpoint does not enforce this โ your agent code is responsible.262263## Tracing264265All toolbox samples emit OpenTelemetry traces. No code changes are required to enable export to Azure Monitor โ it's purely a configuration step.266267- **Local development:** set `APPLICATIONINSIGHTS_CONNECTION_STRING` in the agent's `.env`.268- **Deployed:** the platform injects `APPLICATIONINSIGHTS_CONNECTION_STRING` automatically when the Foundry project is linked to an Application Insights resource.269- **Per-framework instrumentation hooks** (already present in the samples):270- `maf` โ `main.py` calls `enable_instrumentation()`.271- `langgraph` / `azd` โ auto-instrumented by `azure-ai-agentserver-core[tracing]`.272- **Viewing traces:** Azure Portal โ Application Insights โ **Investigate โ Transaction search** (per-trace) or **Application map** (dependency graph).273