Microsoft Foundry 도구 상자는 코드 인터프리터, 파일 검색, 이미지 생성, MCP 및 웹 검색과 같은 호스트된 도구 구성의 명명된 버전이 지정된 서버 쪽 번들입니다. 도구 상자를 사용하면 Foundry에서 도구 구성을 한 번 관리하고 에이전트 간에 다시 사용할 수 있습니다.
에이전트 프레임워크는 도구 상자 사용을 다룹니다. Foundry 포털 또는 azure-ai-projects SDK를 통해 도구 상자 버전을 만들고 업데이트합니다.
중요합니다
FoundryToolbox 는 베타 agent-framework-foundry-hosting 패키지에서 제공되며 안정적인 릴리스 전에 변경할 수 있습니다.
서비스 관리 FoundryAgent의 경우 Foundry의 에이전트 정의에 도구 상자를 연결합니다.
Microsoft Agent Framework로 빌드한 호스팅 에이전트의 경우 다음 예제와 같이 AddFoundryToolboxes에서 Microsoft.Agents.AI.Foundry.Hosting를 사용합니다.
암시적 using이 활성화된 .NET 10 웹 프로젝트를 사용하고, 버전이 일치하는 Microsoft.Agents.AI.Foundry 및 Microsoft.Agents.AI.Foundry.Hosting, DotNetEnv를 사용합니다.
FOUNDRY_MODEL을 기존 도구 상자로, TOOLBOX_NAME을 모델 배포로 설정합니다. 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.
#if USE_LOCAL_AGENT_FRAMEWORK_SOURCE
#endif
var app = builder.Build();
app.MapFoundryResponses();
app.Run();
동일한 호스팅 등록은 도구 상자 연결에서 사용자별 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>"
호스팅 에이전트 샘플은 로컬에서는 FOUNDRY_MODEL를 우선 사용하고, 호스팅 환경에서는 azd가 관리하는 AZURE_AI_MODEL_DEPLOYMENT_NAME로 대체합니다.
Azure Developer CLI를 사용하여 샘플 배포
현재 Python 샘플에서는 호스트된 에이전트, 연결, 도구 상자 및 환경 변수 매핑을 정의하는 데 azure.yaml 하나를 사용합니다. 통합 microsoft.foundry 확장과 함께 Azure 개발자 CLI 1.34.2 이상을 사용합니다.
azd ext install microsoft.foundry
azd provision
azd deploy --all
관리자가 연결된 Azure 리소스에 필요한 역할을 부여하기 전에 Foundry 프로젝트의 관리되는 ID가 존재하도록 먼저 프로비전합니다.
azure.yaml가 포함된 초기화된 프로젝트 디렉터리에서 후속 명령을 실행합니다.
Entra 통과로 구성된 도구의 경우 Foundry는 현재 호출자의 ID를 전달합니다. 호출자는 여전히 대상 리소스에 액세스해야 하며 호스트된 애플리케이션은 이전 요청의 헤더를 다시 사용하는 대신 플랫폼 호출 컨텍스트를 전달해야 합니다.
전체 환경, 역할 할당, 로컬 실행, 배포 및 호출 순서는 Python Foundry 도구 상자 샘플을 참조하세요.
도구 상자 도구 검색을 사용하도록 설정
도구 상자 도구 검색은 모델의 초기 도구 목록을 작게 유지합니다.
ToolSearchToolboxTool을(를) MCP 도구가 포함된 Toolbox 버전에 추가합니다. 모델은 처음에 tool_search 및 call_tool을 확인한 다음, 필요에 따라 기반 MCP 도구를 발견합니다.
이 샘플을 실행하기 전에 Foundry SDK를 업그레이드하세요.
pip install --upgrade "azure-ai-projects>=2.4.0"
Python 샘플은 azure-ai-projects 2.4.0 이상을 사용하여 MCPToolboxTool와 ToolSearchToolboxTool를 모두 포함하는 새 도구 상자 버전을 만듭니다. 정확한 버전에 연결되며 기존 버전은 삭제되지 않습니다. 실행을 시작할 때 기본 도구 목록 전체를 노출하려면 도구 검색 항목을 제거합니다.
버전 만들기 및 MCP 연결 패턴에 대한 Toolbox 도구 검색이 있는 Foundry Chat Client를 참조하세요.
호스트된 에이전트와 함께 사용 FoundryToolbox
FoundryToolbox는 엔드포인트를 확인하고, 제공된 Azure 자격 증명을 사용하여 모든 MCP 요청을 인증하고, 요청당 Foundry 호출 ID를 전달하며, 에이전트의 연결 수명 주기에 참여합니다. 각 작업 경계에서 플랫폼 헤더를 해석하고 유효 요청 식별 정보가 변경되면 MCP 세션을 다시 연결합니다. 따라서 수명이 긴 도구 상자는 이전 호출자의 호출 ID를 유지하지 않습니다.
이 샘플은 결정적 소유권 및 정리를 위해 요청 범위 에이전트 팩터리 내에 도구 상자, 클라이언트 및 자격 증명을 만듭니다. 관련 리소스가 요청에 속하는 경우 이 팩터리 패턴을 사용하지만 Toolbox 호출 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를 사용하여 네이티브 container_file_citation 주석을 내보냅니다. 클라이언트는 이러한 ID를 사용하여 컨테이너 파일 API를 통해 생성된 파일을 검색하고 다운로드할 수 있습니다.
도구 상자 기능 표시
도구 상자는 MCP를 통해 에이전트 기술을 노출할 수 있습니다. 기술만 모델에 표시되어야 할 때는 load_tools=False로 설정한 다음, 해당 MCP 세션이 연결되도록 Toolbox를 도구로 추가하고 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 세션을 사용하도록 하세요. 수명이 긴 Toolbox의 경우 유효 플랫폼 헤더 ID가 변경되면 스킬 검색 캐시가 대체됩니다. 기술과 함께 사용하는 사용자 지정 header_provider는 클로저 또는 ContextVar와 같은 주변 상태에서 확인할 수 있어야 합니다. 기술 및 리소스 읽기 작업에는 함수의 런타임 인수가 전달되지 않기 때문입니다.
다음과 함께 툴박스 사용: FoundryAgent
Foundry의 프롬프트 또는 호스트된 에이전트 정의에 도구 상자를 연결합니다.
FoundryAgent 는 저장된 도구 구성을 사용합니다. 도구 상자 클라이언트 쪽을 전달해도 관리되는 에이전트에 추가되지 않습니다.
MCP를 통해 연결 FoundryToolbox
호스팅된 에이전트를 Toolbox MCP 엔드포인트에 연결하려면 ResponsesHostServer와(과) FoundryToolbox를 사용하세요. 래퍼는 MCP 요청을 인증하고 사용자별 ID 통과를 위해 현재 호스팅된 요청의 호출자 컨텍스트를 전달합니다.
요청 범위 agent 팩터리는 클라이언트, 자격 증명 및 도구 상자에 하나의 정리 경계가 필요한 경우 가장 간단한 옵션으로 유지됩니다. 수명이 긴 Toolbox도 지원되며 플랫폼 헤더 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 스키마 및 유효한 호스트에 대한 링크만 표시합니다. 누락되었거나 잘못된 링크는 기록되며 제외됩니다.
제한 사항
- 도구 상자 내의 MCP 도구는 Foundry
project_connection_id를 통해 서버 쪽 인증을 사용합니다. 에이전트 프레임워크 클라이언트는 업스트림 MCP 전달자 토큰을 보유하지 않습니다. - 도구 상자를 MCP 서버로 사용하려면 도구 상자 엔드포인트에 대한 클라이언트 쪽 Entra ID 인증이 필요합니다.
- 이러한 동의 흐름 응답
CONSENT_REQUIRED은 도구 상자 연결이 만들어지는 동안이 아니라 에이전트가 실행되는 동안 처리됩니다.
Samples
| Sample | 설명 |
|---|---|
| foundry_toolbox/main.py |
FoundryToolbox 호스트된 응답 에이전트를 사용하여 |
| foundry_toolbox_mcp_skills/main.py | 툴박스 지원 에이전트 스킬 |
| foundry_chat_client_with_toolbox.py | MCP를 통한 tool_search 및 call_tool 주문형 도구 상자 검색 |
| foundry_chat_client_with_toolbox_skills.py | 도구 상자 기반 기술 구성 |
| invoke_foundry_toolbox_mcp | 워크플로 쪽 MCP 사용량 |
Go는 Toolbox가 연결된 서비스 관리 에이전트를 호출하거나 표준 MCP 통합을 통해 Toolbox 엔드포인트를 사용할 수 있습니다. 다른 탭에 표시된 전용 FoundryToolbox 또는 AddFoundryToolboxes 도우미는 제공하지 않습니다.
서비스에서 관리되는 에이전트와 함께 Toolbox 사용
Foundry의 에이전트 정의에 도구 상자를 연결한 다음 그 기존 에이전트를 foundryprovider.NewAgent 및 foundryprovider.ServerAgent("<agent-name>")로 호출합니다. 서비스는 저장된 Toolbox 구성을 소유합니다.
개별 로컬 또는 호스팅된 도구 선언을 모델 배포 에이전트에 전달해도 Toolbox는 연결되지 않습니다. 연결 설정 방법은 기존 서버 측 Foundry 에이전트를 참조하세요.
MCP로 연결
애플리케이션 관리형 Go 에이전트에서 Toolbox 도구를 사용하려면:
- 기존 도구 상자의 MCP 엔드포인트를 가져옵니다.
- Azure 자격 증명을 사용하여 도구 상자 요청을 인증하도록 애플리케이션 소유 HTTP 클라이언트를
https://ai.azure.com/.default구성합니다. 필요에 따라 토큰을 갱신하고 자격 증명 전달을 지정된 Toolbox 엔드포인트로 제한하세요. -
Endpoint의 툴박스 엔드포인트를 사용하여mcp.StreamableClientTransport.HTTPClient을(를) 통해 클라이언트를 전달하세요. -
mcptool.Connect를 호출한 다음mcptool.ListTools하고, 반환된 도구를agent.Config.Tools에 등록합니다. - 에이전트가 해당 도구를 사용하는 동안 MCP 세션을 열어 두고 해당 작업이 완료되면 닫습니다.
로컬 MCP 도구와 동일한 검색 및 호출 패턴을 따릅니다. Go 전송 및 도구 등록 API에 대해서는 MCP 서버에 연결을 참조하세요.
Go 통합 제한
일반 Go MCP 통합은 .NET 및 Python 예제에 설명된 호스트된 Toolbox 수명 주기, 플랫폼 헤더 ID 전달 또는 Toolbox 지원 skills adapter를 제공하지 않습니다. 인증 및 리소스 소유권 설정을 애플리케이션 내에서 직접 구성하고, 이러한 헬퍼 기능이 자동으로 실행될 것이라고 가정하지 마세요.