NuGet 包中的 MCP 服务器

NuGet 提供了一种打包和分发以 .NET 编写的 MCP 服务器的便捷方法。 C# MCP SDK 和 .NET 提供了用于生成 MCP 服务器的可靠平台,NuGet 非常适合将 MCP 服务器作为本地工具提供给最终用户。 特定于平台的自包含包可减少运行时兼容性问题,AOT 编译可以进一步改善最终用户体验。

有关模型上下文协议(MCP)的详细信息,请参阅 MCP 网站上的简介。 若要创建自己的 MCP 服务器并使用 NuGet 打包它,请参阅 快速入门指南

Applicable scenarios

通过 NuGet 寄送 MCP 服务器不适用于所有情况。 本文档中使用了术语“MCP 客户端”,指的是一个应用程序,该应用程序协调 AI 代理或 LLM 与对 MCP 服务器的调用之间的交互。 一些示例 MCP 客户端是 Visual Studio CodeVisual StudioGitHub Copilot 编码代理、Claude Code 或 Cursor。

请考虑以下条件来确定将 MCP 服务器作为 NuGet 包传送是否有意义:

  • ✅ 你希望 MCP 服务器在用户的系统上 本地 运行(即,在 MCP 客户端所在的同一上下文中)。
    • 本地 MCP 服务器(例如 NuGet 包中提供的服务器)在 MCP 客户端所在的上下文中运行,并通过标准 IO (stdio) 传输与 MCP 客户端通信。 MCP 客户端负责启动本地 MCP 服务器进程。
  • ✅ MCP 客户端可以使用 .NET SDK。
    • NuGet MCP 服务器是 .NET 工具包,这些包是使用 dnx .NET SDK 安装和执行的。
  • ✅ 你有一个 NuGet 包源,用于托管你的 MCP 服务器包。
    • NuGet.org 可用于发布 MCP 服务器包,并提供定制的 MCP 浏览和消耗体验。 但是,如果希望将 MCP 服务器包保密,可以使用任何 NuGet 包源(如 Azure Artifacts)来托管 MCP 服务器。

将 .NET 和 NuGet 用于 MCP 服务器的好处

使用 NuGet 托管 MCP 服务器有几个好处:

  • 官方 SDK - MCP C# SDK 提供了一个熟悉的接口,用于在 C# 中实现 MCP 服务器,并可以轻松地向 MCP 客户端公开工具。
  • 灵活的运行时选项 - .NET SDK 提供了多个选项,用于如何编译和打包 MCP 服务器。 有关详细信息,请参阅 运行时要求 部分。
  • 可发现性和分发 性 - NuGet.org 提供了一种方法来展示 MCP 服务器,使潜在用户能够找到 MCP 服务器,并从 VS Code 或 Visual Studio 中轻松使用它。 NuGet.org 鼓励使用嵌入式 .mcp/server.json 来声明输入和 McpServer 包类型,以允许 MCP 服务器与其他工具或依赖项包区分开来。
  • 熟悉的创作工作流 - 如果已使用 NuGet 创建依赖项包,创建和发布 MCP 服务器将是一种非常相似的体验。

包下载和执行

若要提取本地 MCP 服务器,必须使用特定于包生态系统的机制(协议)找到并下载服务器的代码。 这通常是通过一次性命令来完成的,该命令接受包名称和参数来下载,并将其作为命令行应用程序来执行。

对于基于 NuGet 的 MCP 服务器,我们建议使用 dnx (.NET 10 预览版 6 中提供的新命令)来获取和执行包。 dnx 目前附带 .NET SDK,但 正在讨论是否将 dnx 包含在 .NET 运行时中

启动 MCP 服务器的命令如下所示:

dnx NuGet.Mcp.Server@0.1.2-preview --yes

环境变量和命令行参数都可用于以自定义方式配置 MCP 服务器。 这些输入允许自定义 MCP 服务器的行为以满足特定需求。

这将从配置的包源下载 NuGet.Mcp.Server 版本 0.1.2-preview 包(默认情况下 NuGet.org),并启动包含的 CLI 工具。 对于 MCP 服务器,你可能会看到日志消息显示在 stderr 中,但进程将显示为挂起。 这是预期的,因为该过程正在等待 MCP 客户端通过 stdin 发送 MCP 协议消息。

通常,MCP 客户端将通过特定于工具的 MCP 配置(例如 mcp.json Visual Studio Code 和 Visual Studio 使用的文件)调用此命令。

所有这些工具都支持安装替代来源。 例如, dnx 只要配置了所需的凭据或凭据提供程序,就可以使用 --source 参数从 Azure DevOps 进行安装,从而允许使用专用 MCP 服务器。

Runtime requirements

下载包后,需要运行时才能在包内执行代码。 .NET 工具包(以及基于 NuGet 的 MCP 服务器扩展)支持各种选项来编译和打包该工具。 通过这些选项,MCP 服务器作者可以确定应在 MCP 服务器的用户上放置哪些运行时要求。

有关如何打包 MCP 服务器的主要选项有三种:

  1. 依赖于框架:要求 MCP 客户端有权访问兼容的 .NET 运行时。 如果 dnx 用于下载和执行包,则运行时将可用。
  2. 自包含模式:将运行时与包捆绑在一起。 使用剪裁 可以减少包的大小。 自包含 .NET 工具使用 <PublishSelfContained>true</PublishSelfContained>
  3. 预编译 (AOT):启用了 AOT 编译的自包含包。 请参阅本机 AOT 部署以获取更多信息。 AOT .NET 工具使用 <PublishAot>true</PublishAot>

对于 MCP 服务器,我们建议使用选项 #2(不包含 AOT 的自包含包),因为它无需用户环境中存在任何特定的 .NET 运行时版本。 如果可以保证预期执行环境中的兼容运行时版本,选项 #1 是合理的。 选项 #3(使用 AOT)也是一个不错的选择,但它强制你或依赖项使代码与 AOT 编译兼容。 C# MCP SDK 兼容 AOT,但你打算使用的其他依赖项可能尚不兼容 AOT。

请考虑在 mcpserverMicrosoft.Extensions.AI.Templates 模板包中使用模板,以使用最新的建议默认值。

与其他生态系统的比较

其他生态系统对打包和运行 MCP 服务器有类似的要求和工作流:

  • NuGet/.NET:使用 dnx 命令下载和执行 .NET 工具包。 需要 .NET SDK 用于dnx。 可将其他运行时依赖项捆绑到包中。
  • npm:使用 npx 命令下载和执行 npm 包,并递归安装依赖项。 Requires Node.js.
  • Python:使用 uvx 命令下载和执行 Python 包,递归地安装依赖项。 需要 Python 运行时。
  • Docker:使用 docker run 命令下载和执行映像。 需要 Docker 引擎。 Docker 映像可以面向多个 CPU 体系结构并提供出色的隔离,但通常大于 NuGet、npm 或 Python 包。

在所有这些情况下,MCP 客户端需要具有必要的特定于生态系统的工具(例如,dnxnpx)来下载和执行基于包的 MCP 服务器。