在 Day 22 我們介紹了 MCP 的基本概念和核心組成,今天直接來實作一個簡單的範例,使用 Microsoft 的 Semantic Kernel 來串接一個 MCP Server,並透過 Streamable HTTP 模式來進行通訊。這個範例會展示如何設定 Semantic Kernel 作為 MCP Client,串接 Context7 MCP Server (一個開放的 MCP Server),測試是否能成功通訊取得 MCP Server 所暴露的工具。
Context7 是由 Upstash 團隊開發的開源工具,專門為 AI 程式開發助手提供最新、版本特定的官方文檔和程式碼範例。 它的目的在於解決大型語言模型(LLM)經常生成過時或錯誤程式碼的問題,尤其是在模型訓練截止日期之後發布或更新的程式,是許多開發人員在使用 AI Coding 工具時重要的資源。
Context7 的工作原理是動態將最新的官方文件直接注入到你的提示詞中,所以當你在 VS-Code 、 Cursor、Claude Desktop、Windsurf 等支援 MCP(Model Context Protocol)的編輯器中使用時,只需在問題中加入 "use context7",系統就會自動獲取相關程式庫的最新文檔,並將其整合到 AI 助手的上下文視窗中,以減少程式碼錯誤的可能性。
dotnet add package ModelContextProtocol --version 0.4.0-preview.1
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
apiKey: Config.OpenAI_ApiKey,
modelId: Config.ModelId)
.Build();
// 連線到 MCP Server (Streamable HTTP,原 SSE模式請建議改用 Streamable HTTP取代)
var clientTransport = new HttpClientTransport(new()
{
Endpoint = new Uri("https://mcp.context7.com/mcp"),
Name = "Context7Server",
AdditionalHeaders = new Dictionary<string, string>
{
{ "Authorization", "Bearer xx-your-api-token" }
}
});
await using var mcpClient = await McpClient.CreateAsync(clientTransport!);
// 取得 MCP Server 工具清單
var tools = await mcpClient.ListToolsAsync();
// 工具清單顯示
foreach (var tool in tools)
{
Console.WriteLine($"Connected to Context7 MCP server with tools: {tool.Name}");
}
// 匯入工具並組裝 Agent
kernel.Plugins.AddFromFunctions("McpTools", tools.Select(t => t.AsKernelFunction()));
ChatCompletionAgent agent =
new(){
Name = "ProgramerAgent",
Description = "一個可以回答C#程式碼的助手",
Instructions =
"""
你是一個熟悉 C#/.NET 的程式碼撰寫助理,角色定位是快速、準確的輸出程式碼,一律使用 context7 工具確認程式碼正確性。
## 你的任務是:
— 必須使用 context 7 工具來確認程式碼的正確性。
- 依照使用者的指示,產出正確、可編譯的 C# 程式碼。
- 程式碼中採用正確的語法、命名與常見 C# 實務(例如 async/await、可空參考、正確 using 區塊)
- 除非使用者要求解釋,否則只輸出程式碼區塊,不多加贅述。
- 如果你不確定程式碼是否正確,請使用 context 7 工具來驗證。
- 如果使用者要求解釋,請簡要說明程式碼的功能和邏輯。
- 不得輸出惡意、危險或繞過安全機制的內容。
## 輸出格式:
```csharp
...(程式碼)
```
""",
Kernel = kernel,
Arguments = new(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() })
};
// 建立對話歷史 thread
ChatHistoryAgentThread agentThread = new();
Console.Write("User > ");
string? userInput;
while ((userInput = Console.ReadLine()) is not null)
{
if (string.IsNullOrWhiteSpace(userInput) || userInput.Equals("exit", StringComparison.OrdinalIgnoreCase))
break;
ChatMessageContent message = new(AuthorRole.User, userInput);
bool isFirst = false;
await foreach (StreamingChatMessageContent response in agent.InvokeStreamingAsync(message, agentThread))
{
if (string.IsNullOrEmpty(response.Content))
{
StreamingFunctionCallUpdateContent? functionCall = response.Items.OfType<StreamingFunctionCallUpdateContent>().SingleOrDefault();
//追蹤function calling調用
if (!string.IsNullOrEmpty(functionCall?.Name))
{
Console.WriteLine($"\n# trace {response.Role} - {response.AuthorName ?? "*"}: FUNCTION CALL - {functionCall.Name}");
}
continue;
}
if (!isFirst)
{
Console.Write($"{response.Role} - {response.AuthorName ?? "*"} > ");
isFirst = true;
}
Console.Write($"{response.Content}");
}
Console.WriteLine();
Console.WriteLine($"\n# trace chat thread with agent: {agent.Name} - {agent.Description},threadId: {agentThread.Id} \n");
Console.Write("User > ");
}
Connected to Context7 MCP server with tools: resolve-library-id
Connected to Context7 MCP server with tools: get-library-docs
User > qdranmt 向量資料庫範例
# trace Assistant - ProgramerAgent: FUNCTION CALL - McpTools-resolve-library-id
# trace Assistant - ProgramerAgent: FUNCTION CALL - McpTools-get-library-docs
assistant - ProgramerAgent > ```csharp
// 使用 Qdrant 向量資料庫的 C# 範例(僅示範用 REST API 與 HttpClient 基本用法)
// 官方沒有 C# Client,可直接呼叫 REST API
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Threading.Tasks;
public class QdrantVector
{
public int Id { get; set; }
public float[] Vector { get; set; }
public Dictionary<string, object>? Payload { get; set; }
}
....(以下省略)
透過這個範例,示範如何使用 Semantic Kernel 開發作為 MCP Client的 Agent,串接外部的 Context7 MCP Server,並利用 Streamable HTTP 模式來進行通訊。這種方式能夠動態獲取最新的程式碼範例和官方文檔,提升 AI 助手的準確性和實用性。未來可以將這個架構應用到更多場景中,例如結合其他 MCP Server 或擴展更多功能,打造更強大的 AI Agent。
在 0.4.0-preview.1 版本中,原本使用的 SSE 模式已被標記為過時,建議改用 Streamable HTTP 模式來取代。Streamable HTTP 提供了更穩定和高效的通訊方式,適合在各種網路環境下使用。如果你正在使用舊版本的 MCP 套件,升級 ModelContextProtocol 後,必須改用 HttpClientTransport 取代 SseClientTransport,而原本的McpClientFactory.CreateAsync方法也改為 McpClient.CreateAsync 方法。