ClaudeMap

·MCP 服务器

Model Context Protocol(MCP)实战讲解:它解决了什么问题、核心概念有哪些,以及如何用 TypeScript 写一个可被 Claude 调用的 MCP 服务器。

什么是模型上下文协议(MCP)?从概念到搭建你的第一个 MCP 服务器

模型上下文协议(Model Context Protocol,简称 MCP)是 Anthropic 在 2024 年 11 月开源的一项开放标准,用来把 AI 助手与外部工具、数据源和服务连接起来。如果你曾经手工把一个工具接到某个聊天机器人里,然后又把同一个工具改写一遍接到另一个机器人,你已经体会到了 MCP 想要解决的问题。本指南会讲清楚协议本身、梳理它的术语、把它和函数调用(function calling)做个对比,最后带你跑通一个本地的 TypeScript 服务器,并连到 Claude Desktop。

MCP 解决了什么问题

在 MCP 出现之前,要让一个助手访问外部世界,意味着你要写大量定制的胶水代码。每家模型厂商的函数调用格式都略有不同;而你想暴露的每一个工具——数据库、文件系统、某个 SaaS API——都要为每一个可能调用它的客户端单独打包。一个为某个助手写的文件系统工具,换一个助手往往得重写。

MCP 为这类集成定义了一套与客户端无关的统一协议。你把工具写一次,封装成 MCP 服务器;任何兼容 MCP 的客户端(Claude Desktop、Claude Code、Cursor、自研 Agent)都能调用它。反过来也一样:一个支持 MCP 的 Agent 可以访问任何 MCP 服务器,而不必关心服务器内部是怎么实现的。

你可以把它理解成「AI 工具界的 USB-C」——一个标准插头,把工具和模型解耦开来。

核心术语

MCP 的名词不多,理清之后,后面的内容会豁然开朗。

  • Host(宿主)——用户直接交互的应用。Claude Desktop、Claude Code、某个 IDE 插件都是 Host。Host 拥有对话过程,也掌握安全边界。
  • Client(客户端)——宿主内部的一个协议对象,与某一个服务器保持一对一连接。一个连了五个服务器的 Host,会跑五个 Client。
  • Server(服务器)——一个向外暴露能力的小程序,通过协议与 Client 通信。服务器通常轻量且聚焦,例如「文件系统」「GitHub」「Postgres」。
  • Tool(工具)——模型可以决定调用的函数,包含名字、用 JSON Schema 描述的入参,以及一个返回内容给模型的处理器。工具是 MCP 服务器让模型「行动」的方式。
  • Resource(资源)——模型可以读取的结构化数据,用 URI 寻址。日志文件、数据库行、配置文档都可以是资源。资源是 MCP 服务器让模型「读取」的方式。
  • Prompt(提示模板)——服务器发布的可复用、可带参的提示词模板。客户端可以在 UI 里展示它们(比如放在斜杠命令选择器里)。

一个服务器可以任意组合暴露工具、资源和提示模板。大多数真实服务器以工具为主。

在这些名词之下,MCP 本质上就是承载在传输层之上的 JSON-RPC 2.0 消息流。你实际会遇到两种传输方式:stdio(Host 把服务器作为子进程拉起,通过标准输入输出通信)和 HTTP + Server-Sent Events(服务器作为远端进程运行)。本地开发几乎总是用 stdio。

MCP 与函数调用

MCP 并不是函数调用的竞争对手——两者处在不同的层级。

函数调用是模型的一种能力:模型发出一个结构化的请求来调用某个具名函数,调用方执行它并把结果返回。它由各家模型厂商各自定义。

MCP 则是一种集成协议:它标准化了 Host 如何发现可用的函数、服务器如何描述这些函数,以及结果如何回流。当一个 MCP Host(比如 Claude)决定调用某个工具时,它内部仍然使用函数调用——MCP 只是为它提供了一种统一的方式去「知道这个工具存在」并「触达实现这个工具的服务器」。

简而言之:函数调用是模型使用的「机制」,MCP 是把许多服务器与许多 Host 连起来、免去定制胶水的「管道」。

动手写第一个 MCP 服务器

我们来搭一个最小但真实的。会暴露两个工具:add 把两个数字相加,echo 原样返回你发的字符串。使用官方 TypeScript SDK 和 stdio 传输。

1. 初始化项目

mkdir mcp-demo && cd mcp-demo
npm init -y
npm install @modelcontextprotocol/sdk zod
npm pkg set type="module"

之所以设 "type": "module",是因为 SDK 以 ESM 形式发布;而加 zod,是因为高层 Server API 用 Zod schema 来描述工具入参。

2. 写服务器

创建 index.js

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: "demo-server",
  version: "1.0.0",
});

// 求和工具。第三个参数是用 Zod 描述的入参 schema,
// SDK 会据此推导出 JSON Schema。
server.tool(
  "add",
  { a: z.number(), b: z.number() },
  async ({ a, b }) => ({
    content: [{ type: "text", text: String(a + b) }],
  }),
);

// 原样回显字符串,附带一段可选的描述。
server.tool(
  "echo",
  { message: z.string() },
  async ({ message }) => ({
    content: [{ type: "text", text: message }],
  }),
);

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

几点值得注意:

  • new McpServer({ name, version }) 注册了服务器的身份,Host 会把它展示给用户。
  • server.tool(name, schema, handler) 是高层辅助函数。handler 会收到经过校验的参数,且必须返回 { content: [...] },其中每个 content 项都有 type(通常是 "text")。
  • StdioServerTransport 把服务器接到标准输入输出上,这样 Host 就能把它作为子进程拉起。

3. 不依赖 Host 先做测试

SDK 自带一个交互式的 MCP Inspector,可以让你在接任何 Host 之前,先在浏览器 UI 里调用工具:

npx @modelcontextprotocol/inspector node index.js

打开它打印的 URL,找到 add 工具,用 a: 2b: 3 调用一次。如果看到返回 5,说明你的服务器跑通了。

把它连到 Claude Desktop

Claude Desktop 通过一个配置文件来发现服务器。macOS 上它在 ~/Library/Application Support/Claude/claude_desktop_config.json(Windows 上是 %APPDATA%\Claude\claude_desktop_config.json)。在 mcpServers 下加一条,指向你服务器的绝对路径:

{
  "mcpServers": {
    "demo": {
      "command": "node",
      "args": ["/绝对路径/mcp-demo/index.js"]
    }
  }
}

重启 Claude Desktop,打开对话,问:「用 add 工具算一下 7 加 35。」Claude 会决定调用你的 add 工具,执行后回答 42。输入框旁边的锤子图标可以确认你的工具已被加载。

而这同一份服务器代码,无需改动,也能在任何其他兼容 MCP 的 Host 里跑——Claude Code(通过 .mcp.json)、Cursor 等等。这种可移植性正是 MCP 最大的回报。

继续深入

基础打通后,自然的下一步是:

  • server.resource(...) 添加资源,暴露可读数据,比如更新日志或目录列表。
  • server.prompt(...) 添加提示模板,发布可复用的斜杠命令式模板。
  • 把传输方式换成 HTTP + SSE,让服务器能跑在远端,而不是每次会话都被拉起。
  • 浏览生态——ClaudeMap 收录了数十个 MCP 服务器(文件系统、GitHub、Postgres、浏览器等),可以作为参考实现来安装和研究。

从一个工具起步,用 Inspector 确认往返正常,再接到某个 Host 上。MCP 的设计刻意收窄,所以从「hello world」到「能用的服务器」之间,距离很短。

本文基于截至 2026 年 7 月的公开信息,相关 API 可能演进。