🚀 LLM Researcher
LLM Researcher 是一款輕量級的 MCP(模型上下文協議)服務器,專為大語言模型編排設計,具備高效的網頁內容搜索與提取能力。藉助這款 CLI 工具,大語言模型可在 DuckDuckGo 上進行搜索,並從網頁中提取簡潔、適配大語言模型的內容。
項目採用 TypeScript、tsup 和 vitest 構建,帶來現代化的開發體驗。
✨ 主要特性
- 支持 MCP 服務器:提供模型上下文協議服務器,便於與大語言模型集成。
- 免費使用:使用 DuckDuckGo 的 HTML 端點,無需支付 API 費用。
- GitHub 代碼搜索:可在 GitHub 倉庫中搜索代碼示例和實現模式。
- 智能內容提取:結合 Playwright 和 @mozilla/readability,提取簡潔內容。
- 適配大語言模型的輸出:輸出經過淨化處理的 Markdown 格式(僅包含 h1 - h3、粗體、斜體和鏈接)。
- 速率限制:遵循 DuckDuckGo 的速率限制,每秒僅發起 1 次請求。
- 跨平臺支持:可在 macOS、Linux 和 WSL 上運行。
- 多種模式:提供 CLI、MCP 服務器、搜索、直接 URL 和交互模式。
- 類型安全:完全採用 TypeScript 實現,具備嚴格的類型檢查。
- 現代化工具:使用 tsup 打包工具和 vitest 測試框架。
📦 安裝指南
前提條件
- Node.js 20.0.0 或更高版本。
- 無需本地安裝 Chrome,使用 Playwright 自帶的 Chromium 瀏覽器。
安裝步驟
cd light-research-mcp
pnpm install
pnpm build
pnpm install-browsers
pnpm link --global
💻 使用示例
MCP 服務器模式
作為模型上下文協議服務器,為大語言模型提供搜索和內容提取工具:
llmresearcher --mcp
與 Claude Code 集成
claude mcp add light-research-mcp /path/to/light-research-mcp/dist/bin/llmresearcher.js --mcp
claude mcp add light-research-mcp -s project /path/to/light-research-mcp/dist/bin/llmresearcher.js --mcp
claude mcp list
claude mcp get light-research-mcp
MCP 工具使用示例
配置完成後,可在 Claude 中使用這些工具:
> 在 GitHub 上搜索 React 鉤子示例
Tool: github_code_search
Query: "useState useEffect hooks language:javascript"
> 搜索 TypeScript 最佳實踐
Tool: duckduckgo_web_search
Query: "TypeScript best practices 2024"
Locale: us-en (或 wt-wt 表示無區域限制)
> 從搜索結果中提取內容
Tool: extract_content
URL: https://example.com/article-from-search-results
命令行界面
llmresearcher "machine learning transformers"
llmresearcher -g "useState hooks language:typescript"
llmresearcher -u https://example.com/article
llmresearcher
llmresearcher -v "search query"
llmresearcher --mcp
📚 詳細文檔
開發腳本
pnpm build
pnpm dev
pnpm test
pnpm test:run
pnpm test -- --coverage
pnpm type-check
pnpm clean
pnpm install-browsers
交互式命令
在搜索結果視圖中:
- 1 - 10:通過編號選擇結果。
- b 或 back:返回搜索結果。
- open <n>:在外部瀏覽器中打開第 n 個結果。
- q 或 quit:退出程序。
在查看內容時:
- b 或 back:返回搜索結果。
- /<term>:在提取的內容中搜索指定術語。
- open:在外部瀏覽器中打開當前頁面。
- q 或 quit:退出程序。
配置
環境變量
在項目根目錄下創建 .env 文件:
USER_AGENT=Mozilla/5.0 (compatible; LLMResearcher/1.0)
TIMEOUT=30000
MAX_RETRIES=3
RATE_LIMIT_DELAY=1000
CACHE_ENABLED=true
MAX_RESULTS=10
配置文件
在主目錄下創建 ~/.llmresearcherrc 文件:
{
"userAgent": "Mozilla/5.0 (compatible; LLMResearcher/1.0)",
"timeout": 30000,
"maxRetries": 3,
"rateLimitDelay": 1000,
"cacheEnabled": true,
"maxResults": 10
}
配置選項
| 選項 |
默認值 |
描述 |
userAgent |
Mozilla/5.0 (compatible; LLMResearcher/1.0) |
HTTP 請求的用戶代理 |
timeout |
30000 |
請求超時時間(毫秒) |
maxRetries |
3 |
失敗請求的最大重試次數 |
rateLimitDelay |
1000 |
請求間隔時間(毫秒) |
cacheEnabled |
true |
啟用/禁用本地緩存 |
maxResults |
10 |
顯示的最大搜索結果數 |
架構
核心組件
- MCPResearchServer (
src/mcp-server.ts)
- 模型上下文協議服務器的實現。
- 提供三個主要工具:github_code_search、duckduckgo_web_search、extract_content。
- 以 JSON 格式響應,便於大語言模型使用。
- DuckDuckGoSearcher (
src/search.ts)
- 支持按地區對 DuckDuckGo 搜索結果進行 HTML 抓取。
- 對
/l/?uddg= 格式的鏈接進行 URL 解碼。
- 實現速率限制和重試邏輯。
- GitHubCodeSearcher (
src/github-code-search.ts)
- 通過 gh CLI 集成 GitHub 代碼搜索 API。
- 支持使用語言、倉庫和文件過濾器進行高級查詢。
- 實現身份驗證和速率限制。
- ContentExtractor (
src/extractor.ts)
- 使用 Playwright 渲染頁面並阻止資源加載。
- 使用 @mozilla/readability 提取主要內容。
- 使用 DOMPurify 進行內容淨化和 Markdown 轉換。
- CLIInterface (
src/cli.ts)
- 提供交互式命令行界面。
- 支持搜索結果導航。
- 支持內容查看和文本搜索。
- Configuration (
src/config.ts)
- 加載環境變量和 RC 文件配置。
- 支持詳細日誌記錄。
內容處理流程
MCP 服務器模式
- 搜索:
- DuckDuckGo:通過 HTML 端點獲取結果 → 解析結果 → 以 JSON 格式響應並支持分頁。
- GitHub:使用代碼搜索 API → 格式化結果 → 以 JSON 格式響應幷包含代碼片段。
- 提取:從搜索結果中獲取 URL → 使用 Playwright 導航到頁面 → 提取內容。
- 處理:使用 @mozilla/readability 提取內容 → 使用 DOMPurify 淨化內容 → 輸出乾淨的 JSON。
- 輸出:以結構化 JSON 格式輸出,供大語言模型使用。
CLI 模式
- 搜索:通過 DuckDuckGo HTML 端點獲取結果 → 解析結果 → 顯示編號列表。
- 提取:使用 Playwright 導航到頁面 → 阻止資源加載 → 進行 JS 渲染。
- 處理:使用 @mozilla/readability 提取內容 → 使用 DOMPurify 淨化內容 → 轉換為 Turndown Markdown。
- 輸出:輸出乾淨的 Markdown 格式,僅包含 h1 - h3、粗體、斜體 和 鏈接。
安全特性
- 資源阻止:為提高速度和安全性,阻止加載圖像、CSS 和字體。
- 內容淨化:使用 DOMPurify 移除腳本、iframe 和危險元素。
- 受限 Markdown:僅允許安全的格式化元素(h1 - h3、strong、em、a)。
- 速率限制:遵循 DuckDuckGo 的速率限制,採用指數退避策略進行重試。
示例
MCP 服務器與 Claude Code 結合使用
1. GitHub 代碼搜索
你: "查找用於狀態管理的 React 鉤子示例"
Claude 使用 github_code_search 工具:
{
"query": "useState useReducer state management language:javascript",
"results": [
{
"title": "facebook/react/packages/react/src/ReactHooks.js",
"url": "https://raw.githubusercontent.com/facebook/react/main/packages/react/src/ReactHooks.js",
"snippet": "function useState(initialState) {\n return dispatcher.useState(initialState);\n}"
}
],
"pagination": {
"currentPage": 1,
"hasNextPage": true,
"nextPageToken": "2"
}
}
2. 帶地區設置的網頁搜索
你: "搜索日語的 Vue.js 教程"
Claude 使用 duckduckgo_web_search 工具:
{
"query": "Vue.js チュートリアル 入門",
"locale": "jp-jp",
"results": [
{
"title": "Vue.js入門ガイド",
"url": "https://example.com/vue-tutorial",
"snippet": "Vue.jsの基本的な使い方を學ぶチュートリアル..."
}
]
}
3. 內容提取
你: "從那個 Vue.js 教程中提取完整內容"
Claude 使用 extract_content 工具:
{
"url": "https://example.com/vue-tutorial",
"title": "Vue.js入門ガイド",
"extractedAt": "2024-01-15T10:30:00.000Z",
"content": "# Vue.js入門ガイド\n\nVue.jsは...\n\n## インストール\n\n..."
}
CLI 示例
基本搜索
$ llmresearcher "python web scraping"
🔍 搜索結果:
══════════════════════════════════════════════════
1. Python Web Scraping Tutorial
URL: https://realpython.com/python-web-scraping-practical-introduction/
完整的使用 Python 和 requests、Beautiful Soup 進行網頁抓取的教程...
2. Web Scraping with Python - BeautifulSoup and requests
URL: https://www.dataquest.io/blog/web-scraping-python-tutorial/
學習如何使用 Python、Beautiful Soup 和 requests 進行網頁抓取...
══════════════════════════════════════════════════
命令: [1-10] 選擇結果 | b) 返回 | q) 退出 | open <n>) 在瀏覽器中打開
> 1
📥 正在從 "Python Web Scraping Tutorial" 提取內容
📄 內容:
══════════════════════════════════════════════════
**Python Web Scraping Tutorial**
來源: https://realpython.com/python-web-scraping-practical-introduction/
提取時間: 2024-01-15T10:30:00.000Z
──────────────────────────────────────────────────
網頁抓取是從網頁收集和解析原始數據的過程...
網頁抓取是一種自動訪問和提取大量網頁數據的技術...
══════════════════════════════════════════════════
命令: b) 返回結果 | /<term>) 在文本中搜索 | q) 退出 | open) 在瀏覽器中打開
> /beautiful soup
🔍 找到 3 個與 "beautiful soup" 匹配的結果:
──────────────────────────────────────────────────
第 15 行: Beautiful Soup is a Python library for parsing HTML and XML documents.
第 42 行: from bs4 import BeautifulSoup
第 67 行: soup = BeautifulSoup(html_content, 'html.parser')
直接 URL 模式
$ llmresearcher -u https://docs.python.org/3/tutorial/
📄 內容:
══════════════════════════════════════════════════
**The Python Tutorial**
來源: https://docs.python.org/3/tutorial/
提取時間: 2024-01-15T10:35:00.000Z
──────────────────────────────────────────────────
Python 是一種易於學習、功能強大的編程語言...
在以下示例中,輸入和輸出是有區別的...
詳細日誌模式
$ llmresearcher -v "nodejs tutorial"
[詳細信息] 正在搜索: https://duckduckgo.com/html/?q=nodejs%20tutorial&kl=us-en
[詳細信息] 響應狀態碼: 200,耗時 847ms
[詳細信息] 解析了 10 個結果
[詳細信息] 正在啟動瀏覽器...
[詳細信息] 阻止資源: https://example.com/style.css
[詳細信息] 阻止資源: https://example.com/image.png
[詳細信息] 正在導航到頁面...
[詳細信息] 頁面加載完成,耗時 1243ms
[詳細信息] 正在使用 Readability 處理內容...
[詳細信息] Readability 提取成功
[詳細信息] 正在關閉瀏覽器...
測試
運行測試
pnpm test
pnpm test:run
pnpm test -- --coverage
測試覆蓋率
測試套件包括:
- 單元測試:對單個組件進行測試。
search.test.ts:測試 DuckDuckGo 搜索功能、URL 解碼和速率限制。
extractor.test.ts:測試內容提取、Markdown 轉換和資源管理。
config.test.ts:測試配置驗證和環境處理。
- 集成測試:進行端到端的工作流測試。
integration.test.ts:測試完整的搜索到提取工作流、錯誤處理和清理操作。
測試特性
- 快速:由 vitest 提供支持,可快速獲得反饋。
- 類型安全:測試代碼完全支持 TypeScript。
- 隔離性:每個測試會清理其使用的資源。
- 全面性:覆蓋搜索、提取、配置和集成等場景。
故障排除
常見問題
“未找到瀏覽器” 錯誤
pnpm install-browsers
速率限制問題
- 工具會自動處理速率限制,每次請求間隔 1 秒。
- 若遇到 429 錯誤,工具會自動使用指數退避策略進行重試。
內容提取失敗
- 部分網站可能會阻止自動化訪問。
- 工具包含備用提取方法(優先提取主內容,若失敗則提取 body 內容)。
- 使用詳細日誌模式 (
-v) 查看詳細錯誤信息。
權限拒絕(Unix/Linux)
chmod +x bin/llmresearcher.js
性能優化
該工具針對速度進行了優化:
- 資源阻止:自動阻止加載圖像、CSS 和字體。
- 網絡空閒檢測:等待 JavaScript 渲染完成。
- 內容緩存:支持本地緩存,避免重複請求。
- 依賴精簡:使用輕量級、專注的庫。
開發
項目結構
light-research-mcp/
├── dist/ # 構建生成的 JavaScript 文件
│ ├── bin/
│ │ └── llmresearcher.js # CLI 入口點(可執行文件)
│ └── *.js # 編譯後的 TypeScript 模塊
├── src/ # TypeScript 源代碼文件
│ ├── bin.ts # CLI 入口點
│ ├── index.ts # 主要的 LLMResearcher 類
│ ├── mcp-server.ts # MCP 服務器實現
│ ├── search.ts # DuckDuckGo 搜索實現
│ ├── github-code-search.ts # GitHub 代碼搜索實現
│ ├── extractor.ts # 使用 Playwright 進行內容提取
│ ├── cli.ts # 交互式 CLI 界面
│ ├── config.ts # 配置管理
│ └── types.ts # TypeScript 類型定義
├── test/ # 測試文件(使用 vitest)
│ ├── search.test.ts # 搜索功能測試
│ ├── extractor.test.ts # 內容提取測試
│ ├── config.test.ts # 配置測試
│ ├── mcp-locale.test.ts # MCP 地區功能測試
│ ├── mcp-content-extractor.test.ts # MCP 內容提取器測試
│ └── integration.test.ts # 端到端集成測試
├── tsconfig.json # TypeScript 配置文件
├── tsup.config.ts # 構建配置文件
├── vitest.config.ts # 測試配置文件
├── package.json
└── README.md
依賴項
運行時依賴
- @modelcontextprotocol/sdk:模型上下文協議服務器實現。
- @mozilla/readability:從 HTML 中提取內容。
- cheerio:用於解析搜索結果的 HTML。
- commander:CLI 參數解析。
- dompurify:HTML 淨化。
- dotenv:加載環境變量。
- jsdom:用於服務器端處理的 DOM 操作。
- playwright:用於瀏覽器自動化和 JS 渲染。
- turndown:將 HTML 轉換為 Markdown。
開發依賴
- typescript:TypeScript 編譯器。
- tsup:快速的 TypeScript 打包工具。
- vitest:快速的單元測試框架。
- @types/*:TypeScript 類型定義。
📄 許可證
本項目採用 MIT 許可證,詳情請查看 LICENSE 文件。
貢獻指南
- Fork 倉庫。
- 創建功能分支。
- 進行修改。
- 如有必要,添加測試。
- 提交拉取請求。
路線圖
計劃功能
- 增強 MCP 工具:添加用於文檔、API 等的專業搜索工具。
- 緩存層:基於 SQLite 實現 URL 到 Markdown 的緩存,緩存有效期為 24 小時。
- 搜索引擎抽象:支持 Brave Search、Bing 等其他搜索引擎。
- 內容摘要:提供可選的 AI 驅動的內容摘要功能。
- 導出格式:支持 JSON、純文本等輸出格式。
- 批量處理:支持從文件輸入處理多個 URL。
- SSE 傳輸:支持服務器發送事件(Server-Sent Events)的 MCP 傳輸。
性能改進
- 並行處理:對多個結果進行併發內容提取。
- 智能緩存:根據內容新鮮度智能使緩存失效。
- 內存優化:對大文檔採用流式內容處理。