Microsoft Foundry ツールボックスは、コード インタープリター、ファイル検索、イメージ生成、MCP、Web 検索など、ホストされるツール構成の名前付きのバージョン管理されたサーバー側バンドルです。 ツールボックスを使用すると、Foundry でツール構成を 1 回管理し、エージェント間で再利用できます。
Agent Framework では、ツールボックスの使用量について説明します。 Foundry ポータルまたは azure-ai-projects SDK を使用してツールボックスのバージョンを作成および更新します。
Important
FoundryToolbox はベータ agent-framework-foundry-hosting パッケージによって提供され、安定リリース前に変更される可能性があります。
サービスで管理される FoundryAgentの場合は、Foundry のエージェント定義にツールボックスをアタッチします。
Microsoft Agent Framework で構築されたホスト型エージェントの場合は、次の例に示すように、Microsoft.Agents.AI.Foundry.HostingのAddFoundryToolboxesを使用します。
暗黙的な using が有効になっている .NET 10 の Web プロジェクトを使用し、Microsoft.Agents.AI.Foundry、Microsoft.Agents.AI.Foundry.Hosting、DotNetEnv のバージョンを一致させます。
TOOLBOX_NAMEを既存のツールボックスに設定し、モデルデプロイにFOUNDRY_MODELします。 Foundry は、デプロイされたホストに FOUNDRY_PROJECT_ENDPOINT を提供します。 ローカル モデルにアクセスするには、FOUNDRY_PROJECT_ENDPOINTを設定し、Azure CLIを使用してサインインします。 ホスト型デプロイは、azd で管理される AZURE_AI_MODEL_DEPLOYMENT_NAME にフォールバックされます。 ホスティング統合では、 FOUNDRY_PROJECT_ENDPOINT が使用可能になるとツールボックス ツールが読み込まれます。
using DotNetEnv;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry.Hosting;
// Load .env file if present (for local development)
Env.TraversePath().Load();
string endpoint = System.Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")
?? throw new InvalidOperationException("FOUNDRY_PROJECT_ENDPOINT is not set.");
string deploymentName = FirstNonBlank(
System.Environment.GetEnvironmentVariable("FOUNDRY_MODEL"),
System.Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME"),
"gpt-4o")!;
string toolboxName = FirstNonBlank(
System.Environment.GetEnvironmentVariable("TOOLBOX_NAME"),
"my-toolset")!;
// WARNING: DefaultAzureCredential is convenient for development but requires careful consideration in production.
// In production, consider using a specific credential (e.g., ManagedIdentityCredential) to avoid
// latency issues, unintended credential probing, and potential security risks from fallback mechanisms.
// Use a chained credential: try a temporary dev token first (for local Docker debugging),
// then fall back to DefaultAzureCredential (for local dev via dotnet run / managed identity in production).
.AsAIAgent(
model: deploymentName,
Use the available tools to answer user questions.
If a tool is not available for a request, let the user know clearly.
""",
name: System.Environment.GetEnvironmentVariable("AGENT_NAME") ?? "hosted-toolbox-agent",
description: "Hosted agent backed by Foundry Toolbox MCP tools");
// ── Build the host ────────────────────────────────────────────────────────────
var builder = WebApplication.CreateBuilder(args);
// Register the agent and response handler
// Register Foundry Toolbox: connects to the MCP proxy at startup and makes tools available.
// The toolbox name must match a toolbox registered in your Foundry project.
// When FOUNDRY_PROJECT_ENDPOINT is absent (e.g., in local development without Foundry
// infrastructure), startup succeeds without error and no toolbox tools are loaded.
builder.Services.AddFoundryToolboxes(credential, toolboxName);
app.Run();
static string? FirstNonBlank(params string?[] candidates) =>
Array.Find(candidates, candidate => !string.IsNullOrWhiteSpace(candidate));
// ── DevTemporaryTokenCredential ───────────────────────────────────────────────
同じホスティング登録では、ツールボックス接続でユーザーごとの OAuth 同意用に構成されたツールがサポートされます。 ユーザーには引き続き必要なアクセス許可と同意が必要です。別のホスト登録ブロックは必要ありません。
プロジェクト ファイルと配置手順については、「 Hosted-Toolbox」を参照してください。 ユーザーごとの同意のセットアップについては、「 Hosted-Toolbox-AuthPaths」を参照してください。
パッケージをインストールする
pip install agent-framework-foundry-hosting agent-framework-foundry --pre
FoundryToolbox は agent_framework.foundry からインポートされ、 agent-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>"
hosted-agent サンプルでは、ローカル FOUNDRY_MODEL を優先し、ホストされている場合は azd マネージド AZURE_AI_MODEL_DEPLOYMENT_NAME にフォールバックします。
ホストされているエージェントで FoundryToolbox を使用する
FoundryToolboxはエンドポイントを解決し、指定されたAzure資格情報を使用してすべての MCP 要求を認証し、Foundry 要求ごとの呼び出し ID を転送して、エージェントの接続ライフサイクルに参加します。 各操作境界でプラットフォーム ヘッダーを解決し、有効な要求 ID が変更されたときに MCP セッションを再接続します。 そのため、有効期間が長いツールボックスでは、以前の呼び出し元の呼び出し ID は保持されません。
このサンプルでは、決定論的な所有権とクリーンアップのために、要求スコープのエージェント ファクトリ内にツールボックス、クライアント、認証情報を作成します。 このファクトリ パターンは、関連リソースが要求で所有されている場合に使用しますが、ツールボックス呼び出し ID を最新の状態に保つためだけに必要なわけではありません。
import asyncio
import os
from contextlib import AsyncExitStack
from types import TracebackType
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.core import AgentConfig, get_request_context
from azure.identity.aio import AzureCliCredential, ManagedIdentityCredential
from dotenv import load_dotenv
def create_agent() -> Agent:
"""Create request-owned SDK resources and close them with the agent."""
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_MODEL") or os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
credential = (
ManagedIdentityCredential(client_id=os.environ.get("FOUNDRY_AGENT_INSTANCE_CLIENT_ID"))
if AgentConfig.from_env().is_hosted
else AzureCliCredential()
)
class RequestClient(FoundryChatClient):
async def __aenter__(self) -> RequestClient:
return self
async def __aexit__(
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
) -> None:
async with AsyncExitStack() as cleanup:
cleanup.push_async_callback(credential.close)
cleanup.push_async_callback(self.project_client.close)
cleanup.push_async_callback(self.client.close)
toolbox = FoundryToolbox(credential)
client = RequestClient(
project_endpoint=endpoint,
model=model,
credential=credential,
default_headers=get_request_context().platform_headers(),
)
return Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=toolbox,
)
async def main() -> None:
load_dotenv()
server = ResponsesHostServer(agent=create_agent, history_source="agent_server")
await server.run_async()
ツールボックス コード インタープリターでファイルが生成され、アシスタントの応答でそのファイル名が示されると、ホストされた応答アダプターは、コンテナー ID とファイル ID を使用してネイティブの container_file_citation 注釈を出力します。 応答クライアントはこれらの ID を使用して、コンテナ ファイル API を介して生成されたファイルを検出し、ダウンロードできます。
ツールボックスのスキルを公開する
ツールボックスは、MCP 経由でエージェント スキルを公開できます。 スキルのみをモデルで表示する必要がある場合に load_tools=False 設定し、ツールとしてツールボックスを追加して、MCP セッションが接続し、コンテキスト プロバイダーとして as_skills_provider() を使用できるようにします。
import asyncio
import os
from contextlib import AsyncExitStack
from types import TracebackType
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.core import AgentConfig, get_request_context
from azure.identity.aio import AzureCliCredential, ManagedIdentityCredential
from dotenv import load_dotenv
def create_agent() -> Agent:
"""Keep skill caches, credentials and the MCP lifecycle request-owned."""
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_MODEL") or os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
credential = (
ManagedIdentityCredential(client_id=os.environ.get("FOUNDRY_AGENT_INSTANCE_CLIENT_ID"))
if AgentConfig.from_env().is_hosted
else AzureCliCredential()
)
class RequestClient(FoundryChatClient):
async def __aenter__(self) -> RequestClient:
return self
async def __aexit__(
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
) -> None:
async with AsyncExitStack() as cleanup:
cleanup.push_async_callback(credential.close)
cleanup.push_async_callback(self.project_client.close)
cleanup.push_async_callback(self.client.close)
# tools= connects the MCP session; context_providers= reads skills from that same session.
toolbox = FoundryToolbox(credential, load_tools=False)
skills_provider = toolbox.as_skills_provider(disable_load_skill_approval=True)
client = RequestClient(
project_endpoint=endpoint,
model=model,
credential=credential,
default_headers=get_request_context().platform_headers(),
)
return 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],
)
async def main() -> None:
load_dotenv()
server = ResponsesHostServer(agent=create_agent, history_source="agent_server")
await server.run_async()
スキル操作では、承認は既定で有効なままです。 個々の承認は、信頼された無人シナリオに対してのみ無効にします。
ツールボックスとそのスキル プロバイダーを一緒に保持して、両方とも同じ MCP セッションを使用します。 有効期間が長いツールボックスの場合、実効プラットフォーム ヘッダー識別情報が変更されると、スキル検出キャッシュが置き換えられます。 スキルで使用されるカスタム header_provider は、スキルとリソースの読み取りでは関数ランタイム引数を受け取らないので、クロージャや ContextVarなどのアンビエント状態から解決する必要があります。
ツールボックスを使う FoundryAgent
Foundry のプロンプトまたはホストされるエージェント定義にツールボックスをアタッチします。
FoundryAgent その保存されたツール構成を使用します。ツールボックスクライアント側を渡しても、マネージド エージェントに追加されません。
FoundryToolbox を使用して MCP 経由で接続する
FoundryToolboxとResponsesHostServerを使用して、ホストされたエージェントをツールボックス MCP エンドポイントに接続します。 ラッパーは MCP 要求を認証し、現在ホストされている要求の呼び出し元コンテキストをユーザーごとの ID パススルーに転送します。
要求スコープの agent ファクトリは、クライアント、資格情報、ツールボックスで同じクリーンアップ境界線が必要な場合に最もシンプルなオプションです。 長寿命のツールボックスもサポートされ、platform-header ID が変更された場合は、操作の前に再接続されます。
import asyncio
import os
from contextlib import AsyncExitStack
from types import TracebackType
from agent_framework import Agent
from agent_framework.foundry import FoundryChatClient, FoundryToolbox
from agent_framework_foundry_hosting import ResponsesHostServer
from azure.ai.agentserver.core import AgentConfig, get_request_context
from azure.identity.aio import AzureCliCredential, ManagedIdentityCredential
from dotenv import load_dotenv
def create_agent() -> Agent:
"""Create request-owned SDK resources and close them with the agent."""
endpoint = os.environ["FOUNDRY_PROJECT_ENDPOINT"]
model = os.environ.get("FOUNDRY_MODEL") or os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"]
credential = (
ManagedIdentityCredential(client_id=os.environ.get("FOUNDRY_AGENT_INSTANCE_CLIENT_ID"))
if AgentConfig.from_env().is_hosted
else AzureCliCredential()
)
class RequestClient(FoundryChatClient):
async def __aenter__(self) -> RequestClient:
return self
async def __aexit__(
self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
) -> None:
async with AsyncExitStack() as cleanup:
cleanup.push_async_callback(credential.close)
cleanup.push_async_callback(self.project_client.close)
cleanup.push_async_callback(self.client.close)
toolbox = FoundryToolbox(credential)
client = RequestClient(
project_endpoint=endpoint,
model=model,
credential=credential,
default_headers=get_request_context().platform_headers(),
)
return Agent(
client=client,
instructions="You are a friendly assistant. Keep your answers brief.",
tools=toolbox,
)
async def main() -> None:
load_dotenv()
server = ResponsesHostServer(agent=create_agent, history_source="agent_server")
await server.run_async()
ツールボックスの構成の説明に従って、 TOOLBOX_ENDPOINTを設定するか、 FOUNDRY_PROJECT_ENDPOINT と TOOLBOX_NAMEの両方 を設定します。 ローカル実行の FOUNDRY_MODEL を設定します。ホストされたデプロイは azd マネージド AZURE_AI_MODEL_DEPLOYMENT_NAMEにフォールバックします。
OAuth 同意要求を処理する
ツールボックスまたは MCP 操作で OAuth の同意が必要な場合、ストリーミングと非ストリーミングの FoundryAgent と FoundryChatClient 呼び出しは、空のアシスタント メッセージではなく同意リンク付きの Content(type="oauth_consent_request") を返します。 このコンテンツをユーザー入力要求として処理し、内容 consent_link をユーザーに提示してください。
クライアントは、HTTPS スキームで有効なホストを持つリンクのみを表示します。 存在しないか無効なリンクは省略され、ログに記録されます。
Limitations
- ツールボックス内の MCP ツールでは、Foundry
project_connection_idを介したサーバー側認証が使用されます。エージェント フレームワーク クライアントはアップストリーム MCP ベアラー トークンを保持しません。 - ツールボックスを MCP サーバーとして使用するには、ツールボックス エンドポイントのクライアント側のEntra ID認証が必要です。
-
CONSENT_REQUIREDなどの同意フロー応答は、ツールボックス接続の作成中ではなく、エージェントの実行中に処理されます。
Samples
| Sample | 説明 |
|---|---|
| foundry_toolbox/main.py |
FoundryToolbox ホストされた Responses エージェントを使用する |
| 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 エージェントでサポートされているローカルまたはホステッド ツールの宣言を使用します。