
1. 项目概述Fictional Cats MCP 是什么如果你最近在折腾 AI 应用开发特别是想让 AI 助手比如 Claude、Cursor 里的 AI 伙伴能访问外部数据或服务那你大概率听说过 MCPModel Context Protocol。简单来说MCP 就像给 AI 模型装上了一套标准化的“插件系统”让它能安全、可控地调用外部工具或数据源。今天要聊的这个bzannah/catsmcp就是一个非常有趣且实用的 MCP 服务器实现它专门提供了一个“虚构猫咪”的数据库。想象一下你正在开发一个需要生成温馨、有趣内容的 AI 应用比如一个儿童故事生成器、一个社交媒体文案助手或者一个用于测试的模拟数据源。你希望 AI 能获取一些关于猫咪的描述信息但又不想用真实的、可能涉及版权或隐私的图片和数据。这时Fictional Cats MCP 就派上用场了。它通过一个简单的 API为 AI 模型提供了获取虚构猫咪信息的超能力。这个项目本身结构清晰基于一个公开的 Netlify Functions API 构建是学习和理解 MCP 服务器如何工作的绝佳范例。2. MCP 核心概念与 Fictional Cats 的定位在深入代码之前我们得先掰扯清楚 MCP 到底是什么以及 Fictional Cats 在这个生态里扮演什么角色。这能帮你理解为什么我们需要它而不仅仅是“怎么用”。2.1 Model Context Protocol 简析MCP 不是一个具体的软件而是一套协议标准。你可以把它类比成 USB 协议。你的电脑AI 应用有 USB 接口MCP 客户端各种外设U盘、键盘、MCP 服务器只要遵循 USB 协议MCP 规范就能即插即用。这套协议的核心目标是解决 AI 模型与外部世界交互的两个核心问题安全性和标准化。安全性传统的“给 AI 联网”方式可能很危险。MCP 通过定义清晰的工具Tools和资源Resources边界让 AI 只能通过你明确声明的、受控的“通道”去访问外部数据或执行操作而不是拥有整个网络的 raw 访问权限。标准化在没有 MCP 之前每个 AI 应用接入外部服务的方式可能都不同需要大量的定制化开发。MCP 提供了一套统一的 JSON 格式定义只要服务端MCP Server按照这个格式描述自己能做什么客户端MCP Client如 Cursor、Claude Desktop就能自动识别并调用实现了“一次编写处处可用”。Fictional Cats MCP 就是一个遵循此协议的“数据源服务器”。它不执行复杂操作只专注于一件事提供虚构的猫咪数据。这种单一职责的设计使得它结构简单非常适合作为我们理解 MCP 服务器内部机制的切入点。2.2 Fictional Cats MCP 的架构与数据流理解了协议我们再来看这个具体项目的实现。根据文档它的架构非常典型[AI 应用 / MCP 客户端 (如 Cursor)] | | (通过 stdio 或 SSE 传输 MCP 协议消息) | [Fictional Cats MCP Server (本地进程)] | | (发起 HTTP 请求) | [远程 API: fictionalcats.netlify.app]客户端发起请求当你在 Cursor 里向 AI 提问“给我讲一个关于猫咪的故事”AI 模型判断需要猫咪数据于是通过 MCP 协议向已连接的 Fictional Cats Server 发送一个工具调用请求比如get_random_cat。服务器处理请求本地的 Fictional Cats MCP Server一个你运行的 Node.js/Python 等进程收到这个结构化请求。代理访问远程 API服务器根据请求类型构造对应的 HTTP 请求访问部署在 Netlify 上的真实 APIhttps://fictionalcats.netlify.app/.netlify/functions/api/cats/random。返回与格式化获取到 API 返回的 JSON 数据后MCP 服务器并不直接原样转发而是按照 MCP 协议规定的响应格式将数据重新封装返回给客户端。客户端接收并使用AI 客户端收到格式化的数据将其作为上下文提供给 AI 模型。于是AI 就能说出“有一只名叫 Zoey 的猫咪它是个袜子小偷喜欢玩玩具拥有一身蓬松的暹罗猫毛发...”这个过程中MCP 服务器充当了一个安全代理和协议转换器的角色。AI 模型和客户端完全不需要知道远程 API 的具体地址和参数细节它们只和标准的 MCP 工具交互。3. 从零开始Fictional Cats MCP 的部署与集成实操理论说得再多不如亲手跑起来。下面我将以最常见的开发环境为例带你一步步把这个 MCP 服务器跑起来并集成到 Cursor 编辑器中。这是最能体现其价值的部分。3.1 环境准备与依赖安装首先你需要一个基本的 Node.js 开发环境。我推荐使用nvm来管理 Node 版本避免全局依赖冲突。# 1. 克隆项目仓库 git clone https://github.com/bzannah/catsmcp.git cd catsmcp # 2. 检查项目结构通常 MCP 服务器是一个 Node.js 项目 ls -la # 你可能会看到 package.json, server.js, mcp.json 等文件 # 3. 安装项目依赖 npm install这里有个关键点原始的README可能不会详细说明但你需要检查package.json里的scripts字段。一个标准的 MCP 服务器通常会有一个启动脚本比如npm start或node server.js。同时要确认它依赖了官方的modelcontextprotocol/sdk或其他 MCP SDK。如果没有你可能需要手动安装。# 如果 package.json 里没有 modelcontextprotocol/sdk可能需要手动安装 npm install modelcontextprotocol/sdk3.2 配置 MCP 客户端以 Cursor 为例这是将 MCP 服务器“插入”AI 应用的关键一步。Cursor 编辑器内置了 MCP 客户端支持配置非常直观。打开 Cursor进入设置Settings。找到“MCP Servers”或“AI Model Configuration”相关区域。不同版本位置可能略有不同可以搜索 “MCP”。点击添加新的 MCP 服务器。配置通常需要以下信息Name: 一个易识别的名字比如Fictional Cats。Command: 启动你本地服务器的命令。例如如果你的入口文件是server.js这里就填node。Args: 命令的参数即server.js的路径。例如/absolute/path/to/your/catsmcp/server.js。可选Env: 环境变量这个项目通常不需要。重要提示你必须使用绝对路径。相对路径在 Cursor 的上下文中可能无法正确解析。一个常见的错误就是在这里填了相对路径导致连接失败。配置完成后保存设置。Cursor 会尝试在后台启动你指定的命令。你可以打开 Cursor 的“开发者工具”Developer Tools查看控制台日志确认是否有Fictional Cats MCP server started或类似的连接成功信息。3.3 验证与基础测试配置成功后怎么知道它真的在工作了呢直接对话测试在 Cursor 的聊天框里直接问 AI“请调用 Fictional Cats 工具获取一只随机猫咪的信息。” 观察 AI 的回复。如果成功它会返回一只猫咪的详细描述。查看可用工具有些 MCP 客户端支持列出所有已连接服务器的工具。你可以询问 AI“你现在有哪些可用的 MCP 工具” 它应该会列出get_random_cat和get_cats。服务器日志在终端运行你的 MCP 服务器的命令行窗口里你会看到每次 AI 调用时打印的请求和响应日志这是调试的黄金信息。实操心得第一次连接时最容易出问题的地方就是命令路径和端口/进程冲突。确保你的server.js没有语法错误能独立运行可以先用node server.js试试。如果 Cursor 报错说“无法连接”首先去终端看服务器进程是否正常启动有没有报“端口已被占用”之类的错误。MCP 服务器默认可能使用 stdio标准输入输出与客户端通信所以一般不需要配置网络端口。4. 核心功能深度解析与高级用法现在服务器跑起来了我们来深入看看它的两个核心工具并探索一些超越基础用法的场景。4.1get_random_cat随机性的妙用与数据解析这个工具看似简单但它在创意生成场景下威力巨大。每次调用都返回一个结构化的、包含name,description,image的完整猫咪对象。数据结构解读uuid: 全局唯一标识符。重要用途如果你在构建一个需要追踪或引用特定猫咪的应用这个字段就是关键。例如你可以让 AI 记住某只猫咪的uuid在后续对话中请求“获取我们刚才聊过的那只猫UUID: f60dd86b...的图片”。虽然当前 API 可能不支持按 UUID 查询但这展示了结构化数据对未来功能扩展的价值。description: 这是宝藏字段。它通常包含“品种个性爱好”的组合如“袜子小偷蓬松的暹罗猫喜欢玩玩具”。AI 可以轻松地从这句话中提取关键词用于分类、标签化或作为故事生成的种子。image: 提供的是一张稳定的图片 URL。这意味着你可以直接在 Markdown 或 HTML 中引用它来展示图片而不仅仅是文字描述。高级用法示例 假设你在开发一个自动生成社交媒体帖子的机器人。你可以这样设计工作流调用get_random_cat获取一只猫。解析description提取“暹罗猫”、“袜子小偷”、“爱玩”等标签。结合当前热点如“周一综合症”让 AI 生成文案“周一上班找不到袜子可能是被 Zoey 这样蓬松的暹罗猫小偷盯上啦看看它无辜的眼神 #猫咪日常 #暹罗猫 #搞笑宠物”。将imageURL 插入到帖子中。4.2get_cats(n)批量获取与数据驱动应用当你的应用需要更多数据比如生成一个“猫咪图鉴”页面或者需要多只猫的信息来对比、创作一个多角色故事时get_cats就登场了。参数n的实践考量性能与限制虽然文档没提但作为开发者我们必须考虑远程 API 是否有调用频率或单次数量限制。在正式项目中建议先小规模测试如 n5, 10, 20观察响应时间和成功率。不要一次性请求成百上千的数据这可能导致 API 拒绝服务或响应超时。数据去重仔细观察示例返回出现了两只都叫 “Winston” 的猫。这说明数据库允许重名。如果你的应用逻辑要求唯一性就需要在客户端根据uuid或结合其他字段进行去重处理。构建数据驱动应用的思路 你可以用这个工具快速搭建一个原型。例如一个简单的 Node.js 脚本定期获取 10 只猫然后将它们的名字和描述存入本地 SQLite 数据库再提供一个简单的 Web 界面来浏览和搜索这些猫咪。这个过程中Fictional Cats MCP 提供了稳定、有趣的数据源让你能专注于应用逻辑本身而非数据采集的麻烦。5. 深入原理MCP JSON 配置与服务器实现剖析要真正掌握一个 MCP 服务器光会用不行还得看懂它是怎么被定义和实现的。我们根据文档信息来还原其核心配置。5.1mcp.json配置文件解读MCP 服务器的能力通过一个mcp.json文件或类似结构向客户端宣告。对于 Fictional Cats其核心配置可能如下所示{ name: fictional-cats-mcp, version: 1.0.0, protocolVersion: 2024-11-05, description: Provides access to a database of fictional cats., tools: [ { name: get_random_cat, description: Retrieves a single random fictional cat with details like name, description, and image., inputSchema: { type: object, properties: {}, required: [] } }, { name: get_cats, description: Retrieves a specified number of fictional cats., inputSchema: { type: object, properties: { n: { type: integer, description: Number of cats to retrieve., minimum: 1 // 可能还有 maximum 限制 } }, required: [n] } } ], resources: [], // 此项目可能未定义资源Resources server: { command: node, args: [server.js] } }关键字段解析tools: 定义了服务器提供的两个“工具”。每个工具都有name,description和inputSchema。inputSchema使用了 JSON Schema 来严格定义输入参数的格式和规则。get_cats要求一个整数n且通过minimum: 1避免了无效的 0 或负数请求。这正是 MCP标准化和安全性的体现——客户端在调用前就能知道如何正确调用。server: 告诉客户端如 Cursor如何启动这个服务器。这就是我们在 Cursor 设置里填写的依据。5.2 服务器端逻辑实现猜想虽然我们看不到完整的server.js但可以根据 MCP SDK 的通用模式推断其核心结构// server.js 伪代码示例 import { Server } from modelcontextprotocol/sdk/server/index.js; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio.js; import axios from axios; // 假设使用 axios 进行 HTTP 请求 const API_BASE https://fictionalcats.netlify.app/.netlify/functions/api; const server new Server( { name: fictional-cats-mcp, version: 1.0.0, }, { capabilities: { tools: {}, // 声明支持工具 }, } ); // 1. 实现 get_random_cat 工具 server.setRequestHandler(tools/call, async (request) { if (request.params.name get_random_cat) { try { const response await axios.get(${API_BASE}/cats/random); return { content: [ { type: text, text: JSON.stringify(response.data, null, 2), // 格式化返回 }, ], }; } catch (error) { // 错误处理 return { content: [{ type: text, text: Error: ${error.message} }], isError: true, }; } } // 2. 实现 get_cats 工具 if (request.params.name get_cats) { const n request.params.arguments?.n; if (!n || n 1) { return { content: [{ type: text, text: Error: Parameter n must be a positive integer. }], isError: true, }; } try { const response await axios.get(${API_BASE}/cats?n${n}); return { content: [ { type: text, text: JSON.stringify(response.data, null, 2), }, ], }; } catch (error) { return { content: [{ type: text, text: Error: ${error.message} }], isError: true, }; } } // 未知工具 return { content: [{ type: text, text: Unknown tool: ${request.params.name} }], isError: true, }; }); // 启动服务器使用标准输入输出流通信 const transport new StdioServerTransport(); await server.connect(transport); console.error(Fictional Cats MCP server running on stdio);这个伪代码清晰地展示了 MCP 服务器的核心工作流程注册工具 - 监听调用 - 处理业务逻辑访问远程API- 按协议格式返回结果。错误处理是其中至关重要的一环确保了服务器的健壮性。6. 常见问题排查与进阶技巧在实际集成和使用过程中你肯定会遇到一些坑。下面是我总结的常见问题及其解决方案。6.1 连接与配置问题问题现象可能原因排查步骤与解决方案Cursor 提示 “Failed to connect to MCP server”1. 命令路径错误2. 服务器脚本有语法错误3. 依赖未安装4. 端口/进程冲突1.终端独立测试在项目目录下直接运行node server.js看是否有报错。这是第一步也是最重要的一步。2.检查绝对路径确保 Cursor 配置中的Args是server.js的绝对路径如/Users/yourname/projects/catsmcp/server.js。3.查看 Cursor 日志打开 Cursor 开发者工具控制台查看详细的错误信息。4.检查进程用 ps aux服务器进程启动后立即退出1. 缺少依赖包2.server.js中未正确等待连接缺少await server.connect()或类似逻辑3. 使用了错误的 SDK 版本1. 运行npm install确保所有依赖已安装。2. 检查server.js代码末尾确保有保持进程运行的逻辑如监听 stdio。一个简单的 MCP 服务器在连接后应该持续运行而不是执行完就退出。3. 查看package.json中modelcontextprotocol/sdk的版本是否与官方文档示例兼容。AI 无法识别工具1. Cursor 配置未生效2. 服务器工具定义未正确发送给客户端1. 重启 Cursor。有时配置更改需要重启才能完全加载。2. 在 Cursor 中询问 AI“列出你所有的工具”。如果工具列表为空说明连接或握手过程可能有问题回到上一步检查连接。3. 确保服务器在启动时正确地向客户端宣告了其工具列表这在 SDK 中通常是自动处理的。6.2 使用与性能优化问题AI 频繁调用导致响应慢或远程 API 限流技巧实现简单缓存。对于get_random_cat你可以在服务器内存中缓存最近获取的几只猫在短时间内相同的请求直接返回缓存结果。对于get_cats可以缓存常见数量如 n3, 5, 10的结果。注意设置合理的缓存过期时间如 5 分钟。// 简单的内存缓存示例 const cache new Map(); const CACHE_TTL 5 * 60 * 1000; // 5分钟 async function getCatsWithCache(n) { const cacheKey cats_${n}; const cached cache.get(cacheKey); if (cached (Date.now() - cached.timestamp) CACHE_TTL) { return cached.data; } const freshData await fetchFromAPI(n); // 你的实际获取函数 cache.set(cacheKey, { data: freshData, timestamp: Date.now() }); return freshData; }问题返回的 JSON 数据在 AI 回复中格式混乱技巧优化提示词。你可以在向 AI 提问时就明确指示它如何呈现数据。例如“请调用 get_random_cat并将返回的信息用清晰、友好的段落描述出来不要直接输出 JSON。” AI 模型在得到 MCP 返回的原始 JSON 后会遵循你的指令进行格式化输出。问题想扩展功能比如按品种筛选猫咪现状与思路当前的远程 API 和 MCP 工具可能不支持此功能。进阶做法是1. 自己 Fork 这个项目修改服务器代码在获取到所有猫的数据后在内存中进行过滤例如从description字段里匹配“siamese”、“tabby”等关键词。2. 为这个新功能定义一个新的 MCP 工具比如get_cats_by_breed。这需要你修改mcp.json和server.js。这是深入学习 MCP 扩展性的好机会。6.3 安全与生产环境考量虽然这是一个趣味项目但它涉及的模式在严肃应用中通用。API 密钥管理如果远程 API 需要密钥绝对不要硬编码在server.js里。应该通过环境变量传入。# 启动时传入 API_KEYyour_secret_key node server.js在 Cursor 配置中可以在Env字段里添加环境变量。错误处理与降级生产环境的 MCP 服务器必须有完善的错误处理。远程 API 可能挂掉此时你的服务器不应崩溃而应向客户端返回友好的错误信息或者提供降级数据如一个预定义的默认猫咪列表。输入验证虽然inputSchema定义了一些规则但在服务器代码中再次验证n等参数是良好的实践。防止无效或恶意参数被传递到下游 API。7. 项目价值与扩展思考Fictional Cats MCP 的价值远不止于提供一个猫咪数据库。它是一个完美的 MCP 教学样本和原型开发加速器。对于学习者它展示了 MCP 最核心的“工具Tools”概念代码量小逻辑清晰是阅读和理解 MCP SDK 如何工作的绝佳材料。你可以通过它快速掌握 MCP 服务器从配置、实现到集成的全流程。对于快速原型验证它提供了一个即用、有趣、无害的数据源。当你构思一个需要外部数据的 AI 应用创意时不必等待后端开发或寻找复杂的公开 API直接用这个 MCP 就能让 AI 动起来验证想法的可行性。比如半小时内就能搭出一个“AI 猫咪故事生成器”或“每日猫咪推荐”的演示。更进一步你可以以它为蓝本构建属于自己的 MCP 服务器。比如接入一个天气 API 做成Weather MCP接入一个笔记软件 API 做成Notes MCP。模式都是一样的定义工具 - 实现业务逻辑调用外部服务- 格式化返回。当你理解了 Fictional Cats 的每一行代码你就掌握了为 AI 模型打造专属“武器库”的基本方法。我个人在尝试将多个类似的小型 MCP 服务器组合使用时发现这种微服务化的思路让 AI 应用的功能模块非常清晰。每个 MCP 负责一个明确的领域AI 作为“大脑”来协调调度。这种架构不仅易于开发和维护也更符合安全原则——每个服务器的权限都被限制在特定范围内。从这个小猫服务器开始你完全可以逐步构建起一个功能强大的 AI 助手生态。