原來使用 .net 寫個 MCP Server 如此簡單
MCP 的重要性與意義
MCP 的重要性在於它建立了一個標準化的架構,讓開發者能夠快速建構出給 AI Agent 呼叫的各種功能。
舉例來說,假設我們希望實現一個可以透過自然語言對談的請假功能,傳統上我們必須建立一個前端 Chat Bot 作為 UI、還得撰寫後端 API、資料驗證邏輯、資料庫存取介面…等,另外還要設計 Chat Bot 的對話邏輯,才能把請假功能整合到Chat Bot的對談訊息中。
但在 MCP 的架構下,這樣的流程可以大幅簡化。
開發者只需要實作幾個「請假功能」的介面(Tool Interface),接著定義好運行這個功能需要輸入哪些參數(例如請假人、開始時間、代理人、事由…etc.),並透過 JSON 來描述這些參數的格式與驗證邏輯。接著,AI Agent 便可以在對話過程中,自動根據對談前後文理解使用者意圖,挑選出適合的Tool來運行,主動發出呼叫的請求。如此一來,大幅簡化了AI Agent開發的難度。(本質上就是 Function Calling 的概念)
而 .net 又把這個難度降低到人人可以開發的程度,底下是一個使用 .net 開發的 請假功能 MCP Server,並且使用 GitHub Copilot來呼叫的例子:
其實我之前用 Semantic Kernel做個類似的範例,只是如今 .net 讓它變得更簡單,而且輕易地可以透過MCP架構讓不同的 MCP Client端呼叫使用。
如何用 .NET 撰寫 MCP Server
要使用 .NET 撰寫 MCP Server 非常簡單,受益於 Microsoft.Extensions.Hosting 和 ModelContextProtocol 套件,我們可以在幾分鐘內輕鬆地實作 MCP Tool 和 MCP Server 。
以下是MCP Server的完整程式碼:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
最上面的這些 using
匯入了必要的命名空間,提供伺服器構建、Log記錄、MCP Server 功能以及工具描述的支援。
因此,你在建立程式的時候,需要安裝底下套件:
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting
簡單說明如下。
建立伺服器建構器
var builder = Host.CreateApplicationBuilder(args);
使用 Host.CreateApplicationBuilder 建立伺服器建構器,這是 .NET 中用於建構主機應用程式的核心方法。
底下這段程式碼,則是將日誌記錄設定為輸出到主控台,並將最低記錄級別設定為 Trace,以便詳細追蹤伺服器的運行狀態。
builder.Logging.AddConsole(consoleLogOptions =>
{
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
接著註冊 MCP Server
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
最後啟動伺服器
await builder.Build().RunAsync();
建構伺服器並啟動,開始監聽並處理 MCP 工具的請求。
但這樣還不夠,我們還需要建立具體的功能,也就是 MCP Tool。
關於 MCP Tool
MCP Tool 就是實際要被呼叫執行的具體功能。例如,底下這段程式碼中,建立了三個關於請假的功能(當然是模擬的,但你要改寫成串接真實的請假系統肯定不是難事):
[McpServerToolType]
public static class LeaveRequestTool
{
[McpServerTool, Description("取得請假天數")]
public static int GetLeaveRecordAmount([Description("要查詢請假天數的員工名稱")] string employeeName)
{
// 模擬根據員工名稱回傳請假天數
// 在實際應用中,這可能會查詢資料庫
if (employeeName.ToLower() == "david")
return 5;
else if (employeeName.ToLower() == "eric")
return 8;
else
return 3;
}
[McpServerTool, Description("進行請假,回傳結果")]
public static string LeaveRequest(
[Description("請假起始日期")] string 請假起始日期,
[Description("請假天數")] int 天數,
[Description("請假事由")] string 請假事由,
[Description("代理人")] string 代理人,
[Description("請假者姓名")] string 請假者姓名)
{
// 模擬請假處理邏輯,除了事由之外,其他都是必填
if (string.IsNullOrEmpty(請假起始日期) || string.IsNullOrEmpty(請假事由) || string.IsNullOrEmpty(代理人) || string.IsNullOrEmpty(請假者姓名))
{
return "請假失敗,請確認所有必填欄位已填寫。";
}
// 模擬請假成功的回應
var result = $"{請假者姓名} 請假 {天數}天,從 {請假起始日期} 開始,事由為 {請假事由},代理人 {代理人}";
return result;
}
[McpServerTool, Description("取得今天日期")]
public static string GetCurrentDate()
{
return DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss");
}
}
從上面的程式碼中的 Description() Attribute 你應當可以看得出來,這三個MCP Tool的功能分別是:
- GetLeaveRecordAmount: 查詢員工的請假天數。
- LeaveRequest: 提交請假申請,回傳結果。
- GetCurrentDate: 取得目前日期。
有了這三個請假功能,用戶就可以透過對談的方式來查詢請假天數或進行請假。再看一下使用 GitHub Copilot 充當 Client 呼叫這些 Tool 的操作:
你會發現,我們透過自然語言對談,就可以讓 GitHub Copilot自動呼叫適合的API,查詢請假天數、確定今天日期、完成請假動作…etc.
當然,對談的Client端不是只能用 GitHub Copilot,使用GitHub Copilot只是方便測試。(但開發時真的好方便)
最後,我們整理一下建立 MCP Server + Tools 的步驟:
- 建立一個 Console 程式。
- 使用 Host.CreateApplicationBuilder 建立伺服器。
- 註冊 MCP Server 並設定傳輸方式(如標準輸入/輸出)。
- 註冊工具(MCP Tool),讓伺服器能夠執行各種操作。
- 啟動伺服器。
而 .net + VS Code 把這個開發/除錯的機制,建構的非常理想,我們可以直接在 .net console 專案當中,建立底下這樣的 .vscode/mcp.json 檔案:
{
"servers": {
"MinimalMcpServer": {
"type": "stdio",
"command": "dotnet",
"args": [
"run",
"--project",
"${workspaceFolder}/MinimalMcpServer.csproj"
]
}
}
}
這樣就可以在VS Code中,直接啟用該 MCP Server,順帶使用 GitHub Copilot 進行開發時的測試與除錯,輕輕鬆鬆就完成 MCP Server 的開發:
簡單到這個地步,未來自然語言對談的各種功能,估計會蓬勃發展到不行了。
reference repo:
https://github.com/isdaviddong/LeaveRequestMcpServer
留言