模型上下文協議是一種開放標準,定義了應用程序如何向大型語言模型 (LLM) 提供工具和上下文數據。 其可讓外部工具與模型工作流程整合一致且可調整。
Microsoft Agent Framework 支援與模型情境協定(MCP)伺服器整合,讓您的代理能存取外部工具與服務。 本指南說明如何連線到 MCP 伺服器,並在代理程式中使用其工具。
使用第三方 MCP 伺服器的考量
您使用模型情境協定伺服器時,須遵守您與服務提供者之間的條款。 當你連接到非 Microsoft 服務時,你的部分資料(例如提示內容)會被傳給非 Microsoft 服務,或者你的應用程式可能會從非 Microsoft 服務接收資料。 你對使用非 Microsoft 的服務和資料,以及與此使用相關的任何費用負責。
你選擇搭配本文所述的 MCP 工具使用的遠端 MCP 伺服器,是由第三方建立,而非 Microsoft。 Microsoft尚未測試或驗證這些伺服器。 Microsoft 對您或其他人使用任何遠端 MCP 伺服器概不負責。
建議您仔細檢閱並追蹤您新增至代理程式架構型應用程式的 MCP 伺服器。 我們也建議您依賴由受信任的服務提供者自行托管的伺服器,而非代理伺服器。
MCP 工具可讓您傳遞遠端 MCP 伺服器可能需要的自定義標頭,例如驗證金鑰或架構。 建議您檢閱與遠端 MCP 伺服器共用的所有數據,並記錄數據以供稽核之用。 注意非Microsoft的資料保留和定位做法。
這很重要
你可以在每次執行時將標頭納入工具資源中,或在 Python 本地 MCP 工具上設定header_provider。 檢視任何與遠端 MCP 伺服器共享的 API 金鑰、OAuth 存取權杖或其他憑證。
欲了解更多關於 MCP 安全性的資訊,請參見:
- 模型內容通訊協議網站上的安全性最佳做法。
- 理解與緩解 MCP 實作中的安全風險,收錄於 Microsoft 安全性 社群部落格。
.NET 版本的 Agent Framework 可搭配 官方的 MCP C# SDK 使用,讓您的代理程式呼叫 MCP 工具。
下列範例示範如何:
- 設定和 MCP 伺服器
- 從 MCP 伺服器擷取可用工具清單
- 將 MCP 工具
AIFunction轉換為 ,以便將它們新增至代理程式 - 使用函數呼叫從代理程式叫用工具
設定 MCP 用戶端
首先,建立連接到所需 MCP 伺服器的 MCP 用戶端:
using ModelContextProtocol.Client;
// Create an MCPClient for the GitHub server
await using var mcpClient = await McpClient.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工具:
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
AIAgent agent = new AIProjectClient(
new Uri(endpoint),
new DefaultAzureCredential())
.AsAIAgent(
model: deploymentName,
instructions: "You answer questions related to GitHub repositories only.",
tools: [.. mcpTools.Cast<AITool>()]);
Warning
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 McpClient.CreateAsync(...);
使用 await using 可確保 MCP 用戶端連線在超出範圍時正確關閉。
常見的 MCP 伺服器
流行的 MCP 伺服器包括:
-
@modelcontextprotocol/server-github:存取 GitHub 儲存庫和資料 -
@modelcontextprotocol/server-filesystem:檔案系統作業 -
@modelcontextprotocol/server-sqlite:SQLite 資料庫存取
每部伺服器都提供不同的工具和功能來擴充代理程式的功能。 此整合可讓您的客服專員順暢地存取外部資料和服務,同時保持模型內容通訊協定的安全性和標準化優勢。
這使您的代理能夠無縫存取外部工具和服務。
備註
在最小的 Python 安裝中,MCP 支援可能需要手動安裝。 安裝 mcp --pre 以使用 MCPStdioTool、 MCPStreamableHTTPTool或 Agent.as_mcp_server()。 如果你也需要mcp[ws] --pre安裝MCPWebsocketTool。
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(
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.foundry import FoundryChatClient
from azure.identity.aio import AzureCliCredential
async def http_mcp_example():
"""Example using an HTTP-based MCP server."""
async with AzureCliCredential() as credential:
client = FoundryChatClient(credential=credential)
async with (
MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
) as mcp_server,
Agent(
client=client,
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())
建立 MCPStreamableHTTPTool 回應 Cookie 的 HTTP 客戶端不會持久化。 如果伺服器需要 Cookie 來進行驗證、會話或負載平衡,請將 配置 httpx.AsyncClient 過 http_client=的 。 所提供的用戶端仍保留其 cookie 行為,並保持來電者擁有。 將攜帶 Cookie 的客戶端及其 MCP 工具會話範圍設定為一個已認證的主體。
對於已認證的 HTTP 端點,則可使用 static_headers 固定憑證或 header_provider 每次執行所得的值。 這兩條路徑僅在設定的原始請求中新增標頭,並從跨來源重定向中移除標頭。 固定標頭會在建立工具時複製,且不會序列化並行呼叫。 當兩個選項提供相同的標頭時,動態值會優先於 。header_provider
在產生的工具呼叫中, header_provider 只接收執行的主機 function_invocation_kwargs。 即使模型參數名稱相同,也不會接收模型提供的工具參數。 直接 call_tool(...) 通話會將其呼叫者提供的關鍵字參數傳遞給提供者。 模型值仍可在獨立合併的出站工具參數中優先,但它們不控制認證標頭。
固定標頭與動態標頭共同構成 HTTP 會話的有效身份。 標頭名稱會不區分大小寫,而值則保持大小寫區分。 當伺服器架構允許相同名稱時,執行時關鍵字參數也可用於出站工具參數。 為了避免憑證被工具參數影響,請透過關閉機制在提供者中擷取憑證,或 ContextVar使用 static_headers、或提供自訂的 HTTP 用戶端。
框架擁有的會話在連結時綁定了這種有效身份。 若後續執行產生不同身份,工具會在發送呼叫前重新連線,並刷新會話衍生工具與提示發現。 初始化、發現、背景ping及其他連線壽命請求仍會使用綁定至該會話的標頭。
來電者提供的會話仍由來電者擁有。 由於包裝器無法為這些會話建立或重新連接未知身份,因此拒絕對未知身份的動態標頭解析。 改變的身份也會被拒絕;使用一個獨立的框架管理工具實例。
如果工具在執行前積極連線,提供者會收到一個空的連線壽命請求映射。 在此情況下,請在供應商中擷取或刷新施工期憑證。 如果憑證只在執行時才到達,就用 傳遞function_invocation_kwargs未連接的工具run(tools=[...]),讓該執行建立連線。
KeyError只有當沒有執行(no run)做種,且請求繼續且沒有提供者標頭時,提供者才會被容忍。 執行後,連線做種後,缺少金鑰即為設定錯誤,例外會被揭露。
依明確名稱選擇工具
當你在 中設定 allowed_tools 或列出工具 approval_mode時,請使用原始的遠端工具名稱或明確的前綴名稱。 如果一個設定名稱在正規化後匹配多個原始遠端名稱,代理框架會產生 ToolExecutionException。 使用完全相同的原始名稱或更改 tool_name_prefix ,讓當地名稱獨一無二。
MCP 抽樣淘汰
Warning
伺服器發起的 MCP 抽樣 sampling_callback ,自 MCP 規範版本 2026-07-28 起被棄用,最遲於 2027-07-28 移除。
不要在這個功能上建立新的整合。 MCP 伺服器應直接呼叫模型提供者 API。
控制主機有效載荷保留
當主機傳輸(如 AG-UI)使用了 MCP 工具的結果時,代理框架會將完整的 JSON 安全結果與解析後的模型面向值分開保存。 這讓主機能接收如 的 structuredContent 欄位,而不會將僅主機資料加入模型歷史。
在任何 MCP 傳輸中,當結果同時包含 content 和 structuredContent時,請使用tool_result_content選擇模型可見值:
| 價值 | 模型可見結果 |
|---|---|
structured_first |
在有時使用 structuredContent ,否則 content。 此值為預設值。 |
content_first |
使用 nonempty content,否則 structuredContent。 |
content_only |
忽略 structuredContent。 |
structured_only |
忽略 content。 |
both |
在區塊後content附上序列structuredContent。 |
此選擇不會改變保留的宿主有效載荷。
parse_tool_results 會覆蓋選擇政策。
每個 MCP 傳輸預設限制保留的主機有效載荷為 1 MiB。
過大有效載荷會從主機通道中省略,但解析結果仍會傳送到模型。 在傳輸端設定不同的正位元組限制,或僅在下游主機套用自身界限時使用 None :
mcp_server = MCPStreamableHTTPTool(
name="Microsoft Learn MCP",
url="https://learn.microsoft.com/api/mcp",
max_host_payload_size_bytes=256 * 1024,
)
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(
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 asyncio
import os
from agent_framework import Agent, MCPStreamableHTTPTool
from agent_framework.openai import OpenAIChatClient
"""
MCP Authentication Example
This example demonstrates a `header_provider` that authenticates both connection-time and tool-call requests.
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."""
mcp_server_url = os.getenv("MCP_SERVER_URL", "your-mcp-server-url")
api_key = os.getenv("MCP_API_KEY")
if not api_key:
raise ValueError("MCP_API_KEY environment variable must be set.")
async with Agent(
client=OpenAIChatClient(),
name="Agent",
instructions="You are a helpful assistant.",
tools=MCPStreamableHTTPTool(
name="MCP tool",
description="MCP tool description",
url=mcp_server_url,
header_provider=lambda _kwargs: {"Authorization": f"Bearer {api_key}"},
),
) as agent:
query = "What tools are available to you?"
print(f"User: {query}")
result = await agent.run(query)
print(f"Agent: {result.text}")
if __name__ == "__main__":
asyncio.run(api_key_auth_example())
MCP 工具類型
此 mcptool 套件允許代理使用來自模型情境協定(MCP)伺服器的工具。
連線至 MCP 伺服器
import (
"github.com/microsoft/agent-framework-go/tool/mcptool"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
session, err := mcptool.Connect(ctx, &mcp.StreamableClientTransport{
Endpoint: "https://learn.microsoft.com/api/mcp",
})
if err != nil {
panic(err)
}
defer session.Close()
列出並使用 MCP 工具
tools, err := mcptool.ListTools(ctx, session)
if err != nil {
panic(err)
}
a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "You are a helpful assistant.",
Config: agent.Config{
Tools: tools,
},
})
resp, err := a.RunText(ctx, "How to create an Azure storage account using az cli?").Collect()
支援的傳輸方式
-
HTTP/SSE -
mcp.StreamableClientTransport{Endpoint: "https://..."} - Stdio - 啟動本地 MCP 伺服器程序
Tip
完整可執行範例請參閱 MCP 工具範例 。
將代理對象暴露為 MCP 伺服器
你可以將代理暴露為 MCP 伺服器,讓任何相容 MCP 的客戶端(例如 VS Code、GitHub Copilot 代理或其他代理)都能將其作為工具使用。 代理的名稱與描述成為 MCP 伺服器的元資料。
將代理包裹在函式工具中,使用 .AsAIFunction(),建立一個 McpServerTool,並註冊至 MCP 伺服器:
using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ModelContextProtocol.Server;
// Create the agent
AIAgent agent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
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();
Warning
DefaultAzureCredential 開發方便,但在生產過程中需謹慎考量。 在生產環境中,建議使用特定的憑證(例如 ManagedIdentityCredential),以避免延遲問題、意外的憑證探測,以及備援機制帶來的安全風險。
安裝所需的 NuGet 套件:
dotnet add package Microsoft.Agents.AI.Foundry --prerelease
dotnet add package Microsoft.Extensions.Hosting
dotnet add package ModelContextProtocol
呼叫 .as_mcp_server() 代理程式將其暴露為 MCP 伺服器:
備註
Python agent.as_mcp_server() 也取決於可選 mcp 套件。 如果你用的是 slim/core 安裝,先跑。pip install mcp --pre
from agent_framework.openai import OpenAIChatClient
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 = OpenAIChatClient().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)
將代理程式包裝為 agenttool.New,使用 mcptool.AddTool,並透過 stdio 向 MCP 伺服器註冊:
import (
"context"
"github.com/microsoft/agent-framework-go/agent"
"github.com/microsoft/agent-framework-go/provider/foundryprovider"
"github.com/microsoft/agent-framework-go/tool/agenttool"
"github.com/microsoft/agent-framework-go/tool/mcptool"
"github.com/modelcontextprotocol/go-sdk/mcp"
)
jokeAgent := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "You are good at telling jokes.",
Config: agent.Config{
Name: "Joker",
Description: "An agent that tells jokes.",
},
})
server := mcp.NewServer(&mcp.Implementation{
Name: "agent-mcp-server",
Version: "1.0.0",
}, nil)
mcptool.AddTool(server, agenttool.New(jokeAgent, agenttool.Config{}))
if err := server.Run(context.Background(), &mcp.StdioTransport{}); err != nil {
panic(err)
}
Tip
請參閱代理 作為 MCP 工具範例 ,完整可執行範例。