您的程式碼代理在搜尋儲存庫中的內容時表現非常好,只要這些內容是文字。若向 Claude Code 或 Cursor 詢問感測器資料表上關於操作溫度的說明,它會使用 grep,結果什麼也找不到,然後要麼猜測要麼放棄,因為資料表是 PDF,而決策紀錄是 Word 檔。GroupDocs.Search.Mcp 在 Docker 本機執行,為代理提供這些文件的全文索引,使用與程式碼相同的「搜尋‑然後‑讀取」迴圈:

索引 docs 資料夾,然後告訴我感測器資料表上關於操作溫度的說明,以及是哪一份 ADR 決定了遙測儲存。

步驟說明(含設定與除錯)請參考文件:How to let Claude Code or Cursor search the PDFs and Word documents in a repository.

為什麼 grep 會回傳空結果?

因為 PDF 與 DOCX 並未以純文字儲存其單字。DOCX 是 zip 壓縮檔;PDF 則壓縮其文字串流。若逐位元搜尋,文字根本不存在。我們在一個小型儲存庫中測試過:一份 PDF 資料表、一份架構決策紀錄與一份 DOCX 需求文件,以及一個原始碼檔。

$ grep -ri "TimescaleDB\|operating temperature\|I2C" docs/
$ grep -rn "datasheet" src/
src/sensor.py:1:MAX_TEMP_C = 85  # see docs/datasheet

唯一的命中是一行指向文件的程式碼註解,代理無法讀取。這就是缺口:常數背後的原因、設計背後的決策、測試背後的需求,往往正好存在於這些檔案中。

建立索引後會有什麼變化?

代理取得了文件的檢索工具。從儲存庫根目錄註冊伺服器,讓儲存庫被掛載為 storage 資料夾:

claude mcp add groupdocs-search -- docker run --rm -i \
  -v "$(pwd)":/data ghcr.io/groupdocs-search/search-net-mcp:latest

之後相同的問題就能得到答案。以下是我們在測試儲存庫中伺服器回傳的結果(路徑相對於儲存庫根目錄):

-> add_to_index {"documentsPath":"docs","indexName":"gateway"}
<- Indexed 'docs' into index 'gateway': 3 document(s) added,
   3 in the index.

-> search {"query":"TimescaleDB","indexName":"gateway"}
<- documentsFound 1: docs/adr-007-telemetry-storage.docx

-> get_text_fragments {"query":"I2C","indexName":"gateway"}
<- === docs/requirements-v2.docx (1 occurrence(s)) ===
     …REQ-15: the I2C bus runs at 400 kHz.…
   === docs/tmp117-sensor-datasheet.pdf (1 occurrence(s)) ===
     …I2C address selection: ADD0 pin to GND gives 0x48…

一次查詢同時找到了需求與資料表的行,這類交叉參照若手動執行非常繁瑣,且 grep 完全做不到。在我們的小型索引中,首次呼叫後的搜尋耗時 80 到 240 毫秒。

代理已熟悉的迴圈

user              agent                         Search MCP server
 |  "What does the datasheet say about I2C addresses?"         |
 |---------------->|                                           |
 |                 |-- search {"query":"I2C"} --------------->|
 |                 |<- requirements-v2.docx,                   |
 |                 |   tmp117-sensor-datasheet.pdf ------------|
 |                 |-- get_text_fragments {"query":"I2C"} --->|
 |                 |<- "...ADD0 pin to GND gives 0x48..." -----|
 |<- "0x48 with ADD0 to GND, 0x49 to V+ (datasheet, p.1);      |
 |    REQ-15 runs the bus at 400 kHz."                         |

search 回傳哪些檔案,get_text_fragments 回傳匹配行以及少量上下文,代理會同時引用兩者。這是 grep 的形態,只是擴展到 82 種格式:PDF、DOCX、XLSX、PPTX、HTML、Markdown,甚至是有人匯入儲存庫的電子郵件串。

告訴代理何時使用它

代理會遵循專案指示,決定何時使用工具。CLAUDE.md 或 AGENTS.md 中的三行文字即可讓代理從嘗試 grep、失敗放棄,轉變為先搜尋索引:

PDF, DOCX and XLSX files under docs/ are indexed in the groupdocs-search MCP index
'docs'. grep cannot read them: use search (quote phrases) and get_text_fragments
for anything in specs, datasheets or ADRs, and cite the file.
Run update_index (indexName: docs) after pulling changes.

兩個維護要點。索引寫入掛載資料夾根目錄下的 .groupdocs-search-index/,因此請將其加入 .gitignore。拉取更新後,update_index 只會重新讀取變更的部分,保持索引即時只需一次呼叫。

Cursor 與 VS Code

相同的容器可在任何 MCP 用戶端使用。在 VS Code 中,工作區的 .vscode/mcp.json 可以掛載當前開啟的資料夾,讓索引隨專案移動:

{
  "servers": {
    "groupdocs-search": {
      "type": "stdio",
      "command": "docker",
      "args": [ "run", "--rm", "-i",
                "-v", "${workspaceFolder}:/data",
                "ghcr.io/groupdocs-search/search-net-mcp:latest" ]
    }
  }
}

Cursor 也在 .cursor/mcp.json 的 mcpServers 中使用相同的 command 與 args。將設定檔提交後,專案中的每位開發者都能取得此工具;請將索引本身排除在 git 之外。

為什麼不先把所有檔案轉成文字?

可以這麼做:讓代理在需要時逐一轉換 PDF,或檢查儲存庫中的 Markdown 副本。對少量檔案而言這兩種方式皆可行。索引則只會在第一次轉換,之後只需一次呼叫即可保持最新,並在代理讀取任何檔案之前就告訴哪個檔案重要,這一步能大幅縮減長對話的上下文。背後的引擎是 GroupDocs.Search,它直接讀取 Office 與 PDF 文件,而不需要您自行維護轉換器。

誠實的限制

  • 評估模式下,索引最多容納 100 份文件,搜尋最多回傳 10 筆結果;請先呼叫 get_license_status。
  • 全文檢索,而非語意搜尋:代理必須使用文件中的原始用詞,或自行嘗試變形。
  • 不支援 OCR:掃描的資料表若沒有文字層,僅會以檔案屬性建立索引。
  • 僅支援 Docker。於 Linux 上執行時,加入 --user "$(id -u):$(id -g)",讓容器能寫入您擁有的儲存庫。

FAQ

Claude Code 能讀取我儲存庫中的 PDF 檔嗎?
不能使用 grep。使用 GroupDocs.Search MCP 伺服器即可在本機搜尋並引用 PDF,無需先轉換。

在 Cursor 與 VS Code 也能使用嗎?
可以。於 .cursor/mcp.json 或 .vscode/mcp.json 中使用相同的 docker run 參數;VS Code 甚至可以掛載 ${workspaceFolder}。

索引會不會被提交到我的 commit 中?
只有您允許時才會。請將 .groupdocs-search-index/ 加入 .gitignore。

深入了解