Skip to main content
Glama
andresfrei

Google Drive MCP Server

by andresfrei

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
Install Server
A
security – no known vulnerabilities
F
license - not found
A
quality - confirmed to work

Latest Blog Posts

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