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(默认)、text或htmlwaitMs- 页面加载后额外等待的时间,以防内容出现缓慢timeoutMs- 放弃前等待的时间(默认:15 秒)maxChars- 返回的最大内容量(默认:40,000 个字符)includeHtml- 设置为true以同时返回原始 HTML 和内容headless- 设置为false以查看浏览器窗口(用于调试)
返回:
url- 请求的 URLfinalUrl- 任何重定向后的 URLtitle- 页面标题content- 提取的内容(以请求的格式)html- 原始 HTML(仅当includeHtml为 true 时)meta- 页面元数据(描述、作者、发布时间等)fetchedAt- 获取页面时的 ISO 时间戳truncated- 内容是否被截断以适应maxChars
friendly_search
搜索网络并返回结果列表。
参数:
query(必需)- 要搜索的内容engine- 使用哪个搜索引擎(duckduckgo或google)maxResults- 返回多少结果(默认:10,最大:50)timeoutMs- 放弃前等待的时间(默认:15 秒)headless- 设置为false以查看浏览器窗口
返回:
query- 使用的搜索查询engine- 使用了哪个搜索引擎results- 结果数组,每个结果包含title、url和snippetsearchedAt- 执行搜索时的 ISO 时间戳fallback_result_html- 页面的原始 HTML(仅在未找到结果时包含)debug_info- 关于搜索尝试的诊断信息
CAPTCHA 处理:
如果在无头模式下运行时检测到 CAPTCHA,该工具会自动使用可见的浏览器窗口重试。这让你有机会手动解决 CAPTCHA。debug_info.retried 字段指示是否使用了此回退。
friendly_web_extract
从 URL 提取内容。自动检测 URL 指向的是 PDF 还是网页,并相应地处理每种情况。
参数:
url(必需)- 要获取的 URL(PDF 或网页)maxChars- 返回的最大文本量(默认:40,000 个字符)offset- 起始字符位置(默认:0)。使用此参数对大型内容进行分页。search- 搜索短语并返回带有周围上下文的匹配项,而不是完整内容contextChars- 每个搜索匹配项周围的上下文字符数(默认:200)waitMs- 页面加载后额外等待动态内容的时间(仅限网页)timeoutMs- 放弃前等待的时间(默认:15 秒,仅限网页)headless- 设置为false以查看浏览器窗口(仅限网页)
返回(正常模式):
url- 请求的 URLcontentType-pdf或htmltitle- 页面/文档标题author- PDF 作者(仅限 PDF,如果可用)creationDate- PDF 创建时间(仅限 PDF,如果可用)pageCount- 页数(仅限 PDF)totalChars- 总字符数(与offset一起用于分页)offset- 使用的偏移量content- 提取的文本内容fetchedAt- ISO 时间戳truncated- 此块之后是否还有更多内容
返回(搜索模式):
url、contentType、title、totalChars、fetchedAt- 与上面相同search- 使用的搜索短语matchCount- 找到的匹配项数量matches- 匹配项数组,每个匹配项包含position、context、prefix和suffix
friendly_web_ask
获取 URL(PDF 或网页)并让 LLM 回答有关它的问题。自动检测内容类型。文档在单独的上下文中处理,保持你的主对话简洁。
参数:
url(必需)- 要获取的 URL(PDF 或网页)ask(必需)- 给 LLM 的问题或指令(总结、提取信息、回答问题等)askMaxInputTokens- 每次 LLM 调用的最大输入令牌数(默认:150,000)askMaxOutputTokens- 每次 LLM 调用的最大输出令牌数(默认:4,096)askTimeout- 超时时间(毫秒)(默认:300,000 = 5 分钟)askSplitAndSynthesize- 对于大型文档:拆分成块,处理每个块,然后综合结果(默认:false)。警告:会消耗大量令牌。waitMs- 页面加载后额外等待动态内容的时间(仅限网页)timeoutMs- 放弃前等待的时间(默认:15 秒,仅限网页)headless- 设置为false以查看浏览器窗口(仅限网页)
返回:
url- 请求的 URLcontentType-pdf或htmltitle- 页面/文档标题totalChars- 文档中的总字符数ask- 给出的指令answer- LLM 的响应model- 生成响应的模型chunksProcessed- 处理的块数(小型文档为 1,使用askSplitAndSynthesize时更多)fetchedAt- ISO 时间戳
询问模式 使用 MCP 采样让 LLM 根据任何指令处理文档。这对于以下情况很有用:
- 可能超出上下文限制的大型文档
- 降低主对话的令牌成本
当启用 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- 已重新索引的文档 IDerrors- 遇到的任何错误documents- 更新的文档记录数组
stash_list
列出资料库中的文档。
参数:
topic- 过滤到某个主题(可选)limit- 最大结果数(默认:50)offset- 分页偏移量(默认:0)
返回:
type-all或topictotalDocuments- 文档总数(仅当type为all时)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- 文档数组,每个文档包含:id、filename、fileType、summary、charCount、createdAtmatchType-filename、content或filename+contentmatches- 每个匹配位置的{ line, context }数组
使用 line 值与 stash_extract 可直接跳转到匹配位置。
stash_extract
从暂存文档中提取内容以供阅读。使用 stash_search 结果中的行号可直接跳转到匹配处。
参数:
id(必需)- 来自stash_list/stash_search的文档 IDmaxChars- 返回的最大文本量(默认:40,000 字符)offset- 起始字符位置(与line互斥)line- 起始行号(与offset互斥)
返回:
id、filename、fileType、summary- 文档元数据totalChars- 文档总字符数offset- 字符偏移量(使用line作为参考时包含)line- 行号(仅当使用了line参数时)content- 提取的文本内容truncated- 此块之后是否还有更多内容
stash_ask
让 LLM 回答关于暂存文档的问题。文档在单独的上下文中处理,保持主对话的简洁。
参数:
id(必需)- 来自stash_list/stash_search的文档 IDask(必需)- 向 LLM 提出的问题或指令askMaxInputTokens- 每次 LLM 调用的最大输入令牌数(默认:150,000)askMaxOutputTokens- 每次 LLM 调用的最大输出令牌数(默认:4,096)askTimeout- 超时时间(毫秒)(默认:300,000 = 5 分钟)askSplitAndSynthesize- 对于大型文档:拆分为块,分别处理,然后综合结果(默认:false)
返回:
id、filename、fileType、summary- 文档元数据totalChars- 文档总字符数ask- 给出的指令answer- LLM 的响应model- 生成响应的模型chunksProcessed- 处理的块数
典型流程
- 将文件放入
~/.research-friend/inbox/ - 运行
stash_process_inbox - 使用
stash_list浏览主题 - 使用
stash_search查找相关文档 - 使用
stash_extract阅读特定文档,或使用stash_ask对其提问
故障排除
“浏览器意外关闭”或类似错误
尝试重新安装浏览器:
npx playwright install chromium --force
在 Linux 上,你可能还需要系统依赖项:
npx playwright install-deps chromium
服务器无法启动
确保你使用的是 Node.js 20 或更新版本:
node --version
如果你的版本较旧,请访问 nodejs.org 下载更新版本。
许可证
MIT