MCP Research Friend Server
chính thứcCông cụ nghiên cứu, bao gồm kho tài liệu hỗ trợ bởi Sqlite
Tài liệu
Research Friend
Một trợ lý thân thiện dành cho các công cụ AI cần tra cứu thông tin trên web và quản lý kho lưu trữ nghiên cứu cục bộ.
Research Friend là một máy chủ MCP cung cấp cho các công cụ AI của bạn khả năng tải trang web và tìm kiếm trên internet. Nó sử dụng một trình duyệt web thực sự ở phía sau, vì vậy nó hoạt động ngay cả với các trang web hiện đại phụ thuộc nhiều vào JavaScript. Nó cũng bao gồm một "kho lưu trữ" cục bộ để lưu trữ tài liệu, trích xuất văn bản và tìm kiếm trong thư viện của bạn.
Để tận dụng tất cả các tính năng của nó, bạn sẽ cần một máy khách MCP hỗ trợ prompt (phổ biến) và sampling (ít phổ biến hơn). Chúng tôi đang xây dựng Research Friend cùng với Chabeau, hỗ trợ cả hai.
Nó có thể làm gì?
- Tải trang web bằng trình duyệt thực (bao gồm các trang web nặng về JS)
- Tải PDF và trích xuất nội dung văn bản của chúng
- Tìm kiếm trên web qua DuckDuckGo hoặc Google
- Duy trì kho lưu trữ cục bộ tài liệu để tìm kiếm, liệt kê và trích xuất
Bắt đầu
Bạn sẽ cần Node.js phiên bản 20 trở lên được cài đặt trên máy tính của bạn.
1. Cài đặt các phụ thuộc
Mở một terminal trong thư mục này và chạy:
npm install
2. Cài đặt hỗ trợ trình duyệt
Research Friend sử dụng Playwright để điều khiển một trình duyệt web. Sau khi cài đặt các phụ thuộc, bạn sẽ cần cài đặt trình duyệt:
npx playwright install chromium
Thao tác này tải xuống một bản sao của Chromium mà Playwright sẽ sử dụng. Nó tách biệt với bất kỳ trình duyệt nào bạn đã cài đặt.
3. Khởi động máy chủ
node src/index.js
Máy chủ giao tiếp qua stdio (đầu vào/đầu ra tiêu chuẩn), đó là cách các máy khách MCP kết nối với nó.
Thêm vào máy khách MCP của bạn
Cách bạn thêm Research Friend phụ thuộc vào máy khách MCP bạn đang sử dụng. Dưới đây là một ví dụ chung về cấu hình có thể trông như thế nào:
[[mcp_servers]]
id = "research-friend"
command = "node"
args = ["/path/to/mcp-research-friend/src"]
transport = "stdio"
Thay thế /path/to/mcp-research-friend bằng đường dẫn thực tế đến thư mục này trên máy tính của bạn.
Công cụ
Công cụ web
friendly_web_fetch
Tải một trang web và trả về nội dung của nó. Theo mặc định, trả về markdown với các liên kết được bảo toàn — lý tưởng cho các LLM. Sử dụng Readability để trích xuất nội dung chính (loại bỏ điều hướng, quảng cáo, v.v.). Đối với PDF, phân trang hoặc tìm kiếm trong nội dung, hãy sử dụng friendly_web_extract thay thế.
Tham số:
url(bắt buộc) - Địa chỉ web cần tảioutputFormat- Định dạng đầu ra:markdown(mặc định),text, hoặchtmlwaitMs- Thời gian chờ thêm sau khi trang tải, trong trường hợp nội dung xuất hiện chậmtimeoutMs- Thời gian chờ trước khi bỏ cuộc (mặc định: 15 giây)maxChars- Lượng nội dung tối đa cần trả về (mặc định: 40.000 ký tự)includeHtml- Đặt thànhtrueđể cũng trả về HTML thô cùng với nội dungheadless- Đặt thànhfalseđể xem cửa sổ trình duyệt (hữu ích cho việc gỡ lỗi)
Trả về:
url- URL đã được yêu cầufinalUrl- URL sau bất kỳ chuyển hướng nàotitle- Tiêu đề trangcontent- Nội dung đã trích xuất (theo định dạng được yêu cầu)html- HTML thô (chỉ khiincludeHtmllà true)meta- Siêu dữ liệu trang (mô tả, tác giả, thời gian xuất bản, v.v.)fetchedAt- Dấu thời gian ISO khi trang được tảitruncated- Liệu nội dung có bị cắt bớt để phù hợp vớimaxCharshay không
friendly_search
Tìm kiếm trên web và trả về danh sách kết quả.
Tham số:
query(bắt buộc) - Nội dung cần tìm kiếmengine- Sử dụng công cụ tìm kiếm nào (duckduckgohoặcgoogle)maxResults- Số lượng kết quả cần trả về (mặc định: 10, tối đa: 50)timeoutMs- Thời gian chờ trước khi bỏ cuộc (mặc định: 15 giây)headless- Đặt thànhfalseđể xem cửa sổ trình duyệt
Trả về:
query- Truy vấn tìm kiếm đã được sử dụngengine- Công cụ tìm kiếm nào đã được sử dụngresults- Mảng kết quả, mỗi kết quả cótitle,url, vàsnippetsearchedAt- Dấu thời gian ISO khi tìm kiếm được thực hiệnfallback_result_html- HTML thô của trang (chỉ được bao gồm nếu không tìm thấy kết quả)debug_info- Thông tin chẩn đoán về nỗ lực tìm kiếm
Xử lý CAPTCHA:
Nếu CAPTCHA được phát hiện khi đang chạy ở chế độ headless, công cụ sẽ tự động thử lại với cửa sổ trình duyệt hiển thị. Điều này cho bạn cơ hội giải CAPTCHA thủ công. Trường debug_info.retried cho biết liệu phương án dự phòng này có được sử dụng hay không.
friendly_web_extract
Trích xuất nội dung từ một URL. Tự động phát hiện xem URL trỏ đến PDF hay trang web và xử lý từng loại một cách phù hợp.
Tham số:
url(bắt buộc) - URL cần tải (PDF hoặc trang web)maxChars- Lượng văn bản tối đa cần trả về (mặc định: 40.000 ký tự)offset- Vị trí ký tự bắt đầu (mặc định: 0). Sử dụng để phân trang qua nội dung lớn.search- Tìm kiếm một cụm từ và trả về các kết quả khớp với ngữ cảnh xung quanh thay vì toàn bộ nội dungcontextChars- Số ký tự ngữ cảnh xung quanh mỗi kết quả khớp tìm kiếm (mặc định: 200)waitMs- Thời gian chờ thêm sau khi tải trang cho nội dung động (chỉ trang web)timeoutMs- Thời gian chờ trước khi bỏ cuộc (mặc định: 15 giây, chỉ trang web)headless- Đặt thànhfalseđể xem cửa sổ trình duyệt (chỉ trang web)
Trả về (chế độ bình thường):
url- URL đã được yêu cầucontentType- Hoặcpdfhoặchtmltitle- Tiêu đề trang/tài liệuauthor- Tác giả PDF (chỉ PDF, nếu có)creationDate- Thời điểm PDF được tạo (chỉ PDF, nếu có)pageCount- Số trang (chỉ PDF)totalChars- Tổng số ký tự (sử dụng vớioffsetđể phân trang)offset- Độ lệch đã được sử dụngcontent- Nội dung văn bản đã trích xuấtfetchedAt- Dấu thời gian ISOtruncated- Liệu còn nội dung nào sau đoạn này không
Trả về (chế độ tìm kiếm):
url,contentType,title,totalChars,fetchedAt- Giống như trênsearch- Cụm từ tìm kiếm đã được sử dụngmatchCount- Số lượng kết quả khớp được tìm thấymatches- Mảng các kết quả khớp, mỗi kết quả cóposition,context,prefix, vàsuffix
friendly_web_ask
Tải một URL (PDF hoặc trang web) và yêu cầu LLM trả lời các câu hỏi về nó. Tự động phát hiện loại nội dung. Tài liệu được xử lý trong một ngữ cảnh riêng biệt, giữ cho cuộc trò chuyện chính của bạn gọn gàng.
Tham số:
url(bắt buộc) - URL cần tải (PDF hoặc trang web)ask(bắt buộc) - Câu hỏi hoặc hướng dẫn cho LLM (tóm tắt, trích xuất thông tin, trả lời câu hỏi, v.v.)askMaxInputTokens- Token đầu vào tối đa cho mỗi lần gọi LLM (mặc định: 150.000)askMaxOutputTokens- Token đầu ra tối đa cho mỗi lần gọi LLM (mặc định: 4.096)askTimeout- Thời gian chờ tính bằng mili giây (mặc định: 300.000 = 5 phút)askSplitAndSynthesize- Đối với tài liệu lớn: chia thành các đoạn, xử lý từng đoạn, sau đó tổng hợp kết quả (mặc định: false). Cảnh báo: tiêu tốn nhiều token.waitMs- Thời gian chờ thêm sau khi tải trang cho nội dung động (chỉ trang web)timeoutMs- Thời gian chờ trước khi bỏ cuộc (mặc định: 15 giây, chỉ trang web)headless- Đặt thànhfalseđể xem cửa sổ trình duyệt (chỉ trang web)
Trả về:
url- URL đã được yêu cầucontentType- Hoặcpdfhoặchtmltitle- Tiêu đề trang/tài liệutotalChars- Tổng số ký tự trong tài liệuask- Hướng dẫn đã được đưa raanswer- Phản hồi của LLMmodel- Mô hình đã tạo ra phản hồichunksProcessed- Số đoạn đã xử lý (1 đối với tài liệu nhỏ, nhiều hơn khi sử dụngaskSplitAndSynthesize)fetchedAt- Dấu thời gian ISO
Chế độ hỏi sử dụng MCP sampling để LLM xử lý tài liệu với bất kỳ hướng dẫn nào. Điều này hữu ích cho:
- Các tài liệu lớn có thể làm quá tải ngữ cảnh
- Giảm chi phí token cho cuộc trò chuyện chính
Khi askSplitAndSynthesize được bật, các tài liệu vượt quá askMaxInputTokens sẽ tự động được chia thành các đoạn chồng lấp. Mỗi đoạn được xử lý riêng biệt và kết quả được tổng hợp thành một câu trả lời mạch lạc duy nhất. Phản hồi cuối cùng được cung cấp bằng cùng ngôn ngữ với yêu cầu của bạn, bất kể ngôn ngữ của tài liệu.
Kho lưu trữ tài liệu
Kho lưu trữ là một thư viện tài liệu cục bộ, có thể tìm kiếm. Nó hỗ trợ PDF, tệp HTML và văn bản thuần túy (Markdown/TXT). Khi bạn thêm một tài liệu, Research Friend lưu trữ tệp gốc, trích xuất văn bản (đối với PDF/HTML) và lưu siêu dữ liệu trong cơ sở dữ liệu cục bộ. Tìm kiếm sử dụng ripgrep bên dưới để khớp cụm từ nhanh chóng, nhận biết ngữ cảnh.
Vị trí kho lưu trữ
Kho lưu trữ nằm trong ~/.research-friend/:
inbox/- Thả tệp vào đây để được xử lýstore/- Lưu trữ tài liệu có tổ chức và văn bản đã trích xuấtstash.db- Cơ sở dữ liệu siêu dữ liệu
Loại tệp được hỗ trợ
- PDF:
.pdf(văn bản được trích xuất) - HTML:
.html,.htm(văn bản được trích xuất) - Markdown:
.md,.markdown(lưu trữ dưới dạng văn bản thuần túy) - Văn bản:
.txt(lưu trữ dưới dạng văn bản thuần túy)
Công cụ kho lưu trữ
stash_open_inbox
Mở thư mục hộp thư đến của kho lưu trữ trong trình quản lý tệp của bạn để dễ dàng kéo thả.
Trả về:
opened- Liệu yêu cầu mở thư mục đã được gửi hay chưainboxPath- Đường dẫn tuyệt đối đến hộp thư đếncommand- Lệnh hệ điều hành được sử dụngargs- Các đối số lệnh được sử dụng
stash_process_inbox
Xử lý các tệp trong inbox/, phân loại chúng thành các chủ đề, trích xuất văn bản và lưu trữ kết quả.
Đối với các tài liệu dài, việc phân loại sử dụng các phần được lấy mẫu (đầu/giữa/cuối cộng với một vài đoạn ngẫu nhiên) để cải thiện độ chính xác của chủ đề.
Trả về:
processed- Mảng tên tệp đã được xử lý thành côngerrors- Bất kỳ lỗi nào gặp phảidocuments- Mảng các bản ghi tài liệu đã tạo
reindex_stash
Tạo lại tóm tắt, phân bổ lại chủ đề và cập nhật siêu dữ liệu lưu trữ cho các tài liệu trong kho. Nếu ids bị bỏ qua hoặc để trống, tất cả tài liệu sẽ được lập chỉ mục lại.
Tham số:
ids- ID tài liệu cần lập chỉ mục lại (tùy chọn)
Trả về:
reindexed- ID tài liệu đã được lập chỉ mục lạierrors- Bất kỳ lỗi nào gặp phảidocuments- Mảng các bản ghi tài liệu đã cập nhật
stash_list
Liệt kê các tài liệu trong kho lưu trữ.
Tham số:
topic- Lọc theo chủ đề (tùy chọn)limit- Kết quả tối đa (mặc định: 50)offset- Độ lệch phân trang (mặc định: 0)
Trả về:
type-allhoặctopictotalDocuments- Tổng số tài liệu (chỉ khitypelàall)count- Kết quả trả về sau khi phân trangoffset- Độ lệch phân trang đã sử dụnglimit- Giới hạn phân trang đã sử dụngtopics- Tóm tắt các chủ đề đã biết và số lượng tài liệudocuments- Danh sách tài liệu với siêu dữ liệu (bao gồmisPrimarykhi liệt kê một chủ đề)
stash_search
Tìm kiếm tên tệp và nội dung trong toàn bộ kho lưu trữ. Tất cả các thuật ngữ tìm kiếm phải có mặt (logic AND). Các kết quả khớp tên tệp được liệt kê trước. Sử dụng dấu ngoặc kép cho các cụm từ chính xác.
Tham số:
query(bắt buộc) - Thuật ngữ tìm kiếm. Sử dụng dấu ngoặc kép cho các cụm từ:"sparkling wine"topic- Lọc theo chủ đề (tùy chọn)ids- Lọc theo ID tài liệu cụ thể (tùy chọn)limit- Số lượng tài liệu tối đa cần trả về (mặc định: 20)offset- Độ lệch phân trang (mặc định: 0)maxMatchesPerDoc- Số lượng kết quả khớp tối đa trên mỗi tài liệu (mặc định: 50)context- Số dòng ngữ cảnh xung quanh mỗi kết quả khớp (mặc định: 1, tối đa: 5). Kiểm soát cả mức độ gần nhau của các thuật ngữ để khớp VÀ lượng văn bản xung quanh được trả về. Trả về:totalMatches- Tổng số tài liệu khớp trước khi phân trangcount- Kết quả trả về sau khi phân trangresults- Mảng các tài liệu, mỗi tài liệu có:id,filename,fileType,summary,charCount,createdAtmatchType-filename,content, hoặcfilename+contentmatches- Mảng{ line, context }cho mỗi vị trí khớp
Sử dụng các giá trị line với stash_extract để nhảy trực tiếp đến các vị trí khớp.
stash_extract
Trích xuất nội dung từ một tài liệu đã lưu trữ để đọc. Sử dụng số dòng từ kết quả stash_search để nhảy trực tiếp đến các vị trí khớp.
Tham số:
id(bắt buộc) - ID tài liệu từstash_list/stash_searchmaxChars- Lượng văn bản tối đa trả về (mặc định: 40.000 ký tự)offset- Vị trí ký tự bắt đầu (loại trừ lẫn nhau vớiline)line- Số dòng bắt đầu (loại trừ lẫn nhau vớioffset)
Trả về:
id,filename,fileType,summary- Siêu dữ liệu tài liệutotalChars- Tổng số ký tự trong tài liệuoffset- Độ lệch ký tự (được bao gồm khi sử dụnglineđể tham chiếu)line- Số dòng (chỉ khi tham sốlineđược sử dụng)content- Nội dung văn bản được trích xuấttruncated- Liệu còn nội dung nào sau đoạn này không
stash_ask
Yêu cầu LLM trả lời câu hỏi về một tài liệu đã lưu trữ. Tài liệu được xử lý trong một ngữ cảnh riêng biệt, giữ cho cuộc trò chuyện chính của bạn gọn gàng.
Tham số:
id(bắt buộc) - ID tài liệu từstash_list/stash_searchask(bắt buộc) - Câu hỏi hoặc hướng dẫn cho LLMaskMaxInputTokens- Token đầu vào tối đa cho mỗi lần gọi LLM (mặc định: 150.000)askMaxOutputTokens- Token đầu ra tối đa cho mỗi lần gọi LLM (mặc định: 4.096)askTimeout- Thời gian chờ tính bằng mili giây (mặc định: 300.000 = 5 phút)askSplitAndSynthesize- Đối với tài liệu lớn: chia thành các đoạn, xử lý từng đoạn, sau đó tổng hợp kết quả (mặc định: false)
Trả về:
id,filename,fileType,summary- Siêu dữ liệu tài liệutotalChars- Tổng số ký tự trong tài liệuask- Hướng dẫn đã được đưa raanswer- Phản hồi của LLMmodel- Mô hình đã tạo ra phản hồichunksProcessed- Số đoạn đã xử lý
Quy trình điển hình
- Thả tệp vào
~/.research-friend/inbox/ - Chạy
stash_process_inbox - Sử dụng
stash_listđể duyệt các chủ đề - Sử dụng
stash_searchđể tìm tài liệu liên quan - Sử dụng
stash_extractđể đọc một tài liệu cụ thể, hoặcstash_askđể đặt câu hỏi về tài liệu đó
Khắc phục sự cố
"Trình duyệt đóng bất ngờ" hoặc các lỗi tương tự
Thử cài đặt lại trình duyệt:
npx playwright install chromium --force
Trên Linux, bạn cũng có thể cần các phụ thuộc hệ thống:
npx playwright install-deps chromium
Máy chủ không khởi động
Đảm bảo bạn đang sử dụng Node.js 20 trở lên:
node --version
Nếu phiên bản của bạn cũ hơn, hãy truy cập nodejs.org để tải xuống phiên bản mới hơn.
Giấy phép
MIT