模型上下文协议是一种开放标准,用于定义应用程序如何向大型语言模型(LLM)提供工具和上下文数据。 它支持将外部工具与模型工作流的一致、可缩放集成。
Microsoft代理框架支持与模型上下文协议 (MCP) 服务器集成,使代理可以访问外部工具和服务。 本指南演示如何连接到 MCP 服务器,并在代理中使用其工具。
使用第三方 MCP 服务器的注意事项
使用模型上下文协议服务器受你和服务提供商之间的条款的约束。 连接到非Microsoft服务时,某些数据(如提示内容)将传递到非Microsoft服务,或者应用程序可能会从非Microsoft服务接收数据。 你负责使用非Microsoft服务和数据,以及与使用该服务相关的任何费用。
你决定与本文中所述的 MCP 工具一起使用的远程 MCP 服务器是由第三方创建的,而不是Microsoft。 Microsoft尚未测试或验证这些服务器。 Microsoft对你或他人使用任何远程 MCP 服务器不负任何责任。
建议仔细查看和跟踪添加到基于代理框架的应用程序的 MCP 服务器。 我们还建议你依赖于受信任的服务提供商本身托管的服务器,而不是代理。
MCP 工具允许你传递远程 MCP 服务器可能需要的自定义标头,例如身份验证密钥或架构。 建议查看与远程 MCP 服务器共享的所有数据,并记录数据以进行审核。 了解与数据保留和位置相关的非Microsoft操作惯例。
重要
只能在每次运行时将标头包含在tool_resources中来指定标头。 这样,可以直接将 API 密钥、OAuth 访问令牌或其他凭据放入请求中。 传入的标头仅适用于当前运行,并且不会持久保存。
有关 MCP 安全性的详细信息,请参阅:
- 模型上下文协议网站上的安全最佳做法。
- 在Microsoft安全社区博客中了解和缓解 MCP 实现中的安全风险。
代理框架的 .NET 版本可与 官方 MCP C# SDK 一起使用,以允许代理调用 MCP 工具。
以下示例演示如何:
- 设置和 MCP 服务器
- 从 MCP 服务器检索可用工具的列表
- 将 MCP 工具转换为
AIFunction's,以便可以将其添加到代理 - 使用函数调用从代理调用工具
设置 MCP 客户端
首先,创建连接到所需 MCP 服务器的 MCP 客户端:
// Create an MCPClient for the GitHub server
await using var mcpClient = await McpClientFactory.CreateAsync(new StdioClientTransport(new()
{
Name = "MCPServer",
Command = "npx",
Arguments = ["-y", "--verbose", "@modelcontextprotocol/server-github"],
}));
在本示例中:
- 名称:MCP 服务器连接的友好名称
- 命令:运行 MCP 服务器的可执行文件(此处使用 npx 运行 Node.js 包)
- 参数:传递给 MCP 服务器的命令行参数
检索可用工具
连接后,检索 MCP 服务器提供的工具列表:
// Retrieve the list of tools available on the GitHub server
var mcpTools = await mcpClient.ListToolsAsync().ConfigureAwait(false);
该方法 ListToolsAsync() 返回 MCP 服务器公开的工具集合。 这些工具会自动转换为代理可以使用的 AITool 对象。
使用 MCP 工具创建代理
在初始化期间创建代理并提供 MCP 工具:
AIAgent agent = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsAIAgent(
instructions: "You answer questions related to GitHub repositories only.",
tools: [.. mcpTools.Cast<AITool>()]);
警告
DefaultAzureCredential 对于开发来说很方便,但在生产中需要仔细考虑。 在生产环境中,请考虑使用特定凭据(例如), ManagedIdentityCredential以避免延迟问题、意外凭据探测以及回退机制的潜在安全风险。
要点:
- 说明:提供与 MCP 工具功能相符的明确说明
-
工具:将 MCP 工具强制转换为
AITool对象并将其分散到工具数组中 - 代理将自动访问 MCP 服务器提供的所有工具
使用代理
配置后,代理可以自动使用 MCP 工具来满足用户请求:
// Invoke the agent and output the text result
Console.WriteLine(await agent.RunAsync("Summarize the last four commits to the microsoft/semantic-kernel repository?"));
代理将:
- 分析用户的请求
- 确定需要哪些 MCP 工具
- 通过 MCP 服务器调用相应的工具
- 将结果合成为一致的响应
环境配置
请确保设置所需的环境变量:
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") ??
throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
资源管理
始终正确处理 MCP 客户端资源:
await using var mcpClient = await McpClientFactory.CreateAsync(...);
使用 await using 可确保 MCP 客户端连接在超出范围时正确关闭。
常见 MCP 服务器
常用的 MCP 服务器包括:
-
@modelcontextprotocol/server-github:访问 GitHub 存储库和数据 -
@modelcontextprotocol/server-filesystem:文件系统作 -
@modelcontextprotocol/server-sqlite:SQLite 数据库访问
每个服务器提供扩展代理功能的不同工具和功能。 通过此集成,代理可以无缝访问外部数据和服务,同时维护模型上下文协议的安全性和标准化优势。
提供 https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/GettingStarted/ModelContextProtocol/Agent_MCP_Server运行此示例的完整源代码和说明。
小窍门
有关完整的可运行示例,请参阅 .NET 示例 。
这样,代理就可以无缝访问外部工具和服务。
MCP 工具类型
代理框架支持三种类型的 MCP 连接:
MCPStdioTool - 本地 MCP 服务器
用于 MCPStdioTool 使用标准输入/输出连接到以本地进程身份运行的 MCP 服务器:
import asyncio
from agent_framework import Agent, MCPStdioTool
from agent_framework.openai import OpenAIChatClient
async def local_mcp_example():
"""Example using a local MCP server via stdio."""
async with (
MCPStdioTool(
name="calculator",
command="uvx",
args=["mcp-server-calculator"]
) as mcp_server,
Agent(
chat_client=OpenAIChatClient(),
name="MathAgent",
instructions="You are a helpful math assistant that can solve calculations.",
) as agent,
):
result = await agent.run(
"What is 15 * 23 + 45?",
tools=mcp_server
)
print(result)
if __name__ == "__main__":
asyncio.run(local_mcp_example())
MCPStreamableHTTPTool - HTTP/SSE MCP 服务器
用于 MCPStreamableHTTPTool 通过 HTTP 连接到 MCP 服务器并 Server-Sent 事件:
import asyncio
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.azure import AzureAIAgentClient
from azure.identity.aio import AzureCliCredential
async def http_mcp_example():
"""Example using an HTTP-based MCP server."""
async with (
AzureCliCredential() as credential,
MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
headers={"Authorization": "Bearer your-token"},
) as mcp_server,
Agent(
chat_client=AzureAIAgentClient(async_credential=credential),
name="DocsAgent",
instructions="You help with Microsoft documentation questions.",
) as agent,
):
result = await agent.run(
"How to create an Azure storage account using az cli?",
tools=mcp_server
)
print(result)
if __name__ == "__main__":
asyncio.run(http_mcp_example())
MCPWebsocketTool - WebSocket MCP 服务器
用于 MCPWebsocketTool 通过 WebSocket 连接连接到 MCP 服务器:
import asyncio
from agent_framework import Agent, MCPWebsocketTool
from agent_framework.openai import OpenAIChatClient
async def websocket_mcp_example():
"""Example using a WebSocket-based MCP server."""
async with (
MCPWebsocketTool(
name="realtime-data",
url="wss://api.example.com/mcp",
) as mcp_server,
Agent(
chat_client=OpenAIChatClient(),
name="DataAgent",
instructions="You provide real-time data insights.",
) as agent,
):
result = await agent.run(
"What is the current market status?",
tools=mcp_server
)
print(result)
if __name__ == "__main__":
asyncio.run(websocket_mcp_example())
常用 MCP 服务器
可与 Python 代理框架一起使用的常见 MCP 服务器:
-
计算器:
uvx mcp-server-calculator- 数学计算 -
文件系统:
uvx mcp-server-filesystem- 文件系统作 -
GitHub:
npx @modelcontextprotocol/server-github- GitHub 存储库访问权限 -
SQLite:
uvx mcp-server-sqlite- 数据库作
每个服务器提供不同的工具和功能,用于扩展代理的功能,同时维护模型上下文协议的安全性和标准化优势。
完整示例
# Copyright (c) Microsoft. All rights reserved.
import os
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.openai import OpenAIResponsesClient
from httpx import AsyncClient
"""
MCP Authentication Example
This example demonstrates how to authenticate with MCP servers using API key headers.
For more authentication examples including OAuth 2.0 flows, see:
- https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/clients/simple-auth-client
- https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/servers/simple-auth
"""
async def api_key_auth_example() -> None:
"""Example of using API key authentication with MCP server."""
# Configuration
mcp_server_url = os.getenv("MCP_SERVER_URL", "your-mcp-server-url")
api_key = os.getenv("MCP_API_KEY")
# Create authentication headers
# Common patterns:
# - Bearer token: "Authorization": f"Bearer {api_key}"
# - API key header: "X-API-Key": api_key
# - Custom header: "Authorization": f"ApiKey {api_key}"
auth_headers = {
"Authorization": f"Bearer {api_key}",
}
# Create HTTP client with authentication headers
http_client = AsyncClient(headers=auth_headers)
# Create MCP tool with the configured HTTP client
async with (
MCPStreamableHTTPTool(
name="MCP tool",
description="MCP tool description",
url=mcp_server_url,
http_client=http_client, # Pass HTTP client with authentication headers
) as mcp_tool,
Agent(
client=OpenAIResponsesClient(),
name="Agent",
instructions="You are a helpful assistant.",
tools=mcp_tool,
) as agent,
):
query = "What tools are available to you?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}")
将代理公开为 MCP 服务器
可以将代理公开为 MCP 服务器,允许它用作任何 MCP 兼容的客户端(例如 VS Code GitHub Copilot 代理或其他代理)的工具。 代理的名称和说明将成为 MCP 服务器元数据。
使用 .AsAIFunction()函数工具包装代理,创建 McpServerTool代理并将其注册到 MCP 服务器:
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Server;
// Create the agent
AIAgent agent = new AzureOpenAIClient(
new Uri("https://<myresource>.openai.azure.com"),
new AzureCliCredential())
.GetChatClient("gpt-4o-mini")
.AsAIAgent(instructions: "You are good at telling jokes.", name: "Joker");
// Convert the agent to an MCP tool
McpServerTool tool = McpServerTool.Create(agent.AsAIFunction());
// Set up the MCP server over stdio
HostApplicationBuilder builder = Host.CreateEmptyApplicationBuilder(settings: null);
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithTools([tool]);
await builder.Build().RunAsync();
安装所需的 NuGet 包:
dotnet add package Microsoft.Extensions.Hosting --prerelease
dotnet add package ModelContextProtocol --prerelease
调用 .as_mcp_server() 代理以将其公开为 MCP 服务器:
from agent_framework.openai import OpenAIResponsesClient
from typing import Annotated
def get_specials() -> Annotated[str, "Returns the specials from the menu."]:
return "Special Soup: Clam Chowder, Special Salad: Cobb Salad"
# Create an agent with tools
agent = OpenAIResponsesClient().as_agent(
name="RestaurantAgent",
description="Answer questions about the menu.",
tools=[get_specials],
)
# Expose the agent as an MCP server
server = agent.as_mcp_server()
设置 MCP 服务器以侦听标准输入/输出:
import anyio
from mcp.server.stdio import stdio_server
async def run():
async with stdio_server() as (read_stream, write_stream):
await server.run(read_stream, write_stream, server.create_initialization_options())
if __name__ == "__main__":
anyio.run(run)