2025年7月18日 星期五

如何製作簡易版的MCP SERVER (最快3分鐘)

      MCP Server (Model Context Proptocol) 是為了LLM 可以外部擴充它的知識和相關可運用的工具的最新方式,例如你詢問LLM : 【今天的天氣如何?】,LLM 的知識是預訓練完成的,怎麼會得知今天或明天的天氣如何? 所以透過 相關的MCP SERVER 讓LLM 去調用相關內容的function 去取得相關的內容,並透過LLM 的分析,並將結果回傳。

如下圖所示: 

MCP Client :連接 LLM 和 MCP 服務器的橋樑。嵌入在 LLM 中


MCP Server: 具有MCP Protocol協定的 SERVER,負責根據 LLM 的請求,例如事先寫好相應的「工具」或「功能」(Function)。例如,如果 LLM 詢問天氣,MCP Server 會調用預先註冊好的「天氣查詢」功能。

前提安裝條件

    本人安裝的環境 .net 9 SDK 也能建置 MCP  SERVER 


一、安裝 MCP 伺服器範本

dotnet new install Microsoft.Extensions.AI.Templates


二、使用 dotnet 指令建立新的 MCP 伺服器應用程式的範本

dotnet new mcpserver -n SampleMcpServer

三、用Vistul studio 開啟專案

SampleMcpServer

├── 相依性(Dependencies

├── .mcp

   └── server.json

├── Tools

   └── RandomNumberTools.cs

├── Program.cs

└── README.md

這是一個典型的 C# 專案結構,說明如下: 

.mcp/server.json:是 MCP Server 的設定檔。 

Tools/RandomNumberTools.cs:應該是封裝隨機數工具的程式碼檔。 

Program.cs:主執行進入點。 

README.md:說明文件。



     沒有寫一行程式碼,這個專案SampleMCP SERVER 已具有基本的框架,也可以測試執行
接下來我們來看看進面的程式碼是什麼吧! 

檔名: Programe.cs
// 引入必要的命名空間
using Microsoft.Extensions.DependencyInjection;  // 用於注入服務(DI)
using Microsoft.Extensions.Hosting;             // 用於建立主機(主控程式架構)
using Microsoft.Extensions.Logging;             // 用於設定日誌系統(Logging)

// 建立主機建構器(HostBuilder),接收命令列參數
var builder = Host.CreateApplicationBuilder(args);

// 設定所有的 log 訊息輸出到標準錯誤(stderr),
// 因為 stdout 是用來傳輸 MCP 協定訊息的
builder.Logging.AddConsole(o => 
    o.LogToStandardErrorThreshold = LogLevel.Trace // 設定最細的日誌等級(Trace)
);

// 註冊 MCP 伺服器服務:
// - 加入 MCP 伺服器
// - 使用 stdio(標準輸入/輸出)當作資料傳輸通道
// - 註冊要提供的工具:RandomNumberTools
builder.Services
    .AddMcpServer()                 // 註冊 MCP server 基礎功能
    .WithStdioServerTransport()     // 使用 stdio 作為通訊方式(與 IDE / client 互動)
    .WithTools<RandomNumberTools>(); // 提供一個叫 RandomNumberTools 的工具(具體功能要看類別定義)

// 建立並啟動主機,非同步執行直到應用程式結束
await builder.Build().RunAsync();
------------------------------------------------------------------------------------------------------------------------------

檔名: RandomNumberTools.cs  : 建置MCP Server 的function 

// 引入用於工具描述與註解的命名空間
using System.ComponentModel;                  // 提供 DescriptionAttribute 等用來顯示說明文字
using ModelContextProtocol.Server;           // MCP server SDK 所提供的屬性與工具

/// <summary>
/// MCP 工具範例類別,用來展示 MCP server 可供 client 呼叫的方法。
/// MCP client 可以呼叫這些方法來執行對應功能。
/// </summary>
internal class RandomNumberTools
{
    // 定義一個 MCP 工具方法,會自動被 MCP Server 掃描並註冊
    [McpServerTool]
    [Description("在指定的最小值與最大值之間產生一個隨機數字(包含最小,不包含最大)")]
    public int GetRandomNumber(
        [Description("最小值(含)")] int min = 0,
        [Description("最大值(不含)")] int max = 100)
    {
        // 使用 .NET 內建的 Random.Shared 產生一個隨機整數
        return Random.Shared.Next(min, max);
    }
}
------------------------------------------------------------------------------------------------------------------------------
檔名:server.json :可以在NuGet 發佈 MCP套件的設定

{
  "$schema": "https://modelcontextprotocol.io/schemas/draft/2025-07-09/server.json",
  "description": "提供基本隨機數字工具的 MCP Server 範例",
  "name": "io.github.your-username/mcp-randomtools",
  "packages": [
    {
      "registry_name": "nuget",                  // 套件來源(這裡是 NuGet 套件註冊中心)
      "name": "Mcp.RandomTools.Server",          // 你在 NuGet 上發布的套件 ID
      "version": "0.1.0-beta",                   // 套件版本
      "package_arguments": [],                   // 若套件支援 CLI 引數,可列在這(目前留空)
      "environment_variables": []                // 若 MCP server 啟動時需要設定環境變數,可列於此
    }
  ],
  "repository": {
    "url": "https://github.com/your-username/mcp-randomtools",  // GitHub 原始碼位置
    "source": "github"                                          // 表示來源是 GitHub
  },
  "version_detail": {
    "version": "0.1.0-beta"  // MCP server 的版本資訊
  }
}

-----------------------------------------------------------------------------------------------------------------

    如果用戶不是用.net Framework 10 就會出現問題了,此時叫出你的好幫手 copilot ,
並下指令prompt : 我的專案build 不過,如何才能build成功,以下是截圖 ,
記得visual Studio 要更新最新版,才能使用copilot 代理人模式



    
四、如何讓copilot 調用MCP Server 的工具

請先建立資料夾.vscode, 並新增檔案 mcp.json以設定要測試的WEATHER_CHOICES環境變數。

檔名: mcp.json

{
  "servers": {
    // 定義一個 MCP server 名稱叫 "SampleMcpServer"
    // VS Code MCP 擴充功能會用這個名稱來顯示可啟動的伺服器
    "SampleMcpServer": {

      // MCP server 的通訊方式為 stdio(標準輸入/輸出)
      // 適合開發環境中使用,與 IDE 直接互動,不需開啟網路 port
      "type": "stdio",

      // 指定執行 MCP Server 的主命令,這裡使用 .NET CLI
      "command": "dotnet",

      // 執行 dotnet 指令時所附加的參數清單
      "args": [
        "run", // 執行 dotnet run
        "--project", // 指定要執行的專案路徑
        "<RELATIVE PATH TO PROJECT DIRECTORY>" // 專案的相對路徑(請替換為實際目錄)
      ],

      // MCP Server 啟動時設定的環境變數
      // 可以讓 server 程式根據這些變數的值改變行為(如工具回傳內容)
      "env": {
        "WEATHER_CHOICES": "sunny,humid,freezing"
        // MCP 工具可以透過讀取這個環境變數來決定回應的天氣選項
      }
    }
  }
}

透過copilot 的視窗 下面的【選擇工具】,並勾選 sampleMCTServer和get_random_number


        雖然我立刻在copilot 立刻下promp 提問: 【請幫我產生1~99的亂數】,它一直跟我鬼打牆,但後來我重新啟動visual studio ,就可以正常調用MCP Server , 所以不要鐵齒,重開治百病。







參考文章: 
https://blog.logto.io/zh-TW/what-is-mcp

https://www.ibest.com.tw/news-detail/what-is-mcp/

https://learn.microsoft.com/zh-tw/dotnet/ai/quickstarts/build-mcp-server