MCP Research Friend Server
oficialHerramientas de investigación, incluyendo un almacén de documentos respaldado por Sqlite
Documentación
Research Friend
Un asistente amigable para herramientas de IA que necesitan buscar cosas en la web y gestionar un archivo local de investigación.
Research Friend es un servidor MCP que brinda a tus herramientas de IA la capacidad de obtener páginas web y buscar en internet. Utiliza un navegador web real en segundo plano, por lo que funciona incluso con sitios web modernos que dependen en gran medida de JavaScript. También incluye un "archivo" local para almacenar documentos, extraer texto y buscar en toda tu biblioteca.
Para aprovechar todas sus funciones, necesitarás un cliente MCP que admita prompts (común) y sampling (menos común). Estamos desarrollando Research Friend junto con Chabeau, que admite ambos.
¿Qué puede hacer?
- Obtener páginas web con un navegador real (incluyendo sitios con mucho JavaScript)
- Obtener PDFs y extraer su contenido de texto
- Buscar en la web a través de DuckDuckGo o Google
- Mantener un archivo local de documentos para buscar, listar y extraer
Primeros pasos
Necesitarás Node.js versión 20 o superior instalado en tu computadora.
1. Instalar dependencias
Abre una terminal en esta carpeta y ejecuta:
npm install
2. Instalar soporte para navegador
Research Friend usa Playwright para controlar un navegador web. Después de instalar las dependencias, necesitarás instalar el navegador:
npx playwright install chromium
Esto descarga una copia de Chromium que Playwright utilizará. Es independiente de cualquier navegador que ya tengas instalado.
3. Iniciar el servidor
node src/index.js
El servidor se comunica a través de stdio (entrada/salida estándar), que es como los clientes MCP se conectan a él.
Agregar a tu cliente MCP
La forma de agregar Research Friend depende del cliente MCP que estés usando. Aquí tienes un ejemplo general de cómo podría verse la configuración:
[[mcp_servers]]
id = "research-friend"
command = "node"
args = ["/path/to/mcp-research-friend/src"]
transport = "stdio"
Reemplaza /path/to/mcp-research-friend con la ruta real a esta carpeta en tu computadora.
Herramientas
Herramientas web
friendly_web_fetch
Obtiene una página web y devuelve su contenido. Por defecto, devuelve markdown con enlaces preservados — ideal para LLMs. Usa Readability para extraer el contenido principal (eliminando navegación, anuncios, etc.). Para PDFs, paginación o búsqueda dentro del contenido, usa friendly_web_extract en su lugar.
Parámetros:
url(requerido) - La dirección web a obteneroutputFormat- Formato de salida:markdown(predeterminado),text, ohtmlwaitMs- Tiempo extra para esperar después de que la página cargue, en caso de que el contenido aparezca lentamentetimeoutMs- Cuánto tiempo esperar antes de rendirse (predeterminado: 15 segundos)maxChars- Cantidad máxima de contenido a devolver (predeterminado: 40,000 caracteres)includeHtml- Establecer entruepara devolver también el HTML sin procesar junto con el contenidoheadless- Establecer enfalsepara ver la ventana del navegador (útil para depuración)
Devuelve:
url- La URL que fue solicitadafinalUrl- La URL después de cualquier redireccióntitle- El título de la páginacontent- El contenido extraído (en el formato solicitado)html- HTML sin procesar (solo siincludeHtmles verdadero)meta- Metadatos de la página (descripción, autor, fecha de publicación, etc.)fetchedAt- Marca de tiempo ISO de cuándo se obtuvo la páginatruncated- Si el contenido fue truncado para ajustarse amaxChars
friendly_search
Busca en la web y devuelve una lista de resultados.
Parámetros:
query(requerido) - Qué buscarengine- Qué motor de búsqueda usar (duckduckgoogoogle)maxResults- Cuántos resultados devolver (predeterminado: 10, máximo: 50)timeoutMs- Cuánto tiempo esperar antes de rendirse (predeterminado: 15 segundos)headless- Establecer enfalsepara ver la ventana del navegador
Devuelve:
query- La consulta de búsqueda que se usóengine- Qué motor de búsqueda se usóresults- Arreglo de resultados, cada uno contitle,url, ysnippetsearchedAt- Marca de tiempo ISO de cuándo se realizó la búsquedafallback_result_html- HTML sin procesar de la página (solo se incluye si no se encontraron resultados)debug_info- Información de diagnóstico sobre el intento de búsqueda
Manejo de CAPTCHA:
Si se detecta un CAPTCHA mientras se ejecuta en modo sin cabeza, la herramienta reintenta automáticamente con una ventana de navegador visible. Esto te da la oportunidad de resolver el CAPTCHA manualmente. El campo debug_info.retried indica si se usó este respaldo.
friendly_web_extract
Extrae contenido de una URL. Detecta automáticamente si la URL apunta a un PDF o a una página web y maneja cada uno apropiadamente.
Parámetros:
url(requerido) - La URL a obtener (PDF o página web)maxChars- Cantidad máxima de texto a devolver (predeterminado: 40,000 caracteres)offset- Posición de carácter desde la cual comenzar (predeterminado: 0). Úsalo para paginar a través de contenido extenso.search- Buscar una frase y devolver coincidencias con contexto circundante en lugar del contenido completocontextChars- Caracteres de contexto alrededor de cada coincidencia de búsqueda (predeterminado: 200)waitMs- Tiempo extra para esperar después de la carga de la página para contenido dinámico (solo páginas web)timeoutMs- Cuánto tiempo esperar antes de rendirse (predeterminado: 15 segundos, solo páginas web)headless- Establecer enfalsepara ver la ventana del navegador (solo páginas web)
Devuelve (modo normal):
url- La URL que fue solicitadacontentType- Ya seapdfohtmltitle- El título de la página/documentoauthor- El autor del PDF (solo PDFs, si está disponible)creationDate- Cuándo se creó el PDF (solo PDFs, si está disponible)pageCount- Número de páginas (solo PDFs)totalChars- Total de caracteres (úselo conoffsetpara paginar)offset- El desplazamiento que se usócontent- El contenido de texto extraídofetchedAt- Marca de tiempo ISOtruncated- Si queda más contenido después de este fragmento
Devuelve (modo búsqueda):
url,contentType,title,totalChars,fetchedAt- Igual que arribasearch- La frase de búsqueda que se usómatchCount- Número de coincidencias encontradasmatches- Arreglo de coincidencias, cada una conposition,context,prefix, ysuffix
friendly_web_ask
Obtiene una URL (PDF o página web) y hace que un LLM responda preguntas al respecto. Detecta automáticamente el tipo de contenido. El documento se procesa en un contexto separado, manteniendo tu conversación principal compacta.
Parámetros:
url(requerido) - La URL a obtener (PDF o página web)ask(requerido) - Pregunta o instrucción para el LLM (resumir, extraer información, responder preguntas, etc.)askMaxInputTokens- Tokens de entrada máximos por llamada al LLM (predeterminado: 150,000)askMaxOutputTokens- Tokens de salida máximos por llamada al LLM (predeterminado: 4,096)askTimeout- Tiempo de espera en milisegundos (predeterminado: 300,000 = 5 minutos)askSplitAndSynthesize- Para documentos grandes: dividir en fragmentos, procesar cada uno, luego sintetizar resultados (predeterminado: falso). Advertencia: consume muchos tokens.waitMs- Tiempo extra para esperar después de la carga de la página para contenido dinámico (solo páginas web)timeoutMs- Cuánto tiempo esperar antes de rendirse (predeterminado: 15 segundos, solo páginas web)headless- Establecer enfalsepara ver la ventana del navegador (solo páginas web)
Devuelve:
url- La URL que fue solicitadacontentType- Ya seapdfohtmltitle- El título de la página/documentototalChars- Total de caracteres en el documentoask- La instrucción que se dioanswer- La respuesta del LLMmodel- El modelo que generó la respuestachunksProcessed- Número de fragmentos procesados (1 para documentos pequeños, más cuando se usaaskSplitAndSynthesize)fetchedAt- Marca de tiempo ISO
El modo Ask usa muestreo MCP para que un LLM procese el documento con cualquier instrucción. Esto es útil para:
- Documentos grandes que abrumarían el contexto
- Mantener bajos los costos de tokens en la conversación principal
Cuando askSplitAndSynthesize está habilitado, los documentos que exceden askMaxInputTokens se dividen automáticamente en fragmentos superpuestos. Cada fragmento se procesa por separado, y los resultados se sintetizan en una sola respuesta coherente. La respuesta final se proporciona en el mismo idioma que tu solicitud, independientemente del idioma del documento.
Archivo de documentos
El archivo es una biblioteca local de documentos con capacidad de búsqueda. Admite PDFs, archivos HTML y texto plano (Markdown/TXT). Cuando agregas un documento, Research Friend almacena el archivo original, extrae texto (para PDFs/HTML) y guarda metadatos en una base de datos local. Las búsquedas usan ripgrep internamente para una coincidencia rápida y consciente de frases.
Ubicación del archivo
El archivo reside en ~/.research-friend/:
inbox/- Coloca archivos aquí para ser procesadosstore/- Almacenamiento organizado de documentos y texto extraídostash.db- Base de datos de metadatos
Tipos de archivo admitidos
- PDF:
.pdf(texto extraído) - HTML:
.html,.htm(texto extraído) - Markdown:
.md,.markdown(almacenado como texto plano) - Texto:
.txt(almacenado como texto plano)
Herramientas del archivo
stash_open_inbox
Abre la carpeta de bandeja de entrada del archivo en tu administrador de archivos para facilitar el arrastrar y soltar.
Devuelve:
opened- Si se envió la solicitud de apertura de carpetainboxPath- Ruta absoluta a la bandeja de entradacommand- Comando del SO utilizadoargs- Argumentos del comando utilizados
stash_process_inbox
Procesa archivos en inbox/, los clasifica en temas, extrae texto y almacena resultados.
Para documentos largos, la clasificación usa secciones muestreadas (inicio/medio/final más algunos fragmentos aleatorios) para mejorar la precisión del tema.
Devuelve:
processed- Arreglo de nombres de archivo procesados exitosamenteerrors- Cualquier error encontradodocuments- Arreglo de registros de documentos creados
reindex_stash
Regenera resúmenes, reasigna temas y actualiza metadatos almacenados para documentos archivados. Si ids se omite o está vacío, todos los documentos se reindexan.
Parámetros:
ids- IDs de documentos a reindexar (opcional)
Devuelve:
reindexed- IDs de documentos reindexadoserrors- Cualquier error encontradodocuments- Arreglo de registros de documentos actualizados
stash_list
Lista documentos en el archivo.
Parámetros:
topic- Filtrar por un tema (opcional)limit- Máximo de resultados (predeterminado: 50)offset- Desplazamiento de paginación (predeterminado: 0)
Devuelve:
type-allotopictotalDocuments- Total de documentos (solo cuandotypeesall)count- Resultados devueltos después de la paginaciónoffset- Desplazamiento de paginación utilizadolimit- Límite de paginación utilizadotopics- Resumen de temas conocidos y conteo de documentosdocuments- Lista de documentos con metadatos (incluyeisPrimaryal listar un tema)
stash_search
Busca nombres de archivo y contenido en todo el archivo. Todos los términos de búsqueda deben estar presentes (lógica AND). Las coincidencias de nombre de archivo se listan primero. Usa comillas para frases exactas.
Parámetros:
query(requerido) - Términos de búsqueda. Usa comillas para frases:"sparkling wine"topic- Filtrar por un tema (opcional)ids- Filtrar por IDs de documentos específicos (opcional)limit- Máximo de documentos a devolver (predeterminado: 20)offset- Desplazamiento de paginación (predeterminado: 0)maxMatchesPerDoc- Máximo de coincidencias por documento (predeterminado: 50)context- Líneas de contexto alrededor de cada coincidencia (predeterminado: 1, máx: 5). Controla tanto qué tan cerca deben aparecer los términos para coincidir como cuánto texto circundante se devuelve. Devuelve:totalMatches- Total de documentos coincidentes antes de la paginacióncount- Resultados devueltos después de la paginaciónresults- Array de documentos, cada uno con:id,filename,fileType,summary,charCount,createdAtmatchType-filename,contentofilename+contentmatches- Array de{ line, context }para cada ubicación de coincidencia
Usa los valores de line con stash_extract para saltar directamente a las ubicaciones de coincidencia.
stash_extract
Extrae contenido de un documento guardado para leerlo. Usa los números de línea de los resultados de stash_search para saltar directamente a las coincidencias.
Parámetros:
id(requerido) - ID del documento destash_list/stash_searchmaxChars- Cantidad máxima de texto a devolver (por defecto: 40,000 caracteres)offset- Posición de carácter desde donde empezar (mutuamente excluyente conline)line- Número de línea desde donde empezar (mutuamente excluyente conoffset)
Devuelve:
id,filename,fileType,summary- Metadatos del documentototalChars- Total de caracteres en el documentooffset- Desplazamiento de carácter (incluido al usarlinecomo referencia)line- Número de línea (solo cuando se usó el parámetroline)content- El contenido de texto extraídotruncated- Si queda más contenido después de este fragmento
stash_ask
Haz que un LLM responda preguntas sobre un documento guardado. El documento se procesa en un contexto separado, manteniendo tu conversación principal compacta.
Parámetros:
id(requerido) - ID del documento destash_list/stash_searchask(requerido) - Pregunta o instrucción para el LLMaskMaxInputTokens- Tokens de entrada máximos por llamada al LLM (por defecto: 150,000)askMaxOutputTokens- Tokens de salida máximos por llamada al LLM (por defecto: 4,096)askTimeout- Tiempo de espera en milisegundos (por defecto: 300,000 = 5 minutos)askSplitAndSynthesize- Para documentos grandes: dividir en fragmentos, procesar cada uno y luego sintetizar resultados (por defecto: false)
Devuelve:
id,filename,fileType,summary- Metadatos del documentototalChars- Total de caracteres en el documentoask- La instrucción que se dioanswer- La respuesta del LLMmodel- El modelo que generó la respuestachunksProcessed- Número de fragmentos procesados
Flujo típico
- Suelta archivos en
~/.research-friend/inbox/ - Ejecuta
stash_process_inbox - Usa
stash_listpara explorar temas - Usa
stash_searchpara encontrar documentos relevantes - Usa
stash_extractpara leer un documento específico, ostash_askpara hacer preguntas sobre él
Solución de problemas
"El navegador se cerró inesperadamente" o errores similares
Intenta reinstalar el navegador:
npx playwright install chromium --force
En Linux, es posible que también necesites dependencias del sistema:
npx playwright install-deps chromium
El servidor no inicia
Asegúrate de estar usando Node.js 20 o más reciente:
node --version
Si tu versión es más antigua, visita nodejs.org para descargar una más nueva.
Licencia
MIT