大家好,我卡颂,专注于AI助力程序员转型 (阅读我的更多思考)
相信很多同学日常编码已经用上了Cursor
。
最近,我在用Cursor
过程中遇到了注册的MCP服务不调用的问题。
经过一顿排查,最终确定是Cursro
自身bug导致。
本文聊聊排查的过程,还蛮有趣。
什么是MCP?
大模型(后文简称LLM
)自身只有多模态(文本、视频、图片...)输出能力,无法使用外部工具,比如:
-
无法联网查询
-
无法从数据库查数据
-
无法操纵浏览器
要赋予LLM使用外部工具的能力,需要搭建如下流程:
其中:
-
蓝色部分流程是LLM表达自己希望做什么
-
绿色部分流程是实际做这件事
蓝色部分 最早由openAI
实现,被称为Function Call
(后续迭代改名为Tool Call
)。
其他主流LLM也都跟进了这个功能(Claude
中这个功能叫Tool use
)。
我们会发现,蓝色部分是一套规范,用于定义LLM如何表达自己希望做什么。
比如,下面是Claude
定义的一个Tool use
,表达希望能调用一个名为 get_weather 的方法获取天气情况
:
json
{
"name": "get_weather",
"description": "获取指定地区的天气",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "指定地区,比如:北京市"
},
"unit": {
"type": "string",
"enum": ["摄氏度", "华氏度"],
"description": "温度单位,"摄氏度"或"华氏度""
}
},
"required": ["location"]
}
}
至于get_weather
方法在哪里,如何执行等如何实际做这件事 (绿色部分),Tool use
规范是没有定义的。
这就造成绿色部分的实现很混乱。
比如,我俩都实现了可以联网查资料的chatbox ,但联网查资料这个功能却没法互相替换。
因为在我俩的实现中,入参、输出、调用方式都不一样。
MCP
(M
odel C
ontext P
rotocal)的出现就是为了规范绿色部分,他是一套:
-
客户端、服务器架构规范
-
数据传输规范
以及规范的具体实现。
只要遵循MCP
规范,所有人实现的联网查资料(以及其他任何绿色部分)都可以互相替换。
我遇到的问题
我遇到的问题很简单 ------ 我按照MCP官方文档实现的查询天气服务 ,在Cursror
中成功注册:
但当我提及天气相关问题 时,Cursor
却没有调用weather MCP
:
也就是说,下述流程的某些环节出错了:
接下来,我们来排查问题原因。
第一步:mcp本身有问题么?
首先,我怀疑我写的mcp
服务本身有问题。
于是,我在Cline
(可以理解为开源版的Cursor
)中注册了weather MCP
:
当我问:上海天气咋样?
可以看到,Cline
可以成功调用weather MCP
。
这表示,weather MCP
本身没问题。
第二步:mcp是如何触发的?
那么,Cline
是如何触发mcp
的呢?
由于他是开源的,很容易调试他的运行流程。
简单来说,当我们在Cline
中输入任何内容后,Cline
的系统提示词包括2条信息:
-
第一条:你的输入(比如:上海天气咋样?)
-
第二条:非常长的
Cline
环境信息(消耗1w+ token)
这条环境信息主要包括:
- 基本介绍 - 定义助手身份和基本行为
- 工具使用 - 详细说明可用工具及其使用方法
- MCP 服务 - 介绍 MCP 的作用以及注册的 MCP
- 文件编辑 - 说明文件编辑工具的使用方法
等11个模块。
weather MCP
的定义出现在MCP服务 部分,所以Cline
(本质是背后的LLM)知道何时该调用。
第三步:Cursor是怎么处理mcp的?
有了前两步的基础,接下来我们分析Cursor
的执行流程。
由于Cursor
是闭源的,我们只能从侧面获取必要信息。
首先,抓取Cursor Composer
模式的请求,分析系统提示词。整段提示词主要包括:
- 核心身份 - 由 LLM 驱动的代理型 AI 编码助手,在 Cursor IDE 中与用户结对编程解决各类编码任务
- 通信规范 - 以专业友好的 MD 格式与用户交流,遵循严格的信息披露限制
- 工具调用 - 按规范使用可用工具,提供必要参数,不向用户直接提及工具名称
- 搜索与阅读 - 主动收集信息解决不确定问题,尽量避免向用户寻求帮助
等8个模块。
整体token消耗只有Cline
系统提示词的 1/10 不到:
虽然没有明确指明MCP
相关内容,但是提到了工具调用的规范。
遵循该规范继续查找,在接口的tools
(也就是前面介绍的Tool use
)字段中,Cursor
定义了不少工具,比如:
- codebase_search: 在代码库中查找与查询语义相关的代码片段
- read_file: 读取文件内容与概要,可指定行范围或读取整个文件
- run_terminal_cmd: 在用户系统上提议或执行终端命令
- list_dir: 列出目录内容,用于初步了解文件结构
- grep_search: 基于正则表达式的文本搜索,用于精确查找字符串模式
- edit_file: 提议对现有文件进行编辑,由更简单的模型应用这些编辑
- file_search: 基于模糊匹配的快速文件路径搜索
- delete_file: 删除指定路径的文件
- reapply: 当编辑结果不符合预期时,调用更智能的模型重新应用上次编辑
- diff_history: 获取最近文件变更历史,了解修改内容
Cursor Composer Agent
之所以能开发项目,底层依赖的就是这些工具。
除此之外,所有在Cursor
中注册的MCP
也会作为tool
出现在这里。
比如,从下图可知,除weather MCP
外,我还注册了一个Sequential Thinking MCP
(通过多步思考过程进行动态问题分析和解决的工具):
在Cursor
发出的LLM请求中,tools
字段下有名为mcp__sequentialthinking
的工具:
json
{
"function": {
"description": "A detailed tool for dynamic and reflective problem-solving through thoughts ...省略",
"name": "mcp__sequentialthinking",
"parameters": {
"properties": {
"branchFromThought": {
"description": "Branching point thought number",
"minimum": 1,
"type": "integer"
},
"branchId": {
"description": "Branch identifier",
"type": "string"
}
// ...省略
},
"required": [
"thought",
"nextThoughtNeeded",
"thoughtNumber",
"totalThoughts"
],
"type": "object"
}
},
"type": "function"
}
从这里就能发现问题 ------ weather
与Sequential Thinking
都成功注册,但请求中并没有带上weather
相关Tool use
。
这就是为什么Cursor
有时不能成功调用mcp
------ 他没有将该mcp
作为Tool use
加入请求中,LLM自然不知道有这么个mcp
可以调用。
总结
当前Cursor
在MCP
服务的注册上存在bug,导致一些注册成功的MCP
服务不会在请求LLM时作为Tool use
被带上。
这是Cursor
不能成功调用MCP
的原因。
PS:如果对
Cursor
系统提示词感兴趣,可以给这篇文章点赞。赞多的话我再出篇文章解析Cursor
各类(Chat、Composer)系统提示词