research-mcp
research-mcp
一个无状态的 MCP 门面,将搜索/读取提供者的层级隐藏在单个 streamable-http MCP 端点之后,并仅暴露 3 个简洁的工具,带有良好的俄语帮助文本。LLM 获得一个简单的“搜索 → 读取”工具集;在背后,多个提供者会被自动尝试、合并和故障转移。
该应用不进行身份验证——它通过主机上的 Traefik + basicAuth 发布。它不保存任何应用状态:唯一持久化的是 data/ 下的日志文件(保存在卷上)。
工具
工具 | 功能 |
| 在所有启用的提供者中搜索,合并 + 去重 → 排名列表(标题、URL、摘要)。仅搜索。 |
| 一个页面或 PDF → 干净的 Markdown。自动检测类型,遍历读取管道(轻 → 重)直到成功。 |
| 最多 20 个 URL 并发 → 列表 |
Related MCP server: serp-it
架构:类型与实例
提供者是插件。我们区分:
类型 — 一个实现类(例如
searxng搜索提供者),每个模块在src/providers/中,使用@register("type")注册。实例 — 一个类型的配置副本,其密钥/URL 从命名环境变量解析(允许一个类型的多个实例,例如
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 秒一个查询,匹配测量的上游限制);当槽位被占用时,它们会跳过当前搜索而不是等待。读取管道(
trafilatura → jina → crawl4ai → tavily-1 → tavily-2 → firecrawl):一个探测 GET 对 URL 进行分类。PDF(Content-Type /.pdf/%PDF魔数)使用 pypdf 提取;对于 HTML,同一主体交给trafilatura,这样热路径不会 GET 两次,然后按顺序尝试其余实例,第一个返回内容>= FALLBACK_MIN_CHARS的获胜。
横切:一次瞬态重试(5xx / 传输错误)带短退避;402(信用不足)/ 429(限流)被视为提供者失败 → 下一个实例(这就是 tavily-1 → tavily-2 故障转移的原因)。
一个实例启用仅当设置了其必需的环境变量;否则跳过并记录日志。trafilatura 不需要配置(始终开启);jina 无密钥工作(其密钥可选)。启动时服务器要求至少一个搜索和一个读取实例,否则以明确消息退出。
添加提供者
编写
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 变量名,而不是值。在
.env.example中记录环境变量。
快速开始
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)配置
所有配置来自 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(一个密钥启用 jina 读取器的密钥模式、jina-search 提供者和搜索重排器;读取器本身也可无密钥工作)、CRAWL4AI_URL + CRAWL4AI_TOKEN、TAVILY_1_API_KEY、TAVILY_2_API_KEY、FIRECRAWL_API_KEY。
代理
任何外部实例都可以通过设置 <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 维护一个池化的 httpx 客户端(以及一个直连客户端),按实例选择,因此代理和直连提供者可以并行运行。需要 socks 额外依赖(httpx[socks],已固定)。
日志
除了 stderr(由 Docker 的轮转上限 json-file 驱动捕获),服务器还会将持久日志文件写入 data/research-mcp.log(默认;LOG_ROTATION=20 MB,LOG_RETENTION=14 days)。它位于 data/ 卷上,因此在容器重启和镜像更新后仍然存在。该文件为每次工具调用携带一行每请求行——搜索(query、实际运行的提供者实例、结果数、延迟)和读取(url、获胜的提供者/层级或 pdf、ok、延迟),以及 read_pages count=N ok=K 摘要——使其可用于分析请求在提供者层级间的分布。不记录请求体或密钥,仅记录 URL/查询、提供者名称、计数、时间。
部署
Gitea Actions 构建镜像并推送到 Gitea 注册表 gitea.vvzvlad.xyz/projects/research-mcp(test → build,标签 latest + sha)。在生产环境,我们通过 docker-compose.yml 拉取预构建镜像(在 Traefik + basicAuth 后面,watchtower 自动更新 latest;data/ 卷在更新期间保留日志文件)——我们从不生产构建。
布局
路径 | 用途 |
| 提供者接口 + |
|
|
| 每个提供者类型一个模块。 |
| PDF 检测 + pypdf 文本提取(由管道使用)。 |
| 代码内实例 + 管道顺序。 |
| 实例加载器 + 搜索/读取逻辑。 |
|
|
| 非秘密旋钮(pydantic-settings)。 |
|
|
| 薄入口点:构建服务器,运行 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