mcp-server-base
MCP Server Base v3.0 — Skalierung & Enterprise (2026)
Modern Model Context Protocol-Server mit dem neuesten Stack:
MCP SDK
1.12+—McpServerHigh-Level-API +StreamableHTTPServerTransport(neu) &StdioServerTransportTypeScript 5.7 ESM +
NodeNext-ModulZod-Validierung → automatisches JSON-Schema + Umgebungsvalidierung (
src/config.ts:1)Express 4 + helmet + CORS-Allowlist + Rate-Limit + Health/Ready + Admin-UI
Dualer Transport: STDIO (Claude Desktop) und Streamable HTTP (remote, 2025-03-Spezifikation, zustandslos + zustandsbehaftete Fortsetzbarkeit über RedisEventStore)
Strukturierte Tool-/Ressourcen-/Prompt-Module + RAG-Hybrid (BM25+Vector), Web (gecacht), GitHub-Integrationen
Plugin-SDK (
src/plugin/index.ts:1) + Integrationen (slack/notion/linear), Registry (smithery.yaml, mcpName), Prompt-Playground unter/adminv3.0 Enterprise: Multi-Tenant (
X-Tenant-Id, namensbasierte Stores), SSO OIDC, Control-Plane-CRUD, Cluster-Modus, Prometheus/Grafana-StackOTEL-Tracing/Metriken (
src/utils/otel.ts:1), Tasks (experimentell +create_task), k6-Lastteststsx-Watch,vitest(178 Tests, 88% Abdeckung), Graceful Shutdown,docker-compose(redis, postgres, qdrant, otel-collector, prometheus, grafana)
🚀 Schnellstart
npm install
npm run build
# STDIO (for Claude Desktop, Cursor, opencode, etc.)
npm start
# HTTP (Streamable HTTP - latest)
npm run start:http
# → http://localhost:3000/mcp
# → health http://localhost:3000/healthEntwicklung
npm run dev # stdio watch
npm run dev:http # http watch (Streamable HTTP at http://localhost:3000/mcp)
npm test # unit + e2e (InMemory + HTTP)
npm run test:coverage # coverage 80% thresholds
npm run lint # eslint 9 flat config
npm run format:check # prettier
npm run typecheck # tsc --noEmit
npm run buildCI
.github/workflows/ci.yml läuft bei push/PR auf main mit Node-20+22-Matrix: lint, format:check, typecheck, test:coverage, build, docker build.
Related MCP server: TokenHub MCP
🔌 Transporte
Transport | Verwendung | Befehl |
STDIO | Lokale Clients (Claude Desktop) |
|
Streamable HTTP | Remote / Docker / Cloud |
|
Streamable HTTP ist der neue Standard und ersetzt SSE (veraltet seit März 2025).
🧰 Werkzeuge (40)
Werkzeug | Beschreibung | Eingabe |
| Echo-Nachricht |
|
| add/sub/mul/div |
|
| Aktuelle Zeit |
|
| URL abrufen |
|
| Dateien unter ALLOWED_ROOT auflisten |
|
| Datei lesen (1-MB-Limit) |
|
| Datei schreiben + Ressourcenänderung |
|
| Text in Dateien suchen |
|
| KV im Speicher setzen |
|
| KV abrufen |
|
| KV löschen |
|
| KVs auflisten | — |
| Alle löschen | — |
| SQL über alasql (users, notes) |
|
| Tabellenzeilen zählen | — |
| Shell (Allowlist, standardmäßig deaktiviert) |
|
| Elicitation-Demo (Kontakt/Präferenzen) |
|
| Sampling-Demo (LLM) |
|
| Text aufnehmen (gechunkt, eingebettet) |
|
| Hybride Suche (Vektor+BM25) |
|
| Dokumente auflisten | — |
| Vektor-Store leeren | — |
| Brave-API (Mock ohne Schlüssel) |
|
| Tavily-API (Mock ohne Schlüssel) |
|
| Gecachter Web-Abruf |
|
| GitHub-Repository-Suche |
|
| GitHub-Repository abrufen |
|
| GitHub-Issue abrufen |
|
| Hintergrundaufgabe erstellen |
|
| Aufgabenstatus abrufen |
|
| Aufgabenergebnis abrufen |
|
| Slack-Kanäle (Plugin) | — |
| Slack-Nachricht senden (Plugin) |
|
| Slack-Suche (Plugin) |
|
| Notion-Suche (Plugin) |
|
| Notion-Seite (Plugin) |
|
| Notion-Seite erstellen (Plugin) |
|
| Linear-Issues (Plugin) |
|
| Linear-Issue erstellen (Plugin) |
|
| Linear-Issue abrufen (Plugin) |
|
📦 Ressourcen (6)
config://server-info— Server-Metadaten (JSON, enthält jetztfeatures)greeting://{name}— dynamische Begrüßungsvorlagefile:///{+path}— sandboxed Datei (ALLOWED_ROOT), Liste + Vervollständigung,file:///notes.txtmemory://{key}— Memory-KV, Liste + Vervollständigungdb://{table}/{id}— Demo-DB-Zeile (users/notes), Liste + Vervollständigungdocs://{id}— RAG-Chunk (überrag_ingestaufgenommen), Liste + Vervollständigung
💬 Prompts (4)
code-review— Argumente:language,codeexplain-concept— Argumente:concept,levelsummarize— Argumente:text,length(short/medium/long),style(bullets/paragraph/tldr)research— Argumente:topic,depth(overview/deep),audience(beginner/expert/executive)
⚙️ Client-Konfiguration
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"mcp-server-base": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"]
}
}
}HTTP-Client
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
const client = new Client({ name: 'my-client', version: '1.0.0' });
await client.connect(new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp')));
const tools = await client.listTools();Inspector
npm run inspect
# or
npx @modelcontextprotocol/inspector node dist/index.js
npx @modelcontextprotocol/inspector http://localhost:3000/mcp🐳 Docker
# Single container
docker build -t mcp-server-base .
docker run -p 3000:3000 --env TRANSPORT=http mcp-server-base
# Full stack (app + redis + postgres + qdrant) — see docker-compose.yml
docker compose up -d
docker compose logs -f app
# → http://localhost:3000/health, http://localhost:3000/mcp
# → redis :6379, postgres :5432, qdrant :6333RAG-Demo (ingest → search → docs://)
# via MCP tools (Inspector or Client)
# 1. ingest
rag_ingest { "text": "MCP is Model Context Protocol...", "id": "mcp-intro" }
# 2. search
rag_search { "query": "what is MCP?", "topK": 3 }
# 3. read resource
# docs://mcp-intro → returns ingested text📁 Struktur
src/
├── index.ts # entry: stdio + http (helmet/cors/rateLimit/auth/RBAC/OTEL/metrics)
├── server.ts # createMcpServer() factory (v2.1.0, instructions)
├── config.ts # zod env (AUTH, CORS, rateLimit, RAG, cache, integrations, OTEL, admin, tasks)
├── types.ts # Zod schemas
├── middleware/auth.ts # AUTH_MODE none|apiKey|bearer
├── middleware/rateLimit.ts
├── middleware/requestId.ts
├── middleware/rbac.ts # RBAC reader/writer/admin + mcpRbacMiddleware (v2.1)
├── observability/otel-real.ts # OTEL NodeSDK init (v2.1)
├── observability/slo.ts # checkSlo() for /health/ready (v2.1)
├── utils/logger.ts # stderr, JSON/text, redaction, child(requestId)
├── utils/eventStore.ts # InMemoryEventStore
├── utils/redisEventStore.ts # RedisEventStore (scale)
├── utils/cache.ts # MemoryCache (TTL) + defaultCache
├── utils/queue.ts # SimpleQueue
├── utils/metrics.ts # prom-client Registry (v2.1)
├── utils/persistence.ts # save/load backup (v2.1)
├── utils/otel.ts # stub OTEL spans/metrics
├── tools/ # 40 tools: echo, fs, memory, db, shell, rag (hybrid), web, github, elicitation, sampling, tasks
│ ├── filesystem.tool.ts, memory.tool.ts, database.tool.ts, shell.tool.ts
│ ├── rag.tool.ts, web.tool.ts, github.tool.ts, elicitation.tool.ts, sampling.tool.ts, tasks.tool.ts
├── plugin/index.ts # Plugin SDK: definePlugin/registerPlugin (v2.2)
├── integrations/ # slack/notion/linear plugins (v2.2)
├── middleware/tenant.ts # Multi-tenant X-Tenant-Id + scoped stores (v3.0)
├── routes/controlplane.ts# Tenants CRUD + key rotation (v3.0)
├── utils/cluster.ts # Cluster mode horizontal scale (v3.0)
├── resources/ # 6 resources: config, greeting, file, memory, db, docs
├── routes/admin.ts # Admin UI + metrics/spans/stores (v2.0) + /metrics Prometheus (v2.1)
└── prompts/ # 4 prompts: code-review, explain-concept, summarize, researchNeues Tool hinzufügen: src/tools/my.tool.ts erstellen → registerMyTool(server) exportieren → zu src/tools/index.ts hinzufügen.
🔐 Sicherheit (Phase 2)
Helmet-Header (
x-dns-prefetch-control,x-frame-options,x-content-type-optionsusw.) überhelmet@7(src/index.ts:1)CORS-Allowlist (
CORS_ORIGIN=*oder Komma-Liste) mitcors-Credentials-Handling (src/config.ts:60)Auth
AUTH_MODE=none|apiKey|beareruntersrc/middleware/auth.ts:1—401ohne gültigenX-API-KeyoderAuthorization: Bearer(health/ready & OPTIONS ausgenommen)Rate-Limiting
express-rate-limit(Standard 100/15min) auf/mcp—429 Too Many Requests(src/middleware/rateLimit.ts:1)RequestId (
X-Request-IdrandomUUID, Echo-Header, Child-Logger-Korrelation) (src/middleware/requestId.ts:1)Zod-Umgebungsvalidierung (
src/config.ts:1) —parseEnv()validiertPORT,AUTH_MODE,API_KEYkreuzfeldbezogen, bricht bei ungültiger Umgebung sofort abStrukturierter Logger JSON/Text,
[REDACTED]fürauthorization,apiKey,token(src/utils/logger.ts:24)Fortsetzbarkeit
InMemoryEventStore(src/utils/eventStore.ts:1) + zustandsbehaftete Session-Map, wennRESUMABILITY_ENABLED=true(Replay überLast-Event-ID,GET /mcp-Stream,DELETE-Schließen)Docker-Härtung Nicht-Root-
appuser+HEALTHCHECK(Dockerfile:1)Tests:
tests/unit/auth.test.ts,tests/unit/logger.test.ts,tests/unit/eventStore.test.ts,tests/e2e/security.test.ts(helmet/auth/rateLimit/resumability) —67 Tests → 130 gesamt mit Phase 5, 90,89% Abdeckung
🔗 Integrationen (Phase 4)
Cache
MemoryCacheTTL (src/utils/cache.ts:1) —defaultCachefür Web/GitHub,SimpleQueue(src/utils/queue.ts:1)RAG lokaler Vektor (Hash-Embedding 128-dim, Kosinus, Chunk 500/50) unter
src/tools/rag.tool.ts:1—rag_ingest(gechunkt +sendResourceListChanged),rag_search(topK, threshold),rag_list,rag_clear+docs://{id}-RessourceWeb
src/tools/web.tool.ts:1—brave_search(Mock ohneBRAVE_API_KEY),tavily_search(Mock),web_fetch(gecacht überdefaultCache,CACHE_TTL_MS)GitHub
src/tools/github.tool.ts:1—github_search_repos,github_get_repo,github_get_issue(gecacht,GITHUB_TOKENfür Rate-Limit)Stack
docker-compose.yml:1(App + redis:7 + postgres:16 + qdrant:v1.12.4) mit HealthchecksDemo
rag_ingest → rag_search → docs://E2E verifiziert intests/integrations.test.ts:1(21 Tests)
🏢 Skalierung & Enterprise (Phase 5 — v3.0) — NEU
Multi-Tenant
src/middleware/tenant.ts:1—X-Tenant-Id-Header (oder?tenant=),tenantMiddlewareweist400zurück, wennTENANT_REQUIRED=trueund fehlt, mandantenspezifischer SpeichergetTenantMemory(tid)(isolierte Stores), namespaced Cache-Schlüsseltenant:{id}:key, RegistrycreateTenant/deleteTenantSSO OIDC
src/middleware/auth.ts:1—AUTH_MODE=oidc: strukturelle Bearer-JWT-Validierung (3 Teile,exp,issvs.OIDC_ISSUER,audvs.OIDC_AUDIENCE), Claims anreq.oidcClaimsangehängt; in Produktion wird die JWKS-Signaturprüfung eingesetztControl Plane
src/routes/controlplane.ts:1— CRUD/admin/tenants(POST/GET/PATCH/DELETE+ 409 Duplikat/400 ungültige ID),POST /admin/tenants/:id/rotate-key,GET /admin/tenants/:id/storeIsolationsprüfung; durch Admin-Token geschütztLaufzeitskalierung
src/utils/cluster.ts:1—initCluster()forktCLUSTER_WORKERS(Standard CPU-1), automatischer Neustart bei Worker-Exit,CLUSTER_MODE=true; zustandslos +RedisEventStorefür echte horizontale SkalierungMonitoring-Stack
docker-compose.override.yml:1— Prometheus (prometheus.ymlscrapedapp:3000/metrics) auf :9090 + Grafana auf :3001Tests
tests/v3_0.test.ts:1(15 Tests: Tenant-Extraktion/Isolation/erforderlich-400, OIDC-Token-Validierung + Issuer/Audience + HTTP 401/200, Control-Plane-Lebenszyklus 201/409/400/404/rotate-key/store-Inspektion/deaktiviert-404, Cluster-No-op, Compose-Dienste) — insgesamt 178
🔌 Ökosystem & DX (Phase 5 — v2.2)
Plugin-SDK
src/plugin/index.ts:1—definePlugin({name, version, register}),registerPlugin(server, plugin)(duplikattolerant),getRegisteredPlugins(), automatischesendToolListChanged-BenachrichtigungenIntegrationen
src/integrations/—slackPlugin(list/post/search),notionPlugin(search/get/create),linearPlugin(list/create/get) — alle ohne Tokens gemockt (SLACK_TOKEN,NOTION_TOKEN); automatisch registriert insrc/server.ts:1Registry
smithery.yaml:1— Smithery-Konfiguration + MCP-Registry-Nameio.github.ahmedalbanna/mcp-server-base,package.json:1mcpName/files-FelderHybrid-RAG
src/tools/rag.tool.ts:1—rag_search-Modivector|bm25|hybrid(Standard hybrid, Alpha 0.5), BM25 (k1=1.5, b=0.75) normalisiert + Kosinus-Re-Ranking; Evaluierungssettests/eval/rag-eval.json(20 Q/A) mit p@5 ≥0.8 verifiziert intests/v2_2.test.ts:1Prompt-Playground
src/routes/admin.ts:1—POST /admin/prompts/:name/previewrendert Prompts serverseitig; Playground-UI im/admin-DashboardTests
tests/v2_2.test.ts:1(16 Tests: Plugin-SDK define/register/dup/Tools aufrufbar, Registry-Dateien, Hybrid-Modi, Eval p@5, Playground-Vorschau/UI/Anzahl) — insgesamt 163
📈 Skalierung & Betriebsfähigkeit (Phase 5 — v2.0)
Versioniertes MCP
v2.0.0(package.json:1,config.MCP_SERVER_VERSION) mit Anweisungen pro Minor (src/server.ts:1)OTEL Tracing/Metriken (
src/utils/otel.ts:1) —createSpan/withSpan,incrementCounter/recordHistogram,getMetrics/getSpans, JSON-Export-Stub fürOTEL_EXPORTER_OTLP_ENDPOINT,OTEL_ENABLED-FlagRedisEventStore (
src/utils/redisEventStore.ts:1) —EventStore-Implementierung mitstoreEvent/replayEventsAfter, In-Memory-Fallback,eventStoreFactory.create()für horizontale Skalierung (EVENT_STORE_TYPE=memory|redis,REDIS_URL)Admin-UI (
src/routes/admin.ts:1) —GET /admin(HTML-Dashboard),/admin/tools|resources|prompts|metrics|spans|stores|health(JSON), geschützt überADMIN_TOKEN(X-Admin-Token),ADMIN_ENABLED-FlagAufgaben (
src/tools/tasks.tool.ts:1) — experimentellesdelay_task(falls SDK-Aufgaben verfügbar) + Fallbackcreate_task/get_task/get_task_result(In-Memory, Polling),SimpleQueue/MemoryCache-InfrastrukturBench
k6/load.js:1—http_req_duration p(95)<100ms,stages10→50 VUs,checks >99%,npm run bench/bench:localCompose
docker-compose.yml:1enthält bereits redis/postgres/qdrant für SkalierungTests:
tests/scale.test.ts:1(OTEL-Spans/Metriken, RedisEventStore-Replay, Cache-TTL, Queue, Admin-HTML/Metriken/Token/bereit, Aufgaben erstellen/pollen, Version, k6-Skript) — 130 insgesamt (jetzt 147 mit v2.1)Deploy bereit für Fly.io/Cloud Run (zustandslos + RedisEventStore), GHCR über
release.yml, npm2.0.0
🔒 Härtung & Beobachtbarkeit (Phase 5 — v2.1) — NEU
OTEL Real
src/observability/otel-real.ts:1—initOtel()dynamischer Import von@opentelemetry/sdk-node+OTLPTraceExporter(Konsolen-Fallback),OTEL_ENABLED+OTEL_EXPORTER_OTLP_ENDPOINT, sauberesshutdownbei SIGTERMSLOs
src/observability/slo.ts:1—checkSlo()(Speicher/RAG/Cache/Uptime,latencyMs),GET /health→{status, checks, uptime, version, otel, eventStore}+GET /ready→503wenn nichtok,GET /metrics→ Prometheustext/plainüberprom-client(mcp_http_requests_total,mcp_http_request_duration_ms,mcp_sessions_active)RBAC
src/middleware/rbac.ts:1—reader < writer < admin(X-Role-Header, JWT-Stub),TOOL_ROLES-Map (31 Tools),mcpRbacMiddlewareprüfttools/call-Body →403wennreaderversuchtwrite_file/shell_execute,GET /admin→adminerforderlichBackup
src/utils/persistence.ts:1—saveBackup()/loadBackup()/scheduleSave()(500ms Debounce) nachALLOWED_ROOT/.backup.json(dynamischesgetBackupFile()), protokolliert Redis-Sync-Stub wennREDIS_URLgesetzt,loadBackup()beim Start insrc/index.ts:1Metriken
src/utils/metrics.ts:1—prom-clientRegistry+collectDefaultMetrics,httpRequestsTotal/httpRequestDuration/mcpToolCallsTotal/mcpSessionsActive,GET /metrics-HandlerTests
tests/v2_1.test.ts:1(13 Tests: SLO-Prüfungen, RBAChasRole/X-Role403/200,SLO health/metrics200 + Prometheus-Text, OTEL-Span, Backup speichern/laden +scheduleSaveübermemory_set,initOteldeaktiviert/aktiviert) +tests/unit/rbac.test.ts:1(4 Tests) — insgesamt 147Logger stderr-sicher, protokolliert niemals Geheimnisse (Redaktion)
Zod → JSON-Schema über SDK (
src/types.ts:1,src/tools/*.tool.ts)Timeout bei Fetch (10s) + strukturierte Fehler
Sauberes Herunterfahren (
SIGINT/SIGTERM)Health (
GET /health) & Ready (GET /ready) getrennt von MCPZustandslos standardmäßig (
sessionIdGenerator: undefined), zustandsbehaftet wennRESUMABILITY_ENABLED=true(src/index.ts:22)Typsicher, striktes TS + ESLint flat + Prettier + husky + lint-staged
Abdeckung 85% Zeilen / 70% Zweige erzwungen (
vitest.config.ts:1), 178 Tests: Unit + e2e HTTP/Sicherheit/Fähigkeiten/Integrationen/Skalierung/v2.1/v2.2/v3.0
📚 Dokumentation
Vollständige Dokumentation in docs/:
Architektur — Diagramm, Modulübersicht, Anfragelebenszyklus
Konfiguration — jede Umgebungsvariable + Validierungsregeln
API-Referenz — Tools/Ressourcen/Prompts/Endpunkte
Sicherheit — Authentifizierung, RBAC, OIDC, Mandantenfähigkeit, Härtungs-Checkliste
Plugins — Plugin-SDK-Anleitung + Registry-Verteilung
Bereitstellung — Docker, Cluster-/Multi-Replica-Skalierung, Monitoring, k6
Testen — Suite-Übersicht, Muster, CI
🤝 Mitwirken
Siehe CONTRIBUTING.md — nvm use, npm test, Tool/Ressource/Prompt hinzufügen, sicherstellen, dass lint/typecheck/test bestehen. Siehe CODE_OF_CONDUCT.md.
📚 MCP-Dokumentation
This server cannot be deployed
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
A Model Context Protocol server for Wix AI tools
Model Context Protocol server for the Apideck Unified API. Connect any MCP-compatible agent framework to 100+ accounting systems, HRIS platforms, file storage providers, and more through one integration. More information https://www.apideck.com/mcp-server
Persistent memory, hybrid search and a goal graph for AI agents, over stdio or remote HTTP.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA robust server implementing the Model Context Protocol with SSE and STDIO transport, enabling real-time communication and extensible tooling for AI models.452 npm4MIT
- AlicenseBqualityCmaintenanceA production-packaged Model Context Protocol server for coding agents that routes large file, git, web, database, and other tasks through token-budgeted tools and workflows.62 npm1MIT
- AlicenseNot gradedqualityDmaintenanceA production-ready Model Context Protocol suite over Streamable HTTP providing a sandboxed file server with tools, resources, prompts, and both manual and AI-driven clients.MIT
- AlicenseBqualityCmaintenanceEnables running a Model Context Protocol server with a validated echo tool over stdio or Streamable HTTP, including strict schemas, tests, and hardened container deployment.11MIT