MCP Research Friend Server
oficialFerramentas de pesquisa, incluindo um repositório de documentos com suporte a Sqlite
Documentação
Research Friend
Um assistente amigável para ferramentas de IA que precisam buscar coisas na web e gerenciar um repositório local de pesquisa.
O Research Friend é um servidor MCP que oferece às suas ferramentas de IA a capacidade de buscar páginas da web e pesquisar na internet. Ele usa um navegador web real por trás dos panos, então funciona até mesmo com sites modernos que dependem muito de JavaScript. Ele também inclui um "repositório" local para armazenar documentos, extrair texto e pesquisar em toda a sua biblioteca.
Para aproveitar todos os seus recursos, você precisará de um cliente MCP que suporte prompts (comum) e sampling (menos comum). Estamos desenvolvendo o Research Friend junto com o Chabeau, que suporta ambos.
O que ele pode fazer?
- Buscar páginas da web com um navegador real (incluindo sites com muito JS)
- Buscar PDFs e extrair seu conteúdo de texto
- Pesquisar na web via DuckDuckGo ou Google
- Manter um repositório local de documentos para pesquisa, listagem e extração
Primeiros passos
Você precisará do Node.js versão 20 ou mais recente instalado no seu computador.
1. Instalar dependências
Abra um terminal nesta pasta e execute:
npm install
2. Instalar suporte ao navegador
O Research Friend usa o Playwright para controlar um navegador web. Após instalar as dependências, você precisará instalar o navegador:
npx playwright install chromium
Isso baixa uma cópia do Chromium que o Playwright usará. É separado de quaisquer navegadores que você já tenha instalado.
3. Iniciar o servidor
node src/index.js
O servidor se comunica via stdio (entrada/saída padrão), que é como os clientes MCP se conectam a ele.
Adicionando ao seu cliente MCP
A forma de adicionar o Research Friend depende de qual cliente MCP você está usando. Aqui está um exemplo geral de como a configuração pode ser:
[[mcp_servers]]
id = "research-friend"
command = "node"
args = ["/path/to/mcp-research-friend/src"]
transport = "stdio"
Substitua /path/to/mcp-research-friend pelo caminho real para esta pasta no seu computador.
Ferramentas
Ferramentas web
friendly_web_fetch
Busca uma página da web e retorna seu conteúdo. Por padrão, retorna markdown com links preservados — ideal para LLMs. Usa o Readability para extrair o conteúdo principal (removendo navegação, anúncios, etc.). Para PDFs, paginação ou pesquisa dentro do conteúdo, use friendly_web_extract em vez disso.
Parâmetros:
url(obrigatório) - O endereço web a ser buscadooutputFormat- Formato de saída:markdown(padrão),textouhtmlwaitMs- Tempo extra para esperar após o carregamento da página, caso o conteúdo apareça lentamentetimeoutMs- Quanto tempo esperar antes de desistir (padrão: 15 segundos)maxChars- Quantidade máxima de conteúdo a retornar (padrão: 40.000 caracteres)includeHtml- Defina comotruepara também retornar o HTML bruto junto com o conteúdoheadless- Defina comofalsepara ver a janela do navegador (útil para depuração)
Retorna:
url- A URL que foi solicitadafinalUrl- A URL após quaisquer redirecionamentostitle- O título da páginacontent- O conteúdo extraído (no formato solicitado)html- HTML bruto (somente seincludeHtmlfor verdadeiro)meta- Metadados da página (descrição, autor, horário de publicação, etc.)fetchedAt- Timestamp ISO de quando a página foi buscadatruncated- Se o conteúdo foi truncado para caber emmaxChars
friendly_search
Pesquisa na web e retorna uma lista de resultados.
Parâmetros:
query(obrigatório) - O que pesquisarengine- Qual mecanismo de busca usar (duckduckgoougoogle)maxResults- Quantos resultados retornar (padrão: 10, máximo: 50)timeoutMs- Quanto tempo esperar antes de desistir (padrão: 15 segundos)headless- Defina comofalsepara ver a janela do navegador
Retorna:
query- A consulta de pesquisa que foi usadaengine- Qual mecanismo de busca foi usadoresults- Array de resultados, cada um comtitle,urlesnippetsearchedAt- Timestamp ISO de quando a pesquisa foi realizadafallback_result_html- HTML bruto da página (incluído apenas se nenhum resultado foi encontrado)debug_info- Informações de diagnóstico sobre a tentativa de pesquisa
Tratamento de CAPTCHA:
Se um CAPTCHA for detectado durante a execução em modo headless, a ferramenta automaticamente tenta novamente com uma janela do navegador visível. Isso lhe dá a chance de resolver o CAPTCHA manualmente. O campo debug_info.retried indica se esse fallback foi usado.
friendly_web_extract
Extrai conteúdo de uma URL. Detecta automaticamente se a URL aponta para um PDF ou uma página da web e trata cada um adequadamente.
Parâmetros:
url(obrigatório) - A URL a ser buscada (PDF ou página da web)maxChars- Quantidade máxima de texto a retornar (padrão: 40.000 caracteres)offset- Posição do caractere para começar (padrão: 0). Use isso para paginar através de conteúdo grande.search- Pesquisar por uma frase e retornar correspondências com contexto ao redor em vez do conteúdo completocontextChars- Caracteres de contexto ao redor de cada correspondência de pesquisa (padrão: 200)waitMs- Tempo extra para esperar após o carregamento da página para conteúdo dinâmico (apenas páginas da web)timeoutMs- Quanto tempo esperar antes de desistir (padrão: 15 segundos, apenas páginas da web)headless- Defina comofalsepara ver a janela do navegador (apenas páginas da web)
Retorna (modo normal):
url- A URL que foi solicitadacontentType-pdfouhtmltitle- O título da página/documentoauthor- O autor do PDF (apenas PDFs, se disponível)creationDate- Quando o PDF foi criado (apenas PDFs, se disponível)pageCount- Número de páginas (apenas PDFs)totalChars- Total de caracteres (use comoffsetpara paginar)offset- O deslocamento que foi usadocontent- O conteúdo de texto extraídofetchedAt- Timestamp ISOtruncated- Se mais conteúdo permanece após este trecho
Retorna (modo de pesquisa):
url,contentType,title,totalChars,fetchedAt- Igual ao acimasearch- A frase de pesquisa que foi usadamatchCount- Número de correspondências encontradasmatches- Array de correspondências, cada uma composition,context,prefixesuffix
friendly_web_ask
Busca uma URL (PDF ou página da web) e faz com que um LLM responda a perguntas sobre ela. Detecta automaticamente o tipo de conteúdo. O documento é processado em um contexto separado, mantendo sua conversa principal compacta.
Parâmetros:
url(obrigatório) - A URL a ser buscada (PDF ou página da web)ask(obrigatório) - Pergunta ou instrução para o LLM (resumir, extrair informações, responder perguntas, etc.)askMaxInputTokens- Tokens de entrada máximos por chamada do LLM (padrão: 150.000)askMaxOutputTokens- Tokens de saída máximos por chamada do LLM (padrão: 4.096)askTimeout- Tempo limite em milissegundos (padrão: 300.000 = 5 minutos)askSplitAndSynthesize- Para documentos grandes: dividir em partes, processar cada uma e depois sintetizar os resultados (padrão: falso). Aviso: consome muitos tokens.waitMs- Tempo extra para esperar após o carregamento da página para conteúdo dinâmico (apenas páginas da web)timeoutMs- Quanto tempo esperar antes de desistir (padrão: 15 segundos, apenas páginas da web)headless- Defina comofalsepara ver a janela do navegador (apenas páginas da web)
Retorna:
url- A URL que foi solicitadacontentType-pdfouhtmltitle- O título da página/documentototalChars- Total de caracteres no documentoask- A instrução que foi dadaanswer- A resposta do LLMmodel- O modelo que gerou a respostachunksProcessed- Número de partes processadas (1 para documentos pequenos, mais ao usaraskSplitAndSynthesize)fetchedAt- Timestamp ISO
O modo de pergunta usa MCP sampling para que um LLM processe o documento com qualquer instrução. Isso é útil para:
- Documentos grandes que sobrecarregariam o contexto
- Manter os custos de token baixos na conversa principal
Quando askSplitAndSynthesize está habilitado, documentos que excedem askMaxInputTokens são automaticamente divididos em partes sobrepostas. Cada parte é processada separadamente e os resultados são sintetizados em uma única resposta coerente. A resposta final é fornecida no mesmo idioma da sua solicitação, independentemente do idioma do documento.
Repositório de documentos
O repositório é uma biblioteca local e pesquisável de documentos. Ele suporta PDFs, arquivos HTML e texto simples (Markdown/TXT). Quando você adiciona um documento, o Research Friend armazena o arquivo original, extrai texto (para PDFs/HTML) e salva metadados em um banco de dados local. As pesquisas usam o ripgrep internamente para correspondência rápida e com reconhecimento de frases.
Localização do repositório
O repositório reside em ~/.research-friend/:
inbox/- Solte arquivos aqui para serem processadosstore/- Armazenamento organizado de documentos e texto extraídostash.db- Banco de dados de metadados
Tipos de arquivo suportados
- PDF:
.pdf(texto extraído) - HTML:
.html,.htm(texto extraído) - Markdown:
.md,.markdown(armazenado como texto simples) - Texto:
.txt(armazenado como texto simples)
Ferramentas do repositório
stash_open_inbox
Abre a pasta da caixa de entrada do repositório no seu gerenciador de arquivos para facilitar o arrastar e soltar.
Retorna:
opened- Se a solicitação de abertura da pasta foi enviadainboxPath- Caminho absoluto para a caixa de entradacommand- Comando do SO usadoargs- Argumentos do comando usados
stash_process_inbox
Processa arquivos em inbox/, classifica-os em tópicos, extrai texto e armazena os resultados.
Para documentos longos, a classificação usa seções amostradas (início/meio/fim mais alguns trechos aleatórios) para melhorar a precisão do tópico.
Retorna:
processed- Array de nomes de arquivo processados com sucessoerrors- Quaisquer erros encontradosdocuments- Array de registros de documentos criados
reindex_stash
Regenera resumos, realoca tópicos e atualiza metadados armazenados para documentos no repositório. Se ids for omitido ou vazio, todos os documentos são reindexados.
Parâmetros:
ids- IDs de documentos para reindexar (opcional)
Retorna:
reindexed- IDs de documentos reindexadoserrors- Quaisquer erros encontradosdocuments- Array de registros de documentos atualizados
stash_list
Lista documentos no repositório.
Parâmetros:
topic- Filtrar por um tópico (opcional)limit- Máximo de resultados (padrão: 50)offset- Deslocamento de paginação (padrão: 0)
Retorna:
type-alloutopictotalDocuments- Total de documentos (somente quandotypeéall)count- Resultados retornados após a paginaçãooffset- Deslocamento de paginação usadolimit- Limite de paginação usadotopics- Resumo de tópicos conhecidos e contagens de documentosdocuments- Lista de documentos com metadados (incluiisPrimaryao listar um tópico)
stash_search
Pesquisa nomes de arquivo e conteúdo em todo o repositório. Todos os termos de pesquisa devem estar presentes (lógica E). Correspondências de nome de arquivo são listadas primeiro. Use aspas para frases exatas.
Parâmetros:
query(obrigatório) - Termos de pesquisa. Use aspas para frases:"sparkling wine"topic- Filtrar por um tópico (opcional)ids- Filtrar por IDs de documentos específicos (opcional)limit- Máximo de documentos a retornar (padrão: 20)offset- Deslocamento de paginação (padrão: 0)maxMatchesPerDoc- Máximo de correspondências por documento (padrão: 50)context- Linhas de contexto ao redor de cada correspondência (padrão: 1, máx: 5). Controla tanto quão próximos os termos devem aparecer para corresponder QUANTO quanto texto ao redor é retornado. Retorna:totalMatches- Total de documentos correspondentes antes da paginaçãocount- Resultados retornados após a paginaçãoresults- Array de documentos, cada um com:id,filename,fileType,summary,charCount,createdAtmatchType-filename,contentoufilename+contentmatches- Array de{ line, context }para cada local de correspondência
Use os valores line com stash_extract para pular diretamente para os locais de correspondência.
stash_extract
Extrai conteúdo de um documento armazenado para leitura. Use números de linha dos resultados de stash_search para pular diretamente para as correspondências.
Parâmetros:
id(obrigatório) - ID do documento destash_list/stash_searchmaxChars- Quantidade máxima de texto a retornar (padrão: 40.000 caracteres)offset- Posição do caractere para iniciar (mutuamente exclusivo comline)line- Número da linha para iniciar (mutuamente exclusivo comoffset)
Retorna:
id,filename,fileType,summary- Metadados do documentototalChars- Total de caracteres no documentooffset- Deslocamento de caractere (incluído ao usarlinepara referência)line- Número da linha (somente quando o parâmetrolinefoi usado)content- O conteúdo de texto extraídotruncated- Se mais conteúdo permanece após este trecho
stash_ask
Faz com que um LLM responda perguntas sobre um documento armazenado. O documento é processado em um contexto separado, mantendo sua conversa principal compacta.
Parâmetros:
id(obrigatório) - ID do documento destash_list/stash_searchask(obrigatório) - Pergunta ou instrução para o LLMaskMaxInputTokens- Tokens de entrada máximos por chamada do LLM (padrão: 150.000)askMaxOutputTokens- Tokens de saída máximos por chamada do LLM (padrão: 4.096)askTimeout- Tempo limite em milissegundos (padrão: 300.000 = 5 minutos)askSplitAndSynthesize- Para documentos grandes: divide em partes, processa cada uma e depois sintetiza os resultados (padrão: false)
Retorna:
id,filename,fileType,summary- Metadados do documentototalChars- Total de caracteres no documentoask- A instrução que foi dadaanswer- A resposta do LLMmodel- O modelo que gerou a respostachunksProcessed- Número de partes processadas
Fluxo típico
- Solte arquivos em
~/.research-friend/inbox/ - Execute
stash_process_inbox - Use
stash_listpara navegar pelos tópicos - Use
stash_searchpara encontrar documentos relevantes - Use
stash_extractpara ler um documento específico oustash_askpara fazer perguntas sobre ele
Solução de problemas
"Navegador fechado inesperadamente" ou erros semelhantes
Tente reinstalar o navegador:
npx playwright install chromium --force
No Linux, você também pode precisar de dependências do sistema:
npx playwright install-deps chromium
O servidor não inicia
Certifique-se de estar usando Node.js 20 ou mais recente:
node --version
Se sua versão for mais antiga, visite nodejs.org para baixar uma mais nova.
Licença
MIT