Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
3.0 KiB
3.0 KiB
inclusion
| inclusion |
|---|
| always |
Coding Standards — beam-mcp-server
Projektstruktur
src/
├── index.ts # MCP Server, Tool-Registrierung, Label-Mappings, Error-Handling
├── api.ts # BEAM GraphQL/REST API Client, Diagramm-Funktionen
├── auth.ts # Token-Management (Keychain + Playwright Browser-Login)
└── keychain.ts # OS-Keychain Abstraktionsschicht (macOS/Windows)
TypeScript-Konventionen
- ESM (
"type": "module"in package.json), alle Imports mit.js-Suffix - Strict mode aktiviert, kein
any— nutzeRecord<string, unknown>oder konkrete Interfaces - Target: ES2022, Module: Node16
- Build:
npm run build(tsc), Output indist/
MCP Tool-Konventionen
- Alle Tools nutzen
server.registerTool()(NICHTserver.tool()) - Tool-Namen:
beam_Prefix + snake_case (z.B.beam_search_factsheets) - Jedes Tool braucht:
title: Kurzer deutscher Titeldescription: Ausführliche Beschreibung mit Args, Returns, ExamplesinputSchema: Zod-Schemas mit.describe()und Validierung (.min(),.max())annotations:readOnlyHint,destructiveHint,idempotentHint,openWorldHint
- Jeder Tool-Handler ist in try/catch gewrappt und nutzt
handleError()bei Fehlern - Große Responses werden mit
truncateIfNeeded()auf CHARACTER_LIMIT (25k) gekürzt
Error-Handling Pattern
async (params) => {
try {
// ... Logik ...
return { content: [{ type: "text", text: result }] };
} catch (error) {
return handleError(error);
}
}
handleError() gibt { isError: true, content: [...] } zurück mit kontextbezogenen Meldungen:
- 401/403 → Hinweis auf
beam_get_token - 404 → ID/Suchbegriff prüfen
- 429 → Rate-Limit, warten
API-Schicht (api.ts)
gql()— Shared GraphQL-Client mit Auth-Header- Alle API-Funktionen sind
asyncund werfen Errors mit HTTP-Status - UUID-Erkennung:
/^[0-9a-f-]{36}$/i— alles andere wird als Beam-ID/Name per Suche aufgelöst - Neue API-Funktionen gehören in
api.ts, nicht inindex.ts
Label-Mappings (index.ts)
BEAM-interne Werte werden auf deutsche Labels gemappt:
LC— Lebenszyklus (active→Aktiv, phaseOut→Ausgliederungsphase, ...)ST— Supporttyp (leading→Führend, supports→Unterstützt)FS_TYPE— Fact-Sheet-Typen (Application→Anwendung, ...)STATE— Status (APPROVED→Bestätigt, ...)
Auth (auth.ts) & Keychain (keychain.ts)
- Token-Priorität: In-Memory Cache → OS-Keychain → Playwright Browser-Login
- Token wird im OS-Keychain gespeichert (macOS: Keychain Access, Windows: DPAPI)
- Keine .env-Datei für Secrets — nur für Konfigurations-URLs
- Gültigkeit: JWT exp-Claim minus 60s Puffer
- Bei Invalidierung (401): Token aus Memory + Keychain gelöscht
- Logging nur auf stderr (stdio-Transport!)
Build & Test
npm run build # TypeScript kompilieren
npm start # Server starten (stdio)
npm run login # Manueller Browser-Login + Token im Keychain speichern
Nach jeder Änderung: npm run build muss fehlerfrei durchlaufen.