一次排查 Cursor Bug 的經歷
大家好,我卡頌。
相信很多同學日常編碼已經用上了Cursor。
最近,我在用Cursor過程中遇到了「注冊的MCP服務不調用」的問題。
經過一頓排查,最終確定是Cursro自身bug導致。
本文聊聊排查的過程,還蠻有趣。
什么是MCP?
大模型(后文簡稱LLM
)自身只有多模態(tài)(文本、視頻、圖片...)輸出能力,無法使用外部工具,比如:
- 無法聯網查詢
- 無法從數據庫查數據
- 無法操縱瀏覽器
要賦予LLM「使用外部工具的能力」,需要搭建如下流程:
其中:
- 藍色部分流程是「LLM表達自己希望做什么」
- 綠色部分流程是「實際做這件事」
「藍色部分」最早由openAI實現,被稱為Function Call(后續(xù)迭代改名為Tool Call)。
其他主流LLM也都跟進了這個功能(Claude中這個功能叫Tool use)。
我們會發(fā)現,藍色部分是一套規(guī)范,用于定義「LLM如何表達自己希望做什么」。
比如,下面是Claude定義的一個Tool use,表達希望能調用一個名為 get_weather 的方法獲取天氣情況:
{
"name": "get_weather",
"description": "獲取指定地區(qū)的天氣",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "指定地區(qū),比如:北京市"
},
"unit": {
"type": "string",
"enum": ["攝氏度", "華氏度"],
"description": "溫度單位,“攝氏度”或“華氏度”"
}
},
"required": ["location"]
}
}
至于get_weather方法在哪里,如何執(zhí)行等「如何實際做這件事」(綠色部分),Tool use規(guī)范是沒有定義的。
這就造成綠色部分的實現很混亂。
比如,我倆都實現了「可以聯網查資料的chatbox」,但「聯網查資料」這個功能卻沒法互相替換。
因為在我倆的實現中,入參、輸出、調用方式都不一樣。
MCP(Model Context Protocal)的出現就是為了規(guī)范綠色部分,他是一套:
- 客戶端、服務器架構規(guī)范
- 數據傳輸規(guī)范
以及規(guī)范的具體實現。
只要遵循MCP規(guī)范,所有人實現的「聯網查資料」(以及其他任何綠色部分)都可以互相替換。
我遇到的問題
我遇到的問題很簡單 —— 我按照MCP官方文檔[1]實現的「查詢天氣服務」,在Cursror
中成功注冊:
綠點代表服務成功在Cursor中注冊
但當我提及「天氣相關問題」時,Cursor卻沒有調用weather MCP:
也就是說,下述流程的某些環(huán)節(jié)出錯了:
接下來,我們來排查問題原因。
第一步:mcp本身有問題么?
首先,我懷疑我寫的mcp服務本身有問題。
于是,我在Cline(可以理解為開源版的Cursor)中注冊了weather MCP:
當我問:上海天氣咋樣?
可以看到,Cline可以成功調用weather MCP。
這表示,weather MCP本身沒問題。
第二步:mcp是如何觸發(fā)的?
那么,Cline是如何觸發(fā)mcp的呢?
由于他是開源的,很容易調試他的運行流程。
簡單來說,當我們在Cline中輸入任何內容后,Cline的系統(tǒng)提示詞包括2條信息:
- 第一條:你的輸入(比如:上海天氣咋樣?)
- 第二條:非常長的
Cline
環(huán)境信息(消耗1w+ token)
這條環(huán)境信息主要包括:
- 「基本介紹」 - 定義助手身份和基本行為
- 「工具使用」 - 詳細說明可用工具及其使用方法
- 「MCP 服務」 - 介紹 MCP 的作用以及注冊的 MCP
- 「文件編輯」 - 說明文件編輯工具的使用方法
等11個模塊。
weather MCP的定義出現在「MCP服務」部分,所以Cline(本質是背后的LLM)知道何時該調用。
第三步:Cursor是怎么處理mcp的?
有了前兩步的基礎,接下來我們分析Cursor的執(zhí)行流程。
由于Cursor是閉源的,我們只能從側面獲取必要信息。
首先,抓取Cursor Composer模式的請求,分析系統(tǒng)提示詞。整段提示詞主要包括:
- 「核心身份」 - 由 LLM 驅動的代理型 AI 編碼助手,在 Cursor IDE 中與用戶結對編程解決各類編碼任務
- 「通信規(guī)范」 - 以專業(yè)友好的 MD 格式與用戶交流,遵循嚴格的信息披露限制
- 「工具調用」 - 按規(guī)范使用可用工具,提供必要參數,不向用戶直接提及工具名稱
- 「搜索與閱讀」 - 主動收集信息解決不確定問題,盡量避免向用戶尋求幫助
等8個模塊。
整體token消耗只有Cline系統(tǒng)提示詞的 1/10 不到:
雖然沒有明確指明MCP相關內容,但是提到了「工具調用」的規(guī)范。
遵循該規(guī)范繼續(xù)查找,在接口的tools(也就是前面介紹的Tool use)字段中,Cursor定義了不少工具,比如:
- codebase_search: 在代碼庫中查找與查詢語義相關的代碼片段
- read_file: 讀取文件內容與概要,可指定行范圍或讀取整個文件
- run_terminal_cmd: 在用戶系統(tǒng)上提議或執(zhí)行終端命令
- list_dir: 列出目錄內容,用于初步了解文件結構
- grep_search: 基于正則表達式的文本搜索,用于精確查找字符串模式
- edit_file: 提議對現有文件進行編輯,由更簡單的模型應用這些編輯
- file_search: 基于模糊匹配的快速文件路徑搜索
- delete_file: 刪除指定路徑的文件
- reapply: 當編輯結果不符合預期時,調用更智能的模型重新應用上次編輯
- diff_history: 獲取最近文件變更歷史,了解修改內容
Cursor Composer Agent之所以能開發(fā)項目,底層依賴的就是這些工具。
除此之外,所有在Cursor中注冊的MCP也會作為tool出現在這里。
比如,從下圖可知,除weather MCP外,我還注冊了一個Sequential Thinking MCP(通過多步思考過程進行動態(tài)問題分析和解決的工具):
在Cursor發(fā)出的LLM請求中,tools字段下有名為mcp__sequentialthinking的工具:
{
"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"
}
從這里就能發(fā)現問題 —— weather與Sequential Thinking都成功注冊,但請求中并沒有帶上weather相關Tool use。
這就是為什么Cursor有時不能成功調用mcp —— 他沒有將該mcp作為Tool use加入請求中,LLM自然不知道有這么個mcp可以調用。
總結
當前Cursor在MCP服務的注冊上存在bug,導致一些注冊成功的MCP服務不會在請求LLM時作為Tool use被帶上。
這是Cursor不能成功調用MCP的原因。
參考資料
[1]MCP官方文檔: https://modelcontextprotocol.io/introduction。