research-mcp
research-mcp
ステートレスなMCPファサードで、検索/読み取りプロバイダのピラミッドを単一のstreamable-http MCPエンドポイントの背後に隠し、優れたロシア語のヘルプテキストを持つ3つのクリーンなツールだけを公開します。LLMはシンプルな「検索→読み取り」ツールセットを取得します。その背後では、複数のプロバイダが自動的に試行され、マージされ、フェイルオーバーされます。
このアプリは認証を行いません — ホスト上でTraefik + basicAuthを介して公開されます。アプリケーションの状態は保持されません。永続化されるのはdata/ディレクトリ(ボリューム上に保持)のログファイルのみです。
Tools
Tool | 説明 |
| 有効なすべてのプロバイダを横断して検索し、マージ+重複排除→ランク付けされたリスト(タイトル、URL、スニペット)を返します。検索のみ。 |
| 1つのページまたはPDF→クリーンなMarkdown。タイプを自動検出し、読み取りパイプライン(軽量→重量)を成功するまで順に試行します。 |
| 最大20のURLを並行して処理→ |
Related MCP server: serp-it
Architecture: types + instances
プロバイダはプラグインです。以下を分離します:
タイプ — 実装クラス(例:
searxng検索プロバイダ)。src/providers/内の各モジュールに1つ存在し、@register("type")で登録されます。インスタンス — タイプの設定済みコピーで、シークレット/URLが名前付き環境変数から解決されます(1つのタイプの複数インスタンスが許可されます。例:異なるキーを持つ
tavily-1/tavily-2)。
どのインスタンスが存在し、各パイプラインがそれらを試行する順序はコード内(src/pipeline_config.py)で設定されます。キー/URLは環境変数名によってENVから取得されます。
検索パイプライン(
searxng → brave → jina-search → serper → exa):有効なインスタンスは並行して実行されます。結果は正規化されたURLでマージされ、重複排除されます(パイプラインの前の位置が優先)。JINA_API_KEYが設定されている場合(かつSEARCH_RERANK_ENABLEDがオフでない場合)、マージされた全リストはjina-reranker-v3.5によって再ランク付けされ、num_resultsへの切り詰めが盲目的なパイプライン順序のプレフィックスではなく、最も関連性の高いヒットを保持します。再ランク付けが失敗した場合は、マージ順序にフォールバックします。searxngとbraveはさらにローカルでスロットルをかけます(それぞれ45秒に1クエリ、1.1秒に1クエリ。測定された上流の制限に一致)。スロットが占有されている場合、待機する代わりに現在の検索をスキップします。読み取りパイプライン(
trafilatura → jina → crawl4ai → tavily-1 → tavily-2 → firecrawl):単一のプローブGETがURLを分類します。PDF(Content-Type /.pdf/%PDFマジック)はpypdfで抽出されます。HTMLの場合、その同じボディがtrafilaturaに渡されるため、ホットパスは2回GETしません。その後、残りのインスタンスが順に試行され、>= FALLBACK_MIN_CHARSのコンテンツを返す最初のインスタンスが勝ちます。
横断的:短いバックオフ付きの一時的なリトライを1回(5xx / トランスポートエラー)。402(クレジット不足)/ 429(レート制限)はプロバイダの失敗として扱われ、次のインスタンスに進みます(これがtavily-1 → tavily-2のフェイルオーバーを実現します)。
インスタンスは、必要な環境変数が設定されている場合にのみ有効になります。それ以外の場合はログ行とともにスキップされます。trafilaturaは設定不要(常にオン)です。jinaはキーレスで動作します(キーはオプション)。起動時にサーバーは少なくとも1つの検索インスタンスと1つの読み取りインスタンスを必要とし、ない場合は明確なメッセージで終了します。
Adding a provider
src/providers/<type>.pyを作成し、@register("<type>")でデコレートされたクラスがSearchProvider.search(...)またはReadProvider.read(...)を実装します。src/providers/__init__.pyでモジュールをインポートします(デコレータが実行されるように)。src/pipeline_config.pyにInstance("name", "<type>", api_key_env="YOUR_ENV_NAME")の行を追加し、SEARCH_PIPELINE/READ_PIPELINEでそのnameを参照します。環境変数名を使用し、値は使用しないでください。.env.exampleに環境変数を文書化します。
Quick start
make install # create .venv + install dev/test deps
cp .env.example .env # fill in the keys you have (shortcut: make env)
make test # run tests
make run # run the server (streamable-http on MCP_HOST:MCP_PORT, endpoint /mcp)Configuration
すべての設定はENV / .envから取得されます(.env.exampleを参照)。プロバイダのシークレット/URLはインスタンスローダーで名前によって読み取られ、Settingsフィールドとして宣言されません。非シークレットのノブ(すべてデフォルトあり):MCP_HOST、MCP_PORT、LOG_LEVEL、LOG_FILE、LOG_ROTATION、LOG_RETENTION、REQUEST_TIMEOUT、FALLBACK_MIN_CHARS、READ_PAGES_CONCURRENCY、RETRIES、SEARCH_RERANK_ENABLED、JINA_TOKEN_BUDGET。read_pagesの呼び出しごとのURL上限は固定の20(ハード定数、ツールの説明と一致)であり、設定不可です。
プロバイダ環境変数:SEARXNG_URL、BRAVE_API_KEY、SERPER_API_KEY、EXA_API_KEY、JINA_API_KEY(1つのキーでjinaリーダーがキー付きモードで有効になり、jina-searchプロバイダと検索リランカーも有効になります。リーダー単体はキーレスでも動作します)、CRAWL4AI_URL + CRAWL4AI_TOKEN、TAVILY_1_API_KEY、TAVILY_2_API_KEY、FIRECRAWL_API_KEY。
Proxy
外部インスタンスは、<INSTANCE>_PROXYを設定することで、独自のSOCKS5/HTTPプロキシを経由させることができます。これは、IPベースのブロック(例:Exaの前のCloudflare)を回避するためのクリーンな出口に役立ちます。インスタンスごとにサポート:EXA_PROXY、BRAVE_PROXY、SERPER_PROXY、JINA_PROXY、TAVILY_1_PROXY、TAVILY_2_PROXY、FIRECRAWL_PROXY。内部インスタンス(searxng、crawl4ai、trafilatura)にはプロキシがありません。
値はそのままhttpxに渡されます。socks5://host:portはプロキシ側DNSを実行します(ターゲットのホスト名はプロキシによって解決されます。curl --socks5-hostnameと同様)。socks5h:// / http://host:portも受け入れられます。未設定の場合、そのインスタンスは直接接続します。パイプラインは、プロキシURLごとに1つのプールされたhttpxクライアント(および1つの直接クライアント)を保持し、インスタンスごとに選択されるため、プロキシ経由と直接のプロバイダが並行して実行されます。socksエクストラ(httpx[socks]、すでに固定)が必要です。
Logging
stderr(Dockerのローテーション上限付きjson-fileドライバーでキャプチャ)に加えて、サーバーは永続的なログファイルをdata/research-mcp.log(デフォルト。LOG_ROTATION=20 MB、LOG_RETENTION=14 days)に書き込みます。これはdata/ボリューム上にあるため、コンテナの再起動やイメージの更新後も存続します。ファイルには、ツール呼び出しごとにリクエストごとの行が1つ含まれます — 検索(query、実際に実行されたプロバイダインスタンス、結果数、レイテンシ)と読み取り(url、勝利したプロバイダ/ティアまたはpdf、ok、レイテンシ)、さらにread_pages count=N ok=Kの要約 — これにより、リクエストがプロバイダティア全体にどのように分散するかを分析するのに役立ちます。リクエストボディやシークレットはログに記録されません。URL/クエリ、プロバイダ名、カウント、タイミングのみです。
Deployment
Gitea Actionsがイメージをビルドし、Giteaレジストリgitea.vvzvlad.xyz/projects/research-mcpにプッシュします(test → build、タグlatest + sha)。本番ではdocker-compose.ymlを介してビルド済みイメージをプルします(Traefik + basicAuthの背後、watchtowerがlatestを自動更新。data/ボリュームが更新間でログファイルを保持)— 本番でビルドすることはありません。
Layout
Path | 目的 |
| プロバイダインターフェース + |
|
|
| プロバイダタイプごとに1つのモジュール。 |
| PDF検出 + pypdfテキスト抽出(パイプラインで使用)。 |
| コード内のインスタンス + パイプライン順序。 |
| インスタンスローダー + 検索/読み取りロジック。 |
|
|
| 非シークレットのノブ(pydantic-settings)。 |
| 3つの |
| 薄いエントリポイント:サーバーをビルドし、streamable-httpを実行。 |
| pytestスイート(ネットワークはrespxでモック)。 |
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for web crawling, searching, and AI-powered content extraction, supporting single-page, batch, and full-site crawling along with text, news, image, book, and video search.81MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that aggregates web search results from multiple engines and optionally renders pages to Markdown, providing a unified search interface.103ISC
- AlicenseAqualityBmaintenanceMulti-source web search MCP server with RRF fusion, 4-layer URL extraction, and provider health tracking.68MIT
- AlicenseAqualityBmaintenanceAn MCP server that fetches web pages and extracts clean, AI-usable context from them, enabling tools for link discovery, content search, and integrated fetch-and-search operations.571MIT
Related MCP Connectors
Free remote MCP server for fetching public web pages through a rotating proxy pool.
Hosted MCP: 1404 structured web-data tools for search, maps, commerce, social, gaming & finance.
Federated commerce search across independent WooCommerce merchants. Keyless, read-only MCP server.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/vvzvlad/research-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server