MCP Research Friend Server

官方

研究工具,包含一個基於 Sqlite 的文件儲存庫

文件

Research Friend

一個友善的輔助工具,專為需要在網路上查詢資料並管理本地研究儲存庫的 AI 助手設計。

Research Friend 是一個 MCP 伺服器,能讓你的 AI 工具具備擷取網頁和搜尋網路的能力。它在背後使用真實的網頁瀏覽器,因此即使是高度依賴 JavaScript 的現代網站也能正常運作。它還包含一個本地的「儲存庫」,用於儲存文件、提取文字,並在你的文件庫中進行搜尋。

若要使用它的所有功能,你需要一個支援提示(常見)和取樣(較少見)的 MCP 用戶端。我們正與 Chabeau 一起開發 Research Friend,它兩者都支援。

它能做什麼?

  • 使用真實瀏覽器擷取網頁(包含大量 JS 的網站)
  • 擷取 PDF 並提取其文字內容
  • 透過 DuckDuckGo 或 Google 搜尋網路
  • 維護本地儲存庫,用於搜尋、列出和提取文件

入門指南

你的電腦上需要安裝 Node.js 第 20 版或更新版本。

1. 安裝相依套件

在此資料夾中開啟終端機並執行:

npm install

2. 安裝瀏覽器支援

Research Friend 使用 Playwright 來控制網頁瀏覽器。安裝相依套件後,你需要安裝瀏覽器:

npx playwright install chromium

這會下載一份 Playwright 將使用的 Chromium 副本。它與你已安裝的任何瀏覽器是分開的。

3. 啟動伺服器

node src/index.js

伺服器透過 stdio(標準輸入/輸出)進行通訊,這也是 MCP 用戶端連接它的方式。

新增到你的 MCP 用戶端

如何新增 Research Friend 取決於你使用的 MCP 用戶端。以下是一個設定可能樣貌的一般範例:

[[mcp_servers]]
id = "research-friend"
command = "node"
args = ["/path/to/mcp-research-friend/src"]
transport = "stdio"

請將 /path/to/mcp-research-friend 替換為你電腦上此資料夾的實際路徑。

工具

網頁工具

friendly_web_fetch

擷取網頁並回傳其內容。預設情況下,回傳保留連結的 Markdown 格式——非常適合 LLM。使用 Readability 來提取主要內容(移除導覽列、廣告等)。對於 PDF、分頁或搜尋內容,請改用 friendly_web_extract

參數:

  • url(必要)- 要擷取的網址
  • outputFormat - 輸出格式:markdown(預設)、texthtml
  • waitMs - 頁面載入後額外的等待時間,以防內容出現較慢
  • timeoutMs - 放棄前的等待時間(預設:15 秒)
  • maxChars - 回傳的最大內容量(預設:40,000 個字元)
  • includeHtml - 設為 true 可同時回傳原始 HTML 與內容
  • headless - 設為 false 可查看瀏覽器視窗(用於除錯時很有用)

回傳:

  • url - 請求的網址
  • finalUrl - 任何重新導向後的網址
  • title - 頁面標題
  • content - 提取的內容(以請求的格式)
  • html - 原始 HTML(僅當 includeHtml 為 true 時)
  • meta - 頁面中繼資料(描述、作者、發布時間等)
  • fetchedAt - 擷取頁面時的 ISO 時間戳記
  • truncated - 內容是否因符合 maxChars 而被截斷

friendly_search

搜尋網路並回傳結果列表。

參數:

  • query(必要)- 要搜尋的內容
  • engine - 要使用的搜尋引擎(duckduckgogoogle
  • maxResults - 要回傳的結果數量(預設:10,最大:50)
  • timeoutMs - 放棄前的等待時間(預設:15 秒)
  • headless - 設為 false 可查看瀏覽器視窗

回傳:

  • query - 使用的搜尋查詢
  • engine - 使用了哪個搜尋引擎
  • results - 結果陣列,每個結果包含 titleurlsnippet
  • searchedAt - 執行搜尋時的 ISO 時間戳記
  • fallback_result_html - 頁面的原始 HTML(僅在找不到結果時包含)
  • debug_info - 關於搜尋嘗試的診斷資訊

CAPTCHA 處理: 如果在無頭模式下偵測到 CAPTCHA,工具會自動以可見的瀏覽器視窗重試。這讓你有機會手動解決 CAPTCHA。debug_info.retried 欄位會指出是否使用了此回退機制。

friendly_web_extract

從網址提取內容。自動偵測網址指向的是 PDF 還是網頁,並分別進行適當處理。

參數:

  • url(必要)- 要擷取的網址(PDF 或網頁)
  • maxChars - 回傳的最大文字量(預設:40,000 個字元)
  • offset - 起始的字元位置(預設:0)。使用此參數來對大型內容進行分頁。
  • search - 搜尋片語並回傳包含前後文的匹配項,而非完整內容
  • contextChars - 每個搜尋匹配項周圍的前後文字元數(預設:200)
  • waitMs - 頁面載入後等待動態內容的額外時間(僅限網頁)
  • timeoutMs - 放棄前的等待時間(預設:15 秒,僅限網頁)
  • headless - 設為 false 可查看瀏覽器視窗(僅限網頁)

回傳(一般模式):

  • url - 請求的網址
  • contentType - 可能是 pdfhtml
  • title - 頁面/文件標題
  • author - PDF 作者(僅限 PDF,若有提供)
  • creationDate - PDF 建立時間(僅限 PDF,若有提供)
  • pageCount - 頁數(僅限 PDF)
  • totalChars - 總字元數(與 offset 搭配使用以進行分頁)
  • offset - 使用的偏移量
  • content - 提取的文字內容
  • fetchedAt - ISO 時間戳記
  • truncated - 此區塊之後是否還有更多內容

回傳(搜尋模式):

  • urlcontentTypetitletotalCharsfetchedAt - 與上述相同
  • search - 使用的搜尋片語
  • matchCount - 找到的匹配項數量
  • matches - 匹配項陣列,每個包含 positioncontextprefixsuffix

friendly_web_ask

擷取網址(PDF 或網頁)並讓 LLM 回答相關問題。自動偵測內容類型。文件在獨立的上下文中處理,保持你的主要對話精簡。

參數:

  • url(必要)- 要擷取的網址(PDF 或網頁)
  • ask(必要)- 給 LLM 的問題或指令(摘要、提取資訊、回答問題等)
  • askMaxInputTokens - 每次 LLM 呼叫的最大輸入 token 數(預設:150,000)
  • askMaxOutputTokens - 每次 LLM 呼叫的最大輸出 token 數(預設:4,096)
  • askTimeout - 逾時時間,以毫秒為單位(預設:300,000 = 5 分鐘)
  • askSplitAndSynthesize - 對於大型文件:分割成區塊,分別處理,然後綜合結果(預設:false)。警告:會消耗大量 token。
  • waitMs - 頁面載入後等待動態內容的額外時間(僅限網頁)
  • timeoutMs - 放棄前的等待時間(預設:15 秒,僅限網頁)
  • headless - 設為 false 可查看瀏覽器視窗(僅限網頁)

回傳:

  • url - 請求的網址
  • contentType - 可能是 pdfhtml
  • title - 頁面/文件標題
  • totalChars - 文件中的總字元數
  • ask - 給予的指令
  • answer - LLM 的回應
  • model - 產生回應的模型
  • chunksProcessed - 處理的區塊數(小型文件為 1,使用 askSplitAndSynthesize 時會更多)
  • fetchedAt - ISO 時間戳記

提問模式 使用 MCP 取樣讓 LLM 以任何指令處理文件。這對於以下情況很有用:

  • 會超出上下文限制的大型文件
  • 降低主要對話的 token 成本

askSplitAndSynthesize 啟用時,超過 askMaxInputTokens 的文件會自動分割成重疊的區塊。每個區塊單獨處理,然後將結果綜合成一個連貫的答案。最終回應會以與你請求相同的語言提供,無論文件的語言為何。

文件儲存庫

儲存庫是一個本地的、可搜尋的文件庫。它支援 PDF、HTML 檔案和純文字(Markdown/TXT)。當你新增文件時,Research Friend 會儲存原始檔案、提取文字(針對 PDF/HTML),並將中繼資料儲存在本地資料庫中。搜尋在底層使用 ripgrep,以實現快速、可識別片語的匹配。

儲存庫位置

儲存庫位於 ~/.research-friend/ 之下:

  • inbox/ - 將檔案拖放到此處以進行處理
  • store/ - 有組織的文件儲存和提取的文字
  • stash.db - 中繼資料資料庫

支援的檔案類型

  • PDF:.pdf(文字已提取)
  • HTML:.html.htm(文字已提取)
  • Markdown:.md.markdown(以純文字儲存)
  • 文字:.txt(以純文字儲存)

儲存庫工具

stash_open_inbox

在你的檔案管理器中開啟儲存庫收件匣資料夾,以便更輕鬆地拖放檔案。

回傳:

  • opened - 是否已傳送資料夾開啟請求
  • inboxPath - 收件匣的絕對路徑
  • command - 使用的作業系統指令
  • args - 使用的指令參數

stash_process_inbox

處理 inbox/ 中的檔案,將其分類到主題中,提取文字,並儲存結果。 對於長文件,分類會使用取樣的部分(開頭/中間/結尾加上一些隨機區塊)來提高主題準確性。

回傳:

  • processed - 成功處理的檔案名稱陣列
  • errors - 遇到的任何錯誤
  • documents - 建立的文件記錄陣列

reindex_stash

為儲存的文件重新產生摘要、重新分配主題,並更新儲存庫中繼資料。如果省略 ids 或為空,則會重新索引所有文件。

參數:

  • ids - 要重新索引的文件 ID(選用)

回傳:

  • reindexed - 已重新索引的文件 ID
  • errors - 遇到的任何錯誤
  • documents - 更新的文件記錄陣列

stash_list

列出儲存庫中的文件。

參數:

  • topic - 篩選特定主題(選用)
  • limit - 最大結果數(預設:50)
  • offset - 分頁偏移量(預設:0)

回傳:

  • type - alltopic
  • totalDocuments - 文件總數(僅當 typeall 時)
  • count - 分頁後回傳的結果
  • offset - 使用的分頁偏移量
  • limit - 使用的分頁限制
  • topics - 已知主題及其文件數量的摘要
  • documents - 包含中繼資料的文件列表(列出主題時包含 isPrimary

stash_search

在整個儲存庫中搜尋檔案名稱和內容。所有搜尋詞彙都必須存在(AND 邏輯)。檔案名稱匹配項會優先列出。使用引號來進行精確片語搜尋。

參數:

  • query(必要)- 搜尋詞彙。使用引號來指定片語:"sparkling wine"
  • topic - 篩選特定主題(選用)
  • ids - 篩選特定的文件 ID(選用)
  • limit - 要回傳的最大文件數(預設:20)
  • offset - 分頁偏移量(預設:0)
  • maxMatchesPerDoc - 每個文件的最大匹配項數(預設:50)
  • context - 每個匹配項周圍的上下文行數(預設:1,最大:5)。控制詞彙必須多接近才能視為匹配,以及回傳多少周圍的文字。 回傳值:
  • totalMatches - 分頁前符合條件的文件總數
  • count - 分頁後回傳的結果
  • results - 文件陣列,每份文件包含:
    • idfilenamefileTypesummarycharCountcreatedAt
    • matchType - filenamecontentfilename+content
    • matches - 每個符合位置的 { line, context } 陣列

使用 line 值搭配 stash_extract 可直接跳轉到符合的位置。

stash_extract

從已暫存的文件中提取內容以供閱讀。使用 stash_search 結果中的行號直接跳轉到符合的位置。

參數:

  • id(必要)- 來自 stash_list/stash_search 的文件 ID
  • maxChars - 回傳的最大文字量(預設:40,000 個字元)
  • offset - 起始的字元位置(與 line 互斥)
  • line - 起始的行號(與 offset 互斥)

回傳值:

  • idfilenamefileTypesummary - 文件中繼資料
  • totalChars - 文件中的總字元數
  • offset - 字元偏移量(使用 line 作為參考時會包含)
  • line - 行號(僅在使用 line 參數時)
  • content - 提取的文字內容
  • truncated - 此區塊之後是否還有更多內容

stash_ask

讓 LLM 回答關於已暫存文件的問題。文件會在獨立的上下文中處理,讓您的主要對話保持精簡。

參數:

  • id(必要)- 來自 stash_list/stash_search 的文件 ID
  • ask(必要)- 給 LLM 的問題或指示
  • askMaxInputTokens - 每次 LLM 呼叫的最大輸入 token 數(預設:150,000)
  • askMaxOutputTokens - 每次 LLM 呼叫的最大輸出 token 數(預設:4,096)
  • askTimeout - 逾時時間,以毫秒為單位(預設:300,000 = 5 分鐘)
  • askSplitAndSynthesize - 針對大型文件:分割成多個區塊,分別處理後再綜合結果(預設:false)

回傳值:

  • idfilenamefileTypesummary - 文件中繼資料
  • totalChars - 文件中的總字元數
  • ask - 所給予的指示
  • answer - LLM 的回應
  • model - 產生回應的模型
  • chunksProcessed - 處理的區塊數量

典型流程

  1. 將檔案放入 ~/.research-friend/inbox/
  2. 執行 stash_process_inbox
  3. 使用 stash_list 瀏覽主題
  4. 使用 stash_search 尋找相關文件
  5. 使用 stash_extract 閱讀特定文件,或使用 stash_ask 對其提問

疑難排解

「瀏覽器意外關閉」或類似錯誤

請嘗試重新安裝瀏覽器:

npx playwright install chromium --force

在 Linux 上,您可能還需要系統相依套件:

npx playwright install-deps chromium

伺服器無法啟動

請確認您使用的是 Node.js 20 或更新版本:

node --version

如果您的版本較舊,請前往 nodejs.org 下載較新版本。

授權

MIT