Skip to main content
Glama

akij-hr-data-mcp

Ein produktionsreifer, schreibgeschützter, entfernter Model Context Protocol (MCP)-Server, der einen einzelnen Google-Drive-Ordner – das Repository AKIJ HR DATA – über modernen Streamable HTTP-Transport für MCP-kompatible Clients bereitstellt.

Es ist ein Allzweck-Drive-MCP: Es verarbeitet XLSX, XLS, CSV, PDF, DOCX, TXT, Bilder und native Google Docs/Sheets/Slides-Dateien – kein reines Excel-Werkzeug.


1. Was dieses Projekt tut

  • Stellt mithilfe eines Dienstkontos eine Verbindung zu Google Drive her (kein OAuth-Benutzerablauf, keine Browser-Anmeldung).

  • Beschränkt jeden Vorgang auf einen konfigurierten Ordner (GOOGLE_DRIVE_FOLDER_ID) und dessen Unterordner. Dateien außerhalb dieses Baums werden nie zurückgegeben, selbst wenn das Dienstkonto sie technisch sehen könnte.

  • Stellt 11 MCP-Tools zum Entdecken und Lesen von Dateien bereit (Liste, Suche, Metadaten, Inhalt und formatspezifische Extraktion für Excel/CSV/PDF/DOCX).

  • Läuft als Standard-Node/Express-HTTP-Server mit einem einzigen POST /mcp-Endpunkt (Streamable-HTTP-Transport) und einem GET /health-Endpunkt, der auf Render (oder einem beliebigen Node-Host) bereitgestellt werden kann, sodass er weiterläuft, wenn Ihr PC ausgeschaltet ist.

  • Erzwingt eine API-Schlüssel-Authentifizierung für jede MCP-Anfrage.

  • Ist strikt schreibgeschützt – es gibt keinen Codepfad, der eine Drive-Datei hochladen, bearbeiten, löschen, umbenennen, verschieben oder freigeben oder Berechtigungen ändern kann.

Related MCP server: Google Drive MCP Server

2. Architektur

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)

Der Server ist zustandslos: Jede POST /mcp-Anfrage erhält eine eigene McpServer- + StreamableHTTPServerTransport-Instanz (sessionIdGenerator: undefined), sodass keine Session-Affinität erforderlich ist und er sich auf Render ohne Sticky Sessions horizontal skalieren lässt.

Projektstruktur

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.cjs

3. Voraussetzungen

  • Node.js 20+ und npm

  • Ein Google-Cloud-Projekt mit aktivierter Google Drive API

  • Ein Google-Dienstkonto mit Viewer-Zugriff, das für den AKIJ HR DATA-Ordner in Google Drive freigegeben ist

  • Ein GitHub-Konto (zum Bereitstellen auf Render aus einem Repository)

  • Ein Render-Konto

4. Installation

npm install

5. Umgebungsvariablen

Variable

Erforderlich

Beschreibung

PORT

nein (Standard 10000)

Der Port, auf dem der HTTP-Server lauscht. Render setzt diesen automatisch.

GOOGLE_DRIVE_FOLDER_ID

ja

Die Drive-Ordner-ID, auf die dieses MCP beschränkt ist.

GCP_KEY_BASE64

ja

Base64-kodierter JSON-Schlüssel des Dienstkontos.

API_KEYS

ja

Kommaseparierte Liste gültiger API-Schlüssel für POST /mcp.

Siehe .env.example für die Vorlage (es sind keine echten Geheimnisse eingecheckt).

6. Google-Cloud-Einrichtung

  1. Gehen Sie zu console.cloud.google.com und wählen Sie ein Projekt aus oder erstellen Sie eines.

  2. APIs & Services → Library → aktivieren Sie Google Drive API.

  3. APIs & Services → Credentials → Create Credentials → Service Account.

  4. Geben Sie ihm einen Namen (z. B. akij-hr-data-mcp); keine projektweite IAM-Rolle ist erforderlich.

  5. Öffnen Sie das neue Dienstkonto → Keys → Add Key → Create new key → JSON. Dadurch wird eine Datei gcp-key.json heruntergeladen – committen Sie diese Datei nicht.

  6. Notieren Sie die E-Mail-Adresse des Dienstkontos (sie sieht aus wie akij-hr-data-mcp@your-project.iam.gserviceaccount.com).

7. Google-Drive-Berechtigungen

  1. Öffnen Sie den Ordner AKIJ HR DATA in Google Drive (Ordner-ID 1oxYLPcC9MPVuxsbeP0kGgYhLmkxt0w2o).

  2. Klicken Sie auf Share, fügen Sie die E-Mail-Adresse des Dienstkontos ein und gewähren Sie Viewer-Zugriff.

  3. Gewähren Sie keinen Editor-/Eigentümer-Zugriff – dieser Server schreibt nie nach Drive, daher ist Viewer ausreichend und sicherer.

8. Lokale Einrichtung

npm install
cp .env.example .env
# fill in GOOGLE_DRIVE_FOLDER_ID, GCP_KEY_BASE64, API_KEYS in .env
npm run dev

npm run dev führt den TypeScript-Server direkt mit tsx watch aus (kein Build-Schritt für die lokale Iteration erforderlich).

9. Generieren von GCP_KEY_BASE64

Sie sollten das rohe Dienstkonto-JSON niemals in einen Chat, Quellcode oder .env.example einfügen. Generieren Sie den Base64-Wert lokal aus Ihrer heruntergeladenen gcp-key.json-Datei und legen Sie ihn nur in Ihrer lokalen .env (gitignored) oder in den Umgebungsvariablen von Render ab.

PowerShell:

[Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\Downloads\gcp-key.json")) | Set-Clipboard

Dies liest die Schlüsseldatei und kopiert die Base64-Zeichenfolge direkt in Ihre Zwischenablage – fügen Sie sie als Wert von GCP_KEY_BASE64 in .env (lokal) oder im Render-Dashboard (für die Bereitstellung) ein. Passen Sie den Pfad an, wenn sich gcp-key.json nicht in Ihrem Downloads-Ordner befindet.

Falls Sie es lieber im Terminal ausgeben möchten statt in die Zwischenablage:

[Convert]::ToBase64String([IO.File]::ReadAllBytes("$HOME\Downloads\gcp-key.json"))

10. Lokales Testen

Starten Sie den Server:

npm run dev

Health-Check prüfen:

curl http://localhost:10000/health

Rufen Sie ein MCP-Tool (Beispiel: list_files) mit curl auf, indem Sie die Sequenz initialize → tools/call verwenden, oder richten Sie einen beliebigen Streamable-HTTP-fähigen MCP-Client auf http://localhost:10000/mcp mit dem Header X-Api-Key: <einer Ihrer API_KEYS>.

11. Erstellen

npm run build

Kompiliert src/ (TypeScript, NodeNext ESM) nach dist/. Führen Sie npm run typecheck aus, um den Typcheck ohne Dateiausgabe durchzuführen.

Test-Suite ausführen:

npm test

Dies führt Jest im In-Band-Modus aus (46 Tests in 10 Suiten: Konfiguration, Authentifizierung, Google-Authentifizierung, Durchsetzung des Drive-Ordnerbereichs, alle 11 Tools und die /health-//mcp-HTTP-Endpunkte).

12. GitHub-Einrichtung

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 und *.key sind bereits gitignored – überprüfen Sie vor dem Committen mit git status, dass nichts Geheimes bereitgestellt wird.

13. Render-Bereitstellung

  1. Gehen Sie zu render.com → New → Web Service.

  2. Verbinden Sie Ihr GitHub-Repository (akij-hr-data-mcp).

  3. Render erkennt render.yaml (Blueprint) automatisch, oder Sie konfigurieren manuell:

    • Build Command: npm install && npm run build

    • Start Command: npm start

    • Health Check Path: /health

  4. Fügen Sie die Umgebungsvariablen (Abschnitt 14) im Render-Dashboard hinzu – committen Sie sie nie.

  5. Bereitstellen. Render erstellt den Build, startet den Dienst und hält ihn unabhängig von Ihrem PC am Laufen.

14. Render-Umgebungsvariablen

Setzen Sie diese in Render → Ihr Dienst → 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>

Generieren Sie starke, zufällige API-Schlüssel, z. B.:

[Convert]::ToBase64String([Guid]::NewGuid().ToByteArray()) -replace '[+/=]',''

15. Health-Endpunkt

GET /health
{ "status": "ok", "timestamp": "2026-08-17T12:00:00.000Z" }

Keine Authentifizierung erforderlich; es werden keine Geheimnisse oder internen Zustände offengelegt.

16. MCP-Endpunkt

POST /mcp
  • Implementiert den MCP-Streamable HTTP-Transport (@modelcontextprotocol/sdk StreamableHTTPServerTransport), zustandslos (sessionIdGenerator: undefined) – kein reines SSE-Fallback.

  • Erfordert Authentifizierung: Authorization: Bearer <API_KEY>- oder X-Api-Key: <API_KEY>-Header.

  • GET /mcp und DELETE /mcp geben 405 zurück – dieser Server verwaltet keine Sitzungen und unterstützt den optionalen SSE-Stream nicht.

17. Verbinden des entfernten MCP mit Clients

Nach der Bereitstellung lautet Ihr MCP-Endpunkt:

https://<your-render-service>.onrender.com/mcp

Für MCP-Clients, die Remote-/HTTP-Server unterstützen, fügen Sie einen Servereintrag hinzu mit:

  • URL: https://<your-render-service>.onrender.com/mcp

  • Transport: Streamable HTTP

  • Headers: X-Api-Key: <einer Ihrer API_KEYS> (oder Authorization: Bearer <API_KEY>)

Beispiel für eine generische Client-Konfiguration:

{
  "mcpServers": {
    "akij-hr-data": {
      "url": "https://<your-render-service>.onrender.com/mcp",
      "headers": {
        "X-Api-Key": "<API_KEY>"
      }
    }
  }
}

18. Sicherheit

  • Schreibgeschützt: Es gibt kein Upload-/Lösch-/Bearbeiten-/Umbenennen-/Verschieben-/Freigabe-/Berechtigungstool in dieser Codebasis.

  • Ordnerbezogen: GoogleDriveClient.assertFileInScope durchläuft die parents-Kette jeder Datei bis zur konfigurierten Wurzel, bevor Metadaten oder Inhalte zurückgegeben werden; Dateien außerhalb des Baums lösen eine ForbiddenError aus.

  • API-Schlüssel-Authentifizierung: Jede POST /mcp-Anfrage wird mit einem timing-sicheren Vergleich (crypto.timingSafeEqual) gegen API_KEYS geprüft. Fehlende/ungültige Schlüssel erhalten 401.

  • Anmeldeinformationen werden nie protokolliert oder zurückgegeben: Das dekodierte Dienstkonto-JSON bleibt in google-auth.ts; kein Tool, keine Protokollzeile und keine Fehlermeldung kann es offenlegen. Fehlerantworten werden durch toSafeErrorMessage geleitet, das Stack-Traces und rohe Upstream-Fehlertexte entfernt.

  • Größen-/Ausgabelimits: Downloads sind begrenzt (LIMITS.MAX_DOWNLOAD_BYTES / MAX_PARSE_BYTES), Textextraktion wird abgeschnitten (MAX_TEXT_OUTPUT_CHARS), Zeilen werden paginiert (DEFAULT_ROW_LIMIT/MAX_ROW_LIMIT), und jeder ausgehende Google-API-Aufruf hat ein Timeout (GOOGLE_API_TIMEOUT_MS).

  • Erweiterbare Authentifizierung: req.identity ist eine kleine, stabile Struktur ({ keyId }), die so entworfen wurde, dass eine zukünftige benutzerbezogene Schlüssel-, OAuth- oder rollenbasierte Autorisierungsebene umfangreichere Ansprüche anhängen kann, ohne jede Aufrufstelle zu ändern.

  • Bekannte Abhängigkeitswarnung: Das Paket xlsx (SheetJS), das für das Parsen von altem .xls verwendet wird, hat eine veröffentlichte Warnung mit hohem Schweregrad (Prototype Pollution / ReDoS). Es wird nur für interne, zugriffsgeschützte Dateien aus Ihrem eigenen Drive-Ordner verwendet (nicht für willkürliche Internet-Uploads), und Dateien werden vor dem Parsen größenmäßig begrenzt. Führen Sie regelmäßig npm audit aus und erwägen Sie einen Ersatz, sobald eine gepatchte Version verfügbar ist.

Sicherheits-Checkliste

  • gcp-key.json wurde nie in Git eingecheckt

  • .env wurde nie in Git eingecheckt

  • API_KEYS sind in Render auf starke, zufällige Werte gesetzt (nicht den lokalen Entwicklerwert)

  • Dienstkonto hat nur Viewer-Zugriff auf den Drive-Ordner

  • GOOGLE_DRIVE_FOLDER_ID entspricht dem vorgesehenen Repository-Ordner

  • Render-Umgebungsvariablen werden direkt im Dashboard gesetzt, nie in committeten Werten von render.yaml

19. Fehlerbehebung

Symptom

Ursache

Behebung

Server beendet sich sofort mit einem ConfigError

Fehlende/ungültige Umgebungsvariable

Überprüfen Sie die genaue Variable, die in der Fehlermeldung genannt wird, anhand von Abschnitt 5

GCP_KEY_BASE64 is not valid base64

Falsche Datei kodiert, oder die Zeichenfolge wurde durch Kopieren/Einfügen abgeschnitten

Mit dem PowerShell-Befehl in Abschnitt 9 neu generieren

403 Forbidden von der Drive API

Dienstkonto nicht für den Ordner freigegeben oder mit der falschen E-Mail freigegeben

Abschnitt 7 erneut prüfen; bestätigen Sie, dass die client_email in Ihrem Schlüssel übereinstimmt

File ... is outside the configured repository folder

Sie haben eine file_id übergeben, die nicht im Baum von GOOGLE_DRIVE_FOLDER_ID liegt

Verwenden Sie list_supported_files oder search_repository, um gültige IDs zu erhalten

401 bei jedem /mcp-Aufruf

Fehlender/ungültiger API-Schlüssel

Senden Sie X-Api-Key oder Authorization: Bearer <key> entsprechend einem Eintrag in API_KEYS

FILE_TOO_LARGE-Fehler

Datei überschreitet das konfigurierte Byte-Limit

Das ist beabsichtigt; große Dateien werden abgelehnt, anstatt vollständig in den Speicher geladen zu werden (siehe src/utils/limits.ts)

Render-Dienst schläft / Start dauert lange (Cold Start)

Kostenlose/Starter-Render-Pläne wechseln nach Inaktivität in den Ruhezustand

Render-Plan upgraden oder die Cold-Start-Verzögerung bei der ersten Anfrage akzeptieren

Tests hängen lokal minutenlang

ts-jest prüft die vollständigen googleapis-Typen unter parallelen Workern

Bereits entschärft: npm test führt Jest mit --runInBand aus; entfernen Sie dieses Flag nicht


Verbleibende manuelle Schritte (nur Sie können diese ausführen)

  1. Generieren Sie GCP_KEY_BASE64 aus Ihrer heruntergeladenen gcp-key.json (Abschnitt 9) und fügen Sie sie Ihrer lokalen .env-Datei für Tests hinzu.

  2. Teilen Sie den AKIJ HR DATA Drive-Ordner mit der E-Mail-Adresse Ihres Dienstkontos als Viewer (Abschnitt 7).

  3. Führen Sie es lokal aus (npm run dev) und bestätigen Sie, dass GET /health und ein echter list_files-Aufruf gegen Ihren echten Drive-Ordner funktionieren.

  4. Pushen Sie zu GitHub (Abschnitt 12).

  5. Erstellen Sie den Render-Webdienst, verbinden Sie das Repository und setzen Sie die vier Umgebungsvariablen im Render-Dashboard (Abschnitte 13–14) — Render wird automatisch bauen und bereitstellen.

  6. Generieren Sie Produktions-API_KEYS (verschieden von jedem lokalen Entwicklungs-Key) und speichern Sie diese sicher für Ihre MCP-Clients.

  7. Verbinden Sie Ihren MCP-Client mit https://<your-render-service>.onrender.com/mcp (Abschnitt 17).

Related MCP Connectors

Related MCP Servers