随着生成式人工智能 (GenAI) 应用的日益普及,如何让大型语言模型 (LLM) 能够安全、高效地访问外部数据源和工具变得至关重要。 模型上下文协议 (MCP) 应运而生,它作为一个开放标准,提供了一种统一的方式来连接 LLM 与各种服务,例如 API、数据库和企业应用。本文将深入探讨如何使用 .NET Core 和 Docker 构建 MCP 服务器,实现与自定义 REST API 和 PostgreSQL 数据库的集成,并探索如何利用 Docker MCP 工具包的预构建服务器,最终实现在 VS Code 等 IDE 中无缝集成和使用。

MCP:GenAI 应用的通用连接器

模型上下文协议 (MCP) 是一种旨在弥合 LLM 和外部世界之间差距的技术。它定义了一种清晰的客户端-主机-服务器架构,其中 AI“主机”(例如 IDE 或代理应用)运行 MCP 客户端,这些客户端连接到 MCP 服务器,服务器则负责公开各种工具和资源。 这种设计的巧妙之处在于其模块化和安全性。每个 MCP 服务器 提供特定的功能(例如,访问 REST API 或数据库),而无需了解整个 AI 上下文,从而降低了安全风险,并简化了集成过程。

想象一下,你正在使用一个 AI 驱动的代码助手,它可以根据你的意图自动生成代码。如果需要访问外部 API 来获取最新的股票数据,传统的做法可能是编写大量的定制代码来实现与 API 的交互。但是,使用 MCP,你只需配置一个 MCP 服务器,该服务器负责处理与 API 的所有交互。代码助手通过 MCP 客户端 连接到该服务器,并调用相应的工具来获取数据。这不仅简化了开发过程,还提高了代码的可维护性和可重用性。

.NET Core:构建 MCP 服务器的强大平台

.NET Core 作为一个跨平台的、高性能的开发框架,是构建 MCP 服务器 的理想选择。它提供了丰富的库和工具,可以轻松地处理各种任务,例如 HTTP 请求、数据库连接和 JSON 序列化。此外,.NET Core 还支持依赖注入和配置管理等功能,这些功能对于构建可扩展和可维护的服务器至关重要。

使用 .NET Core 构建 MCP 服务器 的关键是使用 MCP C# SDK。该 SDK 提供了一组易于使用的 API,可以轻松地定义和公开 MCP 工具。 通过使用 [McpServerToolType][McpServerTool] 等属性,你可以将 .NET 方法标记为 MCP 工具,服务器会自动发现并注册这些工具。 这大大简化了服务器的开发过程,使你可以专注于实现具体的业务逻辑。

Docker:简化 MCP 服务器的部署和管理

Docker 是一种流行的容器化技术,它可以将应用程序及其所有依赖项打包到一个独立的容器中。 这使得应用程序可以在任何支持 Docker 的平台上运行,而无需担心环境差异带来的问题。 使用 Docker 部署 MCP 服务器 可以带来许多好处:

  • 一致性: Docker 容器确保 MCP 服务器 在开发、测试和生产环境中以相同的方式运行。
  • 可移植性: Docker 容器可以在任何支持 Docker 的平台上运行,包括本地计算机、云服务器和 Kubernetes 集群。
  • 隔离性: Docker 容器提供了一个隔离的环境,可以防止 MCP 服务器 受到其他应用程序的影响。
  • 易于管理: Docker 提供了丰富的工具和 API,可以轻松地管理和监控 MCP 服务器

在文章中,作者展示了如何使用 Dockerfile 来构建 MCP 服务器 的镜像。 通过使用多阶段构建,可以将构建过程分为多个阶段,每个阶段都有不同的依赖项和配置。这可以减小镜像的大小,提高部署速度。

构建自定义 REST API 的 MCP 服务器

文章提供了一个具体的案例,演示了如何构建一个 MCP 服务器,该服务器封装了一个自定义 REST API。 该 API 允许用户查询书籍的信息,例如根据 ID 获取书籍信息和根据标题搜索书籍。

using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;

[McpServerToolType]
public static class ApiTools
{
    static readonly HttpClient httpClient = new HttpClient();

    [McpServerTool, Description("Get book information by ID from the custom API")]
    public static async Task<string> GetBookAsync(int bookId)
    {
        string baseUrl = Environment.GetEnvironmentVariable("API_BASE_URL");
        httpClient.BaseAddress = new Uri(baseUrl);
        string response = await httpClient.GetStringAsync($"books/{bookId}");
        return response;
    }

    [McpServerTool, Description("Search books by title from the custom API")]
    public static async Task<string> SearchBooksAsync(string title)
    {
        string baseUrl = Environment.GetEnvironmentVariable("API_BASE_URL");
        httpClient.BaseAddress = new Uri(baseUrl);
        string response = await httpClient.GetStringAsync($"books?search={Uri.EscapeDataString(title)}");
        return response;
    }
}

这段代码定义了一个名为 ApiTools 的静态类,该类包含了两个 MCP 工具GetBookAsyncSearchBooksAsync。 这两个工具都使用 HttpClient 来与 REST API 进行交互。 API_BASE_URL 环境变量用于配置 API 的基本 URL。

构建 PostgreSQL 数据库的 MCP 服务器

另一个案例演示了如何构建一个 MCP 服务器,该服务器允许用户查询 PostgreSQL 数据库。 该服务器提供了两个工具:GetProductCountAsyncGetProductAsyncGetProductCountAsync 工具返回数据库中产品的数量,而 GetProductAsync 工具根据 ID 返回产品的详细信息。

using ModelContextProtocol.Server;
using Npgsql;
using System.ComponentModel;
using System.Threading.Tasks;

[McpServerToolType]
public static class DbTools
{
    [McpServerTool, Description("Get number of products in the database")]
    public static async Task<string> GetProductCountAsync()
    {
        string connString = Environment.GetEnvironmentVariable("DB_CONNECTION");
        await using var conn = new NpgsqlConnection(connString);
        await conn.OpenAsync();
        using var cmd = new NpgsqlCommand("SELECT COUNT(*) FROM products", conn);
        long count = (long)await cmd.ExecuteScalarAsync();
        return $"There are {count} products in the catalog.";
    }

    [McpServerTool, Description("Get a product's details by ID")]
    public static async Task<string> GetProductAsync(int id)
    {
        string connString = Environment.GetEnvironmentVariable("DB_CONNECTION");
        await using var conn = new NpgsqlConnection(connString);
        await conn.OpenAsync();
        var cmd = new NpgsqlCommand("SELECT name, price FROM products WHERE id = @id", conn);
        cmd.Parameters.AddWithValue("id", id);
        await using var reader = await cmd.ExecuteReaderAsync();
        if (await reader.ReadAsync())
        {
            string name = reader.GetString(0);
            decimal price = reader.GetDecimal(1);
            return $"Product {id}: {name}, price ${price}.";
        }
        return "Product not found.";
    }
}

这段代码与 REST API 的案例非常相似,它定义了一个名为 DbTools 的静态类,该类包含了两个 MCP 工具。 这两个工具都使用 NpgsqlConnection 来连接到 PostgreSQL 数据库。 DB_CONNECTION 环境变量用于配置数据库连接字符串。

Docker MCP 工具包:探索预构建的 MCP 服务器

除了构建自定义 MCP 服务器 之外,还可以使用 Docker MCP 工具包,该工具包提供了一个预构建的 MCP 服务器 目录。 这些服务器可以轻松地集成到你的 GenAI 应用中,而无需编写任何代码。

例如,Docker MCP 工具包提供了 Atlassian Jira 和 Confluence 的 MCP 服务器。 这使得你可以轻松地从你的 AI 驱动的应用中访问 Jira 和 Confluence 的数据。 要使用这些服务器,你需要配置一些环境变量,例如 Jira 和 Confluence 的 URL、用户名和 API 令牌。

以下是如何使用 Docker 运行 Atlassian Jira 的 MCP 服务器 的示例:

docker run --rm -i \
  -e JIRA_URL=https://your-domain.atlassian.net \
  -e JIRA_USERNAME=you@company.com \
  -e JIRA_API_TOKEN=YOUR_JIRA_TOKEN \
  mcp/atlassian:latest

IDE 集成:在 VS Code 中使用 MCP

最后,文章介绍了如何在 VS Code 中集成 MCP。 通过启用 GitHub Copilot 的 Agent Mode,你可以在 VS Code 中使用 MCP 服务器。 这使得你可以使用自然语言来与外部数据源和工具进行交互。

要启用 MCP 支持,你需要将以下配置添加到你的 VS Code 设置中:

{
  "chat.mcp.enabled": true
}

然后,你需要配置 MCP 服务器。 你可以通过创建一个 .vscode/mcp.json 文件来实现这一点。 该文件应该包含一个 servers 对象,该对象定义了要使用的 MCP 服务器

例如,以下配置文件定义了两个 MCP 服务器:一个用于自定义 REST API,一个用于 PostgreSQL 数据库。

{
  "servers": {
    "books-server": {
      "type": "stdio",
      "command": "dotnet",
      "args": ["run", "--project", "${workspaceFolder}/CustomApiMcpServer/CustomApiMcpServer.csproj"]
    },
    "db-server": {
      "type": "stdio",
      "command": "dotnet",
      "args": ["run", "--project", "${workspaceFolder}/PostgresMcpServer/PostgresMcpServer.csproj"]
    }
  }
}

结论:MCP 的强大潜力

模型上下文协议 (MCP) 为 GenAI 应用提供了一种强大的方式来访问外部数据源和工具。 通过使用 .NET Core 和 Docker,你可以轻松地构建、部署和管理 MCP 服务器。 此外,Docker MCP 工具包提供了预构建的 MCP 服务器 目录,可以轻松地集成到你的应用中。 最后,通过 IDE 集成,你可以在 VS Code 等开发环境中无缝地使用 MCP。 总之,MCP 降低了 LLM 应用开发和集成的复杂性,提升了效率与安全性。 随着 MCP 标准的不断发展,我们可以期待更多创新和突破。