4-6 如何开发 MCP 伺服器?

2025年5月12日

持續學習最新的 AI 應用
更多深入的 AI 內容,都在 E+ 成長計畫 👉前往了解

在这个单元中,我们将进一步探讨如何开发 MCP (Model Context Protocol) 伺服器。我们会先回顾 MCP 的整体架构,并详细介绍如何快速实作一个 MCP 伺服器。我们也会透过一个简单的范例,展示如何使用 Node.js 开发 MCP 伺服器,并以 GitHub 的 MCP 伺服器为例,说明如何将现有 API 转换为 MCP 伺服器。

MCP 整体架构回顾

以下是来自 MCP 官方文件的架构图(如下所述,详细图请参考官方文件)。

MCP 官方分享的架构图
MCP 官方分享的架构图

图片来源:https://modelcontextprotocol.io/introduction

在之前的单元中,我们曾简略提到这个架构。MCP 的架构包含以下主要部分:

  • MCP 客户端:位于架构的最左侧,负责与 MCP 伺服器进行通讯。
  • MCP 主机:负责管理多个 MCP 客户端。例如,当我们使用 Cursor 时,Cursor 本身就是一个 MCP 主机,负责在背后管理不同的 MCP 客户端。
  • MCP 伺服器:位于架构的右侧,负责与资料源或工具源对接,并透过 MCP 的协定与客户端进行互动。
  • 资料源与工具源:MCP 伺服器背后可以对接到本地的资料源(例如 SQLite 资料库)或远端的 Web API(例如天气 API 或 GitHub API)。

以架构图为例,假设一个 MCP 主机管理三个 MCP 客户端,这三个客户端分别连线到三个不同的 MCP 伺服器,每个伺服器可以对接到不同的资料源。

MCP 伺服器对接不同的资料源
MCP 伺服器对接不同的资料源

举例来说:

  • 本地的 SQLite 资料库。
  • 远端的天气 API,供查询天气资讯。
  • GitHub API,供执行像是提交 Pull Request 的操作。

透过这种架构,MCP 伺服器能让 AI(如 Cursor)与不同的工具或资料源整合,从而提升工作效率。

快速实作 MCP 伺服器

为了让大家快速上手 MCP 伺服器的开发,我们将以官方提供的「天气 MCP 伺服器」范例为基础,展示如何使用 Node.js 实作一个简单的 MCP 伺服器。以下是具体步骤:

步骤 1:参考官方文件

MCP 官方网站 (Model Context Protocol) 提供了一个针对伺服器开发者的快速指南 (连结)。在这个指南中,有一个简单的教学,展示如何开发一个天气相关的 MCP 伺服器,让使用者能在 Cursor 或其他 MCP 客户端上查询天气资讯。官方范例支援多种程式语言,包括 Python、Node.js、Java、C# 等。本文将以 Node.js 为例进行说明。

步骤 2:环境准备

在开始开发前,请确保本机已安装以下工具:

  • Node.jsNPM
  • 一个专案资料夹,用于存放 MCP 伺服器的程式码。

接着,根据官方范例,执行以下步骤:

  1. 建立一个新的专案资料夹。
  2. 初始化专案:运行 npm init
  3. 安装必要套件:
    • model-context-protocol:MCP 的官方 SDK。
    • zod:用于参数验证。
    • Typescript:作为开发依赖(可选,视需求而定)。

执行以下指令安装依赖:

npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript

步骤 3:撰写 MCP 伺服器程式码

MCP 的 SDK 已封装了协定相关的复杂逻辑,因此开发 MCP 伺服器非常简单。核心工作是将现有的资料源或 Web API 包装成 MCP 伺服器。以下是一个简单的天气 MCP 伺服器的程式码范例:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "weather",
  version: "1.0.0",
});

server.tool("getWeather", { city: z.string() }, async ({ city }) => {
  // 写一些不同的逻辑
  // 去呼叫某一个 API
  return {
    content: [
      {
        type: "text",
        text: `现在 ${city} 的天气非常好,大晴天出太阳,但又不会太热,适合全家出门玩`,
      },
    ],
  };
});

const transport = new StdioServerTransport();
await server.connect(transport);

这段程式码的逻辑如下:

  1. 引入 MCP 的 Server 模组,建立一个伺服器实例。
  2. 使用 tool 方法为伺服器添加一个名为 getWeather 的工具,该工具接受一个 city 参数,并回传天气资讯。
  3. 使用 StdioServerTransport 建立通讯通道,并将伺服器与该通道连系。

步骤 4:测试 MCP 伺服器

完成伺服器程式码后,可以在 Cursor 中进行测试。步骤如下:

  1. 启动 MCP 伺服器(运行程式码)。
  2. 在 Cursor 中配置 MCP 伺服器的连线(具体配置方式请参考前单元)。
  3. 测试功能,例如输入:「台北现在的天气如何?」。

假设伺服器运行正常,Cursor 会找到 getWeather 工具,将「台北」作为 city 参数传入,并显示回传结果:「现在台北的天气很好,适合全家出游!」。你可以在 Cursor 的 MCP 输出日志中查看请求和回应的详细资讯。

运作流程总结

以下是 MCP 伺服器在 Cursor 中运作的完整流程:

天气 MCP 伺服器运作流程
天气 MCP 伺服器运作流程
  1. 使用者透过 Cursor 提问,例如:「台北现在的天气如何?」。
  2. Cursor (作为 MCP 主机) 在已连线的 MCP 客户端中搜寻合适的工具,找到 getWeather
  3. Cursor 的 AI 模型 (例如 GPT) 解析问题,将「台北」提取为 city 参数。
  4. MCP 客户端将参数传送至 MCP 伺服器。
  5. MCP 伺服器执行 getWeather 工具,处理参数并回传结果。
  6. Cursor 接收结果,进行格式化后显示给使用者。

进阶范例:开发 GitHub MCP 伺服器

为了展示如何将现有 API 转换为 MCP 伺服器,我们以 GitHub 的 MCP 伺服器为例,说明如何让 Cursor 支援提交 Pull Request 的功能。

参考官方开源专案

MCP 官方的开源专案中有一个 servers 资料夹 (连结),包含多个官方 MCP 伺服器的实作,其中就包括 GitHub MCP。

以下是 GitHub MCP 伺服器的核心运作方式

GitHub MCP 伺服器运作流程
GitHub MCP 伺服器运作流程

跟上面的天气范例相比,GitHub 的核心逻辑类似,差异在于工具的处理逻辑。天气范例模拟了一个简单的回传结果,GitHub 范例则实际呼叫了 GitHub 的 API。

具体来说 GitHub MCP 伺服器的运作流程如下:

  1. Cursor 的 MCP 客户端呼叫 GitHub MCP 伺服器,传入参数。
  2. 伺服器验证参数并呼叫 GitHub API。
  3. API 回传结果后,伺服器格式化结果并传回 Cursor。
  4. Cursor 显示结果给使用者。

此系列文章为 《给工程师的 Cursor 工作流 — 透过 AI 代理全方位提升开发生产力》 搭配的教材。希望透过这系列文章,将过去协助导入 AI 工具及使用 Cursor 的经验扩展并分享给想提升生产力的读者。如果对课程感兴趣的读者,可以加入 E+ 成长计划,观看影片学习。

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們