使用 C# 创建最小 MCP 服务器并发布到 NuGet

在本快速入门中,你将使用 适用于 MCP 的 C# SDK 创建最小模型上下文协议(MCP)服务器,使用 GitHub Copilot 连接到它,并将其发布到 NuGet。 MCP 服务器是通过模型上下文协议(MCP)向客户端公开功能的服务。

注释

Microsoft.Extensions.AI.Templates 体验目前处于预览版状态。 该模板使用 ModelContextProtocol 库和 MCP 注册表 server.json 架构,它们均处于预览状态。

先决条件

创建项目

  1. 在终端窗口中,安装 MCP 服务器模板(版本 9.7.0-preview.2.2.25356.2 或更高版本):

    dotnet new install Microsoft.Extensions.AI.Templates
    
  2. 使用 dotnet new mcpserver 以下命令创建新的 MCP 服务器应用:

    dotnet new mcpserver -n SampleMcpServer
    
  3. 导航到 SampleMcpServer 目录:

    cd SampleMcpServer
    
  4. 生成项目:

    dotnet build
    
  5. 更新 .csproj 文件中的 <PackageId>,以便在 NuGet.org 中实现唯一,例如 <NuGet.org username>.SampleMcpServer

在 Visual Studio Code 中配置 MCP 服务器

配置用于 Visual Studio Code 的 GitHub Copilot 以使用自定义 MCP 服务器:

  1. 如果尚未打开,请在 Visual Studio Code 中打开项目文件夹。

  2. 在项目的根目录中创建文件夹 .vscode

  3. mcp.json文件夹中添加一个.vscode文件,内容如下:

    {
      "servers": {
        "SampleMcpServer": {
          "type": "stdio",
          "command": "dotnet",
          "args": [
            "run",
            "--project",
            "<RELATIVE PATH TO PROJECT DIRECTORY>"
          ]
        }
      }
    }
    
  4. 保存文件。

测试 MCP 服务器

MCP 服务器模板包括一个名为 get_random_number 的工具,可用于测试以及作为开发的起点。

  1. 在 Visual Studio Code 中打开 GitHub Copilot 并切换到聊天模式。

  2. 选择 “选择工具 ”图标,验证 SampleMcpServer 是否可用于列出的示例工具。

    显示可用 MCP 工具的屏幕截图。

  3. 输入运行 get_random_number 工具的提示:

    Give me a random number between 1 and 100.
    
  4. GitHub Copilot 请求获取权限以运行针对提示的 get_random_number 工具。 选择 “继续 ”或使用箭头选择更具体的行为:

    • 当前会话 始终在当前 GitHub Copilot 代理模式会话中运行作。
    • 当前工作区 始终运行当前 Visual Studio Code 工作区的命令。
    • 始终允许 将此操作设置为始终在 GitHub Copilot 代理模式的任何会话或任何 Visual Studio Code 工作区中运行。
  5. 验证服务器是否使用随机数进行响应:

    Your random number is 42.
    

添加输入和配置选项

在此示例中,将增强 MCP 服务器以使用环境变量中设置的配置值。 这可能是 MCP 服务器正常运行所需的配置,例如 API 密钥、要连接到的终结点或本地目录路径。

  1. Tools/RandomNumberTools.cs中的GetRandomNumber方法后,添加另一个工具方法。 更新工具代码以使用环境变量。

    [McpServerTool]
    [Description("Describes random weather in the provided city.")]
    public string GetCityWeather(
        [Description("Name of the city to return weather for")] string city)
    {
        // Read the environment variable during tool execution.
        // Alternatively, this could be read during startup and passed via IOptions dependency injection
        var weather = Environment.GetEnvironmentVariable("WEATHER_CHOICES");
        if (string.IsNullOrWhiteSpace(weather))
        {
            weather = "balmy,rainy,stormy";
        }
    
        var weatherChoices = weather.Split(",");
        var selectedWeatherIndex =  Random.Shared.Next(0, weatherChoices.Length);
    
        return $"The weather in {city} is {weatherChoices[selectedWeatherIndex]}.";
    }
    
  2. .vscode/mcp.json更新为设置WEATHER_CHOICES环境变量以进行测试。

    {
       "servers": {
         "SampleMcpServer": {
           "type": "stdio",
           "command": "dotnet",
           "args": [
             "run",
             "--project",
             "<RELATIVE PATH TO PROJECT DIRECTORY>"
           ],
           "env": {
              "WEATHER_CHOICES": "sunny,humid,freezing"
           }
         }
       }
     }
    
  3. 在 VS Code 中使用 Copilot 尝试另一个提示,例如:

    What is the weather in Redmond, Washington?
    

    VS Code 应返回随机天气说明。

  4. 更新 .mcp/server.json 以声明您的环境变量输入。 文件 server.json 架构由 MCP 注册表项目 定义,NuGet.org 用于生成 VS Code MCP 配置。

    • 使用 environment_variables 属性声明应用程序的环境变量,这些变量将由客户端使用 MCP 服务器(例如 VS Code)来设置。

    • 使用该 package_arguments 属性定义将传递给应用的 CLI 参数。 有关更多示例,请参阅 MCP 注册表项目

    {
      "$schema": "https://modelcontextprotocol.io/schemas/draft/2025-07-09/server.json",
      "description": "<your description here>",
      "name": "io.github.<your GitHub username here>/<your repo name>",
      "packages": [
        {
          "registry_name": "nuget",
          "name": "<your package ID here>",
          "version": "<your package version here>",
          "package_arguments": [],
          "environment_variables": [
            {
              "name": "WEATHER_CHOICES",
              "value": "{weather_choices}",
              "variables": {
                "weather_choices": {
                  "description": "Comma separated list of weather descriptions to randomly select.",
                  "is_required": true,
                  "is_secret": false
                }
              }
            }
          ]
        }
      ],
      "repository": {
        "url": "https://github.com/<your GitHub username here>/<your repo name>",
        "source": "github"
      },
      "version_detail": {
        "version": "<your package version here>"
      }
    }
    

    NuGet.org 在 server.json 中使用的唯一信息是第一个packages数组项,该项的registry_name值与nuget匹配。 除了该属性之外的其他顶级属性 packages 当前未使用,并且适用于即将推出的中央 MCP 注册表。 可以保留占位符值,直到 MCP 注册表处于活动状态并准备好接受 MCP 服务器条目。

在继续之前,可以 再次测试 MCP 服务器

打包并发布到 NuGet

  1. 打包项目:

    dotnet pack -c Release
    
  2. 将包发布到 NuGet:

    dotnet nuget push bin/Release/*.nupkg --api-key <your-api-key> --source https://api.nuget.org/v3/index.json
    

    如果要在发布到 NuGet.org 之前测试发布流程,可以在 NuGet Gallery 集成环境中注册帐户:https://int.nugettest.org命令会被修改为:push

    dotnet nuget push bin/Release/*.nupkg --api-key <your-api-key> --source https://apiint.nugettest.org/v3/index.json
    

有关详细信息,请参阅 发布包

发现 NuGet.org 上的 MCP 服务器

  1. NuGet.org 上搜索您的 MCP 服务器包(如果是发布到集成环境,则在 int.nugettest.org 上搜索),并从列表中选择它。

    显示 NuGet.org 上搜索 MCP 服务器的屏幕截图。

  2. 查看包详细信息,并从“MCP 服务器”选项卡中复制 JSON。

    显示 NuGet.org 上显示的特定 MCP 服务器的屏幕截图。

  3. .vscode文件夹中的mcp.json文件中,添加复制的 JSON,如下所示:

    {
      "inputs": [
        {
          "type": "promptString",
          "id": "weather_choices",
          "description": "Comma separated list of weather descriptions to randomly select.",
          "password": false
        }
      ],
      "servers": {
        "Contoso.SampleMcpServer": {
          "type": "stdio",
          "command": "dnx",
          "args": ["Contoso.SampleMcpServer@0.0.1-beta", "--yes"],
          "env": {
            "WEATHER_CHOICES": "${input:weather_choices}"
          }
        }
      }
    }
    

    如果发布到 NuGet Gallery 集成环境中,则需要在"--add-source", "https://apiint.nugettest.org/v3/index.json"数组末尾添加"args"

  4. 保存文件。

  5. 在 GitHub Copilot 中,选择 “选择工具 ”图标以验证 SampleMcpServer 是否可用于列出的工具。

  6. 输入运行新 get_city_weather 工具的提示:

    What is the weather in Redmond?
    
  7. 如果将输入添加到 MCP 服务器(例如 WEATHER_CHOICES),系统会提示您提供数值。

  8. 验证服务器是否响应随机天气:

    The weather in Redmond is balmy.
    

常见问题

找不到运行 SampleMcpServer 所需的命令“dnx”。

如果 VS Code 在启动 MCP 服务器时显示此错误,则需要安装兼容版本的 .NET SDK。

显示 VS Code 中缺少 dnx 命令的屏幕截图。

dnx 命令作为 .NET SDK 的一部分提供,从版本 10 预览版 6 开始。 安装 .NET 10 SDK 以解决此问题。

GitHub Copilot 不使用您的工具(提供答案而不调用您的工具)。

通常而言,会告知 GitHub Copilot 这样的 AI 代理,其某些工具由客户端应用程序(例如 VS Code)提供。 某些工具(如示例随机数工具)可能不会被 AI 代理利用,因为它内置了类似的功能。

如果您的工具未被使用,请检查以下步骤:

  1. 验证工具是否显示在 VS Code 已启用的工具列表中。 有关如何检查此问题 ,请参阅“测试 MCP 服务器 ”中的屏幕截图。
  2. 在提示中显式引用工具的名称。 在 VS Code 中,可以按名称引用工具。 例如,Using #get_random_weather, what is the weather in Redmond?
  3. 验证 MCP 服务器是否能够启动。 可以通过单击 VS Code 用户或工作区设置中 MCP 服务器配置上方可见的“开始”按钮进行检查。

显示 VS Code 配置中已启动的 MCP 服务器的屏幕截图。