1. 从 Cursor 的 MCP 限制说起
上一篇文章里,我用 TypeScript 实现了一个 MCP 服务,同时注册了 Resources、Prompts、Tools 三类能力,但接到 Cursor 后只有 Tools 按钮能正常触发,Resources 和 Prompts 一直看不到入口。原作者说换 Claude 客户端可以看全整个调用链路,所以我打算复现一遍,但对个人开发者来说,官方客户端的每日免费额度用起来很紧。后来我把客户端请求地址统一指到 TaoToken(https://taotoken.net/?utm_source=taotoken_aicg_blog_end),用同一套 mcp-demo 配置完整调通了 Tools、Prompts、Resources,连 Roots 的边界行为也一并验证了。
这个过程的本质并不复杂:Claude 客户端提供的是“展示层”,它知道怎么把 MCP 服务里的三类能力画成按钮、附件和模板文件;TaoToken 提供的是“模型通道”,让 Claude 客户端的请求不再依赖官方免费额度,而是走我自己创建的 API Key。两者配合,正好补上了 Cursor 缺失的验证环节。
所以本文不是让你抛弃 Cursor,而是建议你先把 MCP 的全貌看完,再回到 Cursor 里理解“为什么同一个服务,那边只能看到 tools”。下面按我实际操作的顺序,把配置文件和客户端里每个入口对应的位置都写清楚。
2. MCP 的四个核心概念,先对齐一次
MCP 可以理解为 AI 应用程序的“USB-C 接口”:它标准化了 AI 模型连接到数据源和外部工具的方式。写 MCP 服务时,你往服务器上挂哪些能力,客户端就能在界面上按约定展示哪些能力。通常涉及四类:
- Resources(资源):服务端公开的数据内容,供客户端读取后作为大模型上下文,相当于直接给模型塞一份文件或知识片段。
- Prompts(提示):可复用的提示词模板,客户端把它展示给用户或模型,相当于一个提示词库。
- Tools(工具):最常用的能力,暴露可执行的函数供模型按需调用,通常需要用户确认。
- Roots(根):定义 MCP 服务可以操作的文件范围,主要用来限制像 filesystem 这类服务的活动边界。
Cursor 目前只实现了 Tools 的标准调用流程,Resources 和 Prompts 虽然在服务端注册了,但客户端没有对应 UI,用户自然看不到。Claude 桌面客户端对这三类能力都有内置入口,区别只是藏在不同的按钮里。
这里顺便说一句:Claude 客户端的模型请求默认走官方通道。如果你不想被官方每日次数约束,可以把请求地址指到 TaoToken,这样模型调用消耗的是你自己 Key 的额度,MCP 服务配置不用动。下一步就需要打开 TaoToken 创建 API Key,然后写进客户端的配置文件。
3. claude_desktop_config.json 里把 API 指到 TaoToken
3.1 下载安装并打开配置文件
先去官网下载 Claude 桌面客户端,这一步和原文一致。安装完成后,点击右上角设置,进入 Developer 面板,选择 Edit Config,系统会用编辑器打开claude_desktop_config.json。这个文件就是 Claude 客户端的全局配置,mcpServers 和环境变量都写在这里。
注意,配置文件里有两个完全不同的区块:env控制客户端内模型的请求地址和认证信息;mcpServers声明要加载哪些 MCP 服务。很多人只添加了 mcpServers,忘了改 env,结果客户端界面能看到工具,一执行就报认证失败。
3.2 写入环境变量,让模型请求走 TaoToken
在claude_desktop_config.json顶层加一个"env"字段,把三个环境变量填进去:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "your-model-id" }, "mcpServers": { "mcp-demo": { "command": "node", "args": [ "--experimental-specifier-resolution=node", "/Users/chen/Desktop/workspace/demo-projects/mcp/mcp-demo/build/index.js" ] } } }这里有几个容易填错的地方,单独列一下:
ANTHROPIC_BASE_URL必须是https://taotoken.net/api,末尾不要加/v1,也不要带任何查询参数。这是填进工具里的接口地址,不是浏览器里打开的官网地址。ANTHROPIC_AUTH_TOKEN填YOUR_API_KEY,Key 需要从 TaoToken 控制台创建,不要在命令行里裸奔。ANTHROPIC_MODEL里的your-model-id替换成模型广场当时列出的模型 ID,以 模型广场 为准,不要凭印象填旧名字。
改完保存文件,完全退出 Claude 客户端再重新打开。客户端启动时会重新读取这份配置,不重启的话,mcpServers 的加载状态不会刷新。
4. mcpServers 挂上自己写的 mcp-demo
4.1 配置加载前后的界面变化
重启后,点击客户端左侧第二个图标按钮,正常情况下会看到mcp-demo这个服务,展开后是服务里注册的若干个工具。我在自己的服务里注册了两个:echo_message和另一个测试函数。这一步和原文描述一致,差别只是底部模型请求已经落到 TaoToken 通道上。
如果列表里没有出现 mcp-demo,先检查args里那串路径是否存在。原文给出的是一台 macOS 机器上的绝对路径,你换成自己上一篇文章构建出的build/index.js实际位置。路径写错时,客户端往往不会报红,只是服务一直转圈加载不出来。
4.2 mcp-demo 的启动参数说明
mcp-demo 是用 TypeScript 写的,运行入口是编译后的 JS 文件,所以command用node,args第一段参数是 Node 的 ES module 解析开关,第二段参数才是脚本路径。如果你的服务是用 Python 写的,这里应该换成python加脚本路径;如果是官方@modelcontextprotocol/server-filesystem这类现成包,则用npx直接拉起。下面是原文后来追加的 filesystem 配置,也是我们后面验证 Roots 时要用到的:
{ "mcpServers": { "mcp-demo": { "command": "node", "args": [ "--experimental-specifier-resolution=node", "/Users/chen/Desktop/workspace/demo-projects/mcp/mcp-demo/build/index.js" ] }, "filesystem": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "/Users/chen/Downloads" ] } } }文件里两个服务的配置结构完全一致:command告诉客户端用什么程序启动,args传入启动参数和权限限定。filesystem 服务最后的/Users/chen/Downloads就是 Roots 边界——这个服务只能操作 Downloads 目录下的文件。
5. Tools 调用:先让 echo_message 跑一次
Tools 的执行入口在客户端第二个图标按钮里。点击展开 mcp-demo,能看到工具描述和参数说明。直接创建一个新对话,向模型发送一条“你好”,模型会根据上下文判断需要调用echo_message工具,执行后把结果原样返回。
我在自己的服务端实现里加了一行控制台日志,调用时终端会输出收到的参数。这样能确认调用确实是“模型发起 → 客户端转发 → MCP 服务执行 → 结果截回对话”这条链路走完的,而不是模型自己瞎编了一个回复。
Tools 是 MCP 里被支持得最广泛的一类能力,Cursor 也能正常调用。区别在于:当你在 Cursor 里点同一个工具时,请求走的是 Cursor 自己的模型通道;而在我们这套方案里,请求从 Claude 客户端发出,经过 TaoToken 通道去调模型,工具本身和客户端 UI 无关。第一次跑通后,建议立刻去 TaoToken 控制台看一眼用量记录,确认这一轮对话已经记到你的 Key 名下。
6. Prompts 的入口不在“工具列表”,而在输入框第一个按钮
Prompts 和 Tools 的入口完全不在一个位置,这也是 Cursor 里找不到它的根本原因。回到对话输入框,注意左侧第一个按钮,点击后选 Add,客户端会列出 mcp-demo 注册的所有 Prompts 模板。
我注册的模板叫generate_slogan,作用是根据主题生成一句简短口号。选中它之后,输入框会出现一个参数填写区,我输入“环保”,再点 Add prompt。此时输入框底部多了一个 TXT 文件,里面就是 MCP 服务根据我的输入动态生成的完整提示词。点击这个文件可以直接查看内容,确认无误后再发送给模型。
整个流程的本质是:Prompts 是服务端定义的一组“提示词函数”,客户端负责把函数的返回值展示成一个可预览的文件,用户确认后,这个文件内容会作为系统提示词的一部分发给模型。我打开 TXT 里的内容,看到的正是generate_slogan的loadPrompt实现里拼接的那段文案,包括“你是环保品牌的口号策划师”这类前缀。
这个功能对团队协作价值很大。把常用的 prompt 模板收敛到 MCP 服务的prompts列表里,客户端里就能反复使用,不用每次复制粘贴一长串指令。注意一点:如果客户端对话框没有出现 TXT 文件,多半是 MCP 服务的loadPrompt返回格式不对,检查返回对象里content数组的type字段是否用了text。
7. Resources:先把附件喂给模型,再让它回答
Resources 的入口和 Prompts 类似,同样在输入框左侧第一个按钮的 Add 菜单里。这次选择status,它是 mcp-demo 注册的 Resource 资源,返回一段固定的状态文本。
选择之后,输入框下面会追加一个附件,点击可以查看资源内容。我实现里返回的是一段关于服务运行状态的消息,模型会把它当作已知知识,回答时直接引用附件里的信息。和 Prompts 的区别在于:Prompts 出来的是“指令模板”,Resources 出来的是“参考资料”。日常使用中,你可以把产品文档、运维手册、项目背景等内容做成 Resource,模型回答时就能带上这些上下文。
这一步在 Cursor 里确实做不到,因为 Cursor 的 MCP 面板只为 tools 设计了交互区。你就算在 Cursor 的 MCP 配置文件里把服务注册好,Resources 列表也不会出现在任何位置。这就是我为什么绕道 Claude 客户端来做完整验证:不是 Cursor 不好用,而是它只实现了 MCP 协议的子集。
验证 Resources 成功后,可以和 Tools 混着用。比如先把status资源加载到对话里,然后继续发指令让模型调用echo_message,你会看到资源和工具同时作用于同一个上下文,互不干扰。这种“先给资料再调工具”的组合,才是 MCP 在真实业务里最常见的用法。
8. Roots 顺带验证一下,文件访问边界是怎么拦住的
Roots 需要依靠支持它的真实服务来演示。我在 mcpServers 里加上了filesystem服务,并把参数限定为/Users/chen/Downloads。重启 Claude,新建对话,问一句“我的 Downloads 目录里有哪些文件”。客户端会先弹一个工具调用确认框,点允许之后紧接着弹一个文件夹访问授权框,再点允许,模型就会调用 filesystem 服务的list_directory工具,把目录内容列出来。
接着我让它修改 Downloads 里某个文件名,它执行了move_file工具,把临时测试文件从旧名字改成新名字。整个过程能清楚看到 Roots 的价值:MCP 服务只暴露 Downloads 目录的操作能力,模型不能去读桌面或系统目录。
我试着让它访问 Downloads 外层的文件,客户端返回了权限拦截信息,没有直接放行。这验证了 Roots 是“服务端执行范围”的控制机制,跟模型通道无关。也就是说,TaoToken 只管把请求送到模型,文件访问边界还是由 filesystem 服务自己根据启动参数实现的。如果你开发的 MCP 服务需要限制操作范围,也可以参照这个模式,把允许访问的路径作为启动参数传进去。
9. 调用完去控制台对一下这笔 Token
到这里,整个 Claude 客户端侧的 MCP 四类能力就都跑通了。配置完成后,建议去 TaoToken 控制台看一笔调用记录,确认刚才几轮对话确实走了你的 Key。如果显示为 401,说明ANTHROPIC_AUTH_TOKEN里的 Key 复制有误,回到 创建 Key 页面重新生成。如果提示模型不存在,多半是ANTHROPIC_MODEL里的 ID 写错了,以模型广场当时列表为准。如果客户端压根连不上,检查ANTHROPIC_BASE_URL是否多写了/v1——正确的接口地址是https://taotoken.net/api,不带后缀。
确认无误后,可以把这套 mcp-demo 换成你自己开发的 MCP 服务,继续在 Claude 客户端里试 Prompts 和 Resources 的组合调用。需要更充足的对话配额,可以打开 模型对话 直接测同一条消息,方便对比不同模型 ID 的差异;长期写代码的场景再看 Coding Plan。MCP 的完整接入参数和 Claude Code 环境变量对照,在 接入文档 里有现成说明。
折腾这套配置的那天晚上,我最大的体会是:MCP 本身并不复杂,复杂的是客户端各自对协议的支持范围不一致。Cursor 只做 Tools,Claude 客户端做全,TaoToken 负责把模型通道统一起来,三者各管一段。把这个链路拆开看,排障思路会清晰很多:工具调不通,先查 mcpServers;模型不响应,再查 env;权限不够,最后查 Roots。把这几层分开,以后再换客户端,你也能几分钟定位到问题所在。