从零构建 MCP Server:TypeScript 分步教程 (2026)
完整 MCP Server 构建教程。用 TypeScript 从零开始,30 分钟内搭建一个可用的 Model Context Protocol 服务器。含 Tools、Resources、Prompts 和 Claude Desktop 集成。
MCP(Model Context Protocol)已经成为 AI 工具生态的事实标准。OpenAI、Google、Anthropic 三大巨头全面采纳,IDE 原生支持,社区 Server 数量突破 8,600 个。但大部分开发者还停留在”使用别人写好的 MCP Server”这个阶段——真正自己从零构建过 MCP Server 的人并不多。
这篇教程将用 TypeScript 从头开始,一步一步带你构建一个完整的 MCP Server。不是那种只有 hello world 的示例,而是一个包含 Tools、Resources、Prompts 三大原语的完整实现,最终接入 Claude Desktop 并实际运行。全程大约 30 分钟。
如果你对 MCP 的基本概念还不太熟悉,建议先阅读我们的 MCP 协议入门到实战:5 分钟搞懂 Model Context Protocol,了解 MCP 的架构、三大原语和生态现状后再回来跟着做。
MCP 三大原语快速回顾
在写代码之前,先把 MCP Server 能暴露的三种能力理清楚:
| 原语 | 谁触发 | 用途 | 类比 |
|---|---|---|---|
| Tools | AI 模型自主决定 | 执行操作(查询、创建、修改) | REST API 的 POST/PUT |
| Resources | 客户端/用户请求 | 提供只读数据 | REST API 的 GET |
| Prompts | 用户显式选择 | 预定义的提示词模板 | 快捷指令 |
这三者的区别很重要。Tools 是 AI 模型在对话中自主判断”现在需要调用这个函数”然后主动调用的;Resources 是供客户端读取上下文数据的只读接口;Prompts 是用户可以在界面上直接选择使用的预设模板。
搞清楚这三者之后,接下来的代码就能理解每一步在做什么了。
环境准备
开始之前,确保你的机器上已经安装了以下工具:
- Node.js 18+(推荐 20 LTS 或更高版本)
- npm 或 pnpm(教程以 npm 为例)
- TypeScript(会随项目一起安装)
- Claude Desktop(用于最终测试,从 claude.ai/download 下载)
验证环境:
node --version # 应输出 v18.x.x 或更高
npm --version # 应输出 9.x.x 或更高
如果你还没有安装 Node.js,从 nodejs.org 下载 LTS 版本即可。
Step 1: 项目初始化
创建一个新的 TypeScript 项目,并安装 MCP SDK:
# 创建项目目录
mkdir my-mcp-server
cd my-mcp-server
# 初始化 package.json
npm init -y
# 安装 MCP SDK 和依赖
npm install @modelcontextprotocol/sdk zod
# 安装 TypeScript 开发依赖
npm install -D typescript @types/node
# 初始化 TypeScript 配置
npx tsc --init
修改 tsconfig.json,确保以下配置项正确:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"]
}
修改 package.json,添加构建脚本和 ES module 支持:
{
"name": "my-mcp-server",
"version": "1.0.0",
"type": "module",
"scripts": {
"build": "tsc",
"start": "node build/index.js"
}
}
创建源码目录:
mkdir src
到这一步,项目的基础骨架就搭好了。目录结构如下:
my-mcp-server/
package.json
tsconfig.json
src/ # 源码目录,接下来的代码都放在这里
node_modules/
Step 2: 创建基础 MCP Server(含第一个 Tool)
在 src/index.ts 中创建 MCP Server 的核心代码。我们先实现一个最基础的版本,只包含一个 Tool:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// 创建 MCP Server 实例
const server = new McpServer({
name: "my-mcp-server",
version: "1.0.0",
description: "一个用于学习的 MCP Server 示例",
});
// 注册第一个 Tool:字符串分析工具
server.tool(
"analyze_text", // 工具名称
"分析文本的字数、字符数和行数", // 工具描述
{ // 参数 schema(使用 Zod)
text: z.string().describe("要分析的文本内容"),
},
async ({ text }) => { // 处理函数
const charCount = text.length;
const wordCount = text.split(/\s+/).filter(Boolean).length;
const lineCount = text.split("\n").length;
return {
content: [
{
type: "text",
text: [
`文本分析结果:`,
`- 字符数:${charCount}`,
`- 单词/词组数:${wordCount}`,
`- 行数:${lineCount}`,
].join("\n"),
},
],
};
}
);
// 使用 stdio 传输层启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);
这段代码做了三件事:
- 创建 Server 实例:
McpServer是 SDK 提供的高层封装,内部处理了 JSON-RPC 协议、能力协商、消息路由等所有底层细节。 - 注册 Tool:
server.tool()方法接受工具名称、描述、参数 schema 和处理函数。参数 schema 使用 Zod 定义,SDK 会自动将其转换为 JSON Schema 供客户端使用。 - 启动传输层:
StdioServerTransport使用标准输入/输出(stdin/stdout)与客户端通信。这是 Claude Desktop 等桌面客户端使用的主要通信方式。
构建并测试:
npm run build
如果没有报错,说明代码编译成功。build/index.js 就是编译后的 MCP Server 入口文件。
关于 Zod 参数验证
MCP SDK 使用 Zod 来定义工具的参数 schema。Zod 是 TypeScript 生态中最流行的 schema 验证库,MCP SDK 内部会自动把 Zod schema 转换成 JSON Schema,发送给客户端做能力发现。
常用的 Zod 类型:
z.string() // 字符串
z.number() // 数字
z.boolean() // 布尔值
z.enum(["option1", "option2"]) // 枚举
z.string().optional() // 可选字符串
z.string().describe("字段说明") // 带描述(推荐!)
z.object({ key: z.string() }) // 嵌套对象
z.array(z.string()) // 字符串数组
给每个参数加上 .describe() 是一个好习惯。这些描述会被发送给 AI 模型,帮助它理解每个参数的用途,从而更准确地填写参数值。
Step 3: 添加 Resource
Resources 是 MCP Server 对外暴露的只读数据接口。客户端可以读取 Resources 来获取上下文信息。
在 server.tool() 之后,添加以下代码来注册 Resource:
// 注册一个静态 Resource:服务器状态信息
server.resource(
"server-status", // 资源名称
"status://server", // 资源 URI
{
description: "当前服务器的运行状态",
mimeType: "application/json",
},
async () => {
const status = {
serverName: "my-mcp-server",
version: "1.0.0",
uptime: process.uptime(),
nodeVersion: process.version,
platform: process.platform,
memoryUsage: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
};
return {
contents: [
{
uri: "status://server",
mimeType: "application/json",
text: JSON.stringify(status, null, 2),
},
],
};
}
);
Resource 和 Tool 的关键区别在于:
- Tool 由 AI 模型在对话中自主决定调用,可以执行任何操作(查询、创建、删除等)。
- Resource 由客户端请求读取,是只读的。它更像一个数据源,AI 模型可以从中获取上下文信息,但不会通过 Resource 来执行操作。
Resource 模板
除了固定 URI 的 Resource,MCP 还支持 Resource Templates——带参数的动态 Resource。这在你需要根据不同参数返回不同数据时非常有用:
// 注册一个 Resource Template:按名称查询配置项
server.resource(
"config-item",
"config://item/{name}", // URI 模板
{
description: "按名称获取配置项的值",
mimeType: "application/json",
},
async (uri) => {
// 从 URI 中提取参数
const url = new URL(uri.href);
const name = url.pathname.split("/").pop() || "";
// 模拟配置数据
const configs: Record<string, string> = {
"max-tokens": "4096",
"temperature": "0.7",
"model": "claude-sonnet-4-20250514",
};
const value = configs[name];
return {
contents: [
{
uri: uri.href,
mimeType: "application/json",
text: JSON.stringify(
value
? { name, value }
: { error: `配置项 "${name}" 不存在` },
null,
2
),
},
],
};
}
);
Step 4: 添加 Prompt
Prompts 是 MCP Server 提供的预定义提示词模板。用户可以在客户端界面直接选择使用某个 Prompt,而不需要自己手动输入完整的提示词。
// 注册一个 Prompt:代码审查助手
server.prompt(
"code-review", // Prompt 名称
"对一段代码进行全面的审查和改进建议", // Prompt 描述
{ // 参数定义
code: z.string().describe("要审查的代码"),
language: z
.string()
.optional()
.describe("编程语言,如 typescript、python"),
},
async ({ code, language }) => {
const langHint = language ? `(语言:${language})` : "";
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `请对以下代码进行全面审查${langHint}。
从以下几个方面给出具体建议:
1. **代码质量**:命名规范、函数长度、单一职责
2. **潜在 Bug**:空值检查、边界条件、异常处理
3. **性能**:是否有不必要的计算、内存泄漏风险
4. **安全性**:输入验证、注入风险、敏感信息暴露
5. **可维护性**:注释完整度、可测试性、耦合度
代码如下:
\`\`\`${language || ""}
${code}
\`\`\`
请用中文回答,对每个问题给出修改前后的代码对比。`,
},
},
],
};
}
);
Prompt 返回的是一个消息数组(messages),每条消息有 role(user 或 assistant)和 content。客户端收到后会将这些消息填充到对话中,AI 模型基于此继续生成回复。
你可以把 Prompt 理解为”一键填入的快捷指令”。用户在 Claude Desktop 中点击一个 Prompt,填入必要的参数,Claude 就会收到一段精心设计的提示词,而不是用户自己从零开始写。
Step 5: 连接 Claude Desktop
现在我们的 MCP Server 已经包含了 Tool、Resource 和 Prompt 三大原语。接下来把它接入 Claude Desktop。
编译项目
npm run build
配置 Claude Desktop
找到 Claude Desktop 的配置文件:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
如果文件不存在,手动创建一个。添加以下配置(注意替换路径为你的实际项目路径):
{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["/absolute/path/to/my-mcp-server/build/index.js"]
}
}
}
Windows 用户注意:路径使用正斜杠 / 或双反斜杠 \\,不要用单反斜杠。
{
"mcpServers": {
"my-mcp-server": {
"command": "node",
"args": ["C:/Users/yourname/projects/my-mcp-server/build/index.js"]
}
}
}
重启 Claude Desktop
完全退出并重新打开 Claude Desktop。在聊天输入框左侧,你会看到一个锤子图标。点击它,应该能看到 analyze_text 工具和 code-review Prompt。
测试
在 Claude Desktop 中输入:
帮我分析这段文字的字数:“MCP 是 AI 工具生态的未来标准,所有主流 AI 厂商都已经支持它。”
Claude 会识别到这个请求可以用 analyze_text 工具来完成,然后自动调用它并返回分析结果。
手动编辑 JSON 配置文件容易出错? 用我们的 MCP Manifest Generator(MCP 配置生成器) 可视化构建你的 claude_desktop_config.json,填入名称、命令和参数就能生成正确格式的配置文件。写好配置后可以用 MCP Config Validator(MCP 配置校验器) 检查格式是否正确,避免因 JSON 语法错误导致 Server 无法加载。
Step 6: 实战示例——笔记管理 MCP Server
前面的示例展示了 MCP 的基本用法。现在让我们把这些概念组合起来,构建一个更实用的 MCP Server:一个内存中的笔记管理系统。这个 Server 将实现:
- 创建、列表、搜索笔记(Tools)
- 暴露笔记数据(Resources)
- 提供笔记摘要的预设 Prompt(Prompts)
创建 src/index.ts(替换之前的内容):
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// ----- 数据层 -----
interface Note {
id: string;
title: string;
content: string;
tags: string[];
createdAt: string;
updatedAt: string;
}
// 内存存储(生产环境应换成数据库)
const notes: Map<string, Note> = new Map();
function generateId(): string {
return Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
}
// ----- MCP Server -----
const server = new McpServer({
name: "notes-mcp-server",
version: "1.0.0",
description: "笔记管理 MCP Server——创建、搜索和管理你的笔记",
});
// ----- Tools -----
// Tool 1: 创建笔记
server.tool(
"create_note",
"创建一条新笔记",
{
title: z.string().describe("笔记标题"),
content: z.string().describe("笔记内容"),
tags: z
.array(z.string())
.optional()
.describe("标签列表,如 ['工作', '想法']"),
},
async ({ title, content, tags }) => {
const id = generateId();
const now = new Date().toISOString();
const note: Note = {
id,
title,
content,
tags: tags || [],
createdAt: now,
updatedAt: now,
};
notes.set(id, note);
return {
content: [
{
type: "text",
text: `笔记创建成功。\n\nID: ${id}\n标题: ${title}\n标签: ${
note.tags.length > 0 ? note.tags.join(", ") : "无"
}\n创建时间: ${now}`,
},
],
};
}
);
// Tool 2: 列出所有笔记
server.tool(
"list_notes",
"列出所有笔记的摘要信息",
{},
async () => {
if (notes.size === 0) {
return {
content: [{ type: "text", text: "当前没有任何笔记。" }],
};
}
const summary = Array.from(notes.values())
.map(
(note) =>
`- [${note.id}] ${note.title}(${note.tags.join(", ") || "无标签"})— ${note.updatedAt}`
)
.join("\n");
return {
content: [
{
type: "text",
text: `共 ${notes.size} 条笔记:\n\n${summary}`,
},
],
};
}
);
// Tool 3: 搜索笔记
server.tool(
"search_notes",
"按关键词搜索笔记标题和内容",
{
query: z.string().describe("搜索关键词"),
tag: z.string().optional().describe("按标签过滤"),
},
async ({ query, tag }) => {
const results = Array.from(notes.values()).filter((note) => {
const matchesQuery =
note.title.toLowerCase().includes(query.toLowerCase()) ||
note.content.toLowerCase().includes(query.toLowerCase());
const matchesTag = tag
? note.tags.some((t) => t.toLowerCase() === tag.toLowerCase())
: true;
return matchesQuery && matchesTag;
});
if (results.length === 0) {
return {
content: [
{
type: "text",
text: `没有找到匹配 "${query}" 的笔记。${
tag ? `(标签过滤:${tag})` : ""
}`,
},
],
};
}
const output = results
.map(
(note) =>
`### ${note.title} [${note.id}]\n标签: ${
note.tags.join(", ") || "无"
}\n\n${note.content.slice(0, 200)}${
note.content.length > 200 ? "..." : ""
}`
)
.join("\n\n---\n\n");
return {
content: [
{
type: "text",
text: `找到 ${results.length} 条匹配结果:\n\n${output}`,
},
],
};
}
);
// Tool 4: 删除笔记
server.tool(
"delete_note",
"根据 ID 删除一条笔记",
{
id: z.string().describe("要删除的笔记 ID"),
},
async ({ id }) => {
const note = notes.get(id);
if (!note) {
return {
content: [
{ type: "text", text: `未找到 ID 为 "${id}" 的笔记。` },
],
};
}
notes.delete(id);
return {
content: [
{
type: "text",
text: `已删除笔记:"${note.title}"(ID: ${id})`,
},
],
};
}
);
// ----- Resources -----
// Resource 1: 所有笔记列表
server.resource(
"all-notes",
"notes://all",
{
description: "获取所有笔记的完整数据",
mimeType: "application/json",
},
async () => {
const allNotes = Array.from(notes.values());
return {
contents: [
{
uri: "notes://all",
mimeType: "application/json",
text: JSON.stringify(allNotes, null, 2),
},
],
};
}
);
// Resource 2: 笔记统计信息
server.resource(
"notes-stats",
"notes://stats",
{
description: "笔记的统计数据(总数、标签分布等)",
mimeType: "application/json",
},
async () => {
const allNotes = Array.from(notes.values());
const tagCounts: Record<string, number> = {};
allNotes.forEach((note) => {
note.tags.forEach((tag) => {
tagCounts[tag] = (tagCounts[tag] || 0) + 1;
});
});
const stats = {
totalNotes: notes.size,
totalTags: Object.keys(tagCounts).length,
tagDistribution: tagCounts,
latestNote: allNotes.length > 0
? allNotes.sort(
(a, b) =>
new Date(b.updatedAt).getTime() -
new Date(a.updatedAt).getTime()
)[0].title
: null,
};
return {
contents: [
{
uri: "notes://stats",
mimeType: "application/json",
text: JSON.stringify(stats, null, 2),
},
],
};
}
);
// ----- Prompts -----
// Prompt 1: 笔记摘要生成
server.prompt(
"summarize-notes",
"对所有笔记生成一份结构化摘要",
{},
async () => {
const allNotes = Array.from(notes.values());
if (allNotes.length === 0) {
return {
messages: [
{
role: "user",
content: {
type: "text",
text: "当前没有笔记。请先使用 create_note 工具创建一些笔记,然后再生成摘要。",
},
},
],
};
}
const notesText = allNotes
.map(
(note) =>
`## ${note.title}\n标签: ${note.tags.join(", ") || "无"}\n\n${note.content}`
)
.join("\n\n---\n\n");
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `请对以下 ${allNotes.length} 条笔记生成一份结构化摘要。
要求:
1. 按主题或标签分组
2. 每条笔记用一句话概括核心内容
3. 在最后给出整体趋势或洞察(如果能看出的话)
笔记内容如下:
${notesText}`,
},
},
],
};
}
);
// Prompt 2: 基于笔记的写作辅助
server.prompt(
"write-from-notes",
"基于已有笔记的内容,辅助写作一篇文章",
{
topic: z.string().describe("文章主题"),
style: z
.enum(["blog", "report", "email"])
.optional()
.describe("写作风格:blog(博客)、report(报告)、email(邮件)"),
},
async ({ topic, style }) => {
const allNotes = Array.from(notes.values());
const styleMap = {
blog: "轻松的博客风格",
report: "正式的报告风格",
email: "简洁的邮件风格",
};
const styleHint = style ? styleMap[style] : "适当的风格";
const notesContext =
allNotes.length > 0
? allNotes
.map((n) => `- ${n.title}: ${n.content.slice(0, 100)}...`)
.join("\n")
: "(当前无笔记内容)";
return {
messages: [
{
role: "user",
content: {
type: "text",
text: `请基于我的笔记内容,帮我用${styleHint}写一篇关于"${topic}"的文章。
我的笔记:
${notesContext}
要求:
1. 以笔记中的信息为基础,但可以合理扩展
2. 结构清晰,有标题和子标题
3. 如果笔记中缺少某方面的信息,请标注出来以便我后续补充`,
},
},
],
};
}
);
// ----- 启动服务器 -----
const transport = new StdioServerTransport();
await server.connect(transport);
这个完整的笔记管理 MCP Server 包含:
- 4 个 Tools:
create_note、list_notes、search_notes、delete_note - 2 个 Resources:全部笔记数据和统计信息
- 2 个 Prompts:笔记摘要和基于笔记的写作辅助
在 Claude Desktop 中你可以这样使用它:
- 告诉 Claude “帮我创建一条关于 MCP Server 开发的笔记”,它会调用
create_note - 说 “查看一下我所有的笔记”,它会调用
list_notes - 说 “搜索包含 TypeScript 的笔记”,它会调用
search_notes - 使用 Prompt 菜单中的 “summarize-notes” 来生成所有笔记的摘要
测试与调试
使用 MCP Inspector
MCP 官方提供了一个调试工具 MCP Inspector,可以在不依赖 Claude Desktop 的情况下测试你的 Server:
npx @modelcontextprotocol/inspector node build/index.js
Inspector 会在浏览器中打开一个界面,你可以:
- 查看 Server 暴露的所有 Tools、Resources 和 Prompts
- 手动调用任何 Tool 并查看返回值
- 读取 Resource 数据
- 测试 Prompt 生成的消息
这是开发阶段最重要的调试工具,强烈建议每次修改 Server 后先用 Inspector 验证,然后再接入 Claude Desktop。
常见问题排查
Server 无法启动
检查 package.json 中是否有 "type": "module"。MCP SDK 使用 ES module,缺少这个配置会导致 import 语法报错。
Claude Desktop 找不到 Server
- 确认配置文件路径正确(macOS 和 Windows 路径不同)
- 确认
args中的路径是绝对路径 - 完全退出 Claude Desktop 后重新打开(不是仅关闭窗口)
- 检查 Claude Desktop 日志文件中是否有错误信息
Tool 调用超时
MCP Server 的 Tool 处理函数默认有超时限制。如果你的工具需要执行耗时操作(比如网络请求),确保在合理的时间内返回结果,或者在处理函数中添加超时处理逻辑。
参数验证失败
Zod schema 定义的参数在运行时会做类型校验。如果 AI 模型传入了不符合 schema 的参数值,SDK 会自动返回验证错误。检查你的 Zod schema 是否过于严格——比如用 .optional() 标记非必填参数。
日志调试技巧
由于 MCP Server 通过 stdin/stdout 通信,你不能直接用 console.log() 输出调试信息(这会干扰 JSON-RPC 消息流)。改用 console.error() 来输出调试信息,它会写入 stderr,不影响正常通信:
// 正确的调试方式
console.error("[DEBUG] 收到 create_note 调用,参数:", JSON.stringify(args));
// 错误的调试方式——不要用 console.log
// console.log("debug info"); // 这会破坏 JSON-RPC 通信
进阶:添加错误处理
生产环境中的 MCP Server 需要健壮的错误处理。以下是推荐的模式:
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
server.tool(
"get_note",
"根据 ID 获取笔记详情",
{
id: z.string().describe("笔记 ID"),
},
async ({ id }) => {
const note = notes.get(id);
if (!note) {
throw new McpError(
ErrorCode.InvalidParams,
`笔记 "${id}" 不存在。请使用 list_notes 查看可用的笔记。`
);
}
return {
content: [
{
type: "text",
text: `# ${note.title}\n\n标签: ${
note.tags.join(", ") || "无"
}\n创建时间: ${note.createdAt}\n更新时间: ${note.updatedAt}\n\n${note.content}`,
},
],
};
}
);
McpError 会生成一个标准的 JSON-RPC 错误响应,客户端能正确识别和展示错误信息。常用的 ErrorCode 有:
ErrorCode.InvalidParams:参数错误(比如 ID 不存在)ErrorCode.InternalError:服务器内部错误ErrorCode.MethodNotFound:请求的方法不存在
进阶:从现有 OpenAPI 接口生成 MCP Server
如果你的团队已经有了完善的 REST API 和 OpenAPI(Swagger)文档,完全不需要从零手写 MCP Server。可以直接用我们的 OpenAPI to MCP 转换器,把 OpenAPI 文档一键转换成 MCP 工具定义,大幅节省开发时间。
转换流程:
- 将你的 OpenAPI JSON 或 YAML 文件粘贴到转换器中
- 工具会自动解析所有 endpoint,提取参数和返回值
- 生成对应的 MCP Tool 定义代码
- 复制代码到你的 MCP Server 项目中,根据需要微调
对于有大量 API endpoint 的项目,这比手写 Server 快一个数量级。
下一步
恭喜你完成了一个完整的 MCP Server 构建。接下来可以探索的方向:
扩展你的 Server
- 接入真实数据源:把内存存储替换为 SQLite、PostgreSQL 或 Redis
- 添加认证:在配置中通过
env传入 API Key,Server 在处理函数中校验 - 发布到 npm:把你的 Server 打包成 npm 包,让其他人可以直接
npx运行
探索 MCP 生态
- 浏览 MCP Server 目录,看看社区已经构建了哪些 Server,获取灵感
- 用 MCP Manifest Generator 管理你日益增长的 MCP Server 配置
- 用 MCP Config Validator 确保你的配置文件始终有效
学习更多
- 官方文档:modelcontextprotocol.io 是 MCP 协议规范和 SDK 文档的权威来源
- MCP 基础概念:如果你在跟教程的过程中对某些概念不太清楚,回头看看我们的 MCP 完全指南
- TypeScript SDK 源码:github.com/modelcontextprotocol/typescript-sdk,SDK 本身代码量不大,很值得通读
- Python 开发者:MCP 同样提供了 Python SDK,用法几乎一致,适合不熟悉 TypeScript 的开发者
MCP 正在从一个协议标准快速演进为 AI 应用的基础设施层。现在掌握 MCP Server 开发,意味着你可以把任何工具、数据源或内部服务暴露给所有主流 AI 助手——一次开发,全平台复用。这不是一个”未来可能有用”的技能,而是一个”现在就能用上”的实战能力。