如果你最近关注 AI 编程工具特别是 Cursor 或 Claude Desktop一定听过MCPModel Context Protocol这个名字。它被宣传为“AI 的 USB 接口”听起来很酷但很多开发者看完概念介绍后依然一头雾水这玩意儿到底怎么用我自己能做一个吗这正是 Matt Pocock 这篇实战教程的价值所在。它没有停留在概念层面而是用5 条核心的 Prompt手把手带你从零搭建一个可运行的 MCP Server。这篇文章不是对原视频的简单翻译而是结合我自己的实践和理解为你拆解其中的关键步骤、技术原理和容易踩的坑。你会发现构建一个 MCP Server 的核心并不在于复杂的代码而在于如何精准地定义工具Tools和资源Resources并用清晰的 Prompt 引导 AI 助手如 Claude去理解和使用它们。读完本文你将能清晰地回答以下问题MCP 到底解决了什么痛点为什么说它是 AI 助手的能力扩展坞5 条关键 Prompt 分别扮演什么角色它们如何一步步引导 Claude 生成可用的代码从零搭建一个 MCP Server 的具体步骤是什么需要哪些环境和技术栈如何测试和验证自己搭建的 Server怎样在 Claude Desktop 或 Cursor 中实际使用它除了教程示例MCP 还能做什么它的设计思想如何应用到你的实际工作流中我们直接开始。1. MCP Server 究竟是什么为什么你需要关注它在深入代码之前我们必须先统一认知MCP 不是一个新的编程框架而是一个通信协议。它的核心目标是标准化 AI 助手Client与外部工具、数据源Server之间的交互方式。想象一下这个场景你想让 Claude 帮你分析公司内部数据库的销售趋势。没有 MCP 时你只能手动查询数据库把结果粘贴到聊天框再让 Claude 分析。这个过程是割裂的。而有了 MCP你可以搭建一个“数据库 MCP Server”Claude 就能像调用内置函数一样直接向这个 Server 发送查询请求并获取结构化数据整个过程在后台自动完成。MCP 解决的核心痛点就是“上下文隔离”。AI 助手被限制在它被训练时的知识范围内无法直接访问你本地的文件系统、数据库、内部 API 或专有工具。MCP 就像为 AI 助手安装了一系列的“驱动程序”或“插件”让它获得了感知和操作外部世界的能力。一个典型的 MCP 架构包含三个角色MCP Server服务提供方你将要构建的东西。它暴露一组定义好的“工具”Tools用于执行操作和“资源”Resources用于提供数据。MCP ClientAI 助手如 Claude Desktop、Cursor 等。它们遵循 MCP 协议可以发现并调用 Server 提供的工具和资源。MCP 协议本身基于 JSON-RPC 的通信规范定义了 Server 和 Client 之间如何打招呼、列出能力、调用和返回结果。Matt Pocock 教程的巧妙之处在于他意识到构建 Server 本身是一个高度结构化、模式化的工作而这正是大型语言模型LLM所擅长的。因此他设计了一套 Prompt让 Claude 扮演“有经验的 MCP 开发者”引导它为我们生成绝大部分的样板代码。我们的角色从“编码者”转变为“需求定义者和质量审核者”。2. 环境准备搭建你的开发舞台在开始“念咒”输入 Prompt之前我们需要准备好舞台。以下是基于教程和最佳实践的完整环境清单。2.1 核心运行环境Node.js 与包管理器MCP Server 可以用多种语言编写Python、TypeScript 等但 Matt 的教程基于 TypeScript/Node.js 生态这是目前 MCP 社区最活跃、工具链最成熟的选择。安装 Node.js请确保你安装了Node.js 18或更高版本。你可以通过以下命令检查node --version如果未安装或版本过低建议从 Node.js 官网 下载 LTS 版本。选择包管理器npm是 Node.js 自带的但教程中使用了更快的pnpm。这也是网络热词中频繁出现pnpm安装失败的原因。我推荐使用pnpm因为它能显著提升依赖安装速度并优化磁盘空间。安装 pnpm# 使用 npm 安装 pnpm npm install -g pnpm # 安装后验证 pnpm --version常见问题pnpm‘ 不是内部或外部命令如果出现此错误说明pnpm的安装路径未添加到系统环境变量PATH中。通常重启终端即可解决若仍未解决需要手动将pnpm的全局安装目录如C:\Users\你的用户名\AppData\Roaming\npm或/usr/local/bin添加到PATH。2.2 开发工具Cursor 或 VS Code你需要一个代码编辑器。教程中提到了Cursor这是一个深度集成 AI 的编辑器非常适合本教程因为它内置了 MCP Client 支持可以无缝测试你的 Server。当然使用VS Code配合相应的 AI 插件也是完全可行的。Cursor从官网下载安装即可。它的优势是开箱即用地支持 MCP配置简单。VS Code你需要安装像Claude for VS Code或Continue这样的扩展来获得 MCP Client 能力。2.3 测试客户端Claude Desktop为了最终验证你的 MCP Server 是否真的能被 AI 助手调用你需要一个 MCP Client。Claude Desktop是 Anthropic 官方应用对 MCP 的支持最原生、最稳定。从 Anthropic 官网 下载并安装 Claude Desktop。安装后其配置文件中可以添加自定义 MCP Server。这是我们测试的终点。环境准备好后我们就可以创建一个全新的项目开始与 Claude 对话用 Prompt 驱动开发了。3. 核心流程拆解五条 Prompt 的魔法Matt Pocock 的教程精髓就在于这五条循序渐进的 Prompt。它们不是随意提问而是精心设计的“引导程序”每一步都让 Claude 完成一个明确的子任务最终组合成一个完整的项目。3.1 Prompt 0项目初始化与角色设定这是对话的开始目标是设定清晰的上下文和约束。你的输入Prompt 0“我们将使用 TypeScript 和 Node.js 构建一个 MCP Server。请担任我的 MCP 开发专家。在我们开始编码之前请首先为我列出构建一个基础 MCP Server 所需的核心步骤并说明每个步骤的目的。然后请为我初始化这个项目创建package.json文件并安装必要的依赖特别是modelcontextprotocol/sdk。”Claude 应该做什么预期行为列出步骤初始化项目、安装 SDK、定义工具/资源、实现 Server 逻辑、编写配置文件、测试。生成package.json文件内容。给出安装依赖的命令如pnpm init -y和pnpm add modelcontextprotocol/sdk。你的操作在 Cursor 或 VS Code 中新建一个空文件夹例如my-first-mcp-server。打开这个文件夹并开启与 Claude 的聊天窗口。将上述 Prompt 粘贴进去并发送。关键点这一步确保了 Claude 在正确的技术栈和项目背景下思考。它生成的package.json是后续所有工作的基础。3.2 Prompt 1定义 Server 能力工具与资源这是最核心的一步。MCP Server 的价值完全取决于它向外暴露了哪些“能力”。Matt 教程示例是创建一个“笔记管理”Server。你的输入Prompt 1“我们将构建一个‘笔记管理’ MCP Server。它应该提供以下能力工具Toolscreate_note: 创建一条新笔记。输入参数title(字符串),content(字符串)。list_notes: 列出所有笔记的标题和ID。read_note: 根据ID读取一条笔记的内容。输入参数id(字符串)。delete_note: 根据ID删除一条笔记。输入参数id(字符串)。资源Resources一个只读资源notes:///summary当被访问时返回当前所有笔记的统计摘要例如笔记总数。 请根据这些需求使用modelcontextprotocol/sdk为我们生成 MCP Server 的初始化代码框架。包括创建 Server 实例、定义工具列表、定义资源列表。”Claude 应该做什么预期行为生成一个src/index.ts或server.ts文件。在代码中导入Server类。使用new Server()创建实例。调用server.setTool()或server.setToolHandler()来定义那四个工具的函数骨架。调用server.setResource()来定义notes:///summary资源。启动 Server 监听例如在端口 3000。关键点这里你是在进行“产品设计”。工具Tools对应“写操作”CUD资源Resources对应“读操作”R。设计得好AI 助手用起来就顺手。Claude 生成的将是骨架代码工具函数内部暂时用// TODO或简单日志填充。3.3 Prompt 2实现数据持久化逻辑骨架有了需要血肉。我们需要决定笔记数据存到哪里内存、文件、数据库并实现真正的业务逻辑。你的输入Prompt 2“很好现在我们需要实现工具函数的具体逻辑。为了简单起见我们将笔记数据存储在一个本地的 JSON 文件中例如notes.json。请实现在项目根目录创建notes.json文件初始内容为[]。实现create_note,list_notes,read_note,delete_note这四个工具函数实现完整的 CRUD 操作所有操作都基于读写notes.json文件。实现notes:///summary资源处理器使其返回{ totalNotes: number }这样的 JSON 数据。 请提供完整的、可运行的代码。”Claude 应该做什么预期行为生成notes.json文件。在src/index.ts中引入fs(文件系统) 模块。编写工具函数每个函数内部包含读取notes.json。解析为 JavaScript 数组。执行相应的查找、添加、删除操作。将更新后的数组写回notes.json。返回适当的成功信息或数据。编写资源处理器读取文件并计算数组长度后返回。关键点这是“脏活累活”但 Claude 能很好地处理这种模式化的 I/O 操作。你需要检查它生成的代码是否包含了错误处理例如文件不存在、JSON 解析错误。如果没有你应该要求它加上try...catch。3.4 Prompt 3编写 Server 配置文件 (mcp.json)MCP Client 如何知道你的 Server 在哪里、怎么启动这就需要配置文件。你的输入Prompt 3“现在请为我们的 MCP Server 创建配置文件mcp.json。这个文件应该定义command: 用于启动 Server 的命令例如使用tsx或node运行编译后的文件。args: 可选的命令行参数。可能的env环境变量。 因为我们是在开发中请配置为使用tsx直接运行 TypeScript 文件。另外请说明在 Claude Desktop 中如何配置才能使用这个 Server。”Claude 应该做什么预期行为生成一个mcp.json文件内容大致如下{ mcpServers: { notes-server: { command: npx, args: [tsx, src/index.ts], env: {} } } }解释如何将 Claude Desktop 的配置文件位于~/Library/Application Support/Claude/claude_desktop_config.json或 Windows 的%APPDATA%对应目录指向这个mcp.json文件。关键点tsx是一个 TypeScript 执行器类似于ts-node让你无需编译即可直接运行.ts文件。你需要确保全局安装了它pnpm add -g tsx。这个配置文件是连接 Server 和 Client 的桥梁。3.5 Prompt 4集成、测试与调试最后一步把所有部分组装起来并解决实际问题。你的输入Prompt 4“我们已经有了所有代码和配置。现在请检查package.json中的scripts部分确保有一个方便的启动脚本例如dev: tsx src/index.ts。提供一个完整的步骤让我能先独立启动 Server 并验证它是否在正常运行例如通过简单的 curl 命令测试健康端点如果我们有暴露的话。指导我如何将 Claude Desktop 配置为使用这个 Server并提供一个测试对话示例比如让 Claude ‘列出所有笔记’ 或 ‘创建一条关于 MCP 学习的笔记’。列出在配置和测试过程中最常见的 2-3 个错误及其解决方法。”Claude 应该做什么预期行为更新package.json添加scripts。建议启动 Server 后使用curl或netcat发送一个简单的 JSON-RPC 消息来测试例如调用list_notes工具。注意标准 MCP Server 通常不暴露 HTTP 健康端点而是通过 stdio 与 Client 通信所以这一步可能需要 Claude 生成一个简单的测试脚本。详细说明 Claude Desktop 配置文件的编辑步骤。预测常见错误command not found: tsx未安装 tsx、配置文件路径错误、端口冲突、notes.json文件权限问题等并给出解决方案。至此通过这五轮高质量的 Prompt 对话你应该已经获得了一个完整、可运行、可测试的“笔记管理 MCP Server”项目。你的角色从程序员变成了架构师和产品经理而 Claude 担任了高级开发工程师。4. 完整示例代码与关键文件解析让我们把上面 Prompt 引导生成的代码具体化看看每个关键文件应该长什么样。以下是我根据教程逻辑整理和优化后的版本包含了更健壮的错误处理。4.1package.json- 项目定义与依赖{ name: notes-mcp-server, version: 0.1.0, description: A simple notes management MCP server, type: module, main: dist/index.js, scripts: { build: tsc, dev: tsx src/index.ts, start: node dist/index.js }, dependencies: { modelcontextprotocol/sdk: ^0.5.0 }, devDependencies: { types/node: ^20.0.0, tsx: ^4.7.0, typescript: ^5.0.0 } }关键点type: “module”允许我们使用 ES Module 语法。dev脚本用于开发时直接运行 TypeScriptstart脚本用于运行编译后的 JavaScript。4.2src/index.ts- Server 核心实现这是最核心的代码文件实现了所有工具和资源。import { Server } from modelcontextprotocol/sdk/server/index.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from modelcontextprotocol/sdk/types.js; import { promises as fs } from fs; import path from path; import { fileURLToPath } from url; const __filename fileURLToPath(import.meta.url); const __dirname path.dirname(__filename); const NOTES_FILE path.join(__dirname, .., notes.json); // 1. 创建 Server 实例 const server new Server( { name: notes-mcp-server, version: 0.1.0, }, { capabilities: { tools: {}, resources: {}, }, } ); // 2. 工具列出所有笔记 server.setRequestHandler(ListToolsRequestSchema, async () { return { tools: [ { name: create_note, description: Create a new note, inputSchema: { type: object, properties: { title: { type: string, description: Title of the note }, content: { type: string, description: Content of the note }, }, required: [title, content], }, }, { name: list_notes, description: List all notes (id and title), inputSchema: { type: object, properties: {} }, }, { name: read_note, description: Read a note by its ID, inputSchema: { type: object, properties: { id: { type: string, description: ID of the note to read }, }, required: [id], }, }, { name: delete_note, description: Delete a note by its ID, inputSchema: { type: object, properties: { id: { type: string, description: ID of the note to delete }, }, required: [id], }, }, ], }; }); // 3. 工具请求处理器 server.setRequestHandler(CallToolRequestSchema, async (request) { const { name, arguments: args } request.params; // 辅助函数读写 notes.json async function readNotes() { try { const data await fs.readFile(NOTES_FILE, utf-8); return JSON.parse(data); } catch (error: any) { if (error.code ENOENT) { // 文件不存在返回空数组 return []; } throw error; } } async function writeNotes(notes: any[]) { await fs.writeFile(NOTES_FILE, JSON.stringify(notes, null, 2), utf-8); } switch (name) { case create_note: { const { title, content } args as { title: string; content: string }; const notes await readNotes(); const newNote { id: note_${Date.now()}, title, content, createdAt: new Date().toISOString(), }; notes.push(newNote); await writeNotes(notes); return { content: [ { type: text, text: Note created successfully with ID: ${newNote.id}, }, ], }; } case list_notes: { const notes await readNotes(); const list notes.map((note: any) - ${note.id}: ${note.title}).join(\n); return { content: [ { type: text, text: notes.length 0 ? Notes:\n${list} : No notes found., }, ], }; } case read_note: { const { id } args as { id: string }; const notes await readNotes(); const note notes.find((n: any) n.id id); if (!note) { throw new Error(Note with ID ${id} not found.); } return { content: [ { type: text, text: # ${note.title}\n\n${note.content}\n\nCreated at: ${note.createdAt}, }, ], }; } case delete_note: { const { id } args as { id: string }; const notes await readNotes(); const initialLength notes.length; const filteredNotes notes.filter((n: any) n.id ! id); if (filteredNotes.length initialLength) { throw new Error(Note with ID ${id} not found.); } await writeNotes(filteredNotes); return { content: [ { type: text, text: Note ${id} deleted successfully., }, ], }; } default: throw new Error(Unknown tool: ${name}); } }); // 4. 资源定义 notes:///summary server.setRequestHandler(ListResourcesRequestSchema, async () { return { resources: [ { uri: notes:///summary, name: Notes Summary, description: Summary of all notes (total count), mimeType: application/json, }, ], }; }); // 5. 资源请求处理器 server.setRequestHandler(ReadResourceRequestSchema, async (request) { const { uri } request.params; if (uri notes:///summary) { const notes await readNotes(); return { contents: [ { uri: notes:///summary, mimeType: application/json, text: JSON.stringify({ totalNotes: notes.length }, null, 2), }, ], }; } throw new Error(Resource not found: ${uri}); }); // 6. 启动 Server使用 stdio 传输层 async function main() { const transport new StdioServerTransport(); await server.connect(transport); console.error(Notes MCP Server running on stdio); } main().catch((error) { console.error(Server error:, error); process.exit(1); });代码解析传输层MCP Server 通常通过stdio标准输入/输出与 Client 通信这是最通用的方式避免了网络端口配置。工具定义ListToolsRequestSchema处理器返回工具列表及其输入模式Schema这相当于告诉 AI 助手“我有这些功能调用时需要这些参数”。工具调用CallToolRequestSchema处理器是核心路由根据工具名name执行对应的业务逻辑。资源资源Resources是只读的数据源通过 URI 标识。这里定义了一个返回笔记总数的 JSON 资源。错误处理代码中包含了文件不存在、笔记未找到等基本错误处理并抛出了结构化的错误这些错误会被 MCP Client 捕获并展示给用户。4.3mcp.json- Claude Desktop 配置文件这个文件告诉 Claude Desktop 如何启动你的 Server。{ mcpServers: { notes-manager: { command: node, args: [ /ABSOLUTE/PATH/TO/YOUR/PROJECT/dist/index.js ], env: {} } } }关键点notes-manager是你给这个 Server 起的名字会在 Claude Desktop 中显示。command和args这里配置为运行编译后的dist/index.js。注意你必须先运行pnpm run build来编译 TypeScript 代码。路径必须是绝对路径。这是最常见的错误来源。在 macOS/Linux 上你可以用pwd命令获取当前目录的绝对路径。在 Windows 上路径类似C:\Users\YourName\Projects\notes-mcp-server\dist\index.js。更简单的开发配置是使用tsx直接运行源码避免每次修改都要编译{ command: npx, args: [tsx, /ABSOLUTE/PATH/TO/YOUR/PROJECT/src/index.ts] }4.4notes.json- 数据存储文件这是一个简单的数据存储文件由 Server 自动创建和管理。[]初始为空数组。Server 运行后创建笔记时会向其中添加对象。5. 运行、测试与集成到 Claude Desktop代码写好了现在是让一切运转起来的时候。5.1 本地运行与基础测试安装依赖在项目根目录下运行。pnpm install编译 TypeScript如果使用编译后运行pnpm run build这将在dist/目录下生成index.js。手动测试 Server为了验证 Server 本身逻辑是否正确我们可以创建一个简单的测试脚本test-server.mjs。// test-server.mjs import { spawn } from child_process; import { stdin as input, stdout as output } from process; import * as readline from readline/promises; const rl readline.createInterface({ input, output }); // 启动你的 MCP Server 进程 const serverProcess spawn(node, [dist/index.js], { stdio: [pipe, pipe, inherit] // 继承 stderr 以便看错误 }); // 简单的 JSON-RPC 请求函数 function sendRequest(method, params {}, id 1) { const request { jsonrpc: 2.0, id, method, params }; const requestStr JSON.stringify(request) \n; console.log(Sending:, requestStr); serverProcess.stdin.write(requestStr); } // 监听 Server 响应 serverProcess.stdout.on(data, (data) { console.log(Received:, data.toString()); }); // 示例发送 initialize 请求MCP 握手 sendRequest(initialize, { protocolVersion: 0.5.0, capabilities: {}, clientInfo: { name: test-client, version: 1.0 } }); // 等待一段时间后可以尝试发送 tools/list 请求 setTimeout(() { sendRequest(tools/list, {}, 2); // 5秒后退出 setTimeout(() { serverProcess.kill(); rl.close(); process.exit(0); }, 5000); }, 1000);运行此脚本node test-server.mjs。如果看到 Server 输出了工具列表说明核心逻辑是通的。5.2 集成到 Claude Desktop 进行真实测试这才是真正的“毕业考试”。定位 Claude Desktop 配置文件macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.jsonLinux:~/.config/Claude/claude_desktop_config.json编辑配置文件如果文件不存在创建它。将前面准备好的mcp.json中的mcpServers对象内容合并到 Claude Desktop 的配置文件中。最终文件结构如下{ // ... 可能已存在的其他配置 ... mcpServers: { notes-manager: { command: node, args: [/ABSOLUTE/PATH/TO/YOUR/PROJECT/dist/index.js] } // 可以在这里添加其他 MCP Servers } }再次强调路径必须是绝对路径。重启 Claude Desktop完全关闭并重新启动 Claude Desktop 应用以加载新的配置。验证与使用打开 Claude Desktop新建一个对话。在输入框里尝试让 Claude 使用你的笔记工具。例如输入“请使用笔记工具创建一条标题为‘MCP学习心得’内容为‘今天学会了用Prompt构建MCP Server非常高效’的笔记。”如果配置成功Claude 会理解你的指令并在后台调用create_note工具。你应该能看到它的回复比如“已创建笔记ID 为 note_123456...”。接着可以测试“列出我所有的笔记”或“读取ID为 note_123456 的笔记内容”。成功标志Claude 能够理解你的自然语言指令并成功执行对应的工具操作且操作结果创建、列表、读取都正确无误。6. 常见问题与排查思路 (FAQ)在实践过程中你几乎一定会遇到一些问题。以下是基于社区反馈和教程经验总结的排查清单。问题现象可能原因排查方式解决方案Claude Desktop 重启后没有发现新工具。1. 配置文件路径错误。2. 配置文件格式错误JSON 语法。3. Server 启动命令执行失败。1. 检查 Claude Desktop 配置文件的路径和内容。2. 使用jsonlint验证 JSON 格式。3. 查看 Claude Desktop 的应用日志通常在配置文件的同级目录或系统日志中。1. 使用绝对路径并确保路径指向编译后的.js文件或正确的tsx命令。2. 修正 JSON 语法错误。3. 尝试在终端手动运行配置中的command和args看能否成功启动 Server。运行pnpm install失败网络错误或超时。网络连接问题或pnpm镜像源问题。检查网络尝试ping registry.npmjs.org。1. 切换 npm/pnpm 镜像源到国内镜像如淘宝源。2. 使用pnpm install --verbose查看详细错误。错误Error: Cannot find module ‘modelcontextprotocol/sdk’依赖未安装或项目不在正确的目录下运行。检查node_modules文件夹是否存在以及package.json中依赖的版本。1. 确保在项目根目录有package.json的目录运行命令。2. 重新运行pnpm install。错误tsx或node命令未找到。tsx未全局安装或 Node.js 未正确安装。在终端运行tsx --version和node --version。1. 全局安装 tsx:pnpm add -g tsx。2. 重新安装 Node.js并确保其bin目录在系统PATH环境变量中。Server 启动后立即退出或 Claude 调用工具无响应。Server 代码存在未捕获的异常或传输层stdio配置有问题。1. 查看终端或 Claude Desktop 日志中的错误信息。2. 使用上文test-server.mjs脚本进行独立测试看错误输出。1. 在 Server 代码的main()函数和工具函数中添加更详细的try-catch和console.error日志。2. 确保使用的是StdioServerTransport并正确connect。工具调用时提示“Invalid parameters”或参数错误。工具定义InputSchema与实际处理函数接收的参数不匹配。对比ListToolsRequestSchema处理器中定义的inputSchema和CallToolRequestSchema处理器中读取args的代码。确保工具name和参数properties的定义完全一致包括类型和必需字段。笔记文件notes.json无法写入。文件权限不足或路径不正确。检查NOTES_FILE路径并尝试手动在对应位置创建文件。1. 确保__dirname计算正确。2. 为简单起见可以先使用path.join(process.cwd(), ‘notes.json’)将文件放在当前工作目录。7. 超越教程MCP Server 的进阶思路与最佳实践掌握了基础构建方法后你可以将这个模式应用到无数场景。关键在于理解 MCP 的范式将任何外部能力封装成“工具”和“资源”。7.1 还可以构建哪些 MCP Server数据库查询 Server连接 MySQL/PostgreSQL提供run_sql_query工具。内部 API 网关 Server封装公司内部 RESTful API让 Claude 能安全地调用。文件系统操作 Server在受控权限下允许 Claude 读取、搜索特定目录的文件。代码仓库分析 Server集成 Git提供get_recent_commits、search_code等工具。第三方服务 Server集成 GitHub API、Jira API、Slack API 等让 Claude 成为你的工作流中枢。7.2 工程化与最佳实践安全性是第一要务永远不要暴露危险的工具如rm -rf。仔细定义每个工具的输入模式进行严格的参数验证和权限控制。考虑在 Server 端实现用户认证和操作审计。错误处理与用户体验工具函数应返回对最终用户在 Claude 聊天框中友好的错误信息而不仅仅是抛出技术异常。状态管理教程中使用文件存储对于简单场景足够。更复杂的 Server 应考虑使用数据库并处理好连接池和并发。配置化将服务器地址、API 密钥等敏感信息通过环境变量或配置文件管理不要硬编码在代码中。日志与监控为 Server 添加详细的日志记录便于调试和监控其运行状态。测试为你的工具函数编写单元测试和集成测试确保其行为符合预期。7.3 Prompt 工程的启示Matt Pocock 的教程本身就是一次精彩的 Prompt 工程示范。它告诉我们分解任务将复杂项目建 MCP Server分解为清晰的、LLM 擅长的子任务初始化、定义接口、实现逻辑、配置、测试。提供上下文在 Prompt 0 中就设定好技术栈和角色让 AI 在正确的轨道上思考。明确输入输出定义工具时清晰地描述名称、参数、类型这直接对应了 AI 生成代码的结构。迭代与修正如果 AI 生成的代码有瑕疵比如缺少错误处理可以继续用 Prompt 要求它改进“请为文件读写操作添加 try-catch 错误处理。”通过这 5 条 Prompt你不仅得到了一个可用的 MCP Server更掌握了一套用自然语言驱动复杂软件构建的方法论。这或许是比 MCP 技术本身更重要的收获如何将你的意图清晰、结构化地传达给 AI让它成为你最高效的协作者。现在你可以尝试将这套方法用于构建你自己的、真正能提升工作效率的 MCP Server 了。