1. 项目概述一个为 Cursor 构建的 MCP 服务器模板如果你和我一样日常重度依赖 Cursor 这类 AI 驱动的代码编辑器那你肯定不止一次想过能不能让 AI 助手更深入地“理解”和“操作”我自己的项目数据比如让它直接读取我本地的 Markdown 笔记、管理待办事项甚至调用我写的内部 API。这就是 MCPModel Context Protocol要解决的问题而ndlxp2008/mcp-temple这个项目为我们提供了一个绝佳的起点。简单来说这是一个基于 TypeScript 的 MCP 服务器模板。它不是一个功能完备的产品而是一个清晰、简洁的“脚手架”。它演示了如何构建一个能与 Cursor或任何兼容 MCP 的客户端通信的服务器实现“资源”的列举与访问、“工具”的调用以及“提示”的构建。原作者用它实现了一个微型笔记系统但这只是冰山一角。通过这个模板你可以快速上手将其改造成连接你私有数据库、内部服务或特定文件格式的桥梁极大地扩展 AI 助手在你工作流中的能力边界。对于前端/全栈开发者、效率工具爱好者或者任何想深度定制 AI 工作流的人来说这个模板的价值在于它剥离了 MCP 的复杂性直击核心概念。你不用从零开始研究协议细节而是直接在一个可运行、可调试的例子上进行魔改。接下来我将带你从零开始不仅复现这个模板更深入理解其每一行代码背后的设计逻辑并分享如何基于它打造属于你自己的、功能强大的 MCP 服务器。2. MCP 核心概念与模板设计思路拆解在动手之前我们必须先搞清楚 MCP 到底是什么以及这个模板是如何围绕其核心思想构建的。你可以把 MCP 想象成 AI 助手客户端和外部数据/服务服务器之间的一种“通用翻译协议”。它定义了双方沟通的语言和规则使得 AI 能够安全、结构化地请求信息或执行操作。2.1 MCP 的三大支柱资源、工具与提示MCP 协议主要围绕三个核心概念展开这也是模板项目md-emoji-mcp重点演示的部分资源代表 AI 可以“读取”的数据实体。在模板中资源就是一条条笔记通过note://{id}这样的统一资源标识符来访问。服务器告诉客户端“我这里有这些资源URI 列表你可以按需读取它们的内容。” 这解决了 AI 访问静态或动态数据的问题。工具代表 AI 可以“调用”的操作或函数。在模板中create_note就是一个工具。AI 助手在理解用户意图后例如“创建一条标题为‘会议纪要’的笔记”会通过 MCP 协议调用这个工具并传入参数。这解决了 AI 执行动态操作的问题。提示这是一种更高级的“资源组合包”。它允许服务器预先定义好一个包含特定资源上下文和指令系统提示的模板供 AI 直接使用。模板中的summarize_notes提示就自动包含了所有笔记的内容作为上下文引导 AI 生成摘要。这简化了复杂任务的上下文构建过程。这个模板的设计思路非常清晰用一个最小化但功能完整的例子笔记系统来逐一演示如何实现这三大概念。它没有引入数据库、复杂权限等干扰项让你可以专注于协议本身的实现逻辑。代码结构干净类型定义完善得益于 TypeScript是绝佳的学习和改造对象。2.2 为什么选择 TypeScript 和这个架构原作者选择 TypeScript 和modelcontextprotocol/sdk这个官方 SDK 是经过考量的。TypeScript 提供了优秀的类型安全和开发体验这对于实现一个需要严格遵循协议规范的服务器至关重要能避免许多低级错误。官方 SDK 则封装了协议通信、序列化/反序列化等底层细节让我们可以专注于业务逻辑。项目的架构是典型的 Node.js 应用结构src/index.ts入口文件初始化服务器并注册资源、工具、提示的处理逻辑。src/server.ts核心服务器逻辑定义了资源列表、工具实现等。package.json定义了构建脚本和依赖。构建输出到build/目录。这种结构分离了协议处理SDK和业务逻辑使得代码易于理解和扩展。当你需要添加一个新工具比如“删除笔记”时你几乎可以照葫芦画瓢在server.ts中添加相应的处理函数即可。3. 环境准备与项目初始化实操理论说得再多不如动手跑起来。我们首先需要把这个模板项目克隆到本地并配置好开发环境。3.1 获取模板代码与依赖安装打开你的终端执行以下命令来获取代码# 克隆模板仓库 git clone https://github.com/ndlxp2008/mcp-temple.git # 进入项目目录 cd mcp-temple # 安装项目依赖 (SDK、TypeScript编译器等) npm install这里有个实操心得由于网络环境差异npm install有时可能会因为官方 SDK 的包源问题而缓慢或失败。如果你遇到这种情况可以尝试以下两种方案检查你的 Node.js 版本建议使用最新的 LTS 版本如 18.x, 20.x。如果速度太慢可以考虑配置 npm 镜像源但请注意对于modelcontextprotocol这类作用域包镜像可能同步不及时。最稳妥的方式是耐心等待或使用稳定的网络环境。安装完成后你的项目目录下会生成node_modules文件夹。此时你可以尝试运行构建命令验证环境是否正常# 编译 TypeScript 代码到 build 目录 npm run build如果看到build目录成功生成并且没有报错说明基础环境已经就绪。3.2 开发与调试模式配置在开发过程中我们经常需要修改代码并立即看到效果。模板提供了watch模式# 启动监听模式文件变动后自动重新编译 npm run watch保持这个终端运行然后我们另开一个终端进行调试。这里是一个关键技巧直接运行编译后的 JS 文件可能无法直观地调试。模板非常贴心地集成了MCP Inspector的调试脚本。MCP Inspector 是一个独立的调试工具它可以充当 MCP 客户端和服务器之间的“中间人”让我们在浏览器中清晰地看到所有的协议请求和响应这对于理解数据流和排查问题至关重要。# 在项目根目录下启动 Inspector npm run inspector运行后终端会输出一个本地 URL通常是http://localhost:5173。用浏览器打开它你会看到 Inspector 的界面。现在我们需要让 Inspector 启动我们的 MCP 服务器。在 Inspector 界面上通常会有一个输入框让你指定服务器启动命令。由于我们的代码在watch模式下会持续编译build/index.js始终是最新的。因此在 Inspector 的命令输入框中你应该填写node /你的/项目/绝对/路径/mcp-temple/build/index.js注意请务必将路径替换为你本地项目的绝对路径。在 macOS/Linux 下你可以使用pwd命令获取当前路径在 Windows 的 PowerShell 中可以使用pwd或$PWD.Path。配置好后在 Inspector 中连接服务器。如果一切正常你将在左侧看到服务器声明的资源列表note://开头的 URI和工具列表create_note右侧可以看到实时的通信日志。这是你探索 MCP 协议运行机制的“显微镜”。4. 核心代码解析与自定义改造指南现在项目已经跑起来了。让我们深入src/server.ts这个核心文件看看它是如何实现 MCP 概念的并以此为基础规划如何改造它。4.1 资源管理如何让 AI “看到”你的数据在server.ts中寻找resources相关的代码。模板使用一个内存中的Map对象来模拟存储笔记// 模拟一个简单的内存存储 const notes new Mapstring, { title: string; content: string }();当客户端如 Cursor请求列出资源时服务器会调用listResources方法。该方法遍历notes这个 Map为每个笔记生成一个资源描述new Resource( note://${id}, // URI资源的唯一标识 { title: note.title, description: A note titled ${note.title}, // 可以在这里添加更多自定义元数据如创建时间、标签等 } )当客户端根据某个 URI如note://1请求读取资源内容时服务器会调用readResource方法从 Map 中查找对应的笔记并将其内容以纯文本形式返回。改造思路 1连接真实数据源你的数据不可能永远放在内存里。你可以将这里的Map替换成任何持久化存储本地文件系统将笔记存储为./notes/{id}.md文件。listResources改为读取notes目录下的所有文件生成列表readResource改为读取对应文件内容。数据库连接 SQLite、PostgreSQL 或 MongoDB。在listResources中执行SELECT查询在readResource中根据 ID 查询具体内容。第三方 API如果你的数据在 Notion、GitHub Issues 或某个内部服务中可以在这里发起 HTTP 请求来获取资源列表和内容。关键点URI 的设计要有意义且稳定。例如文件系统可以用file://notes/{filename}数据库记录可以用db://notes/{record_id}API 数据可以用api://issues/{issue_number}。这有助于 AI 和开发者理解资源的来源。4.2 工具实现如何让 AI “操作”你的系统工具的定义在tools属性或listTools方法中。模板定义了一个create_note工具{ name: create_note, description: Create a new text note, inputSchema: { type: object, properties: { title: { type: string, description: The title of the note }, content: { type: string, description: The content of the note }, }, required: [title, content], }, }当 AI 调用此工具时会触发callTool方法中对应的处理逻辑。模板中的逻辑很简单生成一个 ID将标题和内容存入notes这个 Map。改造思路 2实现增删改查全套工具一个笔记系统显然不止创建。我们可以很容易地添加新工具delete_note在listTools中添加定义接收一个id参数。在callTool中实现从 Map或数据库中删除对应记录的逻辑。update_note接收id,title,content参数实现更新逻辑。search_notes接收keyword参数在notes中过滤标题或内容包含关键词的记录并返回一个资源列表。这甚至不需要修改存储只需在callTool中动态生成一批Resource对象返回即可MCP 协议支持这种动态资源。注意事项工具的参数定义 (inputSchema) 要尽可能清晰、详细。好的description能帮助 AI 更好地理解何时以及如何使用这个工具。对于复杂参数可以使用 JSON Schema 定义嵌套结构。4.3 提示构建如何为 AI 预设复杂任务上下文提示在prompts属性中定义。模板中的summarize_notes提示非常经典{ name: summarize_notes, description: Get a summary of all notes, messages: [ { role: user, content: { type: text, text: Please summarize the following notes:, }, }, ], }它的特殊之处在于messages[0].content里可以嵌入资源。在getPrompt方法中服务器会将所有笔记的内容作为“嵌入资源”填充到提示消息中。这样当客户端获取这个提示时它已经是一个包含了全部笔记内容作为上下文的、立即可用的对话起点。改造思路 3创建领域特定的提示模板这是发挥创造力的地方。你可以为你的数据定制各种提示weekly_report嵌入本周创建的所有笔记或任务提示 AI 生成周报。find_conflicts嵌入项目计划文档和当前任务列表提示 AI 分析时间或资源冲突。brainstorm_from_notes嵌入你收集的灵感碎片笔记提示 AI 进行头脑风暴生成创意大纲。核心技巧提示中的“嵌入资源”是动态的。在getPrompt方法里你可以根据当前时间、用户身份或其他条件动态决定嵌入哪些资源使得每个提示都高度个性化。5. 集成到 Cursor 及其他客户端的完整流程开发调试完成后我们需要让 MCP 服务器真正被 AI 助手使用。这里以 Claude DesktopCursor 的原理类似为例讲解配置过程。5.1 配置 Claude Desktop 连接 MCP 服务器MCP 服务器通过标准输入输出与客户端通信。我们需要在 Claude Desktop 的配置文件中声明我们的服务器。定位配置文件macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%/Claude/claude_desktop_config.jsonLinux:~/.config/Claude/claude_desktop_config.json如果文件或目录不存在请手动创建。编辑配置文件使用任何文本编辑器打开或创建该 JSON 文件。其核心结构是mcpServers对象。{ mcpServers: { my-note-server: { command: node, args: [/ABSOLUTE/PATH/TO/YOUR/mcp-temple/build/index.js], env: { // 可以在这里传递环境变量例如数据库连接字符串 MY_SECRET_KEY: your-secret } } } }my-note-server这是你给服务器起的名字会在客户端界面显示。command启动服务器的命令。对于 Node.js 程序就是node。args命令的参数即编译后的 JS 文件绝对路径。这里必须使用绝对路径相对路径会无法找到。env可选。可以为你服务器的进程设置环境变量用于传递配置如 API 密钥避免硬编码在代码中。重启 Claude Desktop保存配置文件后完全退出并重启 Claude Desktop 应用。5.2 在 Cursor 中验证与使用重启后当你新建一个对话你应该能在输入框附近或设置里看到可用的工具不同客户端界面可能不同。在 Claude Desktop 中通常会在输入框上方出现工具图标。你可以尝试直接对 AI 说“使用我的笔记工具创建一条标题为‘购物清单’的笔记内容是‘牛奶、鸡蛋、面包’。” AI 应该能识别出可用的create_note工具并调用它。调用成功后你可以继续说“列出我所有的笔记。” AI 则会通过listResources获取到刚创建的笔记资源并将其内容作为上下文来回答你。排查技巧如果工具没有出现或调用失败请按以下步骤排查检查配置文件语法确保 JSON 格式正确没有尾随逗号。检查路径确保args中的 JS 文件路径绝对正确且文件存在。查看客户端日志Claude Desktop 通常有日志文件。在 macOS 上可以在~/Library/Logs/Claude/目录下查找Windows 则在%APPDATA%/Claude/logs。查看日志中是否有关于启动 MCP 服务器的错误信息。回归 Inspector用 Inspector 再次测试你的服务器确保其本身功能正常。权限问题确保 Node.js 脚本有可执行权限。5.3 适配其他 MCP 客户端MCP 是一个开放协议除了 Claude Desktop未来会有越来越多的客户端支持。配置原理大同小异都是通过某种方式指定服务器启动命令。关注你所用客户端的官方文档即可。6. 进阶实战从笔记模板到个性化 MCP 服务器掌握了基础我们就可以放飞想象力将这个笔记模板改造成任何我们需要的工具。下面分享两个我实践过的改造方向。6.1 案例一构建项目管理 MCP 服务器假设我们有一个简单的本地项目管理 JSON 文件projects.json。我们可以改造服务器来管理它。第一步定义资源。资源可以是项目 (project://{id})、任务 (task://{project_id}/{task_id})。listResources会读取 JSON 文件生成项目和任务的 URI 列表。第二步定义工具。create_project: 新增项目。create_task: 在指定项目下创建任务。update_task_status: 更新任务状态待办、进行中、完成。get_overdue_tasks: 动态生成一个资源列表包含所有过期未完成的任务。第三步定义提示。project_status_report: 嵌入当前所有项目的资源提示 AI 生成状态报告。prioritize_tasks: 嵌入本周末完成的任务提示 AI 根据工作量进行优先级排序建议。技术要点在readResource方法中需要根据不同的 URI 前缀project://或task://来解析 ID并从 JSON 文件的不同位置读取数据。注意文件读写需要异步操作 (fs.promises)。6.2 案例二构建代码仓库分析 MCP 服务器这个服务器不管理数据而是提供对本地 Git 仓库的分析能力。第一步定义工具核心。资源可能不是必须的我们可以主要暴露工具。analyze_git_log: 接收repo_path和since参数执行git log --oneline --since{since}将结果返回给 AI 分析提交趋势。find_large_files: 执行git ls-files | xargs ls -l | sort -nrk5 | head -10找出仓库中最大的10个文件。get_file_summary: 接收file_path读取文件内容并调用一个本地 LLM或简单的摘要算法生成简短摘要返回。第二步安全考虑。这类服务器需要特别注意。路径限制在工具实现中必须将操作限制在指定的安全目录内防止通过../../../这样的路径遍历访问系统文件。命令注入如果工具涉及执行 Shell 命令如调用 git务必对输入参数进行严格的校验和转义绝对避免直接将用户输入拼接成命令字符串。最好使用 Node.js 的child_process.spawn并传递参数数组。改造心得从模板出发最关键的一步是明确你的服务器要解决的“核心交互”是什么。是让 AI 查询数据资源为主还是让 AI 执行操作工具为主还是为 AI 准备一个复杂的分析场景提示为主想清楚这一点代码改造就有了明确的方向。7. 开发、调试与部署中的常见问题在实际开发和运行中你可能会遇到一些坑。这里记录下我遇到过的典型问题及其解决方案。7.1 协议通信与调试问题问题现象可能原因排查与解决Inspector 连接失败提示“连接错误”或“无法启动服务器”1. 启动命令或路径错误。2. 服务器代码存在语法错误启动即崩溃。3. 端口冲突Inspector 自身。1. 在终端手动运行node /path/to/build/index.js看是否有错误输出。2. 检查npm run build是否成功确保编译无报错。3. 尝试关闭 Inspector 重启或更换 Inspector 的端口。客户端如 Claude Desktop中看不到工具1. 配置文件路径或格式错误。2. 服务器启动失败客户端静默忽略。3. 客户端缓存了旧的配置。1. 使用console.error()在服务器初始化时输出日志确认客户端是否成功启动了进程。2. 检查客户端日志文件见5.2节。3. 彻底重启客户端有时需要清除缓存。工具调用后无反应或报错1. 工具处理函数 (callTool) 中有未捕获的异常。2. 工具返回的格式不符合 MCP 协议规范。3. 资源读取失败。1. 在callTool内部用try-catch包裹并通过console.error打印错误。2. 使用 Inspector 查看完整的请求和响应对比 SDK 文档检查响应结构。3. 确保readResource方法对不存在的 URI 有妥善处理返回错误。7.2 性能与生产环境考量模板项目用于学习和原型设计很棒但要用于生产环境还需要考虑以下几点状态管理模板使用内存Map服务器重启数据就丢失。生产环境必须接入持久化存储数据库、文件。同时注意并发读写可能带来的数据一致性问题。错误处理与日志在生产中不能只依赖console.log。需要集成成熟的日志库如 Winston、Pino将错误、警告和信息日志记录到文件或日志服务中方便排查问题。安全性身份验证如果你的服务器操作敏感数据或系统需要实现身份验证。MCP 协议支持传输层安全但应用层认证需要你自己设计例如通过env传递密钥或在首次握手时进行校验。输入验证对所有工具的参数进行严格的验证防止无效或恶意输入导致程序异常。权限控制不同的工具和资源可能对应不同的操作权限需要在业务逻辑中实现。部署为系统服务在开发机上用node命令运行没问题在生产环境可能需要用systemd(Linux)、launchd(macOS) 或 Windows Service 将其部署为后台服务并配置开机自启和进程守护。7.3 生态与未来展望MCP 协议由 Anthropic 提出但正在成为一个开放标准。除了 Claude Desktop未来 VSCode、JetBrains IDE 等编辑器通过插件支持 MCP 也是可以期待的。这意味着你今天基于此模板开发的服务器未来可能能在更多场景下使用。社区也已经出现了一些有趣的 MCP 服务器例如连接 GitHub、Jira、本地文件系统的服务器。多关注github.com/modelcontextprotocol官方仓库和社区动态能获得很多灵感和现成的解决方案。这个模板项目就像一把钥匙为你打开了定制化 AI 助手能力的大门。它的代码量不大但清晰地勾勒出了 MCP 服务器的骨架。剩下的就是如何根据你的独特需求为其注入血肉和灵魂。从管理你的第二个大脑笔记到操控你的开发环境再到连接你公司内部的各种系统可能性只受限于你的想象力。