我用一个周末开发的MCP工具,让Claude帮我管理了整个项目

graph TD A[开发环境准备] --> B[第一个MCP服务器] B --> C[Hello World示例] C --> D[实用工具开发] D --> E[文件管理服务器] E --> F[部署与集成] F --> G[Claude Desktop] F --> H[Cursor编辑器] style A fill:#FFE4B5 style D fill:#90EE90 style F fill:#87CEEB

3分钟速读:本文将手把手教你从零开发MCP服务器,从环境准备到实际部署,通过构建文件管理工具的完整实战,让你掌握为AI应用添加自定义功能的核心技能。无论你是想提升现有AI工作流,还是为企业构建专属工具,这篇实战指南都将是你的最佳起点。

"能帮我检查一下项目里有哪些TODO还没完成吗?"

我随口问了Claude一句。几秒钟后,它不仅列出了所有待办事项,还按优先级排序,甚至分析了哪些任务可能存在依赖关系。

这不是魔法,也不是Claude突然变聪明了。而是我用一个周末时间,开发了一个MCP服务器,让Claude能够直接访问我的项目文件。

从那以后,我的工作方式彻底改变了。

Claude不再只是一个聊天机器人,而是成了我的项目助手。它能读取代码、分析日志、管理文档,甚至帮我写测试用例。这种感觉就像是给AI装上了一双能够触及现实世界的手。

想知道怎么做到的吗?这篇文章会手把手教你。

🚀 从想法到现实的桥梁

为什么每个开发者都应该学会MCP开发?

在前两篇文章中,我们深入了解了MCP协议的工作原理和生态现状。但了解和会用是两回事。就像你可能很了解React的虚拟DOM机制,但真正让你从零搭建一个复杂应用时,还是会遇到各种实际问题。

MCP开发也是如此。理论知识只是基础,真正的价值在于:

1. 解决个性化需求 每个开发者、每个团队都有独特的工作流程。也许你需要让AI访问公司内部的API,或者连接特定的数据库。现有的MCP服务器可能覆盖不到你的具体需求。

2. 掌握AI时代的核心技能 我最近在GitHub上搜索MCP相关项目,发现数量增长得挺快的。虽然我没有具体统计过,但感觉每周都能看到新的项目冒出来。说实话,这让我觉得MCP可能真的会成为一个重要趋势。能够为AI应用开发定制工具的开发者,很可能会在未来拥有不小的竞争优势。

3. 创造商业价值 我认识的一个朋友,是做电商的。他们公司的客服每天要处理大量重复性问题,比如查询订单状态、处理退款申请等。他花了两个周末时间,开发了一个MCP服务器,让Claude能够直接访问他们的订单系统。

结果?客服工作量直接减少了一大半。以前需要人工处理的查询,现在AI几秒钟就能搞定。他跟我说,这个小工具帮公司每个月节省了好几万的人力成本。听完我就想,这不就是用技术创造真正价值的最好例子吗?

本文你将收获什么?

  • 搭建完整的MCP开发环境
  • 从Hello World到实用工具的完整开发流程
  • 一个可以直接使用的文件管理MCP服务器
  • 与Claude Desktop和Cursor的集成方法
  • 生产环境部署的最佳实践

🛠️ 开发环境准备:工欲善其事必先利其器

技术栈选择:Python vs TypeScript vs Go

在开始之前,我们需要选择合适的技术栈。目前MCP官方提供了多种语言的SDK:

语言 优势 适用场景 学习曲线
TypeScript 生态丰富,调试友好 Web开发者,需要复杂逻辑 中等
Python 语法简洁,AI生态完善 数据处理,机器学习集成 简单
Go 性能优秀,部署简单 高性能需求,系统工具 中等

对于本文的实战项目,我选择TypeScript。为什么?老实说,主要是因为我自己比较熟悉。当然,也有一些客观原因:

  1. 大部分前端开发者都熟悉(这样你们跟着学会比较容易)
  2. 类型安全确实能减少一些低级错误
  3. 调试工具比较完善,遇到问题时不会太抓狂

环境配置步骤

1. 安装Node.js和npm

bash 复制代码
# 推荐使用Node.js 18+
node --version  # 确保版本 >= 18.0.0
npm --version

2. 创建项目目录

bash 复制代码
mkdir my-mcp-server
cd my-mcp-server
npm init -y

3. 安装MCP SDK

bash 复制代码
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node ts-node

4. 配置TypeScript

json 复制代码
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

5. 配置package.json脚本

json 复制代码
{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "ts-node src/index.ts"
  }
}

调试工具配置

MCP服务器的调试有点特殊,因为它们通过stdin/stdout与客户端通信,不像普通的Web API那样可以用Postman测试。我刚开始的时候就被这个搞得很头疼。

好在有个救命工具叫MCP Inspector:

bash 复制代码
npm install -g @modelcontextprotocol/inspector

这个工具提供了Web界面,让你可以直观地测试MCP服务器的功能。虽然界面有点简陋,但至少能用。

👨‍💻 第一个MCP服务器:从Hello World到实用工具

基础服务器结构

让我们从最简单的Hello World开始:

typescript 复制代码
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

// 创建MCP服务器实例
const server = new McpServer({
  name: "my-first-mcp-server",
  version: "1.0.0"
});

// 注册第一个工具
server.tool("hello", 
  { 
    name: { type: "string", description: "Your name" }
  },
  async ({ name }) => {
    return {
      content: [
        {
          type: "text",
          text: `Hello, ${name}! This is my first MCP server.`
        }
      ]
    };
  }
);

// 启动服务器
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("MCP Server running...");
}

main().catch(console.error);

参数验证和错误处理

实际开发中,参数验证和错误处理至关重要。记得先安装zod:

bash 复制代码
npm install zod

然后在代码中使用:

typescript 复制代码
import { z } from "zod";

// 使用zod进行参数验证
const CalculateInputSchema = z.object({
  operation: z.enum(["add", "subtract", "multiply", "divide"]),
  a: z.number(),
  b: z.number()
});

server.tool("calculate",
  CalculateInputSchema,
  async ({ operation, a, b }) => {
    try {
      let result: number;
      
      switch (operation) {
        case "add":
          result = a + b;
          break;
        case "subtract":
          result = a - b;
          break;
        case "multiply":
          result = a * b;
          break;
        case "divide":
          if (b === 0) {
            throw new Error("Division by zero is not allowed");
          }
          result = a / b;
          break;
      }
      
      return {
        content: [
          {
            type: "text",
            text: `${a} ${operation} ${b} = ${result}`
          }
        ]
      };
    } catch (error) {
      return {
        content: [
          {
            type: "text",
            text: `Error: ${error.message}`
          }
        ],
        isError: true
      };
    }
  }
);

本地测试

bash 复制代码
# 编译并运行
npm run build
npm start

# 或者直接运行TypeScript
npm run dev

使用MCP Inspector测试:

bash 复制代码
mcp-inspector dist/index.js

这会启动一个Web界面,你可以在浏览器中测试工具调用。第一次看到自己的工具被成功调用时,那种成就感还是挺爽的。

🔧 进阶开发:构建实用的文件管理工具

现在让我们开发一个真正实用的MCP服务器------文件管理工具。这个服务器将提供以下功能:

  • 读取文件内容
  • 写入文件
  • 列出目录内容
  • 创建和删除文件/目录

安全性考虑

在处理文件系统操作时,安全性绝对是首要考虑。我之前就犯过一个低级错误,没有限制访问路径,结果测试时差点把系统文件给搞坏了。从那以后,我就养成了一个习惯:任何涉及文件操作的工具,都要先做路径验证。

typescript 复制代码
import * as path from "path";
import * as fs from "fs/promises";

class FileManager {
  private allowedPaths: string[];
  
  constructor(allowedPaths: string[]) {
    // 规范化允许的路径
    this.allowedPaths = allowedPaths.map(p => path.resolve(p));
  }
  
  private isPathAllowed(filePath: string): boolean {
    const resolvedPath = path.resolve(filePath);
    return this.allowedPaths.some(allowedPath => 
      resolvedPath.startsWith(allowedPath)
    );
  }
  
  async readFile(filePath: string): Promise<string> {
    if (!this.isPathAllowed(filePath)) {
      throw new Error("Access denied: Path not in allowed directories");
    }
    
    try {
      return await fs.readFile(filePath, 'utf-8');
    } catch (error) {
      throw new Error(`Failed to read file: ${error.message}`);
    }
  }
}

完整的文件管理服务器

核心的SafeFileManager类:

typescript 复制代码
// src/file-manager-server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import * as fs from "fs/promises";
import * as path from "path";

class SafeFileManager {
  private isPathSafe(filePath: string): boolean {
    const resolved = path.resolve(filePath);
    const allowedDirs = [process.env.MCP_ALLOWED_DIR || process.cwd()];
    return allowedDirs.some(dir => 
      resolved.startsWith(path.resolve(dir))
    );
  }

  async readFile(filePath: string): Promise<string> {
    if (!this.isPathSafe(filePath)) {
      throw new Error("Access denied");
    }
    return await fs.readFile(filePath, 'utf-8');
  }
  
  // writeFile和listDirectory方法类似...
}

注册工具的关键代码:

typescript 复制代码
const server = new McpServer({
  name: "file-manager-mcp",
  version: "1.0.0"
});

const fileManager = new SafeFileManager();

// 读取文件工具
server.tool("read_file",
  z.object({ path: z.string().describe("File path to read") }),
  async ({ path: filePath }) => {
    try {
      const content = await fileManager.readFile(filePath);
      return {
        content: [{ type: "text", text: `File: ${filePath}\n\n${content}` }]
      };
    } catch (error) {
      return {
        content: [{ type: "text", text: `Error: ${error.message}` }],
        isError: true
      };
    }
  }
);

// 启动服务器
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main().catch(console.error);

完整代码:由于篇幅限制,这里只展示了核心部分。完整的代码包括写入文件和列出目录功能,你可以按照相同的模式来实现。

配置管理

为了让服务器更灵活,我们可以添加配置文件支持:

typescript 复制代码
// config.ts
interface Config {
  allowedDirectories: string[];
  maxFileSize: number;
  logLevel: 'debug' | 'info' | 'warn' | 'error';
}

export function loadConfig(): Config {
  const configPath = process.env.MCP_CONFIG_PATH || './mcp-config.json';
  
  try {
    const configFile = require(configPath);
    return {
      allowedDirectories: configFile.allowedDirectories || [process.cwd()],
      maxFileSize: configFile.maxFileSize || 1024 * 1024, // 1MB
      logLevel: configFile.logLevel || 'info'
    };
  } catch {
    return {
      allowedDirectories: [process.cwd()],
      maxFileSize: 1024 * 1024,
      logLevel: 'info'
    };
  }
}

🚀 部署与集成:让你的工具为AI所用

Claude Desktop集成

  1. 编译服务器
bash 复制代码
npm run build
  1. 配置Claude Desktop

在macOS上,编辑 ~/Library/Application Support/Claude/claude_desktop_config.json

json 复制代码
{
  "mcpServers": {
    "file-manager": {
      "command": "node",
      "args": ["/absolute/path/to/your/project/dist/index.js"],
      "env": {
        "MCP_ALLOWED_DIR": "/Users/yourname/Documents"
      }
    }
  }
}

在Windows上,编辑 %APPDATA%/Claude/claude_desktop_config.json

  1. 重启Claude Desktop

重启后,你应该能在Claude的工具列表中看到你的文件管理工具。第一次看到自己开发的工具出现在Claude的界面里,那种感觉真的很棒。就像是你的代码突然活了过来,成为了AI的一部分。

Cursor编辑器配置

Cursor的配置稍有不同。在Cursor的设置中:

  1. 打开Settings → MCP Tools
  2. 添加新的MCP服务器:
json 复制代码
{
  "name": "File Manager",
  "command": "node",
  "args": ["/path/to/your/dist/index.js"],
  "env": {
    "MCP_ALLOWED_DIR": "/your/project/directory"
  }
}

常见问题排查(我踩过的坑)

1. 服务器无法启动 这个问题我遇到过很多次。通常是:

  • Node.js版本太老(我之前用的16,折腾了半天才发现)
  • 忘记安装依赖(新手常犯的错误)
  • 配置文件有语法错误(JSON格式一定要严格)

2. Claude无法发现工具 这个更坑,因为Claude不会给你明确的错误提示:

  • 配置文件路径写错了(我曾经把macOS和Windows的路径搞混了)
  • JSON格式有问题(少个逗号都不行)
  • 忘记重启Claude Desktop(这个很容易忽略)

3. 权限错误 安全相关的问题最难调试:

  • MCP_ALLOWED_DIR路径不存在(记得先创建目录)
  • 文件系统权限不够(Windows上特别容易出现)
  • 用了相对路径(强烈建议用绝对路径,省心)

调试技巧

添加日志记录:

typescript 复制代码
// 添加到服务器启动代码
console.error(`MCP Server started. Allowed directories: ${ALLOWED_DIRECTORIES.join(', ')}`);

// 在工具中添加调试信息
server.tool("debug_info", {}, async () => {
  return {
    content: [
      {
        type: "text",
        text: JSON.stringify({
          allowedDirs: ALLOWED_DIRECTORIES,
          nodeVersion: process.version,
          platform: process.platform
        }, null, 2)
      }
    ]
  };
});

📋 最佳实践与扩展方向

代码组织原则(我的血泪经验)

在开发了十几个MCP服务器之后,我总结出了几个重要原则:

  1. 单一职责:每个工具只做一件事。我之前贪心,想让一个工具既能读文件又能发邮件,结果代码变得特别难维护。
  2. 错误处理:始终处理可能的异常。这个真的很重要,因为MCP服务器一旦崩溃,整个AI工作流就断了。
  3. 参数验证:使用zod等库进行严格验证。相信我,用户输入永远比你想象的更奇葩。
  4. 安全第一:限制文件系统访问权限。这个我前面提过,但还是要再强调一遍。

性能优化建议

typescript 复制代码
// 使用流处理大文件
import { createReadStream } from 'fs';

server.tool("read_large_file",
  z.object({ path: z.string() }),
  async ({ path: filePath }) => {
    const stream = createReadStream(filePath, { encoding: 'utf-8' });
    let content = '';
    
    for await (const chunk of stream) {
      content += chunk;
      // 限制最大读取大小
      if (content.length > 100000) {
        content += '\n\n[File truncated - too large]';
        break;
      }
    }
    
    return { content: [{ type: "text", text: content }] };
  }
);

扩展方向

  1. 数据库集成:添加SQLite或PostgreSQL支持
  2. API调用:集成外部REST API
  3. 图像处理:添加图片处理功能
  4. 系统监控:提供系统状态查询工具

开源发布

如果你的MCP服务器足够通用,考虑发布到npm:

bash 复制代码
# 发布前准备
npm version 1.0.0
npm publish

记得添加README和使用文档。

🎯 总结与展望

通过这篇实战指南,你已经掌握了:

完整的开发流程 :从环境搭建到部署集成

实用的代码模板 :可以直接使用的文件管理服务器

最佳实践 :安全性、性能和可维护性考虑

调试技巧:快速定位和解决问题的方法

下一步建议

  1. 完善你的文件管理器:添加更多功能,如文件搜索、批量操作
  2. 开发专属工具:根据你的工作需求,开发定制化的MCP服务器
  3. 参与社区:在GitHub上分享你的项目,贡献给MCP生态

MCP开发的本质,就是在AI和现实世界之间搭建桥梁。

每一个你开发的MCP服务器,都是在为AI赋予新的能力。今天你让它读取文件,明天它可能就能帮你管理整个数据库。这不是科幻,而是正在发生的现实。

💡 金句分享:"最好的AI工具不是那些功能最多的,而是那些最懂你需求的。而MCP,就是让AI真正懂你的关键。"

现在,是时候开始你的MCP开发之旅了!记住,每一行代码都可能改变你与AI的协作方式。


💬 互动讨论

思考题

  1. 你最希望为哪个应用开发MCP服务器? 是为了提升个人工作效率,还是解决团队协作问题?
  2. 在开发过程中遇到的最大挑战是什么? 是技术实现,还是需求分析?
  3. 如何平衡功能复杂度和易用性? 你认为MCP服务器应该专注单一功能还是提供综合能力?

实践作业

  1. 完成文章中的文件管理服务器开发,并成功集成到Claude Desktop或Cursor
  2. 扩展一个新功能,比如文件搜索或内容替换
  3. 分享你的开发经验,在社交媒体上展示你的MCP服务器

下期预告:《企业级MCP集成方案 - 构建统一的AI工具平台》将深入探讨如何在企业环境中规模化部署和管理MCP服务器,敬请期待!

关注专栏,获取更多MCP实战干货!

相关推荐
jerrywus2 小时前
前端老哥的救命稻草:用 Obsidian 搞定 Claude Code 的「金鱼记忆」
前端·agent·claude
KEEN的创享空间2 小时前
AI编程从0到1之10X提效(Vibe Coding 氛围式编码 )09篇
openai·ai编程
AlienZHOU3 小时前
为 AI Agent 编写高质量 Skill:Claude 官方指南
agent·ai编程·claude
恋猫de小郭4 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
KaneLogger5 小时前
【翻译】打造 Agent Skills 的最佳实践
agent·ai编程·claude
QCY5 小时前
「完全理解」1 分钟实现自己的 Coding Agent
前端·agent·claude
王小酱5 小时前
Everything Claude Code 文档
openai·ai编程·aiops
mCell6 小时前
从零构建一个 Mini Claude Code:面向初学者的 Agent 开发实战指南
typescript·agent·claude
雮尘6 小时前
如何在非 Claude IDE (TARE、 Cursor、Antigravity 等)下使用 Agent Skills
前端·agent·ai编程
刘贺同学6 小时前
Day12-龙虾哥打工日记:OpenClaw 子 Agent 到底看到了什么?
aigc·ai编程