🚀 LLM Researcher
LLM Researcherは、LLMオーケストレーション用の軽量MCP(Model Context Protocol)サーバーです。効率的なウェブコンテンツの検索と抽出機能を提供し、CLIツールを通じてLLMがDuckDuckGoを検索し、ウェブページからLLMに適したクリーンなコンテンツを抽出できるようになります。
このプロジェクトは、TypeScript、tsup、vitestを用いて構築されており、最新の開発体験を提供します。
✨ 主な機能
- MCPサーバーサポート:LLMとの統合に必要なModel Context Protocolサーバーを提供します。
- 無料運用:DuckDuckGoのHTMLエンドポイントを使用するため、APIコストが発生しません。
- GitHubコード検索:GitHubリポジトリからコード例や実装パターンを検索できます。
- スマートコンテンツ抽出:Playwrightと@mozilla/readabilityを使用してクリーンなコンテンツを抽出します。
- LLM最適化出力:クリーンなMarkdown形式(h1 - h3、太字、斜体、リンクのみ)で出力されます。
- レート制限:DuckDuckGoの制限に従い、1秒あたり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サーバーモード
Model Context Protocolサーバーとして使用し、LLMに検索とコンテンツ抽出ツールを提供します。
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で地域指定なし)
> 検索結果のURLからコンテンツを抽出
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 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)
- Model Context Protocolサーバーの実装
- 3つの主要ツール:github_code_search、duckduckgo_web_search、extract_content
- LLMが消費できるJSONベースのレスポンス
-
DuckDuckGoSearcher (src/search.ts)
- ロケールをサポートしたDuckDuckGo検索結果のHTMLスクレイピング
/l/?uddg= 形式のリンクのURLデコード
- レート制限とリトライロジック
-
GitHubCodeSearcher (src/github-code-search.ts)
- gh CLIを介したGitHub Code Search APIの統合
- 言語、リポジトリ、ファイルフィルターを持つ高度なクエリサポート
- 認証とレート制限
-
ContentExtractor (src/extractor.ts)
- リソースブロッキングを持つPlaywrightベースのページレンダリング
- @mozilla/readabilityによるメインコンテンツの抽出
- DOMPurifyによるサニタイズとMarkdown変換
-
CLIInterface (src/cli.ts)
- インタラクティブなコマンドラインインターフェイス
- 検索結果のナビゲーション
- コンテンツの閲覧とテキスト検索
-
Configuration (src/config.ts)
- 環境とRCファイルの設定読み込み
- 詳細ログのサポート
コンテンツ処理パイプライン
MCPサーバーモード
- 検索:
- DuckDuckGo: HTMLエンドポイント → 結果の解析 → ページネーション付きのJSONレスポンス
- GitHub: Code Search API → 結果の整形 → コードスニペット付きのJSONレスポンス
- 抽出:検索結果のURL → Playwrightナビゲーション → コンテンツの抽出
- 処理:@mozilla/readability → DOMPurifyによるサニタイズ → クリーンなJSON出力
- 出力:LLMが消費できる構造化されたJSON
CLIモード
- 検索:DuckDuckGo HTMLエンドポイント → 結果の解析 → 番号付きリストの表示
- 抽出:Playwrightナビゲーション → リソースブロッキング → JSレンダリング
- 処理:@mozilla/readability → DOMPurifyによるサニタイズ → TurndownによるMarkdown変換
- 出力:h1 - h3、太字、斜体、リンクのみのクリーンなMarkdown
セキュリティ機能
- リソースブロッキング:画像、CSS、フォントの読み込みを防止し、速度とセキュリティを向上させます。
- コンテンツサニタイズ:DOMPurifyによりスクリプト、iframe、危険な要素を削除します。
- 制限付きMarkdown:安全なフォーマット要素(h1 - h3、strong、em、a)のみを許可します。
- レート制限:DuckDuckGoのレート制限に従い、指数バックオフで自動的にリトライします。
例
MCPサーバーをClaude Codeで使用する例
1. GitHubコード検索
You: "Find React hook examples for state management"
Claude uses github_code_search tool:
{
"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. ロケール付きのウェブ検索
You: "Search for Vue.js tutorials in Japanese"
Claude uses duckduckgo_web_search tool:
{
"query": "Vue.js チュートリアル 入門",
"locale": "jp-jp",
"results": [
{
"title": "Vue.js入門ガイド",
"url": "https://example.com/vue-tutorial",
"snippet": "Vue.jsの基本的な使い方を学ぶチュートリアル..."
}
]
}
3. コンテンツ抽出
You: "Extract the full content from that Vue.js tutorial"
Claude uses extract_content tool:
{
"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"
🔍 Search Results:
══════════════════════════════════════════════════
1. Python Web Scraping Tutorial
URL: https://realpython.com/python-web-scraping-practical-introduction/
Complete guide to web scraping with Python using requests and Beautiful Soup...
2. Web Scraping with Python - BeautifulSoup and requests
URL: https://www.dataquest.io/blog/web-scraping-python-tutorial/
Learn how to scrape websites with Python, Beautiful Soup, and requests...
══════════════════════════════════════════════════
Commands: [1-10] select result | b) back | q) quit | open <n>) open in browser
> 1
📥 Extracting content from: Python Web Scraping Tutorial
📄 Content:
══════════════════════════════════════════════════
**Python Web Scraping Tutorial**
Source: https://realpython.com/python-web-scraping-practical-introduction/
Extracted: 2024-01-15T10:30:00.000Z
──────────────────────────────────────────────────
Web scraping is the process of collecting and parsing raw data from the web...
Web scraping is a technique to automatically access and extract large amounts...
══════════════════════════════════════════════════
Commands: b) back to results | /<term>) search in text | q) quit | open) open in browser
> /beautiful soup
🔍 Found 3 matches for "beautiful soup":
──────────────────────────────────────────────────
Line 15: Beautiful Soup is a Python library for parsing HTML and XML documents.
Line 42: from bs4 import BeautifulSoup
Line 67: soup = BeautifulSoup(html_content, 'html.parser')
直接URLモード
$ llmresearcher -u https://docs.python.org/3/tutorial/
📄 Content:
══════════════════════════════════════════════════
**The Python Tutorial**
Source: https://docs.python.org/3/tutorial/
Extracted: 2024-01-15T10:35:00.000Z
──────────────────────────────────────────────────
Python is an easy to learn, powerful programming language...
In the following examples, input and output are distinguished...
詳細モード
$ llmresearcher -v "nodejs tutorial"
[VERBOSE] Searching: https://duckduckgo.com/html/?q=nodejs%20tutorial&kl=us-en
[VERBOSE] Response: 200 in 847ms
[VERBOSE] Parsed 10 results
[VERBOSE] Launching browser...
[VERBOSE] Blocking resource: https://example.com/style.css
[VERBOSE] Blocking resource: https://example.com/image.png
[VERBOSE] Navigating to page...
[VERBOSE] Page loaded in 1243ms
[VERBOSE] Processing content with Readability...
[VERBOSE] Readability extraction successful
[VERBOSE] Closing browser...
テスト
テストの実行
pnpm test
pnpm test:run
pnpm test -- --coverage
テストカバレッジ
テストスイートには以下が含まれます。
テストの特徴
- 高速:vitestにより迅速なフィードバックが得られます。
- 型安全:テストでも完全なTypeScriptサポートがあります。
- 分離:各テストは自身のリソースをクリーンアップします。
- 包括的:検索、抽出、設定、統合シナリオを網羅しています。
トラブルシューティング
一般的な問題
"Browser not found" エラー
pnpm install-browsers
レート制限の問題
- ツールは自動的に1秒の遅延でレート制限を処理します。
- 429エラーが発生した場合、ツールは指数バックオフで自動的にリトライします。
コンテンツ抽出の失敗
- 一部のサイトは自動アクセスをブロックする場合があります。
- ツールにはフォールバックの抽出方法(メイン → ボディコンテンツ)が含まれています。
- 詳細モード (
-v) を使用して詳細なエラー情報を確認できます。
Permission Denied (Unix/Linux)
chmod +x bin/llmresearcher.js
パフォーマンス最適化
このツールは速度を重視して最適化されています。
- リソースブロッキング:自動的に画像、CSS、フォントをブロックします。
- ネットワークアイドル:JavaScriptのレンダリングが完了するのを待ちます。
- コンテンツキャッシュ:繰り返しのリクエストを避けるためにローカルキャッシュをサポートしています。
- 最小限の依存関係:軽量で焦点を絞ったライブラリを使用しています。
開発
プロジェクト構造
light-research-mcp/
├── dist/ # Built JavaScript files (generated)
│ ├── bin/
│ │ └── llmresearcher.js # CLI entry point (executable)
│ └── *.js # Compiled TypeScript modules
├── src/ # TypeScript source files
│ ├── bin.ts # CLI entry point
│ ├── index.ts # Main LLMResearcher class
│ ├── mcp-server.ts # MCP server implementation
│ ├── search.ts # DuckDuckGo search implementation
│ ├── github-code-search.ts # GitHub Code Search implementation
│ ├── extractor.ts # Content extraction with Playwright
│ ├── cli.ts # Interactive CLI interface
│ ├── config.ts # Configuration management
│ └── types.ts # TypeScript type definitions
├── test/ # Test files (vitest)
│ ├── search.test.ts # Search functionality tests
│ ├── extractor.test.ts # Content extraction tests
│ ├── config.test.ts # Configuration tests
│ ├── mcp-locale.test.ts # MCP locale functionality tests
│ ├── mcp-content-extractor.test.ts # MCP content extractor tests
│ └── integration.test.ts # End-to-end integration tests
├── tsconfig.json # TypeScript configuration
├── tsup.config.ts # Build configuration
├── vitest.config.ts # Test configuration
├── package.json
└── README.md
依存関係
ランタイム依存関係
- @modelcontextprotocol/sdk:Model Context Protocolサーバーの実装
- @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ファイルを参照してください。
コントリビューション
- リポジトリをフォークします。
- 機能ブランチを作成します。
- 変更を加えます。
- 適用可能な場合はテストを追加します。
- プルリクエストを送信します。
ロードマップ
予定されている機能
- 拡張MCPツール:ドキュメント、APIなどのための追加の特殊検索ツール
- キャッシュ層:24時間のTTLを持つSQLiteベースのURL → Markdownキャッシュ
- 検索エンジンの抽象化:Brave Search、Bingなどの他のエンジンのサポート
- コンテンツ要約:オプションのAIベースのコンテンツ要約
- エクスポート形式:JSON、プレーンテキストなどの出力形式
- バッチ処理:ファイル入力から複数のURLを処理
- SSEトランスポート:Server-Sent Events MCPトランスポートのサポート
パフォーマンスの改善
- 並列処理:複数の結果の同時コンテンツ抽出
- スマートキャッシュ:コンテンツの新鮮さに基づくインテリジェントなキャッシュ無効化
- メモリ最適化:大きなドキュメントのストリーミングコンテンツ処理