Skip to main content
Glama

Google Drive MCP Server

Servidor MCP (Model Context Protocol) modernizado para gestión de múltiples cuentas de Google Drive con acceso de solo lectura.

🎯 Características

  • StreamableHTTP Transport: Arquitectura stateless HTTP moderna (reemplaza SSE deprecado)

  • MCP SDK v1.19.1: Usando McpServer high-level API con validación automática

  • Multi-cliente: Múltiples clientes pueden conectarse simultáneamente (stateless)

  • Puerto configurable: Ideal para VPS con múltiples servicios MCP

  • Multi-cuenta: Gestiona múltiples cuentas de Google Drive simultáneamente

  • 7 Herramientas MCP: Incluyendo listado recursivo de carpetas

  • Arquitectura modular: Tools organizadas en módulos independientes

  • Autenticación segura: Query parameter o header API key

  • Operaciones de archivos: Listar, buscar, recursivo y obtener contenido

  • Soporta Google Workspace: Docs, Sheets, Slides

  • Archivos de texto: TXT, Markdown

  • Logging estructurado: Winston con múltiples niveles

  • Validación robusta: Zod schemas en todas las herramientas

  • Path alias @/: Imports absolutos desde src/

  • Oxlint + Prettier: Linting ultrarrápido y formato consistente

  • Docker-ready: Configuración lista para deployment en VPS

📁 Estructura del Proyecto

src/ config/ config-loader.ts # Gestión de configuración de Drives types.ts # Tipos y esquemas Zod services/ drive-service.ts # Servicio de Google Drive API (incluye recursivo) utils/ logger.ts # Sistema de logging con Winston mcp/ auth.ts # Autenticación de requests MCP server.ts # Configuración del servidor MCP (33 líneas) tools/ # 🆕 Herramientas modularizadas index.ts # Exportador central list-drives.ts # Listar cuentas configuradas add-drive.ts # Agregar cuenta remove-drive.ts # Eliminar cuenta list-files.ts # Listar archivos con filtros list-files-recursive.ts # 🆕 Listado recursivo get-file-content.ts # Obtener contenido search-files.ts # Buscar por nombre index.ts # Entry point del servidor tests/ test-mcp-client.ts # Test de conexión general test-recursive.ts # Test de listado recursivo test-drive.ts # Test de API de Drive README.md # Documentación de tests

🚀 Instalación y Deployment

Desarrollo Local

# Clonar repositorio git clone https://github.com/andresfrei/mcp-google-drive-server.git cd mcp-google-drive-server # Instalar dependencias pnpm install # Configurar environment cp .env.example .env nano .env # Desarrollo (con hot reload) pnpm dev # El servidor estará disponible en http://localhost:3001

Producción con Docker

# Build y run con docker-compose docker-compose up -d # Ver logs docker-compose logs -f mcp-drive # Detener docker-compose down

VPS con Múltiples MCPs

Para ejecutar varios servidores MCP en el mismo VPS, configura diferentes puertos:

# MCP Drive en puerto 3001 MCP_DRIVE_PORT=3001 docker-compose up -d # En otro directorio, otro MCP en puerto 3002 cd ../otro-mcp && MCP_OTRO_PORT=3002 docker-compose up -d

⚙️ Configuración

1. Service Account de Google

  1. Crear proyecto en Google Cloud Console

  2. Habilitar Google Drive API

  3. Crear Service Account y descargar JSON

  4. Compartir carpetas/archivos de Drive con el email del Service Account

  5. Guardar JSON en credentials/

2. Archivo de Configuración

El servidor usa drives-config.json para gestionar cuentas:

{ "drives": { "personal": { "name": "Drive Personal", "description": "Mi Drive personal", "serviceAccountPath": "./credentials/personal-sa.json" }, "work": { "name": "Drive Trabajo", "description": "Cuenta corporativa", "serviceAccountPath": "./credentials/work-sa.json" } } }

Nota: El archivo se crea automáticamente vacío si no existe. Usa la herramienta add_drive para agregar cuentas.

3. Variables de Entorno

# Configuración del servidor HTTP MCP_DRIVE_PORT=3001 # Puerto del servidor (default: 3001) MCP_DRIVE_HOST=0.0.0.0 # Host de escucha (0.0.0.0 para Docker) # Configuración de Drives DRIVES_CONFIG_PATH=./drives-config.json # Nivel de logging (debug, info, warn, error) LOG_LEVEL=info # API key para autenticación de requests MCP (opcional) MCP_API_KEY=tu_api_key_seguro

🛠️ Herramientas MCP

El servidor expone 7 herramientas vía protocolo MCP:

Gestión de Drives

list_drives

Lista todas las cuentas de Google Drive configuradas.

Parámetros: Ninguno

Respuesta:

[ { "id": "personal", "name": "Drive Personal", "description": "Mi Drive personal" } ]

add_drive

Agrega una nueva cuenta de Google Drive a la configuración.

Parámetros:

  • driveId (string, requerido): ID único (ej: 'personal', 'work')

  • name (string, requerido): Nombre descriptivo

  • description (string, opcional): Descripción de la cuenta

  • serviceAccountPath (string, requerido): Ruta al archivo JSON de Service Account

Ejemplo:

{ "driveId": "personal", "name": "Drive Personal", "description": "Mi cuenta personal", "serviceAccountPath": "./credentials/personal-sa.json" }

remove_drive

Elimina una cuenta de Drive de la configuración.

Parámetros:

  • driveId (string, requerido): ID del Drive a eliminar

Operaciones de Archivos

list_files

Lista archivos de Google Drive con filtros opcionales.

Parámetros:

  • driveId (string, opcional): ID del Drive (usa el primero si se omite)

  • folderId (string, opcional): ID de carpeta específica

  • modifiedAfter (string, opcional): Fecha ISO 8601

  • modifiedBefore (string, opcional): Fecha ISO 8601

  • mimeType (string, opcional): Tipo MIME específico

  • pageSize (number, opcional): Límite de resultados (default: 100)

Respuesta:

{ "totalFiles": 5, "files": [ { "id": "1abc...", "name": "Documento.docx", "mimeType": "application/vnd.google-apps.document", "modifiedTime": "2024-10-16T10:30:00Z", "size": "12345", "webViewLink": "https://drive.google.com/...", "parents": ["0BwwA4oUTeiV1TGRPeTVjaWRDY1E"] } ] }

get_file_content

Obtiene el contenido de un archivo de Google Drive.

Soporta:

  • Google Docs → exporta como texto plano

  • Google Sheets → exporta como CSV

  • Archivos de texto (.txt, .md) → descarga directa

Parámetros:

  • fileId (string, requerido): ID del archivo

  • driveId (string, opcional): ID del Drive

Respuesta:

{ "fileId": "1abc...", "fileName": "Documento.txt", "mimeType": "text/plain", "content": "Contenido del archivo...", "extractedAt": "2024-10-16T10:30:00Z" }

search_files

Busca archivos por nombre en un Drive específico.

Parámetros:

  • driveId (string, requerido): ID del Drive donde buscar

  • query (string, requerido): Texto a buscar en nombres de archivo

Respuesta:

{ "totalFiles": 3, "files": [ { "id": "1abc...", "name": "Presupuesto 2024.xlsx", "mimeType": "application/vnd.google-apps.spreadsheet", "modifiedTime": "2024-10-16T10:30:00Z", "webViewLink": "https://drive.google.com/..." } ] }

list_files_recursive 🆕

Lista recursivamente todos los archivos y subcarpetas dentro de una carpeta con filtros opcionales por fecha y tipo, ideal para escaneos diarios de documentos modificados.

Parámetros:

  • folderId (string, requerido): ID de la carpeta raíz desde donde iniciar

  • driveId (string, opcional): ID del Drive (usa el primero si se omite)

  • maxDepth (number, opcional): Profundidad máxima de recursión (default: 10)

  • modifiedAfter (string, opcional): Filtrar archivos modificados después de esta fecha (formato RFC 3339: 2024-10-17T08:00:00 o 2024-10-17T08:00:00Z para UTC)

  • mimeType (string, opcional): Filtrar por tipo MIME específico (ej: application/vnd.google-apps.document para Google Docs, application/pdf para PDFs)

Respuesta:

{ "totalItems": 42, "filters": { "modifiedAfter": "2024-10-17T08:00:00", "mimeType": "application/vnd.google-apps.document" }, "items": [ { "id": "1abc...", "name": "Reporte Mensual.docx", "mimeType": "application/vnd.google-apps.document", "modifiedTime": "2024-10-17T10:30:00Z", "size": "12345", "webViewLink": "https://drive.google.com/...", "parents": ["0BwwA4oUTeiV1TGRPeTVjaWRDY1E"], "depth": 0, "path": "/CONTABILIDAD/Reporte Mensual.docx" }, { "id": "2def...", "name": "Presupuesto.docx", "mimeType": "application/vnd.google-apps.document", "modifiedTime": "2024-10-17T14:20:00Z", "size": "470883", "webViewLink": "https://drive.google.com/...", "parents": ["1abc..."], "depth": 2, "path": "/CONTABILIDAD/DOCUMENTOS/Presupuesto.docx" } ] }

Características:

  • Filtros opcionales: Por fecha de modificación y tipo MIME

  • Exploración completa: Las carpetas siempre se recorren, filtros aplican solo a archivos

  • Búsqueda recursiva: DFS (Depth-First Search) en toda la jerarquía

  • Metadatos completos: ID, nombre, ruta completa, fecha, tipo, tamaño

  • Campo : Nivel de anidación (0 = raíz)

  • Campo : Ruta completa desde carpeta inicial

  • Protección: Límite maxDepth previene recursión infinita

  • Optimizado: Doble query para carpetas + archivos filtrados

  • Google Drive API: Límite de 1000 items por nivel

Caso de uso típico (escaneo diario):

// Obtener todos los Google Docs modificados hoy después de las 8 AM const result = await client.callTool({ name: "list_files_recursive", arguments: { folderId: "carpeta-raiz-id", modifiedAfter: "2024-10-17T08:00:00", mimeType: "application/vnd.google-apps.document", maxDepth: 5, }, }); // Resultado: Solo Docs modificados hoy, con rutas completas para procesamiento LLM

🌐 Endpoints HTTP

El servidor expone los siguientes endpoints:

Health Check

GET http://localhost:3001/health # Respuesta { "status": "healthy", "timestamp": "2024-10-16T10:30:00.000Z" }

Conexión MCP (StreamableHTTP)

GET http://localhost:3001/mcp?apiKey=tu-api-key-aqui # Establece conexión StreamableHTTP para comunicación MCP # Autenticación vía query parameter (recomendado) o header X-API-Key

Nota sobre SSE: El transporte SSE (Server-Sent Events) está deprecado en MCP SDK v1.19+. Use StreamableHTTP.

🔌 Conectar desde Cliente

Opción 1: StreamableHTTP (Recomendado) 🆕

Transport moderno stateless para cualquier aplicación:

import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; // Conectar con autenticación por query parameter const transport = new StreamableHTTPClientTransport( new URL("http://localhost:3001/mcp?apiKey=tu-api-key-aqui") ); const client = new Client( { name: "my-app", version: "1.0.0", }, { capabilities: {}, } ); await client.connect(transport); // Listar herramientas disponibles (7 tools) const tools = await client.listTools(); console.log(`Tools disponibles: ${tools.tools.length}`); // Ejecutar herramienta const result = await client.callTool({ name: "list_drives", arguments: {}, }); console.log(result); // Listar recursivamente una carpeta const recursiveResult = await client.callTool({ name: "list_files_recursive", arguments: { folderId: "1AdO2achPP4Kgz4AGmKw2C4wKF49Ce-KC", driveId: "comnet-manuales", maxDepth: 5, }, }); await client.close();

Opción 2: Cliente NestJS (Orquestador)

Recomendado para aplicaciones que necesitan múltiples MCPs:

// src/mcp/mcp.config.ts (NestJS) import { registerAs } from "@nestjs/config"; export default registerAs("mcp", () => ({ servers: { googleDrive: { name: "google-drive-local", transport: { type: "streamableHttp", // 🆕 Cambio de "sse" a "streamableHttp" // Desarrollo: http://localhost:3001/mcp?apiKey=... // Producción Docker: http://mcp-drive:3001/mcp?apiKey=... url: process.env.MCP_DRIVE_URL || `http://localhost:3001/mcp?apiKey=${process.env.MCP_DRIVE_API_KEY}`, }, timeout: 30000, }, }, })); // src/mcp/mcp.service.ts import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; const transport = new StreamableHTTPClientTransport( new URL(config.transport.url) ); await client.connect(transport);

📚 Ver guía completa: docs/NESTJS-CLIENT.md

Características del Cliente

  • CORS habilitado: Funciona desde cualquier dominio

  • API Key dual: Via query parameter ?apiKey=... (recomendado) o header X-API-Key

  • Stateless: No mantiene sesiones, ideal para Docker/Kubernetes

  • Multi-cliente: Múltiples clientes pueden conectarse simultáneamente

  • Retry automático: SDK maneja reconexiones

🔒 Seguridad

  • Solo lectura: Service Account con scope drive.readonly

  • Autenticación opcional: Soporta API key via header X-API-Key

  • CORS configurado: Permite conexiones desde clientes externos

  • Validación robusta: Esquemas Zod para todos los inputs

  • Logging seguro: No expone credenciales en logs

Autenticación con API Key

1. Configurar API key en servidor:

# .env MCP_API_KEY=tu_api_key_super_secreto_aqui

2. Enviar desde cliente:

// Opción 1: Query parameter (recomendado para StreamableHTTP) const transport = new StreamableHTTPClientTransport( new URL("http://localhost:3001/mcp?apiKey=tu_api_key_super_secreto_aqui") ); // Opción 2: Header (alternativa) const transport = new StreamableHTTPClientTransport( new URL("http://localhost:3001/mcp"), { headers: { "X-API-Key": "tu_api_key_super_secreto_aqui", }, } );

3. Comportamiento:

  • ✅ Si MCP_API_KEY NO está configurado → Acceso libre (desarrollo)

  • 🔒 Si MCP_API_KEY está configurado → Requiere header X-API-Key

Seguridad en Producción (VPS)

⚠️ Importante: Este servidor usa HTTP sin cifrado. Para producción:

  1. Reverse Proxy con SSL (nginx/traefik)

  2. Firewall: Restringir acceso por IP

  3. Rate Limiting: Prevenir abuso

  4. API Key: Habilitar autenticación

Ejemplo nginx con SSL:

upstream mcp_drive { server localhost:3001; } server { listen 443 ssl http2; server_name mcp-drive.tudominio.com; ssl_certificate /etc/letsencrypt/live/tudominio.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/tudominio.com/privkey.pem; # Solo permitir IP del orquestador allow 192.168.1.100; deny all; location / { proxy_pass http://mcp_drive; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-API-Key $http_x_api_key; # Pasar API key proxy_buffering off; proxy_cache off; proxy_read_timeout 86400; } }

CORS en Producción

Por defecto, CORS permite cualquier origen (*). Para producción, restringe dominios:

// src/index.ts app.use((req, res, next) => { res.setHeader( "Access-Control-Allow-Origin", "https://tu-app.com" // Solo tu dominio ); // ... resto });

📊 Logging

El servidor genera logs estructurados en JSON:

  • Consola: Formato colorizado para desarrollo

  • error.log: Solo errores críticos

  • combined.log: Todos los niveles

Configurar nivel via LOG_LEVEL env variable.

🐳 Docker

Docker Compose (Recomendado)

# Levantar servicio docker-compose up -d # Ver logs en tiempo real docker-compose logs -f # Detener servicio docker-compose down # Reconstruir después de cambios docker-compose up -d --build

Docker Manual

# Build docker build -t mcp-drive-server . # Run docker run -d \ --name mcp-drive \ -p 3001:3000 \ -e PORT=3000 \ -e HOST=0.0.0.0 \ -e LOG_LEVEL=info \ -v $(pwd)/drives-config.json:/app/config/drives-config.json \ -v $(pwd)/keys:/app/keys:ro \ -v $(pwd)/logs:/app/logs \ mcp-drive-server # Ver logs docker logs -f mcp-drive

Múltiples Instancias en VPS

# Instancia 1 - Drive Personal (puerto 3001) docker run -d --name mcp-drive-personal \ -p 3001:3000 \ -v $(pwd)/config-personal:/app/config \ mcp-drive-server # Instancia 2 - Drive Trabajo (puerto 3002) docker run -d --name mcp-drive-work \ -p 3002:3000 \ -v $(pwd)/config-work:/app/config \ mcp-drive-server

🧪 Desarrollo y Testing

# Desarrollo local con hot reload pnpm dev # Servidor en http://localhost:3001 # Linting con oxlint (ultrarrápido) pnpm lint pnpm lint:fix # Formateo con Prettier pnpm format pnpm format:check # Verificación completa (lint + format) pnpm check # Build para producción pnpm build # Ejecutar versión compilada pnpm start # Tests pnpm test:client # Test de conexión y tools básicas pnpm test:recursive # Test de listado recursivo pnpm test:drive # Test de Google Drive API pnpm test:all # Ejecutar todos los tests # Ver logs de Docker docker-compose logs -f # Reiniciar contenedor docker-compose restart # Reconstruir imagen docker-compose up -d --build

Tests Disponibles

El proyecto incluye 3 tests completos en la carpeta tests/:

  1. test-mcp-client.ts: Conexión general y herramientas básicas

  2. test-recursive.ts: Validación de listado recursivo (166 items en estructura COMNET)

  3. test-drive.ts: Pruebas directas con Google Drive API

📚 Ver documentación completa: tests/README.md

📊 Monitoreo

# Health check curl http://localhost:3001/health # Test de conexión MCP pnpm test:client # Logs en tiempo real docker-compose logs -f mcp-drive # Stats de recursos docker stats mcp-drive # Inspeccionar contenedor docker inspect mcp-drive

🏗️ Arquitectura Técnica

Transport Layer

  • StreamableHTTP: Transport moderno stateless (HTTP-based)

  • Deprecado: SSE (Server-Sent Events) - removido en v2.0.0

  • Ventajas: Sin estado, escalable, compatible con proxies/load balancers

MCP SDK

  • Version: 1.19.1

  • API: McpServer high-level (reemplaza Server low-level)

  • Validación: Zod schemas automáticos en inputSchema/outputSchema

  • Registro: server.registerTool(name, config, handler)

Herramientas Modularizadas

// src/mcp/tools/list-drives.ts export const listDrivesTool = { name: "list_drives", config: { title, description, inputSchema, outputSchema }, handler: async (params) => { /* ... */ }, }; // src/mcp/server.ts (33 líneas) const toolList = Object.values(tools); toolList.forEach((tool) => { server.registerTool(tool.name, tool.config, tool.handler); });

Path Aliases

// tsconfig.json "baseUrl": ".", "paths": { "@/*": ["src/*"] } // En código import { logger } from "@/utils/logger.js"; import { googleDriveService } from "@/services/drive-service.js";

Nota: Los imports usan extensión .js aunque los archivos sean .ts (requisito de TypeScript ESM con "module": "NodeNext")

📝 Tipos MIME Soportados

Google Workspace

  • application/vnd.google-apps.document - Google Docs

  • application/vnd.google-apps.spreadsheet - Google Sheets

  • application/vnd.google-apps.presentation - Google Slides

Archivos de Texto

  • text/plain - Texto plano

  • text/markdown - Markdown

Formatos de Exportación

  • text/plain - Docs exportados

  • text/csv - Sheets exportados

🤝 Contribuir

  1. Fork el repositorio

  2. Crea una rama para tu feature (git checkout -b feature/amazing-feature)

  3. Commit tus cambios (git commit -m 'Add amazing feature')

  4. Push a la rama (git push origin feature/amazing-feature)

  5. Abre un Pull Request

📄 Licencia

Este proyecto está bajo licencia MIT.

🆘 Troubleshooting

Servidor no inicia

# Verificar que el puerto no esté en uso netstat -ano | findstr :3000 # Windows lsof -i :3000 # Linux/Mac # Cambiar puerto si está ocupado PORT=3001 pnpm dev

Error: "Service account file not found"

  • Verifica que el archivo JSON existe en la ruta especificada

  • En Docker, asegúrate de montar el volumen correctamente:

    -v $(pwd)/keys:/app/keys:ro

Error: "Unauthorized: Invalid API key"

  • Verifica que MCP_API_KEY esté configurado en el servidor

  • El API key debe enviarse en el header X-API-Key (no en _meta.apiKey)

  • Formato correcto:

    headers: { "X-API-Key": "tu-api-key" }

No se pueden leer archivos

  • Verifica que el Service Account tenga acceso (compartido con su email)

  • Confirma que el scope sea drive.readonly

  • Revisa permisos de la carpeta/archivo en Drive

Cliente no puede conectar (VPS)

# Verificar que el puerto esté expuesto docker ps | grep mcp-drive # Verificar firewall sudo ufw status sudo ufw allow 3001/tcp # Test de conectividad curl http://vps-ip:3001/health

Logs no aparecen

  • Configura LOG_LEVEL=debug para ver más detalles

  • Verifica permisos de escritura en la carpeta del proyecto

  • En Docker: docker-compose logs -f mcp-drive

Alto uso de memoria

  • Ajusta límites en docker-compose.yml:

    deploy: resources: limits: memory: 256M
Deploy Server
A
security – no known vulnerabilities
F
license - not found
A
quality - confirmed to work

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/andresfrei/mcp-drive'

If you have feedback or need assistance with the MCP directory API, please join our Discord server