S3 Documentation MCP Server

Un servidor ligero del Protocolo de Contexto de Modelo (MCP) que aporta capacidades de RAG (Generación Aumentada por Recuperación) a tu LLM sobre documentación en Markdown almacenada en S3.

Documentación

S3 Documentation MCP Server

CI codecov Build and Push Docker Image Docker Hub

Un servidor ligero de Model Context Protocol (MCP) que aporta capacidades de RAG (Retrieval-Augmented Generation) a tu LLM sobre documentación en Markdown almacenada en S3.

Diseñado para la simplicidad:

  • 🪶 Stack ligero: Sin dependencias pesadas ni servicios en la nube
  • 🏠 Embeddings flexibles: Elige entre Ollama (local, gratuito) o OpenAI (nube, alta precisión)
  • 💾 Almacenamiento basado en archivos: Los índices vectoriales se guardan como archivos simples (HNSWLib)
  • 🔌 Compatible con S3: Funciona con cualquier almacenamiento compatible con S3 (AWS, MinIO, Scaleway, Cloudflare R2...)

[!IMPORTANT]
🚧 Este proyecto está en desarrollo. Las APIs y el comportamiento pueden cambiar en cualquier momento, y no se garantiza compatibilidad hacia atrás. No es adecuado para producción.

Requisitos

  • Proveedor de embeddings (elige uno):
  • Node.js >= 18 (si se ejecuta desde el código fuente) O Docker (recomendado)
  • Almacenamiento compatible con S3 (AWS S3, MinIO, Scaleway, Cloudflare R2, etc.)

Casos de uso

  • 📚 Documentación de producto: Permite que Claude/Cursor/etc respondan desde tu documentación
  • 🏢 Wiki interna: Búsqueda de conocimiento empresarial impulsada por IA
  • 📖 Documentación de API: Ayuda a los desarrolladores a encontrar información de la API
  • 🎓 Contenido educativo: Crea tutores de IA con materiales de curso

Inicio rápido

Con Docker (recomendado)

# 1. Prerequisites
# Install Ollama from https://ollama.ai
ollama pull nomic-embed-text

# 2. Configure
cp env.example .env  # Add your S3 credentials

# 3. Run
docker run -d \
  --name s3-doc-mcp \
  -p 3000:3000 \
  --env-file .env \
  -e OLLAMA_BASE_URL=http://host.docker.internal:11434 \
  -v $(pwd)/data:/app/data \
  yoanbernabeu/s3-doc-mcp:latest

O usa Docker Compose (compilación local):

docker compose up -d

Desde el código fuente

# 1. Prerequisites
# Install Ollama from https://ollama.ai
ollama pull nomic-embed-text

# 2. Install & Run
npm install
cp env.example .env  # Configure your S3 credentials
npm run build && npm start

# 3. For local development
npm run dev

Tu servidor MCP ahora se está ejecutando en http://localhost:3000

Conectar a clientes MCP

Una vez que tu servidor esté en ejecución, debes configurar tu cliente MCP para conectarse a él.

Cursor

Edita tu archivo ~/.cursor/mcp.json y añade:

{
  "mcpServers": {
    "doc": {
        "type": "streamable-http",
        "url": "http://127.0.0.1:3000/mcp",
        "note": "S3 Documentation RAG Server"
    }
  }
}

Claude Desktop

Edita tu archivo de configuración de Claude Desktop:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "doc": {
        "type": "streamable-http",
        "url": "http://127.0.0.1:3000/mcp",
        "note": "S3 Documentation RAG Server"
    }
  }
}

Reinicia tu cliente MCP y ahora deberías ver:

  • 3 herramientas MCP: search_documentation, refresh_index, get_full_document
  • Recursos MCP: Lista completa de archivos de documentación indexados con acceso directo

💡 Consejo: Si usas Docker, asegúrate de que el mapeo de puertos coincida con tu configuración (el predeterminado es 3000:3000)

Características

  • 🔌 S3 universal: AWS S3, MinIO, Scaleway, DigitalOcean Spaces, Cloudflare R2, Wasabi...
  • 🧠 Embeddings flexibles:
    • Ollama (nomic-embed-text) - Local, gratuito, funciona sin conexión
    • OpenAI (text-embedding-3-small, text-embedding-3-large) - Basado en la nube, alta precisión, multilingüe
  • 🔄 Sincronización inteligente: Actualizaciones incrementales mediante comparación de ETag + sincronización completa automática cuando el almacén vectorial está vacío
  • ⚡ Búsqueda rápida: Índice vectorial HNSWLib con similitud coseno
  • 🔐 Autenticación opcional: Autenticación por clave de API para despliegues seguros
  • 🛠️ 3 herramientas MCP: search_documentation, refresh_index y get_full_document
  • 📚 Recursos MCP: Soporte nativo para descubrir y leer archivos indexados mediante la API estándar de Recursos MCP

Cómo funciona

El servidor sigue un pipeline simple:

  1. S3Loader: Escanea tu bucket de S3 en busca de archivos .md, descarga su contenido y rastrea los ETags para detectar cambios
  2. SyncService: Detecta archivos nuevos, modificados o eliminados y realiza una sincronización incremental (sin reprocesamiento innecesario)
  3. VectorStore:
    • Divide los documentos en fragmentos (1000 caracteres por defecto)
    • Genera embeddings usando tu proveedor elegido:
      • Ollama: nomic-embed-text (local, gratuito)
      • OpenAI: text-embedding-3-small o text-embedding-3-large (nube, alta precisión)
    • Indexa los vectores usando HNSWLib para una búsqueda de similitud rápida
  4. Servidor MCP: Expone tanto Herramientas como Recursos vía HTTP:
    • Herramientas: search_documentation, refresh_index, get_full_document para búsqueda semántica y acciones
    • Recursos: resources/list, resources/read para descubrimiento de archivos y acceso directo

¿Qué es HNSWLib?

HNSWLib (Hierarchical Navigable Small World) es una biblioteca ligera de búsqueda vectorial en memoria que es perfecta para este caso de uso:

  • ⚡ Rápido: Búsqueda aproximada del vecino más cercano en milisegundos
  • 💾 Simple: Almacena índices como archivos locales (sin necesidad de base de datos)
  • 🪶 Eficiente: Bajo uso de memoria, ideal para documentación personal o de equipos pequeños
  • 🎯 Preciso: Alta recuperación con similitud coseno para búsqueda semántica

Es el punto óptimo entre simplicidad y rendimiento para aplicaciones RAG.

Configuración

Copia env.example a .env y configura tus variables de entorno:

cp env.example .env

Variables esenciales

# S3 Configuration
S3_BUCKET_NAME=your-bucket-name           # Your S3 bucket name
S3_ACCESS_KEY_ID=your-access-key          # S3 access key
S3_SECRET_ACCESS_KEY=your-secret-key      # S3 secret key
S3_REGION=us-east-1                       # S3 region
S3_ENDPOINT=                              # Optional: for non-AWS S3 (MinIO, Scaleway, etc.)

# Embeddings Provider (choose one)
EMBEDDING_PROVIDER=ollama                 # ollama (default) or openai

# Option 1: Ollama (Local)
OLLAMA_BASE_URL=http://localhost:11434    # Ollama API endpoint
OLLAMA_EMBEDDING_MODEL=nomic-embed-text   # Ollama embedding model

# Option 2: OpenAI (Cloud) - Only if EMBEDDING_PROVIDER=openai
OPENAI_API_KEY=                           # Your OpenAI API key
OPENAI_EMBEDDING_MODEL=text-embedding-3-small  # or text-embedding-3-large

Consulta env.example para todas las opciones disponibles y documentación detallada (parámetros RAG, modo de sincronización, tamaño de fragmento, etc.).

Proveedores de embeddings

El servidor admite dos proveedores de embeddings:

🏠 Ollama (Local) - Predeterminado

Ventajas:

  • ✅ Gratuito: Sin costos de API, uso ilimitado
  • ✅ Privado: Todos los datos permanecen en tu máquina
  • ✅ Sin conexión: Funciona sin conexión a internet
  • ✅ Rápido: Llamadas directas a la API local

Desventajas:

  • ⚠️ Requiere instalación de Ollama y descarga del modelo
  • ⚠️ Usa recursos locales de CPU/GPU

Configuración:

# Install Ollama from https://ollama.ai
ollama pull nomic-embed-text

# Configure
EMBEDDING_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_EMBEDDING_MODEL=nomic-embed-text

☁️ OpenAI (Nube)

Ventajas:

  • ✅ Alta precisión: Embeddings de última generación
  • ✅ Multilingüe: Excelente soporte para más de 20 idiomas
  • ✅ Sin recursos locales: Se ejecuta completamente en la nube
  • ✅ Menor latencia: Respuestas rápidas de la API

Desventajas:

  • ⚠️ Requiere clave de API y créditos
  • ⚠️ Los datos se envían a los servidores de OpenAI
  • ⚠️ Costo por token (muy asequible: ~$0.00002/1K tokens para text-embedding-3-small)

Configuración:

# Get an API key from https://platform.openai.com/api-keys

# Configure
EMBEDDING_PROVIDER=openai
OPENAI_API_KEY=sk-...your-key...
OPENAI_EMBEDDING_MODEL=text-embedding-3-small  # or text-embedding-3-large

Comparación de modelos:

ModeloDimensionesRendimientoCostoMejor para
text-embedding-3-small1536AltoBajoPropósito general, sensible al costo
text-embedding-3-large3072Más altoMedioMáxima precisión, multilingüe

💡 Consejo: Comienza con text-embedding-3-small para la mayoría de los casos de uso. Solo cambia a text-embedding-3-large si necesitas la máxima precisión absoluta o trabajas extensamente con contenido no inglés.

Comportamiento de respaldo:

Si configuras EMBEDDING_PROVIDER=openai pero no proporcionas una OPENAI_API_KEY válida, el servidor recurrirá automáticamente a Ollama (si está configurado). Esto garantiza que el servidor siempre pueda iniciarse, incluso con una configuración incompleta.

Modos de sincronización

El servidor admite tres modos de sincronización mediante SYNC_MODE:

  • startup (predeterminado): Sincroniza al iniciar el servidor
    • ✅ Detección automática: Si el almacén vectorial está vacío, realiza automáticamente una sincronización completa
    • ✅ De lo contrario, realiza una sincronización incremental (solo archivos modificados)
    • ✅ ¡No se necesita refresh_index manual después de reiniciar!
  • periodic: Sincroniza a intervalos regulares (SYNC_INTERVAL_MINUTES)
    • Ejecuta sincronizaciones incrementales automáticamente
  • manual: Sin sincronización automática
    • Debes llamar a la herramienta refresh_index manualmente

💡 Nota: El servidor detecta automáticamente cuando el almacén vectorial está vacío (por ejemplo, después de eliminar la carpeta ./data/ o en el primer inicio) y activa una sincronización completa. Ya no necesitas ejecutar refresh_index manualmente después de cada reinicio.

🔐 Seguridad y autenticación

Autenticación por clave de API (opcional)

Por defecto, el servidor se ejecuta en modo de acceso abierto para facilitar el desarrollo local. Para despliegues compartidos o remotos, puedes habilitar la autenticación por clave de API:

# Enable authentication
ENABLE_AUTH=true

# Set your API key
MCP_API_KEY=your-secret-key-here

Cuando la autenticación está habilitada:

  • ✅ Todos los endpoints (excepto /health) requieren una clave de API válida
  • ✅ La clave de API se puede proporcionar mediante:
    • Cabecera de autorización (recomendado): Authorization: Bearer your-secret-key
    • Parámetro de consulta: ?api_key=your-secret-key
  • ✅ Las claves inválidas o faltantes devuelven HTTP 401 No autorizado

Ejemplos de uso:

# With Authorization header (recommended)
curl -H "Authorization: Bearer your-secret-key" http://localhost:3000/mcp

# With query parameter
curl "http://localhost:3000/mcp?api_key=your-secret-key"

Configuración del cliente MCP con clave de API:

{
  "mcpServers": {
    "doc": {
      "type": "streamable-http",
      "url": "http://127.0.0.1:3000/mcp",
      "headers": {
        "Authorization": "Bearer your-secret-key"
      },
      "note": "S3 Documentation RAG Server with authentication"
    }
  }
}

💡 Buenas prácticas:

  • Mantén la autenticación deshabilitada para el desarrollo local
  • Habilítala para redes compartidas o despliegues remotos
  • Usa claves fuertes y generadas aleatoriamente (por ejemplo, openssl rand -hex 32)
  • El endpoint /health siempre es accesible sin autenticación para monitoreo

Herramientas MCP

search_documentation

{
  "query": "How to configure S3?",
  "max_results": 4
}

Devuelve fragmentos de documentos relevantes con puntuaciones de similitud y fuentes.

refresh_index

{
  "force": false  // default: incremental sync (recommended)
}

Sincroniza el índice de documentación con S3, detectando archivos nuevos, modificados o eliminados.

Parámetros:

  • force (booleano, opcional, predeterminado: false)
    • false: Sincronización incremental - Solo procesa cambios (rápido, eficiente) ✅
    • true: Reindexación completa - Reprocesa TODOS los archivos (lento, costoso) ⚠️

⚠️ Importante: El parámetro force debe establecerse SOLO en true cuando sea explícitamente necesario (por ejemplo, "forzar reindexación", "reconstruir todo desde cero"). La reindexación completa es costosa:

  • Vuelve a descargar todos los archivos de S3
  • Regenera todos los embeddings
  • Reconstruye todo el almacén vectorial

Para operaciones normales, usa siempre la sincronización incremental (comportamiento predeterminado).

get_full_document

{
  "s3_key": "docs/authentification_magique_symfony.md"
}

Recupera el contenido completo de un archivo Markdown de S3 junto con metadatos:

  • Clave S3 completa: El identificador S3 del documento
  • Contenido Markdown completo: Documento entero (no fragmentado)
  • Metadatos: Tamaño en bytes, fecha de última modificación, ETag, número de fragmentos (si está indexado)

Casos de uso:

  • Ver el documento completo después de encontrarlo mediante search_documentation
  • Exportar documentación para uso externo
  • Comprender el contexto completo alrededor de un resultado de búsqueda
  • Mostrar documentos completos en integraciones de terceros

Notas importantes:

  • Si un documento aparece en los resultados de búsqueda pero get_full_document devuelve "no encontrado", significa que el archivo fue eliminado de S3 después de ser indexado
  • Solución: Ejecuta refresh_index para sincronizar el índice con el estado actual de S3
  • La herramienta proporcionará un mensaje de error útil indicando cuándo se necesita una sincronización

Recursos MCP

Además de las 3 herramientas, el servidor implementa Recursos MCP para el descubrimiento de archivos y acceso directo:

  • resources/list: Lista todos los archivos Markdown indexados con metadatos (nombre, URI, tamaño, fragmentos, última modificación)
  • resources/read: Lee el contenido completo de un archivo específico mediante su URI (por ejemplo, s3doc://docs/authentication.md)

Caso de uso: Cuando los usuarios preguntan "¿Qué archivos tienes?" o "Muéstrame el archivo X", el LLM puede navegar y acceder a los archivos directamente sin búsqueda semántica.

🤝 Contribuciones

¡Las contribuciones son bienvenidas! Por favor, lee nuestra Guía de contribución para obtener detalles sobre cómo enviar pull requests, reportar problemas y contribuir al proyecto.

📝 Licencia

MIT

👤 Autor

Yoan Bernabeu