akij-hr-data-mcp
akij-hr-data-mcp
Готовый к продакшену, только для чтения, удалённый Model Context Protocol (MCP) сервер, который открывает доступ к одной папке Google Drive — репозиторию AKIJ HR DATA — для MCP-совместимых клиентов через современный транспорт Streamable HTTP.
Это универсальный Drive MCP: он обрабатывает XLSX, XLS, CSV, PDF, DOCX, TXT, изображения и нативные файлы Google Docs/Sheets/Slides, а не только Excel.
1. Что делает этот проект
Подключается к Google Drive с помощью сервисного аккаунта (без пользовательского OAuth-потока и входа в браузере).
Ограничивает все операции одной настроенной папкой (
GOOGLE_DRIVE_FOLDER_ID) и её подпапками. Файлы вне этого дерева никогда не возвращаются, даже если сервисный аккаунт технически может их видеть.Предоставляет 11 MCP-инструментов для поиска и чтения файлов (список, поиск, метаданные, содержимое и извлечение данных в зависимости от формата для Excel/CSV/PDF/DOCX).
Работает как стандартный HTTP-сервер на Node/Express с единственной конечной точкой
POST /mcp(транспорт Streamable HTTP) и конечной точкойGET /health, разворачивается на Render (или любом Node-хостинге), чтобы продолжать работать, когда ваш ПК выключен.Требует аутентификацию по API-ключу для каждого MCP-запроса.
Является строго только для чтения — в коде нет путей, которые могут загружать, редактировать, удалять, переименовывать, перемещать или открывать доступ к файлам Drive, а также менять права.
Related MCP server: Google Drive MCP Server
2. Архитектура
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)Сервер не сохраняет состояние: каждый запрос POST /mcp получает собственный экземпляр McpServer + StreamableHTTPServerTransport (sessionIdGenerator: undefined), поэтому не требуется привязка к сессии, и он горизонтально масштабируется на Render без липких сессий.
Структура проекта
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. Предварительные требования
Node.js 20+ и npm
Проект Google Cloud с включённым Google Drive API
Google сервисный аккаунт с доступом Viewer, предоставленным на папку AKIJ HR DATA в Drive
Аккаунт GitHub (для развёртывания на Render из репозитория)
Аккаунт Render
4. Установка
npm install5. Переменные окружения
Переменная | Обязательная | Описание |
| нет (по умолчанию | Порт, на котором слушает HTTP-сервер. Render устанавливает его автоматически. |
| да | Идентификатор папки Drive, к которой ограничен этот MCP. |
| да | JSON-ключ сервисного аккаунта в кодировке Base64. |
| да | Список допустимых API-ключей для |
См. .env.example для шаблона (никакие настоящие секреты не фиксируются в репозитории).
6. Настройка Google Cloud
Перейдите на console.cloud.google.com и выберите/создайте проект.
APIs & Services → Library → включите Google Drive API.
APIs & Services → Credentials → Create Credentials → Service Account.
Дайте ему имя (например,
akij-hr-data-mcp), роль IAM на уровне проекта не требуется.Откройте новый сервисный аккаунт → Keys → Add Key → Create new key → JSON. Это загрузит файл
gcp-key.json— не коммитьте этот файл.Запишите email-адрес сервисного аккаунта (выглядит как
akij-hr-data-mcp@your-project.iam.gserviceaccount.com).
7. Права доступа в Google Drive
Откройте папку AKIJ HR DATA в Google Drive (ID папки
1oxYLPcC9MPVuxsbeP0kGgYhLmkxt0w2o).Нажмите Share, вставьте email сервисного аккаунта и предоставьте доступ Viewer.
Не предоставляйте доступ Editor/Owner — этот сервер никогда не пишет в Drive, поэтому Viewer достаточно и безопаснее.
8. Локальная настройка
npm install
cp .env.example .env
# fill in GOOGLE_DRIVE_FOLDER_ID, GCP_KEY_BASE64, API_KEYS in .env
npm run devnpm run dev запускает TypeScript-сервер напрямую через tsx watch (для локальной разработки шаг сборки не нужен).
9. Генерация GCP_KEY_BASE64
Никогда не вставляйте сырой JSON сервисного аккаунта в чат, исходный код или .env.example. Сгенерируйте значение base64 локально из скачанного gcp-key.json и поместите его только в локальный .env (в gitignore) или в настройки переменных окружения Render.
PowerShell:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\Downloads\gcp-key.json")) | Set-ClipboardЭта команда читает файл ключа и копирует base64-строку прямо в буфер обмена — вставьте её как значение GCP_KEY_BASE64 в .env (локально) или на панели Render (для развёртывания). Измените путь, если gcp-key.json не находится в вашей папке Downloads.
Если вы предпочитаете вывести её в терминал, а не в буфер обмена:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\Downloads\gcp-key.json"))10. Локальное тестирование
Запустите сервер:
npm run devПроверьте работоспособность:
curl http://localhost:10000/healthВызовите MCP-инструмент (например, list_files) с помощью curl, используя последовательность initialize → tools/call, или укажите любому MCP-клиенту, поддерживающему Streamable HTTP, адрес http://localhost:10000/mcp с заголовком X-Api-Key: <один из ваших API_KEYS>.
11. Сборка
npm run buildКомпилирует src/ (TypeScript, NodeNext ESM) в dist/. Запустите npm run typecheck для проверки типов без создания файлов.
Запустите набор тестов:
npm testЭто запускает Jest в одном процессе (46 тестов в 10 наборах: config, auth, Google auth, проверка области папки Drive, все 11 инструментов и HTTP-эндпоинты /health//mcp).
12. Настройка 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 и *.key уже в gitignore — перед коммитом проверьте через git status, что никакие секреты не попали в индексацию.
13. Развёртывание на Render
Перейдите на render.com → New → Web Service.
Подключите ваш GitHub-репозиторий (
akij-hr-data-mcp).Render автоматически обнаружит
render.yaml(Blueprint) или настройте вручную:Build Command:
npm install && npm run buildStart Command:
npm startHealth Check Path:
/health
Добавьте переменные окружения (раздел 14) на панели Render — никогда не коммитьте их.
Разверните. Render соберёт и запустит сервис, и он будет работать независимо от вашего ПК.
14. Переменные окружения Render
Задайте их в Render → ваш сервис → 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>Сгенерируйте надёжные случайные API-ключи, например:
[Convert]::ToBase64String([Guid]::NewGuid().ToByteArray()) -replace '[+/=]',''15. Эндпоинт Health
GET /health{ "status": "ok", "timestamp": "2026-08-17T12:00:00.000Z" }Аутентификация не требуется; не раскрывает секретов или внутреннего состояния.
16. Эндпоинт MCP
POST /mcpРеализует транспорт MCP Streamable HTTP (
@modelcontextprotocol/sdkStreamableHTTPServerTransport), не сохраняет состояние (sessionIdGenerator: undefined) — без запасного варианта только SSE.Требует аутентификацию: заголовок
Authorization: Bearer <API_KEY>илиX-Api-Key: <API_KEY>.GET /mcpиDELETE /mcpвозвращают405— этот сервер не поддерживает сессии или опциональный SSE-поток.
17. Подключение удалённого MCP к клиентам
После развёртывания ваш MCP-эндпоинт:
https://<your-render-service>.onrender.com/mcpДля MCP-клиентов, поддерживающих удалённые/HTTP-серверы, добавьте запись сервера с:
URL:
https://<your-render-service>.onrender.com/mcpТранспорт: Streamable HTTP
Заголовки:
X-Api-Key: <один из ваших API_KEYS>(илиAuthorization: Bearer <API_KEY>)
Пример типовой конфигурации клиента:
{
"mcpServers": {
"akij-hr-data": {
"url": "https://<your-render-service>.onrender.com/mcp",
"headers": {
"X-Api-Key": "<API_KEY>"
}
}
}
}18. Безопасность
Только для чтения: в этой кодовой базе нет инструментов загрузки/удаления/редактирования/переименования/перемещения/предоставления доступа/изменения прав.
Ограничение папкой:
GoogleDriveClient.assertFileInScopeпроходит по цепочкеparentsкаждого файла до настроенного корня, прежде чем вернуть любые метаданные или содержимое; файлы вне дерева вызываютForbiddenError.Аутентификация по API-ключу: каждый запрос
POST /mcpпроверяется поAPI_KEYSс помощью сравнения, безопасного по времени (crypto.timingSafeEqual). Отсутствующие/недействительные ключи получают401.Учётные данные никогда не логируются и не возвращаются: декодированный JSON сервисного аккаунта остаётся внутри
google-auth.ts; ни один инструмент, строка лога или сообщение об ошибке не могут его раскрыть. Ответы об ошибках проходят черезtoSafeErrorMessage, который удаляет стек-трейсы и исходные тела ошибок вышестоящего сервиса.Ограничения размера/вывода: загрузки ограничены (
LIMITS.MAX_DOWNLOAD_BYTES/MAX_PARSE_BYTES), извлечение текста обрезается (MAX_TEXT_OUTPUT_CHARS), строки разбиваются на страницы (DEFAULT_ROW_LIMIT/MAX_ROW_LIMIT), и каждый исходящий вызов Google API имеет таймаут (GOOGLE_API_TIMEOUT_MS).Расширяемая аутентификация:
req.identityимеет небольшую стабильную структуру ({ keyId }), спроектированную так, чтобы будущий слой авторизации на основе пользовательских ключей, OAuth или ролей мог добавлять более богатые утверждения без изменения каждого места вызова.Известное предупреждение о зависимости: пакет
xlsx(SheetJS), используемый для разбора устаревших.xls-файлов, имеет опубликованное предупреждение высокой степени серьёзности (prototype pollution / ReDoS). Он используется только для внутренних файлов с контролируемым доступом из вашей собственной папки Drive (не для произвольных интернет-загрузок), а файлы ограничиваются по размеру перед разбором. Периодически запускайтеnpm auditи рассмотрите замену пакета, когда появится исправленная версия.
Контрольный список безопасности
gcp-key.jsonникогда не коммитится в git.envникогда не коммитится в gitAPI_KEYSзаданы надёжными случайными значениями в Render (не локальным dev-значением)Сервисный аккаунт имеет доступ только Viewer к папке Drive
GOOGLE_DRIVE_FOLDER_IDсоответствует целевой папке репозиторияПеременные окружения Render задаются напрямую на панели, а не в закоммиченных значениях
render.yaml
19. Устранение неполадок
Симптом | Причина | Исправление |
Сервер сразу завершает работу с | Отсутствует/недействительна переменная окружения | Проверьте точное имя переменной из сообщения об ошибке по разделу 5 |
| Закодирован не тот файл, или при копировании/вставке строка была обрезана | Перегенерируйте с помощью команды PowerShell из раздела 9 |
| Сервисный аккаунт не предоставлен к папке или предоставлен на неправильный email | Перепроверьте раздел 7; убедитесь, что |
| Вы передали | Используйте |
| Отсутствует/неправильный API-ключ | Отправьте |
Ошибка | Файл превышает настроенный лимит байт | Это намеренно; большие файлы отклоняются, а не загружаются полностью в память (см. |
Сервис Render засыпает / медленно холодно стартует | Бесплатные/стартовые планы Render простаивают после бездействия | Перейдите на более дорогой план Render или примите задержку холодного старта при первом запросе |
Тесты локально зависают на минуты |
| Уже устранено: |
Оставшиеся ручные шаги (выполнить можете только вы)
Сгенерируйте
GCP_KEY_BASE64из загруженногоgcp-key.json(раздел 9) и поместите его в ваш локальный.envдля тестирования.Поделитесь папкой AKIJ HR DATA Drive с адресом электронной почты вашего сервисного аккаунта с правами просмотра (раздел 7).
Запустите локально (
npm run dev) и убедитесь, чтоGET /healthи реальный вызовlist_filesработают с вашей реальной папкой Drive.Запушьте в GitHub (раздел 12).
Создайте Render Web Service, подключите репозиторий и установите четыре переменные окружения в панели Render (разделы 13–14) — Render соберёт и развернёт автоматически.
Сгенерируйте производственные
API_KEYS(отличные от любых локальных ключей разработки) и храните их в безопасности для ваших MCP-клиентов.Подключите ваш MCP-клиент к
https://<your-render-service>.onrender.com/mcp(раздел 17).
This server cannot be deployed
Maintenance
Related MCP Connectors
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
Read-only MCP server exposing a user ORANO library to their own AI agent.
Public read-only MCP server for Genvernium product and developer resources.
Document conversion MCP server: PDF to Markdown, image OCR, spreadsheet parsing.
Related MCP Servers
- -licenseNot gradedqualityAmaintenanceThis MCP server integrates with Google Drive to allow listing, reading, and searching over files.4,556 npm90,939MIT
- AlicenseNot gradedqualityDmaintenanceA 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
- FlicenseNot gradedqualityCmaintenanceA 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.15 npm2-
- 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.436 npm1MIT