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.
87 lines
3.0 KiB
Markdown
87 lines
3.0 KiB
Markdown
---
|
|
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` — nutze `Record<string, unknown>` oder konkrete Interfaces
|
|
- Target: ES2022, Module: Node16
|
|
- Build: `npm run build` (tsc), Output in `dist/`
|
|
|
|
## MCP Tool-Konventionen
|
|
|
|
- Alle Tools nutzen `server.registerTool()` (NICHT `server.tool()`)
|
|
- Tool-Namen: `beam_` Prefix + snake_case (z.B. `beam_search_factsheets`)
|
|
- Jedes Tool braucht:
|
|
- `title`: Kurzer deutscher Titel
|
|
- `description`: Ausführliche Beschreibung mit Args, Returns, Examples
|
|
- `inputSchema`: 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
|
|
|
|
```typescript
|
|
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 `async` und 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 in `index.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
|
|
|
|
```bash
|
|
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.
|