akij-hr-data-mcp
akij-hr-data-mcp
Un servidor Model Context Protocol (MCP) remoto, de solo lectura y listo para producción, que expone una única carpeta de Google Drive — el repositorio AKIJ HR DATA — a clientes compatibles con MCP mediante el moderno transporte Streamable HTTP.
Es un MCP de Drive de propósito general: maneja archivos XLSX, XLS, CSV, PDF, DOCX, TXT, imágenes y archivos nativos de Google Docs/Sheets/Slides — no solo una herramienta de Excel.
1. Qué hace este proyecto
Se conecta a Google Drive mediante una cuenta de servicio (sin flujo OAuth de usuario ni inicio de sesión en el navegador).
Restringe todas las operaciones a una carpeta configurada (
GOOGLE_DRIVE_FOLDER_ID) y sus subcarpetas. Los archivos fuera de ese árbol nunca se devuelven, aunque la cuenta de servicio pudiera verlos técnicamente.Expone 11 herramientas MCP para descubrir y leer archivos (listar, buscar, metadatos, contenido y extracción específica por formato para Excel/CSV/PDF/DOCX).
Se ejecuta como un servidor HTTP estándar de Node/Express con un único endpoint
POST /mcp(transporte Streamable HTTP) y un endpointGET /health, desplegable en Render (o cualquier host de Node) para que siga funcionando cuando tu PC está apagado.Exige autenticación mediante clave de API en cada solicitud MCP.
Es estrictamente de solo lectura — no existe ninguna ruta de código que pueda subir, editar, eliminar, renombrar, mover o compartir un archivo de Drive, ni cambiar permisos.
Related MCP server: Google Drive MCP Server
2. Arquitectura
Google Drive (AKIJ HR DATA folder)
↓ Drive API v3 (read-only scope)
Google Service Account (GCP_KEY_BASE64)
↓
GoogleDriveClient (src/google-drive.ts) — enforces folder-tree scope
↓
MCP Server (src/mcp-server.ts) — 11 tools, Zod-validated inputs
↓
Express app (src/index.ts) — API-key auth, Streamable HTTP transport
↓ POST /mcp (stateless, one transport per request)
↓
Render (always-on host)
↓ HTTPS
Remote MCP Clients (Claude, other MCP-compatible clients)El servidor es sin estado: cada solicitud POST /mcp recibe su propia instancia de McpServer + StreamableHTTPServerTransport (sessionIdGenerator: undefined), por lo que no hay requisito de afinidad de sesión y se escala horizontalmente en Render sin sesiones adhesivas.
Estructura del proyecto
src/
index.ts Express app: /health, /mcp, startup
config.ts Environment variable loading/validation
auth.ts API-key authentication middleware
google-auth.ts Decodes GCP_KEY_BASE64 → JWT auth client
google-drive.ts Drive API client with folder-scope enforcement
mcp-server.ts McpServer wiring: registers all 11 tools
tools/
files.ts list_files, get_file_metadata, get_file_content, list_supported_files
search.ts search_files, search_repository
excel.ts inspect_excel, read_excel_sheet
csv.ts read_csv
pdf.ts extract_pdf_text
docx.ts extract_docx_text
utils/
errors.ts Typed AppError hierarchy + safe error serialization
limits.ts Size/row/timeout/pagination limits
mime-types.ts MIME → file-category classification
tests/ Jest test suite (46 tests, 10 suites)
.env.example
.gitignore
render.yaml Render Blueprint (optional one-click deploy)
README.md
package.json
tsconfig.json
jest.config.cjs3. Requisitos previos
Node.js 20+ y npm
Un proyecto de Google Cloud con la API de Google Drive habilitada
Una cuenta de servicio de Google con acceso de Lector compartida en la carpeta de Drive de AKIJ HR DATA
Una cuenta de GitHub (para desplegar en Render desde un repositorio)
Una cuenta de Render
4. Instalación
npm install5. Variables de entorno
Variable | Requerida | Descripción |
| no (predeterminado | Puerto en el que escucha el servidor HTTP. Render lo establece automáticamente. |
| sí | El ID de la carpeta de Drive a la que está restringido este MCP. |
| sí | Clave JSON de la cuenta de servicio codificada en Base64. |
| sí | Lista separada por comas de claves de API válidas para |
Consulta el archivo .env.example para ver la plantilla (no se incluyen secretos reales en el repositorio).
6. Configuración de Google Cloud
Ve a console.cloud.google.com y selecciona/crea un proyecto.
APIs y servicios → Biblioteca → habilita Google Drive API.
APIs y servicios → Credenciales → Crear credenciales → Cuenta de servicio.
Asígnale un nombre (p. ej.,
akij-hr-data-mcp); no se necesita ningún rol de IAM a nivel de proyecto.Abre la nueva cuenta de servicio → Claves → Añadir clave → Crear clave nueva → JSON. Esto descarga un archivo
gcp-key.json— no hagas commit de este archivo.Anota la dirección de correo de la cuenta de servicio (con el formato
akij-hr-data-mcp@your-project.iam.gserviceaccount.com).
7. Permisos de Google Drive
Abre la carpeta AKIJ HR DATA en Google Drive (ID de carpeta
1oxYLPcC9MPVuxsbeP0kGgYhLmkxt0w2o).Haz clic en Compartir, pega el correo de la cuenta de servicio y concede acceso de Lector.
No concedas Editor/Propietario — este servidor nunca escribe en Drive, por lo que Lector es suficiente y más seguro.
8. Configuración local
npm install
cp .env.example .env
# fill in GOOGLE_DRIVE_FOLDER_ID, GCP_KEY_BASE64, API_KEYS in .env
npm run devnpm run dev ejecuta el servidor TypeScript directamente con tsx watch (no se necesita paso de compilación para la iteración local).
9. Generar GCP_KEY_BASE64
Nunca debes pegar el JSON sin procesar de la cuenta de servicio en un chat, en el código fuente ni en .env.example. Genera el valor base64 localmente desde tu gcp-key.json descargado y colócalo únicamente en tu .env local (gitignored) o en la configuración de variables de entorno de Render.
PowerShell:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\Downloads\gcp-key.json")) | Set-ClipboardEsto lee el archivo de clave y copia la cadena base64 directamente al portapapeles: pégala como valor de GCP_KEY_BASE64 en .env (localmente) o en el panel de Render (para el despliegue). Ajusta la ruta si gcp-key.json no está en tu carpeta de Descargas.
Si prefieres imprimirla en la terminal en lugar de en el portapapeles:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\Downloads\gcp-key.json"))10. Pruebas locales
Inicia el servidor:
npm run devComprueba el estado:
curl http://localhost:10000/healthLlama a una herramienta MCP (ejemplo: list_files) con curl, usando la secuencia initialize → tools/call, o apunta cualquier cliente MCP compatible con Streamable HTTP a http://localhost:10000/mcp con la cabecera X-Api-Key: <one of your API_KEYS>.
11. Compilación
npm run buildCompila src/ (TypeScript, NodeNext ESM) a dist/. Ejecuta npm run typecheck para verificar tipos sin generar archivos.
Ejecuta la suite de pruebas:
npm testEsto ejecuta Jest en banda (46 pruebas en 10 suites: config, auth, Google auth, cumplimiento del ámbito de carpeta de Drive, las 11 herramientas y los endpoints HTTP /health y /mcp).
12. Configuración de GitHub
git init
git add .
git commit -m "Initial commit: akij-hr-data-mcp"
git branch -M main
git remote add origin https://github.com/<your-username>/akij-hr-data-mcp.git
git push -u origin main.env, gcp-key.json, *.pem y *.key ya están en gitignore — verifica con git status antes de hacer commit que no haya nada secreto en el área de staging.
13. Despliegue en Render
Ve a render.com → Nuevo → Web Service.
Conecta tu repositorio de GitHub (
akij-hr-data-mcp).Render detectará
render.yaml(Blueprint) automáticamente, o configúralo manualmente:Build Command:
npm install && npm run buildStart Command:
npm startHealth Check Path:
/health
Añade las variables de entorno (sección 14) en el panel de Render — nunca las hagas commit.
Despliega. Render compila, inicia el servicio y lo mantiene en ejecución de forma independiente de tu PC.
14. Variables de entorno en Render
Configúralas en Render → tu servicio → Environment:
PORT=10000
GOOGLE_DRIVE_FOLDER_ID=1oxYLPcC9MPVuxsbeP0kGgYhLmkxt0w2o
GCP_KEY_BASE64=<paste the base64 string from step 9>
API_KEYS=<comma-separated production keys, e.g. key-abc123,key-def456>Genera claves de API aleatorias y seguras, por ejemplo:
[Convert]::ToBase64String([Guid]::NewGuid().ToByteArray()) -replace '[+/=]',''15. Endpoint de salud
GET /health{ "status": "ok", "timestamp": "2026-08-17T12:00:00.000Z" }No requiere autenticación; no expone secretos ni estado interno.
16. Endpoint MCP
POST /mcpImplementa el transporte MCP Streamable HTTP (
@modelcontextprotocol/sdkStreamableHTTPServerTransport), sin estado (sessionIdGenerator: undefined) — sin respaldo solo-SSE.Requiere autenticación: cabecera
Authorization: Bearer <API_KEY>oX-Api-Key: <API_KEY>.GET /mcpyDELETE /mcpdevuelven405— este servidor no mantiene sesiones ni soporta el flujo SSE opcional.
17. Conectar el MCP remoto a los clientes
Una vez desplegado, tu endpoint MCP es:
https://<your-render-service>.onrender.com/mcpPara clientes MCP que soporten servidores remotos/HTTP, añade una entrada de servidor con:
URL:
https://<your-render-service>.onrender.com/mcpTransporte: Streamable HTTP
Cabeceras:
X-Api-Key: <one of your API_KEYS>(oAuthorization: Bearer <API_KEY>)
Ejemplo de configuración genérica de cliente:
{
"mcpServers": {
"akij-hr-data": {
"url": "https://<your-render-service>.onrender.com/mcp",
"headers": {
"X-Api-Key": "<API_KEY>"
}
}
}
}18. Seguridad
Solo lectura: no existe ninguna herramienta de subir/eliminar/editar/renombrar/mover/compartir/permisos en este código.
Ámbito de carpeta:
GoogleDriveClient.assertFileInScoperecorre la cadenaparentsde cada archivo hasta la raíz configurada antes de devolver cualquier metadato o contenido; los archivos fuera del árbol lanzan unForbiddenError.Autenticación por clave de API: cada solicitud
POST /mcpse comprueba contraAPI_KEYScon una comparación segura en tiempo (crypto.timingSafeEqual). Las claves ausentes o inválidas reciben401.Las credenciales nunca se registran ni se devuelven: el JSON de la cuenta de servicio decodificado permanece dentro de
google-auth.ts; ninguna herramienta, línea de log o mensaje de error puede sacarlo a la luz. Las respuestas de error pasan portoSafeErrorMessage, que elimina los stack traces y los cuerpos de error sin procesar de los servicios ascendentes.Límites de tamaño/salida: las descargas tienen un tope (
LIMITS.MAX_DOWNLOAD_BYTES/MAX_PARSE_BYTES), la extracción de texto se trunca (MAX_TEXT_OUTPUT_CHARS), las filas se paginan (DEFAULT_ROW_LIMIT/MAX_ROW_LIMIT) y cada llamada saliente a la API de Google tiene un tiempo de espera (GOOGLE_API_TIMEOUT_MS).Autenticación extensible:
req.identityes una estructura pequeña y estable ({ keyId }) diseñada para que una futura capa de autorización por clave de usuario, OAuth o por roles pueda adjuntar claims más ricos sin cambiar todos los puntos de llamada.Aviso conocido de dependencia: el paquete
xlsx(SheetJS) utilizado para el análisis de.xlsheredado tiene un aviso publicado de alta gravedad (prototype pollution / ReDoS). Solo se usa para archivos internos controlados por acceso de tu propia carpeta de Drive (no cargas arbitrarias de internet) y los archivos tienen un límite de tamaño antes de analizarse. Ejecutanpm auditperiódicamente y considera reemplazarlo si hay una versión parcheada disponible.
Lista de verificación de seguridad
gcp-key.jsonnunca se hace commit en git.envnunca se hace commit en gitAPI_KEYSconfiguradas con valores fuertes y aleatorios en Render (no el valor de desarrollo local)La cuenta de servicio tiene solo Lector en la carpeta de Drive
GOOGLE_DRIVE_FOLDER_IDcoincide con la carpeta del repositorio previstoLas variables de entorno de Render se configuran directamente en el panel, nunca en los valores commiteados de
render.yaml
19. Solución de problemas
Síntoma | Causa | Solución |
El servidor se cierra inmediatamente con un | Variable de entorno ausente o inválida | Comprueba la variable exacta mencionada en el mensaje de error en la sección 5 |
| Se codificó un archivo equivocado, o el copiar/pegar truncó la cadena | Regenera con el comando de PowerShell de la sección 9 |
| La cuenta de servicio no está compartida en la carpeta, o está compartida con un correo incorrecto | Revisa la sección 7; confirma que el |
| Pasaste un | Usa |
| Clave de API ausente o incorrecta | Envía |
Error | El archivo supera el límite de bytes configurado | Esto es intencional; los archivos grandes se rechazan en lugar de cargarse por completo en memoria (consulta |
El servicio de Render se duerme / tarda en arrancar en frío | Los planes gratuitos/de inicio de Render quedan inactivos tras un periodo de inactividad | Mejora el plan de Render o acepta el retraso de arranque en frío en la primera solicitud |
Las pruebas se cuelgan durante minutos en local |
| Ya está mitigado: |
Pasos manuales restantes (solo tú puedes hacerlos)
Genera
GCP_KEY_BASE64a partir de tugcp-key.jsondescargado (sección 9) y ponlo en tu.envlocal para probar.Comparte la carpeta de Drive de AKIJ HR DATA con el correo electrónico de tu cuenta de servicio como Viewer (sección 7).
Ejecuta localmente (
npm run dev) y confirma queGET /healthy una llamada real alist_filesfuncionan con tu carpeta real de Drive.Haz push a GitHub (sección 12).
Crea el Render Web Service, conecta el repositorio y configura las cuatro variables de entorno en el panel de Render (secciones 13–14): Render compilará y desplegará automáticamente.
Genera
API_KEYSde producción (diferentes de cualquier clave de desarrollo local) y guárdalas de forma segura para tus clientes MCP.Conecta tu cliente MCP a
https://<your-render-service>.onrender.com/mcp(sección 17).
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- -license-qualityAmaintenanceThis MCP server integrates with Google Drive to allow listing, reading, and searching over files.4,90789,405MIT
- Alicense-qualityDmaintenanceA server that provides a Machine Control Protocol (MCP) interface to search, access, and interact with Google Drive files and folders, enabling AI assistants to work with Google Drive content.8MIT
- Flicense-qualityCmaintenanceA read-only Google Drive MCP server that allows searching files, reading file content (with auto-export for Google Docs, Sheets, Slides), and retrieving file metadata via OAuth authentication.262
- AlicenseAqualityAmaintenanceMCP server for interacting with Google Drive using a service account, restricted to a specific root folder. Supports file operations like search, list, create, update, and read.4396MIT
Related MCP Connectors
MCP server for Google search results via SERP API
MCP server for AgentDocs (agentdocs.eu): read, search, write, comment on & share Markdown docs.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/mdshahabdulaziz-beep/mcp-akij'
If you have feedback or need assistance with the MCP directory API, please join our Discord server