你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将代理连接到模型上下文协议服务器

使用 MCP 工具将 Foundry 代理连接到 模型上下文协议 (MCP) 服务器。 此连接使用外部工具和数据源扩展代理功能。 通过连接到远程 MCP 服务器终结点,你的代理的 Foundry 模型可以访问由开发人员和组织托管的工具,这些工具可以被 MCP 兼容客户端(如 Foundry 代理服务)使用。

MCP 是一个开放标准,用于定义应用程序如何向大型语言模型(LLM)提供工具和上下文数据。 它支持将外部工具与模型工作流的一致、可缩放集成。

提示

请考虑使用 工具箱添加此工具。 通过使用工具箱,可以跨代理和运行时重复使用该工具,并通过托管 MCP 终结点集中凭据管理、版本管理和策略强制实施。 请参阅 工具箱快速入门

在本文中,您将学到如何:

  • 将远程 MCP 服务器添加为工具。
  • 使用项目连接向 MCP 服务器进行身份验证。
  • 审查并批准 MCP 工具调用。
  • 排查常见的 MCP 集成问题。

先决条件

在开始之前,请确保具备:

  • 具有活动 Microsoft Foundry 项目的 Azure 订阅。

  • Foundry 项目的 Foundry 用户 角色,用于创建和测试代理。 如果为 MCP 身份验证创建project连接,则还需要在该project上具有 Foundry Project Manager 角色。

    Important

    Foundry RBAC 角色最近已更名。 Foundry UserFoundry OwnerFoundry 帐户所有者Foundry Project Manager此前名为 Azure AI 用户、Azure AI 所有者、Azure AI 帐户所有者和 Azure AI 项目经理。 在重命名推出时,你仍可能会在某些位置看到以前的名称。重命名后,角色 ID 和核心权限保持不变。

  • 针对您的编程语言的最新 SDK 包。 .NET SDK 目前为预览版。 有关安装详细信息,请参阅 快速入门

  • 为身份验证配置的Azure凭据(如 DefaultAzureCredential)。

  • 访问远程 MCP 服务器终结点(例如GitHub的 MCP 服务器https://api.githubcopilot.com/mcp)。

选择任务

任务 路径
连接代理并确认第一次成功的工具调用 按照连接、批准、验证和清理路由操作。
添加凭据或基于标识的访问 Secondary:配置身份验证
连接到专用 MCP 终结点 Secondary:查看公共终结点和专用终结点要求
在后台模式下运行长时间的操作 Secondary:配置长时间运行的操作
了解流式处理和超时行为 Secondary:查看已知限制
配置服务器选项或托管本地服务器 Secondary:设置 MCP 连接托管本地 MCP 服务器

有关 MCP 集成工作原理的概念详细信息,请参阅 其工作原理

使用支持

下表显示了对 MCP 连接的 SDK 和设置支持。

Microsoft Foundry 支持 Python SDK C# SDK JavaScript SDK Java SDK REST API 基本代理设置 标准代理设置
✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️ ✔️

公共和专用 MCP 服务器终结点

代理服务同时支持公共和专用 MCP 服务器终结点:

  • 公共终结点:连接到任何可公开访问的远程 MCP 服务器。 此选项适用于基本代理和标准代理设置。
  • 专用终结点:连接到未暴露于公共 Internet 的 MCP 服务器。 专用 MCP 需要在虚拟网络中 设置专用网络 和专用 MCP 子网。

对于专用 MCP 服务器,将你的 MCP 服务器部署到 Azure 容器应用,在委托给 Microsoft.App/environments 的专用 MCP 子网上使用仅内部入口。 若要开始,请使用 19-private-network-agents-tools-setup 模板,该模板预配所需的网络基础结构,包括 MCP 子网或 11-private-network-basic-project (如果不想自带资源)。

有关网络隔离环境中的工具支持的详细信息,请参阅 具有网络隔离的代理工具

将 Foundry 工具箱用作 MCP 终结点

Foundry 工具箱允许将多个工具(例如 Web 搜索、代码解释器、文件搜索、Azure AI 搜索、MCP 服务器、OpenAPI 工具和代理到代理连接)捆绑到单个 MCP 兼容的终结点。 在 Foundry 中创建工具箱,并使用标准 mcp 工具配置(server_urlserver_label)将代理指向工具箱终结点,而不是在每个代理上单独配置每个工具。

由于工具箱终结点与 MCP 兼容,因此任何可以使用 MCP 服务器的运行时也可以使用工具箱。 此兼容性包括 Foundry 代理服务、Microsoft Agent Framework、LangGraph、GitHub Copilot SDK 和其他已启用 MCP 的客户端。 可以在工具箱中添加、删除或重新配置工具,而无需更改代理代码。

有关设置步骤,请参阅 “创建和使用 Foundry 工具箱”。

工具箱 MCP 终结点通过 MCP 任务 支持长时间运行的操作,该功能目前处于预览阶段。 若要使用长时间运行的工具,请确保代理工具支持 MCP 任务

工具箱 MCP 身份验证和配置

使用与方案匹配的身份验证类型为 MCP 服务器创建项目连接,然后从最小工具箱 YAML 中引用它。

第 1 步。 创建连接

导出项目端点,并将其设置为 azd ai 命令的活动项目:

PROJECT_ENDPOINT="https://<account>.services.ai.azure.com/api/projects/<project>"
azd ai project set $PROJECT_ENDPOINT

选择所需的身份验证变体:

# No auth — public MCP server
azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://learn.microsoft.com/api/mcp \
  --auth-type none

# Custom-keys header (for example, GitHub PAT)
azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://api.githubcopilot.com/mcp/ \
  --auth-type custom-keys \
  --custom-key "Authorization=******"

# OAuth — bring your own app registration
azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://your-mcp-server.example.com \
  --auth-type oauth2 \
  --authorization-url https://auth.example.com/authorize \
  --token-url https://auth.example.com/token \
  --client-id <oauth-client-id> \
  --client-secret <oauth-client-secret> \
  --scopes "<scope1> <scope2>"

# User Entra token (managed user identity passthrough; for example, Microsoft Fabric)
azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://api.fabric.microsoft.com/v1/mcp/fabricaihub/integrations/m365 \
  --auth-type user-entra-token \
  --audience https://analysis.windows.net/powerbi/api

# Project managed identity — the project's system-assigned MI
azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://<resource>.cognitiveservices.azure.com/language/mcp \
  --auth-type project-managed-identity \
  --audience https://cognitiveservices.azure.com

# Agentic identity — the agent's per-project identity
azd ai connection create my-mcp-conn \
  --kind remote-tool \
  --target https://<resource>.cognitiveservices.azure.com/language/mcp \
  --auth-type agentic-identity \
  --audience https://cognitiveservices.azure.com
--auth-type 其他标志
none
custom-keys --custom-key "Header=Value" (可重复)
oauth2 --authorization-url--token-url--client-id--client-secret--scopes
user-entra-token --audience <entra-audience>
project-managed-identity --audience <entra-audience>(可选)
agentic-identity --audience <entra-audience>

对于基于标识的身份验证(user-entra-tokenproject-managed-identityagentic-identity),请先在目标资源上为相应主体分配所需的 RBAC 角色,然后再调用工具箱。

步骤 2。 定义工具箱

# my-toolbox.yaml
description: MCP server tools
connections:
  - name: my-mcp-conn

步骤 3。 创建工具箱

azd ai toolbox create my-toolbox --from-file my-toolbox.yaml

用户第一次在项目中调用具有基于 OAuth 的 MCP 的工具箱时,MCP 终结点会返回一个 CONSENT_REQUIRED 带有同意 URL 的错误(代码 -32006):

{
  "error": {
    "code": -32006,
    "message": "User consent is required. Please visit: https://..."
  }
}

此错误应为预期。 在浏览器中打开许可 URL,完成 OAuth 授权流,然后重试代理调用。 后续调用成功,无需重新提示。

认证

辅助路径: 当 MCP 服务器需要凭据或基于标识的访问时,在首次成功路由后配置身份验证。

许多 MCP 服务器需要身份验证。

在 Foundry 代理服务中,使用项目连接来存储身份验证详细信息,例如 API 密钥或持有者令牌,而不是在应用中对凭据进行硬编码。

若要了解支持的身份验证选项(包括基于密钥、Microsoft Entra标识和 OAuth 标识传递),请参阅 MCP 服务器身份验证

注意

project_connection_id 设置为项目连接的 ID。

提示

通过 Add Tools 目录添加Azure DevOps MCP 服务器(预览版)时,在组织连接步骤期间对Azure DevOps进行身份验证,并将身份验证存储为项目连接。 连接组织时使用最小特权访问并审查范围。

使用 Foundry 工具箱 MCP 终结点时,工具箱将集中管理身份验证。 工具箱在运行时处理捆绑包中所有工具的凭据注入、令牌刷新和策略强制实施。 代理使用Microsoft Entra凭据(如 DefaultAzureCredential)向工具箱终结点本身进行身份验证,并且每个代理无需传递单个工具凭据。 有关工具箱身份验证配置,请参阅 工具箱先决条件

使用非Microsoft服务和服务器时的注意事项

使用连接的非微软服务时,您和服务供应商之间的条款会受约束。 连接到非Microsoft服务时,会将某些数据(例如提示内容)传递到非Microsoft服务,或者应用程序可能会从非Microsoft服务接收数据。 你负责使用非微软服务和数据,以及与使用相关的任何费用。

第三方(而不是Microsoft)创建你决定与本文中所述的 MCP 工具一起使用的远程 MCP 服务器。 Microsoft不会测试或验证这些服务器。 Microsoft对您或其他人使用任何远程MCP服务器不承担任何责任。

仔细查看并跟踪添加到 Foundry 代理服务的 MCP 服务器。 依赖于受信任的服务提供商本身托管的服务器,而不是代理。

MCP 工具允许你传递远程 MCP 服务器可能需要的自定义标头,例如身份验证密钥或架构。 查看与远程 MCP 服务器共享的所有数据,并记录数据以进行审核。 请注意有关保留和数据位置的非Microsoft做法。

注意

Foundry 工具箱不同于第三方 MCP 服务器。 工具箱是在 Microsoft Foundry 项目中创建和管理的组织治理资源。 但是,在策展工具箱内容时,你仍负责工具选择、数据处理和符合性。

最佳做法

有关工具使用情况的一般指南,请参阅 有关在 Microsoft Foundry 代理服务中使用工具的最佳做法

使用 MCP 服务器时,请遵循以下做法:

  • 通过使用 allowed_tools 来使用工具允许列表。
  • 需要批准高风险操作,尤其是写入数据或更改资源的工具。
  • 在批准之前,请查看请求的工具名称和参数。
  • 审核和故障排除所需的日志审批和工具调用。

提示

通过 Add Tools 目录添加 Azure DevOps MCP 服务器时,工具选择配置将映射到本文所述的 allowed_tools 行为。 在目录 UI 中选择一部分工具相当于在代码中指定 allowed_tools 列表。

首次成功路由:连接、批准、验证和清理

对所选语言使用 prompt-agent 示例。 当示例具有代理类型选项卡时,选择 “提示代理”。 此路由使第一个运行侧重于一个任务:连接一台 MCP 服务器,调用一个工具并检查结果。

  1. 连接: 将 MCP 工具 require_approval 配置为“设置为 always”,并将其附加到代理。
  2. 批准: 运行示例,查看请求的服务器、工具和参数,并仅批准预期的调用。
  3. 验证: 确认最终响应包含 MCP 工具返回的信息,如预期输出所示。
  4. 清理: 运行示例的清理操作。 提示代理示例会删除代理版本,TypeScript 示例也会删除其对话。

使用 MCP 工具在Python中创建代理

使用以下代码示例创建代理并调用函数。 .NET SDK 目前为预览版。 有关详细信息,请参阅 快速入门

以下示例演示如何将GitHub MCP 服务器添加到工具箱中,并将工具箱附加到代理。 选择 Prompt Agents以使用 Azure AI Projects SDK 创建服务器端提示代理,或托管代理使用 Agent Framework FoundryChatClient生成临时进程内代理。

提示智能体

import json
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition, MCPTool
from openai.types.responses.response_input_param import McpApprovalResponse, ResponseInputParam

# Format: "https://resource_name.ai.azure.com/api/projects/project_name"
PROJECT_ENDPOINT = "your_project_endpoint"
MCP_CONNECTION_NAME = "my-mcp-connection"

# Create clients to call Foundry API
project = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()

# [START tool_declaration]
tool = MCPTool(
    server_label="api-specs",
    server_url="https://api.githubcopilot.com/mcp",
    require_approval="always",
    project_connection_id=MCP_CONNECTION_NAME,
)
# [END tool_declaration]

# Create a prompt agent with MCP tool capabilities
agent = project.agents.create_version(
    agent_name="MyAgent7",
    definition=PromptAgentDefinition(
        model="gpt-5-mini",
        instructions="Use MCP tools as needed",
        tools=[tool],
    ),
)
print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")

# Create a conversation to maintain context across multiple interactions
conversation = openai.conversations.create()
print(f"Created conversation (id: {conversation.id})")

# Send initial request that will trigger the MCP tool
response = openai.responses.create(
    conversation=conversation.id,
    input="What is my username in my GitHub profile?",
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)

# Process any MCP approval requests that were generated
input_list: ResponseInputParam = []
for item in response.output:
    if item.type == "mcp_approval_request" and item.id:
        print("MCP approval requested")
        print(f"  Server: {item.server_label}")
        print(f"  Tool: {getattr(item, 'name', '<unknown>')}")
        print(
            f"  Arguments: {json.dumps(getattr(item, 'arguments', None), indent=2, default=str)}"
        )

        # Approve only after you review the tool call.
        # In production, implement your own approval UX and policy.
        should_approve = (
            input("Approve this MCP tool call? (y/N): ").strip().lower() == "y"
        )
        input_list.append(
            McpApprovalResponse(
                type="mcp_approval_response",
                approve=should_approve,
                approval_request_id=item.id,
            )
        )

# Send the approval response back to continue the agent's work
response = openai.responses.create(
    input=input_list,
    previous_response_id=response.id,
    extra_body={"agent_reference": {"name": agent.name, "type": "agent_reference"}},
)

print(f"Response: {response.output_text}")

# Clean up resources by deleting the agent version
project.agents.delete_version(agent_name=agent.name, agent_version=agent.version)
print("Agent deleted")

预期输出

以下示例演示运行示例时的预期输出:

Agent created (id: <agent-id>, name: MyAgent7, version: 1)
Created conversation (id: <conversation-id>)
Response: Your GitHub username is "example-username".
Agent deleted

托管代理

FoundryChatClient此示例使用Microsoft代理框架,创建包含GitHub MCP 服务器的工具箱,然后将工具箱终结点附加到托管代理。MCPStreamableHTTPTool 使用 、设置环境变量和登录pip install agent-framework-foundry httpx来安装包FOUNDRY_PROJECT_ENDPOINTFOUNDRY_MODELaz login

import asyncio

import httpx
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.foundry import FoundryChatClient
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import MCPToolboxTool
from azure.identity import AzureCliCredential, get_bearer_token_provider

PROJECT_ENDPOINT = "https://<account>.services.ai.azure.com/api/projects/<project>"
MCP_CONNECTION_NAME = "my-mcp-connection"


class _ToolboxAuth(httpx.Auth):
    def __init__(self, token_provider):
        self._token_provider = token_provider

    def auth_flow(self, request):
        request.headers["Authorization"] = f"Bearer {self._token_provider()}"
        yield request


async def main() -> None:
    credential = AzureCliCredential()

    # 1. Add the GitHub MCP server to a toolbox.
    project = AIProjectClient(endpoint=PROJECT_ENDPOINT, credential=credential)
    server_tool = MCPToolboxTool(
        server_label="api-specs",
        server_url="https://api.githubcopilot.com/mcp",
        require_approval="always",
        project_connection_id=MCP_CONNECTION_NAME,
    )
    toolbox = project.toolboxes.create_version(
        name="mcp-server-toolbox",
        description="Toolbox with the GitHub MCP server",
        tools=[server_tool],
    )

    # 2. The toolbox exposes an MCP-compatible endpoint.
    TOOLBOX_MCP_URL = (
        f"{PROJECT_ENDPOINT}/toolboxes/{toolbox.name}"
        f"/versions/{toolbox.version}/mcp?api-version=v1"
    )

    # 3. Attach the toolbox to the hosted agent as an MCP tool.
    token_provider = get_bearer_token_provider(credential, "https://ai.azure.com/.default")
    http_client = httpx.AsyncClient(
        auth=_ToolboxAuth(token_provider),
        timeout=120.0,
    )

    mcp_tool = MCPStreamableHTTPTool(
        name="toolbox",
        url=TOOLBOX_MCP_URL,
        http_client=http_client,
        load_prompts=False,
    )

    agent = Agent(
        client=FoundryChatClient(credential=credential),
        instructions="You are a helpful assistant that uses your MCP tool "
        "to help with Microsoft documentation questions.",
        tools=[mcp_tool],
    )

    result = await agent.run("What is Microsoft Agent Framework?")
    print(f"Agent: {result.text}")

if __name__ == "__main__":
    asyncio.run(main())

预期输出

代理通过工具箱终结点调用 Microsoft Learn MCP 服务器,并返回基于文档的文本:

Agent: Microsoft Agent Framework is an open-source framework for building, orchestrating, and deploying AI agents ...

有关完整的工具箱托管代理模式,请参阅 将工具箱与托管代理配合使用


使用 MCP 工具创建代理

以下示例演示如何将远程 MCP 服务器添加到工具箱,并将工具箱附加到代理。 选择 Prompt Agents以使用 Azure AI Projects SDK 创建服务器端提示代理,或托管代理使用 Microsoft Agent Framework 生成临时进程内代理。

提示智能体

该示例使用同步方法创建代理。 有关异步方法,请参阅 GitHub 上 .NET 存储库中的 Azure SDK 示例代码

using System;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
var projectEndpoint = "your_project_endpoint";

// Create project client to call Foundry API
AIProjectClient projectClient = new(
    endpoint: new Uri(projectEndpoint),
    tokenProvider: new DefaultAzureCredential());

// Create Agent with the `MCPTool`. Note that in this scenario 
// GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval is used,
// which means that any calls to the MCP server must be approved.
DeclarativeAgentDefinition agentDefinition = new(model: "gpt-5-mini")
{
    Instructions = "You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.",
    Tools = { ResponseTool.CreateMcpTool(
        serverLabel: "api-specs",
        serverUri: new Uri("https://gitmcp.io/Azure/azure-rest-api-specs"),
        toolCallApprovalPolicy: new McpToolCallApprovalPolicy(GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval
    )) }
};
AgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
    agentName: "myAgent",
    options: new(agentDefinition));

// If the tool approval is required, the response item is
// of `McpToolCallApprovalRequestItem` type and contains all
// the information about tool call. This example checks that
// the server label is "api-specs" and approves the tool call.
// All other calls are denied because they should not occur for
// the current configuration.
ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);

CreateResponseOptions nextResponseOptions = new([ResponseItem.CreateUserMessageItem("Please summarize the Azure REST API specifications README")]);
ResponseResult latestResponse = null;

while (nextResponseOptions is not null)
{
    latestResponse = responseClient.CreateResponse(nextResponseOptions);
    nextResponseOptions = null;

    foreach (ResponseItem responseItem in latestResponse.OutputItems)
    {
        if (responseItem is McpToolCallApprovalRequestItem mcpToolCall)
        {
            nextResponseOptions = new CreateResponseOptions()
            {
                PreviousResponseId = latestResponse.Id,
            };
            if (string.Equals(mcpToolCall.ServerLabel, "api-specs"))
            {
                Console.WriteLine($"Approval requested for {mcpToolCall.ServerLabel} (tool: {mcpToolCall.ToolName})");
                Console.Write("Approve this MCP tool call? (y/N): ");
                bool approved = string.Equals(Console.ReadLine(), "y", StringComparison.OrdinalIgnoreCase);
                nextResponseOptions.InputItems.Add(ResponseItem.CreateMcpApprovalResponseItem(approvalRequestId: mcpToolCall.Id, approved: approved));
            }
            else
            {
                Console.WriteLine($"Rejecting unknown call {mcpToolCall.ServerLabel}...");
                nextResponseOptions.InputItems.Add(ResponseItem.CreateMcpApprovalResponseItem(approvalRequestId: mcpToolCall.Id, approved: false));
            }
        }
    }
}

// Output the final response from the agent.
Console.WriteLine(latestResponse.GetOutputText());

// Clean up resources by deleting the agent version.
projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);

预期输出

以下示例演示运行示例时的预期输出:

Approval requested for api-specs...
Response: The Azure REST API specifications repository contains the OpenAPI specifications for Azure services. It is
organized by service and includes guidelines for contributing new specifications. The repository is intended for use by developers building tools and services that interact with Azure APIs.

托管代理

此示例使用 Azure AI Projects SDK 创建 MCP 服务器工具箱,然后使用 ToolboxMcpClientResponsesServer Microsoft Agent Framework 向托管代理公开工具箱工具。 设置 AZURE_AI_PROJECT_ENDPOINTAZURE_OPENAI_ENDPOINT环境变量和 AZURE_AI_MODEL_DEPLOYMENT_NAME 登录 az login

using Azure.AI.AgentServer.Responses;
using Azure.AI.AgentServer.Responses.Models;
using Azure.AI.OpenAI;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;
using Microsoft.Extensions.DependencyInjection;
using OpenAI.Chat;

string projectEndpoint = Environment.GetEnvironmentVariable("AZURE_AI_PROJECT_ENDPOINT")
    ?? "https://<account>.services.ai.azure.com/api/projects/<project>";
string openAiEndpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
    ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = Environment.GetEnvironmentVariable("AZURE_AI_MODEL_DEPLOYMENT_NAME") ?? "gpt-5-mini";

DefaultAzureCredential credential = new();

// 1. Create the MCP server tool and add it to a toolbox.
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: credential);
McpTool mcpTool = ResponseTool.CreateMcpTool(
    serverLabel: "api-specs",
    serverUri: new Uri("https://gitmcp.io/Azure/azure-rest-api-specs"),
    toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
        GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval));

ToolboxVersion toolboxVersion = projectClient.AgentAdministrationClient
    .GetAgentToolboxes().CreateToolboxVersion(
        toolboxName: "mcp-server-toolbox",
        tools: [ProjectsAgentTool.AsProjectTool(mcpTool)],
        description: "Toolbox with the GitHub MCP server");

// 2. The toolbox exposes an MCP-compatible endpoint.
string toolboxMcpEndpoint =
    $"{projectEndpoint}/toolboxes/{toolboxVersion.Name}/versions/{toolboxVersion.Version}/mcp?api-version=v1";

// 3. Attach the toolbox to the hosted agent.
AzureOpenAIClient openAIClient = new(new Uri(openAiEndpoint), credential);
ChatClient chatClient = openAIClient.GetChatClient(deploymentName);

// Toolbox MCP client - discovers tools via tools/list, calls them via tools/call
ToolboxMcpClient toolboxClient = new(toolboxMcpEndpoint, credential);

ResponsesServer.Run<ToolboxHandler>(configure: builder =>
{
    builder.Services.AddSingleton(new AgentConfig(chatClient, toolboxClient));
});

预期输出

调用后,托管代理通过工具箱终结点查询 Microsoft Learn MCP 服务器以获取文档片段和答案:

User: How does one create an Azure storage account using the az CLI?

Agent: To create an Azure storage account using the az CLI, run: `az storage account create --name <name> --resource-group <rg> --location <region> --sku Standard_LRS` ...

有关维护的 .NET Agent Framework 集成,请参阅将工具箱与托管代理配合使用


在项目连接身份验证中使用 MCP 工具创建代理

在此示例中,你将了解如何向工具箱中的GitHub MCP 服务器进行身份验证,然后将工具箱 MCP 终结点附加到代理。 该示例使用同步方法创建工具箱和代理。 有关异步方法,请参阅 GitHub 上 .NET 存储库中的 Azure SDK 示例代码

设置项目连接

运行示例之前:

  1. 登录到GitHub个人资料。
  2. 选择右上角的个人资料图片。
  3. 选择 “设置”。
  4. 在左侧面板中,选择“开发人员设置”和“个人访问令牌>”令牌(经典)。
  5. 在顶部,选择“ 生成新令牌”,输入密码,并创建可读取公共存储库的令牌。
    • 重要: 保存令牌,或使页面保持打开状态,因为页面关闭后,无法再次显示令牌。
  6. 在Azure门户中,打开 Microsoft Foundry。
  7. 在右上角导航中选择“管理”,选择Project详细信息,然后选择“已连接资源”选项卡。
  8. 创建新的 自定义密钥 类型连接。
  9. 为其命名并添加键值对。
  10. 将键名称设置为 Authorization,且其值应有一种 Bearer your_github_token 的形式。

用于创建代理的代码示例

using System;
using Azure.AI.Projects;
using Azure.AI.Extensions.OpenAI;
using Azure.Identity;

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
var projectEndpoint = "your_project_endpoint";
var mcpConnectionName = "my-mcp-connection";

// Create project client to call Foundry API
AIProjectClient projectClient = new(
    endpoint: new Uri(projectEndpoint),
    tokenProvider: new DefaultAzureCredential());

// 1. Add the GitHub MCP server to a toolbox. Using a toolbox is the recommended
//    way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
AgentToolboxes toolboxClient = projectClient.AgentAdministrationClient.GetAgentToolboxes();

McpTool mcpTool = ResponseTool.CreateMcpTool(
    serverLabel: "api-specs",
    serverUri: new Uri("https://api.githubcopilot.com/mcp"),
    toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
        GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval));
mcpTool.ProjectConnectionId = mcpConnectionName;

ToolboxVersion toolboxVersion = toolboxClient.CreateToolboxVersion(
    toolboxName: "mcp-server-toolbox",
    tools: [ProjectsAgentTool.AsProjectTool(mcpTool)],
    description: "Toolbox with the GitHub MCP server");

// 2. The toolbox exposes an MCP-compatible endpoint.
var toolboxMcpUrl = new Uri(
    $"{projectEndpoint}/toolboxes/{toolboxVersion.Name}" +
    $"/versions/{toolboxVersion.Version}/mcp?api-version=v1");

// 3. Create a remote-tool project connection that points at the toolbox endpoint.
//    Use a user Entra token so the caller's identity is passed through
//    (audience https://ai.azure.com). Create the connection once, for example
//    with the Azure Developer CLI:
//
//    azd ai connection create mcp-server-toolbox-conn \
//      --kind remote-tool \
//      --target "<toolboxMcpUrl>" \
//      --auth-type user-entra-token \
//      --audience https://ai.azure.com
var toolboxConnectionName = "mcp-server-toolbox-conn";

// 4. Attach the toolbox to a prompt agent as an MCP tool. Note that in this scenario
//    GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval is used, which means that
//    any calls to the toolbox MCP endpoint must be approved.
McpTool toolboxTool = ResponseTool.CreateMcpTool(
    serverLabel: "toolbox",
    serverUri: toolboxMcpUrl,
    toolCallApprovalPolicy: new McpToolCallApprovalPolicy(
        GlobalMcpToolCallApprovalPolicy.AlwaysRequireApproval));
toolboxTool.ProjectConnectionId = toolboxConnectionName;

DeclarativeAgentDefinition agentDefinition = new(model: "gpt-5-mini")
{
    Instructions = "You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.",
    Tools = { toolboxTool }
};
AgentVersion agentVersion = projectClient.AgentAdministrationClient.CreateAgentVersion(
    agentName: "myAgent",
    options: new(agentDefinition));

// If the tool approval is required, the response item is
// of McpToolCallApprovalRequestItem type and contains all
// the information about tool call. This example checks that
// the server label is "toolbox" and approves the tool call.
// All other calls are denied because they shouldn't happen given
// the current configuration.
ProjectResponsesClient responseClient = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentVersion.Name);

CreateResponseOptions nextResponseOptions = new([ResponseItem.CreateUserMessageItem("What is my username in my GitHub profile?")]);
ResponseResult latestResponse = null;

while (nextResponseOptions is not null)
{
    latestResponse = responseClient.CreateResponse(nextResponseOptions);
    nextResponseOptions = null;

    foreach (ResponseItem responseItem in latestResponse.OutputItems)
    {
        if (responseItem is McpToolCallApprovalRequestItem mcpToolCall)
        {
            nextResponseOptions = new()
            {
                PreviousResponseId = latestResponse.Id,
            };
            if (string.Equals(mcpToolCall.ServerLabel, "toolbox"))
            {
                Console.WriteLine($"Approval requested for {mcpToolCall.ServerLabel} (tool: {mcpToolCall.ToolName})");
                Console.Write("Approve this MCP tool call? (y/N): ");
                bool approved = string.Equals(Console.ReadLine(), "y", StringComparison.OrdinalIgnoreCase);
                nextResponseOptions.InputItems.Add(ResponseItem.CreateMcpApprovalResponseItem(approvalRequestId: mcpToolCall.Id, approved: approved));
            }
            else
            {
                Console.WriteLine($"Rejecting unknown call {mcpToolCall.ServerLabel}...");
                nextResponseOptions.InputItems.Add(ResponseItem.CreateMcpApprovalResponseItem(approvalRequestId: mcpToolCall.Id, approved: false));
            }
        }
    }
}

// Output the final response from the agent.
Console.WriteLine(latestResponse.GetOutputText());

// Clean up resources by deleting the agent version.
projectClient.AgentAdministrationClient.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);

预期输出

以下示例演示运行示例时的预期输出:

Approval requested for toolbox...
Response: Your GitHub username is "example-username".

使用 MCP 工具在 TypeScript 中创建代理

以下 TypeScript 示例演示如何将 MCP 服务器添加到工具箱、将工具箱附加到代理、发送触发 MCP 审批工作流的请求、处理审批请求以及清理资源。 有关 JavaScript 版本,请参阅 GitHub 上 Azure SDK for JavaScript 存储库中的示例代码

import { DefaultAzureCredential } from "@azure/identity";
import { AIProjectClient } from "@azure/ai-projects";
import OpenAI from "openai";
import * as readline from "readline";

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
const PROJECT_ENDPOINT = "your_project_endpoint";

export async function main(): Promise<void> {
  // Create clients to call Foundry API
  const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
  const openai = project.getOpenAIClient();

  console.log("Creating agent with MCP tool...");

  // 1. Add the Azure REST API specifications MCP server to a toolbox. Using a toolbox is
  //    the recommended way to give agents tools. See /azure/foundry/agents/concepts/toolbox-overview
  const toolbox = await project.toolboxes.createVersion(
    "mcp-server-toolbox",
    [
      {
        type: "mcp",
        server_label: "api-specs",
        server_url: "https://gitmcp.io/Azure/azure-rest-api-specs",
        require_approval: "always",
      },
    ],
    { description: "Toolbox with the Azure REST API specifications MCP server" },
  );

  // 2. The toolbox exposes an MCP-compatible endpoint.
  const toolboxMcpUrl =
    `${PROJECT_ENDPOINT}/toolboxes/${toolbox.name}` +
    `/versions/${toolbox.version}/mcp?api-version=v1`;

  // 3. Create a remote-tool project connection that points at the toolbox endpoint.
  //    Use a user Entra token so the caller's identity is passed through
  //    (audience https://ai.azure.com). Create the connection once, for example
  //    with the Azure Developer CLI:
  //
  //    azd ai connection create mcp-server-toolbox-conn \
  //      --kind remote-tool \
  //      --target "<toolboxMcpUrl>" \
  //      --auth-type user-entra-token \
  //      --audience https://ai.azure.com
  const toolboxConnectionName = "mcp-server-toolbox-conn";

  // 4. Attach the toolbox to a prompt agent as an MCP tool.
  // The toolbox tool requires approval for each operation to ensure user control over external requests.
  const agent = await project.agents.createVersion("agent-mcp", {
    kind: "prompt",
    model: "gpt-5-mini",
    instructions:
      "You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.",
    tools: [
      {
        type: "mcp",
        server_label: "toolbox",
        server_url: toolboxMcpUrl,
        require_approval: "always",
        project_connection_id: toolboxConnectionName,
      },
    ],
  });
  console.log(`Agent created (id: ${agent.id}, name: ${agent.name}, version: ${agent.version})`);

  // Create a conversation thread to maintain context across multiple interactions
  console.log("\nCreating conversation...");
  const conversation = await openai.conversations.create();
  console.log(`Created conversation (id: ${conversation.id})`);

  // Send initial request that will trigger the MCP tool to access Azure REST API specs
  // This will generate an approval request since requireApproval="always"
  console.log("\nSending request that will trigger MCP approval...");
  const response = await openai.responses.create(
    {
      conversation: conversation.id,
      input: "Please summarize the Azure REST API specifications Readme",
    },
    {
      body: { agent_reference: { name: agent.name, type: "agent_reference" } },
    },
  );

  // Process any MCP approval requests that were generated
  // When requireApproval="always", the agent will request permission before accessing external resources
  const inputList: OpenAI.Responses.ResponseInputItem.McpApprovalResponse[] = [];

  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
  const ask = (q: string) => new Promise<string>((resolve) => rl.question(q, resolve));
  for (const item of response.output) {
    if (item.type === "mcp_approval_request") {
      if (item.server_label === "toolbox" && item.id) {
        console.log(`\nReceived MCP approval request (id: ${item.id})`);
        console.log(`  Server: ${item.server_label}`);
        console.log(`  Tool: ${item.name}`);

        // Approve only after you review the tool call.
        // In production, implement your own approval UX and policy.
        const answer = (await ask("Approve this MCP tool call? (y/N): ")).trim().toLowerCase();
        const approve = answer === "y";
        inputList.push({
          type: "mcp_approval_response",
          approval_request_id: item.id,
          approve,
        });
      }
    }
  }

  rl.close();

  console.log(`\nProcessing ${inputList.length} approval request(s)`);
  console.log("Final input:");
  console.log(JSON.stringify(inputList, null, 2));

  // Send the approval response back to continue the agent's work
  // This allows the MCP tool to access the GitHub repository and complete the original request
  console.log("\nSending approval response...");
  const finalResponse = await openai.responses.create(
    {
      input: inputList,
      previous_response_id: response.id,
    },
    {
      body: { agent_reference: { name: agent.name, type: "agent_reference" } },
    },
  );

  console.log(`\nResponse: ${finalResponse.output_text}`);

  // Clean up resources by deleting the agent version and conversation
  // This prevents accumulation of unused resources in your project
  console.log("\nCleaning up resources...");
  await openai.conversations.delete(conversation.id);
  console.log("Conversation deleted");

  await project.agents.deleteVersion(agent.name, agent.version);
  console.log("Agent deleted");

  console.log("\nMCP sample completed!");
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

预期输出

以下示例演示运行示例时的预期输出:

Creating agent with MCP tool...
Agent created (id: <agent-id>, name: agent-mcp, version: 1)

Creating conversation...
Created conversation (id: <conversation-id>)

Sending request that will trigger MCP approval...

Received MCP approval request (id: <approval-request-id>)
  Server: api-specs
  Tool: get-readme

Processing 1 approval request(s)
Final input:
[
  {
    "type": "mcp_approval_response",
    "approval_request_id": "<approval-request-id>",
    "approve": true
  }
]

Sending approval response...

Response: The Azure REST API specifications repository contains the OpenAPI specifications for Azure services. It is organized by service and includes guidelines for contributing new specifications. The repository is intended for use by developers building tools and services that interact with Azure APIs.

Cleaning up resources...
Conversation deleted
Agent deleted

MCP sample completed!

在项目连接身份验证中使用 MCP 工具创建代理

以下 TypeScript 示例演示如何将经过身份验证的 MCP 服务器添加到工具箱、将工具箱 MCP 终结点附加到代理、发送触发 MCP 审批工作流的请求、处理审批请求和清理资源。 有关 JavaScript 版本,请参阅 GitHub 上 Azure SDK for JavaScript 存储库中的示例代码

import { DefaultAzureCredential } from "@azure/identity";
import { AIProjectClient } from "@azure/ai-projects";
import OpenAI from "openai";
import * as readline from "readline";

// Format: "https://resource_name.ai.azure.com/api/projects/project_name"
const PROJECT_ENDPOINT = "your_project_endpoint";
const MCP_CONNECTION_NAME = "my-mcp-connection";

export async function main(): Promise<void> {
  // Create clients to call Foundry API
  const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
  const openai = project.getOpenAIClient();

  console.log("Creating agent with MCP tool using project connection...");

  // 1. Add the GitHub MCP server to a toolbox with project connection authentication.
  // The project connection should have Authorization header configured with "Bearer <GitHub PAT token>"
  // Token can be created at https://github.com/settings/personal-access-tokens/new
  const toolbox = await project.toolboxes.createVersion(
    "mcp-server-toolbox",
    [
      {
        type: "mcp",
        server_label: "api-specs",
        server_url: "https://api.githubcopilot.com/mcp",
        require_approval: "always",
        project_connection_id: MCP_CONNECTION_NAME,
      },
    ],
    { description: "Toolbox with the GitHub MCP server" },
  );

  // 2. The toolbox exposes an MCP-compatible endpoint.
  const toolboxMcpUrl =
    `${PROJECT_ENDPOINT}/toolboxes/${toolbox.name}` +
    `/versions/${toolbox.version}/mcp?api-version=v1`;

  // 3. Create a remote-tool project connection that points at the toolbox endpoint.
  //    Use a user Entra token so the caller's identity is passed through
  //    (audience https://ai.azure.com). Create the connection once, for example
  //    with the Azure Developer CLI:
  //
  //    azd ai connection create mcp-server-toolbox-conn \
  //      --kind remote-tool \
  //      --target "<toolboxMcpUrl>" \
  //      --auth-type user-entra-token \
  //      --audience https://ai.azure.com
  const toolboxConnectionName = "mcp-server-toolbox-conn";

  // 4. Attach the toolbox to a prompt agent as an MCP tool.
  const agent = await project.agents.createVersion("agent-mcp-connection-auth", {
    kind: "prompt",
    model: "gpt-5-mini",
    instructions: "Use MCP tools as needed",
    tools: [
      {
        type: "mcp",
        server_label: "toolbox",
        server_url: toolboxMcpUrl,
        require_approval: "always",
        project_connection_id: toolboxConnectionName,
      },
    ],
  });
  console.log(`Agent created (id: ${agent.id}, name: ${agent.name}, version: ${agent.version})`);

  // Create a conversation thread to maintain context across multiple interactions
  console.log("\nCreating conversation...");
  const conversation = await openai.conversations.create();
  console.log(`Created conversation (id: ${conversation.id})`);

  // Send initial request that will trigger the MCP tool
  console.log("\nSending request that will trigger MCP approval...");
  const response = await openai.responses.create(
    {
      conversation: conversation.id,
      input: "What is my username in my GitHub profile?",
    },
    {
      body: { agent_reference: { name: agent.name, type: "agent_reference" } },
    },
  );

  // Process any MCP approval requests that were generated
  const inputList: OpenAI.Responses.ResponseInputItem.McpApprovalResponse[] = [];

  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
  const ask = (q: string) => new Promise<string>((resolve) => rl.question(q, resolve));
  for (const item of response.output) {
    if (item.type === "mcp_approval_request") {
      if (item.server_label === "toolbox" && item.id) {
        console.log(`\nReceived MCP approval request (id: ${item.id})`);
        console.log(`  Server: ${item.server_label}`);
        console.log(`  Tool: ${item.name}`);

        // Approve only after you review the tool call.
        // In production, implement your own approval UX and policy.
        const answer = (await ask("Approve this MCP tool call? (y/N): ")).trim().toLowerCase();
        const approve = answer === "y";
        inputList.push({
          type: "mcp_approval_response",
          approval_request_id: item.id,
          approve,
        });
      }
    }
  }

  rl.close();

  console.log(`\nProcessing ${inputList.length} approval request(s)`);
  console.log("Final input:");
  console.log(JSON.stringify(inputList, null, 2));

  // Send the approval response back to continue the agent's work
  // This allows the MCP tool to access the GitHub repository and complete the original request
  console.log("\nSending approval response...");
  const finalResponse = await openai.responses.create(
    {
      input: inputList,
      previous_response_id: response.id,
    },
    {
      body: { agent_reference: { name: agent.name, type: "agent_reference" } },
    },
  );

  console.log(`\nResponse: ${finalResponse.output_text}`);

  // Clean up resources by deleting the agent version and conversation
  // This prevents accumulation of unused resources in your project
  console.log("\nCleaning up resources...");
  await openai.conversations.delete(conversation.id);
  console.log("Conversation deleted");

  await project.agents.deleteVersion(agent.name, agent.version);
  console.log("Agent deleted");

  console.log("\nMCP with project connection sample completed!");
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

预期输出

以下示例演示运行示例时的预期输出:

Creating agent with MCP tool using project connection...
Agent created (id: <agent-id>, name: agent-mcp-connection-auth, version: 1)
Creating conversation...
Created conversation (id: <conversation-id>)
Sending request that will trigger MCP approval...
Received MCP approval request (id: <approval-request-id>)
  Server: toolbox
  Tool: get-github-username
Processing 1 approval request(s)
Final input:
[
  {
    "type": "mcp_approval_response",
    "approval_request_id": "<approval-request-id>",
    "approve": true
  }
]
Sending approval response...
Response: Your GitHub username is "example-username".
Cleaning up resources...
Conversation deleted
Agent deleted
MCP with project connection sample completed!

在Java代理中使用 MCP 工具

提示

大多数代理使用 工具箱 添加文件搜索工具,并将工具箱作为 MCP 工具附加到代理。 *如果使用 Java SDK,则用于创建工具箱的 API 尚不可用。 使用 Python、REST API、C#、TypeScript 或 Foundry 门户创建工具箱,然后将它作为Java代理引用为 McpToolMCP 终结点。

将依赖项添加到pom.xml

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-ai-agents</artifactId>
    <version>2.2.0</version>
</dependency>

使用 MCP 工具创建代理

import com.azure.ai.agents.AgentsClient;
import com.azure.ai.agents.AgentsClientBuilder;
import com.azure.ai.agents.ResponsesClient;
import com.azure.ai.agents.models.AgentReference;
import com.azure.ai.agents.models.AgentVersionDetails;
import com.azure.ai.agents.models.AzureCreateResponseOptions;
import com.azure.ai.agents.models.McpTool;
import com.azure.ai.agents.models.PromptAgentDefinition;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;

import java.util.Collections;

public class McpToolExample {
    public static void main(String[] args) {
        // Format: "https://resource_name.ai.azure.com/api/projects/project_name"
        String projectEndpoint = "your_project_endpoint";
        // Create the toolbox out-of-band by using Python, REST, the Foundry portal, C#, or TypeScript.
        String toolboxMcpUrl = projectEndpoint + "/toolboxes/mcp-server-toolbox/versions/1/mcp?api-version=v1";
        String toolboxConnectionName = "mcp-server-toolbox-conn";

        AgentsClientBuilder builder = new AgentsClientBuilder()
            .credential(new DefaultAzureCredentialBuilder().build())
            .endpoint(projectEndpoint);

        AgentsClient agentsClient = builder.buildAgentsClient();
        ResponsesClient responsesClient = builder.buildResponsesClient();

        // Attach the toolbox MCP endpoint with server label, URL, connection, and approval mode.
        McpTool mcpTool = new McpTool("toolbox")
            .setServerUrl(toolboxMcpUrl)
            .setProjectConnectionId(toolboxConnectionName)
            .setRequireApproval("always");

        // Create agent with MCP tool
        PromptAgentDefinition agentDefinition = new PromptAgentDefinition("gpt-5-mini")
            .setInstructions("You are a helpful assistant that can use MCP tools.")
            .setTools(Collections.singletonList(mcpTool));

        AgentVersionDetails agent = agentsClient.createAgentVersion("mcp-agent", agentDefinition);
        System.out.printf("Agent created: %s (version %s)%n", agent.getName(), agent.getVersion());

        // Create a response
        AgentReference agentReference = new AgentReference(agent.getName())
            .setVersion(agent.getVersion());

        Response response = responsesClient.createAzureResponse(
            new AzureCreateResponseOptions().setAgentReference(agentReference),
            ResponseCreateParams.builder()
                .input("Summarize the Azure REST API specifications"));

        System.out.println("Response: " + response.output());

        // Clean up
        agentsClient.deleteAgentVersion(agent.getName(), agent.getVersion());
    }
}

预期输出

Agent created: mcp-agent (version 1)
Response: [ResponseOutputItem containing MCP tool results ...]

将 MCP 工具与 REST API 配合使用

以下示例演示如何使用 MCP 工具创建代理,并使用响应 API 调用它。 如果响应中包括type设置为mcp_approval_request的输出项,则需发送包含mcp_approval_response项的后续请求。

先决条件

设置以下环境变量:

  • FOUNDRY_PROJECT_ENDPOINT:项目终结点 URL。
  • FOUNDRY_MODEL_DEPLOYMENT_NAME:模型部署名称。
  • AGENT_TOKEN:Foundry 的持有者令牌。
  • MCP_PROJECT_CONNECTION_NAME (可选):MCP 项目连接名称。

获取访问令牌:

export AGENT_TOKEN=$(az account get-access-token --scope "https://ai.azure.com/.default" --query accessToken -o tsv)

如果工具箱内的 MCP 服务器不需要身份验证,请从工具箱工具定义中省略 project_connection_id 。 代理的 MCP 工具仍用于 project_connection_id 与工具箱终结点建立远程工具连接。

注意

对于 REST API,请使用为工具箱终结点创建的远程工具项目连接名称,就像在代理的 MCP 工具上一样 project_connection_id

提示

有关 MCP 工具架构和审批项的详细信息,请参阅 Microsoft Foundry REST API 参考

1. 使用 MCP 服务器创建工具箱

添加 MCP 服务器的建议方法是通过工具箱,然后将工具箱作为 MCP 工具附加到代理。 请参阅 什么是工具箱?

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/mcp-server-toolbox/versions?api-version=v1" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "description": "Toolbox with the Azure REST API specifications MCP server",
    "tools": [
      {
        "type": "mcp",
        "server_label": "api-specs",
        "server_url": "https://gitmcp.io/Azure/azure-rest-api-specs",
        "require_approval": "never"
      }
    ]
  }'

工具箱公开了 MCP 兼容的终结点,该终结点 $FOUNDRY_PROJECT_ENDPOINT/toolboxes/mcp-server-toolbox/versions/<version>/mcp?api-version=v1<version> 上一次调用返回的版本。

2.创建与工具箱的远程工具连接

创建指向工具箱终结点的远程工具项目连接。 使用用户 Entra 令牌,以便调用方的身份通过 (受众 https://ai.azure.com):

azd ai connection create mcp-server-toolbox-conn \
  --kind remote-tool \
  --target "$FOUNDRY_PROJECT_ENDPOINT/toolboxes/mcp-server-toolbox/versions/<version>/mcp?api-version=v1" \
  --auth-type user-entra-token \
  --audience https://ai.azure.com

3. 创建 MCP 代理

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/agents?api-version=v1" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "name": "<AGENT_NAME>-mcp",
    "description": "MCP agent",
    "definition": {
      "kind": "prompt",
      "model": "'$FOUNDRY_MODEL_DEPLOYMENT_NAME'",
      "instructions": "You are a helpful agent that can use MCP tools to assist users. Use the available MCP tools to answer questions and perform tasks.",
      "tools": [
        {
          "type": "mcp",
          "server_label": "toolbox",
          "server_url": "'$FOUNDRY_PROJECT_ENDPOINT'/toolboxes/mcp-server-toolbox/versions/<version>/mcp?api-version=v1",
          "require_approval": "always",
          "project_connection_id": "mcp-server-toolbox-conn"
        }
      ]
    }
  }'

若要在工具箱中使用经过身份验证的 MCP 服务器,请添加到 "project_connection_id": "'$MCP_PROJECT_CONNECTION_NAME'" 工具箱工具定义。 更改为 server_url 经过身份验证的服务器终结点(例如 https://api.githubcopilot.com/mcp)。

4.创建响应

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "agent": {"type": "agent_reference", "name": "<AGENT_NAME>-mcp"},
    "input": "Please summarize the Azure REST API specifications Readme"
  }'

如果响应包含已设置为typemcp_approval_request输出项,请将审批请求项id复制为APPROVAL_REQUEST_ID。 同时将顶级响应 id 复制为 PREVIOUS_RESPONSE_ID

5. 发送审批响应

如果 MCP 工具需要批准,请发送后续请求:

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "previous_response_id": "'$PREVIOUS_RESPONSE_ID'",
    "input": [
      {
        "type": "mcp_approval_response",
        "approval_request_id": "'$APPROVAL_REQUEST_ID'",
        "approve": true
      }
    ]
  }'

6.清理资源

删除代理:

curl -X DELETE "$FOUNDRY_PROJECT_ENDPOINT/agents/<AGENT_NAME>-mcp?api-version=v1" \
  -H "Authorization: Bearer $AGENT_TOKEN"

工作原理

需要将远程 MCP 服务器(现有的 MCP 服务器终结点)引入 Foundry 代理服务。 可以通过将它们添加为工具来引入多个远程 MCP 服务器。 对于每个工具,需要在同一代理中提供唯一的 server_label 值,以及一个指向远程 MCP 服务器的 server_url 值。 请务必仔细查看添加到 Foundry 代理服务的 MCP 服务器。

除了通过 URL 连接任意远程 MCP 服务器之外,还可以直接从 Foundry 添加工具 目录添加某些 MCP 服务器。 例如,AZURE DEVOPS MCP 服务器(预览版)可用作目录条目。 目录条目简化了连接设置,并与本文中所述的相同审批和审核机制保持一致。

有关使用 MCP 的详细信息,请参阅:

设置 MCP 连接

辅助路径 - 高级操作: 在首次成功路由后使用此引用来限制工具、更改审批行为或添加项目连接。

以下步骤概述了如何从 Foundry 代理服务连接到远程 MCP 服务器:

  1. 查找要连接到的远程 MCP 服务器,例如GitHub MCP 服务器。 使用以下信息创建或更新带 mcp 工具的 Foundry 智能体:
    1. server_url:MCP 服务器的 URL,例如 https://api.githubcopilot.com/mcp/
    2. server_label:此 MCP 服务器对代理的唯一标识符,例如 github
    3. allowed_tools:此代理可以访问和使用的工具的可选列表。 如果未提供此值,则默认值包括 MCP 服务器中的所有工具。
    4. require_approval:(可选)确定是否需要审批。 默认值为 always. 支持的值包括:
      • always:开发人员需要为每个呼叫提供审批。 如果未提供值,则此值为默认值。
      • never:无需审批。
      • {"never":[<tool_name_1>, <tool_name_2>]}:提供不需要审批的工具列表。
      • {"always":[<tool_name_1>, <tool_name_2>]}:提供需要审批的工具列表。
  2. project_connection_id:存储 MCP 服务器的身份验证和其他连接详细信息的项目连接 ID。
  3. 如果模型尝试在 MCP 服务器中调用需要审批的工具,则会收到响应输出项类型为 mcp_approval_request。 在响应输出项中,可以获取有关 MCP 服务器中哪个工具的调用和要传递的参数的更多详细信息。 查看工具和参数,以便你可以做出明智的决策以供审批。
  4. 使用previous_response_id并将approve设置为true以提交审批给代理。

连接到 Azure DevOps MCP 服务器

Azure DevOps MCP 服务器(预览版)可用作 Foundry 中的目录条目。 请添加该短语:

  1. Foundry 门户中,转到你的项目。
  2. 选择 Add Tools>Catalog并搜索“Azure DevOps”。
  3. 选择 Azure DevOps MCP Server (预览版),然后选择 Create
  4. 输入Azure DevOps组织名称,然后选择 Connect
  5. 选择要向代理公开哪些Azure DevOps工具。 可以选择一部分工具,以准确控制代理可以访问的内容。

此基于目录的设置创建 MCP 工具供代理使用,而无需更改代码。 在将该工具集成到生产代码之前,可以在 Foundry 聊天测试体验中验证连接和工具行为。

提示

工具箱版本控制:Foundry 工具箱支持版本控制,因此可以在不影响生产代理的情况下循环访问新版本。 对于生产环境中的智能体,请使用使用者终结点 ({project_endpoint}/toolboxes/{name}/mcp?api-version=v1) - 它始终提供已升级的默认版本。 在推广之前,请使用 版本特定的终结点{project_endpoint}/toolboxes/{name}/versions/{version}/mcp?api-version=v1)进行测试。 保持 server_label 每个代理的唯一性,即使在切换工具箱版本时也是如此。 有关详细信息,请参阅 将版本提升为默认值

长时间运行的操作(预览版)

辅助路径 - 后台模式: 仅在 MCP 操作无法在标准同步超时内完成时使用此模式。

某些 MCP 服务器提供的工具返回结果所需的时间超过标准同步超时时限。 若要支持这些操作,请在 后台模式下运行代理。 后台模式以异步方式运行响应,因此 MCP 工具调用可以继续,而无需保持打开的连接,并轮询响应状态,直到响应状态完成。 这种方法可使 MCP 工具调用超过 已知限制中所述的 100 秒非流式超时。

注意

长时间运行的 MCP 操作目前处于预览阶段。 预览版功能在没有服务级别协议的情况下提供,不建议用于生产工作负荷。 行为和支持的模型可能会更改。

MCP 服务器的要求

代理运行时依赖于 MCP 服务器以异步方式运行操作并报告进度。 服务器必须:

  • 实现 模型上下文协议任务功能 ,以便工具调用可以返回任务引用,而不是在工作完成之前阻止。
  • 当工具启动长时间运行的操作时,在工具结果元数据中返回相关任务标识符(带有 io.modelcontextprotocol/related-tasktaskId 字段)。
  • 提供一种方式,使运行时能够轮询任务状态,并在任务完成后获取最终结果。
  • 可作为远程 MCP 端点被访问,与其他任何 MCP 工具无异。 本地 MCP 服务器必须自行托管,才能提供远程端点。 请参阅 托管本地 MCP 服务器

当代理运行时调用启动长时间运行的操作的工具时,服务器将返回任务引用,运行时会在后台保留响应。 运行时会启动响应,立即返回一个响应 idstatusqueued,并在任务完成时收集结果。 轮询响应 id ,直到 status 变为 completed,然后读取最终输出。

长时间运行的 MCP 操作的后台模式适用于支持后台模式的任何模型,例如 gpt-5.4gpt-5.5

如果代理使用不支持后台模式的模型,MCP 工具调用将同步运行,并受到 100 秒超时。

在 Microsoft Foundry 门户中启用后台模式

你可以在 Microsoft Foundry 门户的演练场中为代理启用后台模式,而无需编写代码:

  1. 打开代理,然后选择 “操场 ”选项卡。

  2. “模型” 列表中,选择支持后台模式的模型,例如 gpt-5.4gpt-5.5

  3. 选择模型旁边的参数图标,然后打开 “后台”模式

  4. “工具”下,添加 MCP 服务器支持 MCP 任务的工具,例如通过 Fabric IQ 工具添加的Fabric数据代理。 有关步骤,请参阅使用 Fabric IQ 将代理连接到Microsoft Fabric

  5. 发送消息。 代理启动后台运行,并在长时间运行的工具调用完成时显示其进度。 运行完成后,响应将显示在聊天中。

使用代码运行后台模式

以下示例调用已使用 MCP 工具配置的代理,并将其设置为backgroundtrue并轮询,直到响应完成。 将占位符值替换为你自己的值。

from time import sleep
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient

PROJECT_ENDPOINT = "your_project_endpoint"
AGENT_NAME = "your_mcp_agent_name"

project = AIProjectClient(
    endpoint=PROJECT_ENDPOINT,
    credential=DefaultAzureCredential(),
)
openai = project.get_openai_client()

# Start a background response. It returns immediately with status "queued".
response = openai.responses.create(
    extra_body={
        "agent_reference": {
            "name": AGENT_NAME,
            "type": "agent_reference",
        }
    },
    input="Run the long-running task and summarize the result.",
    background=True,
)

# Poll the response ID until the MCP tool call completes.
while response.status in ("queued", "in_progress"):
    sleep(5)
    response = openai.responses.retrieve(response.id)

print(response.output_text)
using Azure.Identity;
using Azure.AI.Projects;

var projectEndpoint = "your_project_endpoint";
var agentName = "your_mcp_agent_name";

AIProjectClient projectClient = new(
    endpoint: new Uri(projectEndpoint),
    tokenProvider: new DefaultAzureCredential());

ProjectResponsesClient responsesClient
    = projectClient.ProjectOpenAIClient.GetProjectResponsesClientForAgent(agentName);

// Start a background response. It returns immediately with status "queued".
ResponseResult response = await responsesClient.CreateResponseAsync(
    new CreateResponseOptions
    {
        InputItems = { ResponseItem.CreateUserMessageItem(
            "Run the long-running task and summarize the result.") },
        Background = true,
    });

// Poll the response ID until the MCP tool call completes.
while (response.Status is "queued" or "in_progress")
{
    await Task.Delay(5000);
    response = await responsesClient.RetrieveResponseAsync(response.Id);
}
Console.WriteLine(response.GetOutputText());
import { DefaultAzureCredential } from "@azure/identity";
import { AIProjectClient } from "@azure/ai-projects";

const PROJECT_ENDPOINT = "your_project_endpoint";
const AGENT_NAME = "your_mcp_agent_name";

const project = new AIProjectClient(PROJECT_ENDPOINT, new DefaultAzureCredential());
const openai = project.getOpenAIClient();

// Start a background response. It returns immediately with status "queued".
let response = await openai.responses.create(
  {
    input: "Run the long-running task and summarize the result.",
    background: true,
  },
  { body: { agent_reference: { name: AGENT_NAME, type: "agent_reference" } } },
);

// Poll the response ID until the MCP tool call completes.
while (response.status === "queued" || response.status === "in_progress") {
  await new Promise((r) => setTimeout(r, 5000));
  response = await openai.responses.retrieve(response.id);
}
console.log(response.output_text);
import com.azure.ai.agents.*;
import com.azure.ai.agents.models.AgentReference;
import com.azure.ai.agents.models.AzureCreateResponseOptions;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.openai.models.responses.Response;
import com.openai.models.responses.ResponseCreateParams;

String projectEndpoint = "your_project_endpoint";
String agentName = "your_mcp_agent_name";

AgentsClientBuilder builder = new AgentsClientBuilder()
    .credential(new DefaultAzureCredentialBuilder().build())
    .endpoint(projectEndpoint);
ResponsesClient responsesClient = builder.buildResponsesClient();

AgentReference agentRef = new AgentReference(agentName);

// Start a background response. It returns immediately with status "queued".
Response response = responsesClient.createAzureResponse(
    new AzureCreateResponseOptions()
        .setAgentReference(agentRef)
        .setBackground(true),
    ResponseCreateParams.builder()
        .input("Run the long-running task and summarize the result."));

// Poll the response ID until the MCP tool call completes.
while (response.status().equals("queued") || response.status().equals("in_progress")) {
    Thread.sleep(5000);
    response = responsesClient.getAzureResponse(response.id());
}
System.out.println(response.output());

创建后台响应。 请求会立即返回一个响应 idstatusqueued

curl -X POST "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AGENT_TOKEN" \
  -d '{
    "agent": {"type": "agent_reference", "name": "<AGENT_NAME>-mcp"},
    "input": "Run the long-running task and summarize the result.",
    "background": true
  }'

从结果中复制响应 id,然后对其进行轮询,直到 status 变为 completed

curl "$FOUNDRY_PROJECT_ENDPOINT/openai/v1/responses/$RESPONSE_ID" \
  -H "Authorization: Bearer $AGENT_TOKEN"

statuscompleted 时,output 数组包含 MCP 工具调用结果和最终的助手消息。

已知限制

辅助路径 - 流式处理行为: 如果客户端流响应或 MCP 调用接近同步超时,请在首次成功路由后查看这些限制。

  • 非流式处理 MCP 工具调用超时:非流式处理 MCP 工具调用超时为 100 秒。 如果 MCP 服务器响应的时间超过 100 秒,则调用将失败。 若要避免超时,请确保 MCP 服务器在此限制内响应。 如果用例需要较长的处理时间,请使用支持的模型在 后台模式下 运行代理、优化服务器端逻辑或将操作分解为较小的步骤。
  • 专用 MCP 需要标准代理设置:专用 MCP 服务器连接仅适用于 具有专用网络的标准代理设置 (BYO VNet)。 基本代理设置不支持专用 MCP 终结点。
  • 专用 MCP 托管:专用 MCP 子网上的Azure 容器应用是专用 MCP 服务器的测试配置。 作为专用 MCP 服务器主机的 Function Apps 或应用服务可能有效,但尚未经过内部验证。

常见问题和错误

将 MCP 工具用于 Foundry 代理服务时,可能会出现以下常见问题:

  • “工具架构无效”:

    如果 MCP 服务器定义包含 anyOfallOf或参数接受多种类型的值,则通常会发生此错误。 更新 MCP 服务器定义,然后重试。

  • 来自 MCP 服务器的“未授权”或“禁止访问”:

    确认 MCP 服务器支持身份验证方法,并验证存储在项目连接中的凭据。 对于GitHub,请使用最低特权令牌并定期轮换令牌。

  • 模型从不调用 MCP 工具:

    确认代理说明鼓励使用工具,并验证 server_labelserver_urlallowed_tools 值。 如果设置 allowed_tools,请确保工具名称与 MCP 服务器公开的内容匹配。

  • 代理在批准后永远不会继续:

    确认你发送的后续请求中,previous_response_id 已设置为原始响应 ID,并使用审批请求项 ID 作为 approval_request_id

托管本地 MCP 服务器

代理服务运行时仅接受远程 MCP 服务器终结点。 如果要从本地 MCP 服务器添加工具,则需要在 Azure 容器应用Azure Functions 上自行托管该工具以获取远程 MCP 服务器终结点。

远程终结点可以是公共终结点,也可以是 VNet 中的专用终结点。 对于专用 MCP 服务器,请在专用 MCP 子网上部署具有仅限内部的入口(--internal-only true)的容器应用。 请参阅 公共和专用 MCP 服务器终结点 获取设置详细信息。

在云中托管本地 MCP 服务器时,请考虑以下因素:

本地 MCP 服务器设置 在 Azure 容器应用 中托管 在 Azure Functions 中托管
运输 需要 HTTP POST/GET 终结点。 需要 HTTP 流式传输。
代码更改 需要容器重新生成。 根目录中需要 Azure Functions 特定的配置文件。
认证 需要自定义身份验证实现。 仅基于密钥。 OAuth 需要 API 管理。
语言 在 Linux 容器中运行的任何语言(Python、Node.js、.NET、TypeScript、Go)。 仅限 Python、Node.js、Java、.NET。
容器要求 仅限 Linux(linux/amd64)。 没有特权容器。 不支持容器化服务器。
依赖 所有依赖项都必须位于容器映像中。 不支持 OS 级依赖项(如 Playwright)。
状态 仅限无状态。 仅限无状态。
UVX/NPX 支持。 不支持。 npx 不支持启动命令功能。