Microsoft Foundry 工具箱是托管工具配置的命名、版本控制的服务器端捆绑包,例如代码解释器、文件搜索、图像生成、MCP 和 Web 搜索。 工具箱允许你在 Foundry 中管理工具配置一次,并在代理之间重复使用它。
代理框架涵盖工具箱消耗。 通过 Foundry 门户或 azure-ai-projects SDK 创建和更新工具箱版本。
Important
FoundryToolbox 由 beta agent-framework-foundry-hosting 包提供,可以在稳定发布之前进行更改。
对于服务托管 FoundryAgent,将工具箱附加到 Foundry 中的代理定义。 目前未记录客户端.NET工具箱使用指南。
安装软件包
pip install agent-framework-foundry-hosting agent-framework-foundry --pre
FoundryToolbox是从 .agent_framework.foundryagent-framework-foundry-hosting.
配置工具箱
设置显式工具箱 MCP 终结点:
TOOLBOX_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>/toolboxes/<name>/mcp?api-version=v1"
或者让 FoundryToolbox 构造终结点:
FOUNDRY_PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
TOOLBOX_NAME="<toolbox-name>"
托管代理示例也用于 AZURE_AI_MODEL_DEPLOYMENT_NAMEFoundryChatClient。
FoundryToolbox与托管代理一起使用
FoundryToolbox解析其终结点,使用提供的Azure凭据对每个 MCP 请求进行身份验证,转发 Foundry 每请求调用 ID,并参与代理的连接生命周期。
import asyncio
import os
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox, ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
async def main():
credential = DefaultAzureCredential()
# FoundryToolbox resolves the toolbox endpoint from the environment
# (TOOLBOX_ENDPOINT, or FOUNDRY_PROJECT_ENDPOINT + TOOLBOX_NAME), authenticates
# every request with the credential, and transparently forwards the platform
# per-request call-id to the toolbox. The hosting server enters the agent, which
# connects the toolbox on first use and closes it at shutdown.
toolbox = FoundryToolbox(credential)
# Create the chat client
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=credential,
)
agent = Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=toolbox,
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
default_options={"store": False},
)
server = ResponsesHostServer(agent)
await server.run_async()
公开工具箱技能
工具箱可以通过 MCP 公开代理技能。 仅当技能应为模型可见时设置 load_tools=False ,然后将工具箱添加为工具,以便其 MCP 会话连接并用作 as_skills_provider() 上下文提供程序。
import asyncio
import os
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox, ResponsesHostServer
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv
# Load environment variables from .env file
load_dotenv()
async def main() -> None:
credential = DefaultAzureCredential()
# FoundryToolbox resolves the toolbox endpoint from the environment
# (TOOLBOX_ENDPOINT, or FOUNDRY_PROJECT_ENDPOINT + TOOLBOX_NAME), authenticates
# every request with the credential, and forwards the platform per-request
# call-id. ``load_tools=False`` keeps the toolbox's tools hidden so only its
# Agent Skills (SEP-2640) are surfaced; passing it via ``tools=`` connects the
# MCP session that ``as_skills_provider()`` reads from.
toolbox = FoundryToolbox(credential, load_tools=False)
# as_skills_provider() discovers skills from skill://index.json on the toolbox
# MCP session and exposes them as an agent context provider; SKILL.md bodies are
# fetched on demand via resources/read. disable_load_skill_approval=True registers
# the load_skill tool with approval_mode="never_require" so this unattended agent
# can load skills without an approval round-trip -- the Responses host runs the
# agent without an AgentSession, which the default approval flow requires.
skills_provider = toolbox.as_skills_provider(disable_load_skill_approval=True)
client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=credential,
)
agent = Agent(
client=client,
name=os.environ.get("AGENT_NAME", "hosted-toolbox-mcp-skills"),
instructions="You are a helpful assistant.",
tools=toolbox,
context_providers=[skills_provider],
# History will be managed by the hosting infrastructure, thus there
# is no need to store history by the service. Learn more at:
# https://developers.openai.com/api/reference/resources/responses/methods/create
default_options={"store": False},
)
server = ResponsesHostServer(agent)
await server.run_async()
默认情况下,技能操作仍启用审批。 仅对受信任的无人参与方案禁用单个审批。
将工具箱与 FoundryAgent
将工具箱附加到 Foundry 中的提示或托管代理定义。
FoundryAgent 使用存储的工具配置;传递工具箱客户端不会将其添加到托管代理。
通过原始 MCP 进行连接
当应用程序不使用宿主包装器时直接使用MCPStreamableHTTPToolFoundryToolbox。 通过 提供工具箱终结点和Entra ID持有者令牌header_provider。
import asyncio
import os
from collections.abc import Callable
from typing import Any, cast
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient
from azure.core.credentials import TokenCredential
from azure.identity import AzureCliCredential, DefaultAzureCredential, get_bearer_token_provider
from dotenv import load_dotenv
def make_toolbox_header_provider(credential: TokenCredential) -> Callable[[dict[str, Any]], dict[str, str]]:
"""Build a header_provider that injects a fresh Azure AI bearer token on every MCP request."""
get_token = get_bearer_token_provider(credential, "https://ai.azure.com/.default")
def provide(_kwargs: dict[str, Any]) -> dict[str, str]:
return {
"Authorization": f"Bearer {get_token()}",
}
return provide
async def main() -> None:
credential = DefaultAzureCredential()
toolbox_tool = MCPStreamableHTTPTool(
name="foundry_toolbox",
description="Tools exposed by the configured Foundry toolbox",
url=os.environ["FOUNDRY_TOOLBOX_ENDPOINT"],
header_provider=make_toolbox_header_provider(credential),
load_prompts=False,
)
async with Agent(
client=FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=credential,
),
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?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Assistant: {result}")
较低级别的示例使用 FOUNDRY_TOOLBOX_ENDPOINT。 工具箱技能示例使用 FOUNDRY_TOOLBOX_MCP_SERVER_URL;这些名称属于这些示例,独立于 FoundryToolbox 类 TOOLBOX_ENDPOINT 和 TOOLBOX_NAME 设置。
Limitations
- 工具箱中的 MCP 工具通过 Foundry
project_connection_id使用服务器端身份验证;代理框架客户端不保存上游 MCP 持有者令牌。 - 使用工具箱作为 MCP 服务器需要对工具箱终结点进行客户端Entra ID身份验证。
- 同意流响应(例如
CONSENT_REQUIRED,在代理运行时处理),而不是在创建工具箱连接时处理。
Samples
| Sample | Description |
|---|---|
| foundry_toolbox/main.py |
FoundryToolbox 使用托管响应代理 |
| foundry_toolbox_mcp_skills/main.py | 工具箱支持的代理技能 |
| foundry_chat_client_with_toolbox.py | 使用 MCPStreamableHTTPTool 的工具箱 MCP 使用量 |
| foundry_chat_client_with_toolbox_skills.py | 由工具箱支持的技能配置 |
| invoke_foundry_toolbox_mcp | 工作流端 MCP 消耗 |
Go 当前不公开 Foundry 工具箱帮助程序。 通过 Foundry 配置工具箱,并使用 Go 代理支持的本地或托管工具声明。