从0到1:手把手教你实现一个MCP服务并接入Claude

部署运行你感兴趣的模型镜像

如果你最近在关注AI工具的发展,一定听说过MCP(Model Context Protocol)这个词。2024年11月,Anthropic推出这个开放协议时,很多人的第一反应是"又一个新标准"。但当你真正尝试用它构建一个AI工具时,会发现这个协议解决的问题确实足够痛——它让AI助手能够以标准化的方式连接各种数据源和工具,而不需要为每个新工具重新设计对接方案。

今天这篇文章不讲理论,我们直接上手:从零开始构建一个简单但完整的MCP服务,实现一个"每日诗词"功能,并把它接入到Claude Desktop中。在这个过程中,你会理解MCP的核心概念、开发流程和调试技巧。

准备工作:你需要什么

在开始之前,确保你的开发环境满足这些条件。首先是Node.js 18或更高版本,这是运行MCP TypeScript SDK的基础。然后下载安装Claude Desktop应用,这将作为我们的MCP客户端。代码编辑器方面,VS Code是个不错的选择,它对TypeScript的支持很完善。最后,基本的TypeScript和异步编程知识会让你理解起来更顺畅,但即使你是JavaScript新手,跟着做也能完成整个流程。

用npm全局安装MCP Inspector,这个工具在开发调试阶段非常有用,能让你在接入Claude之前就测试MCP服务是否正常工作。打开终端执行npm install -g @modelcontextprotocol/inspector,安装完成后你就拥有了一个独立的MCP服务调试器。

理解MCP的核心概念

在写代码之前,我们需要理解MCP中的几个关键概念。MCP定义了三种核心"原语"(Primitives),它们是服务器向客户端提供能力的方式。

**Tools(工具)**是可执行的函数,AI可以主动调用它们来完成特定任务。比如"查询天气"、“发送邮件”、“搜索数据库"这些都是工具。当用户问Claude"今天北京天气怎么样”,如果你提供了天气查询工具,Claude就能自动调用它。

**Resources(资源)**是可读取的数据源,为AI提供上下文信息。比如一个文件的内容、数据库的schema、API的返回结果。资源通常是被动的——AI读取它们,但不直接执行操作。

**Prompts(提示模板)**是预定义的交互模板,帮助用户快速启动特定任务。比如"代码审查助手"、"邮件撰写模板"这些都可以作为Prompts提供。

我们今天要实现的"每日诗词"服务,会同时提供一个Tool(获取随机诗词)和一个Resource(诗词数据源说明)。

动手实现:构建诗词MCP服务

创建一个新的项目目录,初始化Node.js项目。在终端中依次执行:

mkdir poetry-mcp
cd poetry-mcp
npm init -y

安装MCP SDK和必要的依赖:

npm install @modelcontextprotocol/sdk
npm install --save-dev @types/node typescript

创建TypeScript配置文件tsconfig.json,确保编译器能正确处理模块系统:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

src目录下创建主文件index.ts。这里是完整的实现代码,包含详细注释:

#!/usr/bin/env node
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";

// 诗词数据(实际项目可以从API或数据库获取)
const poems = [
  { title: "静夜思", author: "李白", content: "床前明月光,疑是地上霜。举头望明月,低头思故乡。" },
  { title: "春晓", author: "孟浩然", content: "春眠不觉晓,处处闻啼鸟。夜来风雨声,花落知多少。" },
  { title: "登鹳雀楼", author: "王之涣", content: "白日依山尽,黄河入海流。欲穷千里目,更上一层楼。" }
];

// 创建MCP服务器实例
const server = new Server(
  {
    name: "poetry-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
      resources: {}
    },
  }
);

// 注册工具列表处理器
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "get_random_poem",
        description: "获取一首随机的中国古诗词",
        inputSchema: {
          type: "object",
          properties: {},
          required: []
        }
      }
    ]
  };
});

// 注册工具调用处理器
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "get_random_poem") {
    const randomPoem = poems[Math.floor(Math.random() * poems.length)];
    return {
      content: [
        {
          type: "text",
          text: `《${randomPoem.title}》\n作者:${randomPoem.author}\n\n${randomPoem.content}`
        }
      ]
    };
  }
  throw new Error(`Unknown tool: ${request.params.name}`);
});

// 注册资源列表处理器
server.setRequestHandler(ListResourcesRequestSchema, async () => {
  return {
    resources: [
      {
        uri: "poetry://info",
        name: "诗词库信息",
        mimeType: "text/plain",
        description: "关于诗词数据源的说明"
      }
    ]
  };
});

// 注册资源读取处理器
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  if (request.params.uri === "poetry://info") {
    return {
      contents: [
        {
          uri: request.params.uri,
          mimeType: "text/plain",
          text: "本诗词库包含精选的中国古典诗词,涵盖唐宋等朝代的经典作品。"
        }
      ]
    };
  }
  throw new Error(`Unknown resource: ${request.params.uri}`);
});

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

main().catch((error) => {
  console.error("服务器启动失败:", error);
  process.exit(1);
});

package.json中添加构建和启动脚本:

{
  "type": "module",
  "bin": {
    "poetry-mcp": "./dist/index.js"
  },
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

编译TypeScript代码:npm run build。如果一切顺利,你会在dist目录下看到编译好的JavaScript文件。

调试阶段:使用MCP Inspector测试

在接入Claude之前,先用MCP Inspector验证服务是否正常。在项目目录下执行:

npx @modelcontextprotocol/inspector node dist/index.js

Inspector会启动一个Web界面,通常在http://localhost:5173。打开浏览器访问这个地址,你会看到一个交互式调试界面。

在左侧面板,你能看到服务器提供的Tools和Resources列表。点击"get_random_poem"工具,然后点击"Call Tool"按钮。如果实现正确,右侧会显示返回的诗词内容。同样地,你可以测试读取"poetry://info"资源,查看是否能正确返回诗词库信息。

这个调试步骤非常关键。很多开发者直接跳过Inspector,把有问题的服务接入Claude,然后花大量时间排查为什么不工作。Inspector提供的实时调试能力能让你快速定位问题——是参数解析错误、返回格式不对、还是异步处理有bug。

接入Claude Desktop:让AI用上你的工具

现在我们的MCP服务已经经过验证,可以接入Claude了。找到Claude Desktop的配置文件。在macOS上,它位于~/Library/Application Support/Claude/claude_desktop_config.json;Windows用户则在%APPDATA%\Claude\claude_desktop_config.json

用文本编辑器打开这个JSON文件,添加你的MCP服务配置:

{
  "mcpServers": {
    "poetry": {
      "command": "node",
      "args": ["/完整路径/poetry-mcp/dist/index.js"]
    }
  }
}

注意这里的路径必须是绝对路径。保存文件后,完全退出Claude Desktop(不是最小化,是真正退出),然后重新启动。

重启后,在Claude的对话界面右下角,你应该能看到一个小工具图标,点击它会显示已连接的MCP服务。如果"poetry"出现在列表中,说明连接成功。现在你可以尝试和Claude对话:“给我读一首古诗吧”。Claude会自动识别这个需求,调用你提供的get_random_poem工具,并把结果整合到回复中。

常见问题与调试技巧

在实际开发中,你可能会遇到一些问题。如果Claude连不上你的MCP服务,首先检查配置文件路径是否正确,JSON格式是否有效。可以用node dist/index.js手动运行服务,看终端是否有错误输出。

如果服务能连接但工具调用失败,回到MCP Inspector验证工具的inputSchema和返回格式。MCP对JSON Schema的校验很严格,字段类型不匹配会导致调用失败。记得在处理器函数中添加try-catch,并输出详细的错误日志到stderr(因为stdout被MCP协议占用)。

对于异步操作,确保所有Promise都被正确await。MCP服务器的请求处理器必须是异步函数,如果你在内部调用API或数据库,忘记await会导致请求超时或返回空结果。

扩展思路:从诗词到实际应用

这个诗词服务只是个起点,展示了MCP的基本工作方式。在实际项目中,你可以扩展很多功能。比如连接真实的API,从今日诗词或古诗文网获取更丰富的内容;添加参数支持,让用户指定朝代、作者或诗词类型;实现缓存机制,避免重复请求外部API。

更进一步,你可以把这个模式应用到其他领域。企业可以开发MCP服务连接内部知识库,让Claude直接访问公司文档;开发者可以封装常用的开发工具,比如Git操作、代码格式化、API测试。MCP的标准化意味着一次开发,多处使用——同样的服务可以接入Claude、也可以接入其他支持MCP的AI客户端。

Suppr的团队已经用这种方式实现了PubMed搜索和文档翻译服务(项目地址:https://github.com/zjg678/suppr-mcp),展示了如何在学术研究场景中应用MCP。他们的实现包含了更复杂的功能,比如异步任务管理、状态跟踪、多语言支持,非常值得学习参考。

写在最后

MCP协议的价值不在于技术多么复杂,而在于它建立了一个开放的生态标准。当越来越多的工具和数据源支持MCP,AI助手能做的事情就会呈指数级增长。作为开发者,现在正是入场的好时机——生态还在早期,标准相对简单,但潜力巨大。

希望通过这篇教程,你不仅学会了如何实现一个MCP服务,更重要的是理解了MCP的设计理念和应用场景。接下来,不妨尝试把你日常工作中重复使用的工具封装成MCP服务,让AI真正成为提升效率的助手。代码写完的那一刻,当你看到Claude自然地调用你的工具完成任务,那种"AI确实在帮我干活"的感觉,会让你觉得这些折腾都值得。


相关资源:

您可能感兴趣的与本文相关的镜像

LobeChat

LobeChat

AI应用

LobeChat 是一个开源、高性能的聊天机器人框架。支持语音合成、多模态和可扩展插件系统。支持一键式免费部署私人ChatGPT/LLM 网络应用程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值