Skip to main content
Glama
ahmedalbanna

mcp-server-base

by ahmedalbanna

MCP Server Base v3.0 — Масштабирование и корпоративное использование (2026)

CI Node 20+ MCP SDK 1.12.1 TypeScript 5.7 License MIT Coverage 88% Version 3.0.0 Smithery

Современный сервер Model Context Protocol на базе последнего стека:

  • MCP SDK 1.12+ — высокоуровневый API McpServer + StreamableHTTPServerTransport (новый) и StdioServerTransport

  • TypeScript 5.7 ESM + модуль NodeNext

  • Zod валидация → автоматическая JSON Schema + валидация env (src/config.ts:1)

  • Express 4 + helmet + CORS allowlist + rate-limit + health/ready + Admin UI

  • Двойной транспорт: STDIO (Claude Desktop) и Streamable HTTP (удалённый, спецификация 2025-03, без сохранения состояния + возобновляемость с сохранением состояния через RedisEventStore)

  • Структурированные модули инструментов/ресурсов/промптов + RAG гибрид (BM25+vector), Web (кэшированный), интеграции GitHub

  • Plugin SDK (src/plugin/index.ts:1) + интеграции (slack/notion/linear), Registry (smithery.yaml, mcpName), Prompt Playground на /admin

  • v3.0 Enterprise: мультитенантность (X-Tenant-Id, пространства имён для хранилищ), SSO OIDC, CRUD для control plane, кластерный режим, стек Prometheus/Grafana

  • OTEL трассировка/метрики (src/utils/otel.ts:1), Tasks (экспериментальный + create_task), k6 нагрузочные тесты

  • tsx watch, vitest (178 тестов, 88% покрытие), graceful shutdown, docker-compose (redis, postgres, qdrant, otel-collector, prometheus, grafana)


🚀 Быстрый старт

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/health

Dev

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 build

CI

.github/workflows/ci.yml запускается на push/PR в main с матрицей Node 20+22: lint, format:check, typecheck, test:coverage, build, docker build.


Related MCP server: TokenHub MCP

🔌 Транспорты

Транспорт

Использование

Команда

STDIO

Локальные клиенты (Claude Desktop)

node dist/index.js

Streamable HTTP

Удалённый / Docker / Cloud

node dist/index.js --http

Streamable HTTP — новый стандарт, заменяющий SSE (устарел в марте 2025).


🧰 Инструменты (40)

Инструмент

Описание

Входные данные

echo

Эхо-сообщение

message, uppercase?

calculator

add/sub/mul/div

operation, a, b

get_time

Текущее время

timezone?

fetch_url

Получить URL

url, maxLength?

list_files

Список файлов в ALLOWED_ROOT

path?, recursive?

read_file

Чтение файла (лимит 1MB)

path

write_file

Запись файла + уведомление об изменении ресурса

path, content

search_files

Поиск текста в файлах

query, path?, maxResults?

memory_set

Установить KV в памяти

key, value

memory_get

Получить KV

key

memory_delete

Удалить KV

key

memory_list

Список KV

—

memory_clear

Очистить всё

—

database_query

SQL через alasql (users, notes)

sql

database_tables

Список таблиц с количеством строк

—

shell_execute

Shell (allowlist, отключено по умолчанию)

command, timeout?

collect_user_info

Демо-сбор информации (контакты/предпочтения)

infoType?

generate_with_sampling

Демо-сэмплирование (LLM)

prompt, maxTokens?

rag_ingest

Загрузка текста (чанки, эмбеддинги)

text, id?, metadata?, chunk?

rag_search

Гибридный поиск (vector+BM25)

query, topK?, threshold?, mode?

rag_list

Список документов

—

rag_clear

Очистить векторное хранилище

—

brave_search

Brave API (мок, если нет ключа)

query, count?

tavily_search

Tavily API (мок, если нет ключа)

query, maxResults?, includeAnswer?

web_fetch

Кэшированное получение веб-страницы

url, useCache?, maxLength?

github_search_repos

Поиск репозиториев GitHub

query, perPage?

github_get_repo

Получить репозиторий GitHub

repo

github_get_issue

Получить issue GitHub

repo, issueNumber

create_task

Создать фоновую задачу

duration?, payload?

get_task

Получить статус задачи

taskId

get_task_result

Получить результат задачи

taskId

slack_list_channels

Каналы Slack (плагин)

—

slack_post_message

Отправка сообщения в Slack (плагин)

channel, text

slack_search

Поиск в Slack (плагин)

query, count?

notion_search

Поиск в Notion (плагин)

query, page_size?

notion_get_page

Страница Notion (плагин)

page_id

notion_create_page

Создание страницы Notion (плагин)

title, content?

linear_list_issues

Issues Linear (плагин)

team?, limit?

linear_create_issue

Создание issue Linear (плагин)

title, description?, team?

linear_get_issue

Issue Linear (плагин)

id

📦 Ресурсы (6)

  • config://server-info — метаданные сервера (JSON, теперь включает features)

  • greeting://{name} — динамический шаблон приветствия

  • file:///{+path} — файл в песочнице (ALLOWED_ROOT), список + автодополнение, file:///notes.txt

  • memory://{key} — KV в памяти, список + автодополнение

  • db://{table}/{id} — демо-строка БД (users/notes), список + автодополнение

  • docs://{id} — RAG-чанк (загружен через rag_ingest), список + автодополнение

💬 Промпты (4)

  • code-review — аргументы: language, code

  • explain-concept — аргументы: concept, level

  • summarize — аргументы: text, length (short/medium/long), style (bullets/paragraph/tldr)

  • research — аргументы: topic, depth (overview/deep), audience (beginner/expert/executive)


⚙️ Конфигурация клиента

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "mcp-server-base": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-server/dist/index.js"]
    }
  }
}

HTTP-клиент

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 :6333

RAG-демо (загрузка → поиск → 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

📁 Структура

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, research

Чтобы добавить новый инструмент: создайте src/tools/my.tool.ts → экспортируйте registerMyTool(server) → добавьте в src/tools/index.ts.


🔐 Безопасность (Фаза 2)

  • Helmet заголовки (x-dns-prefetch-control, x-frame-options, x-content-type-options и др.) через helmet@7 (src/index.ts:1)

  • CORS allowlist (CORS_ORIGIN=* или список через запятую) с обработкой cors credentials (src/config.ts:60)

  • Аутентификация AUTH_MODE=none|apiKey|bearer в src/middleware/auth.ts:1 — 401 без валидного X-API-Key или Authorization: Bearer (health/ready и OPTIONS исключены)

  • Ограничение скорости express-rate-limit (по умолчанию 100/15мин) на /mcp — 429 Too Many Requests (src/middleware/rateLimit.ts:1)

  • RequestId (X-Request-Id randomUUID, эхо-заголовок, корреляция дочернего логгера) (src/middleware/requestId.ts:1)

  • Zod валидация env (src/config.ts:1) — parseEnv() проверяет PORT, AUTH_MODE, API_KEY на перекрёстные поля, быстрый отказ при невалидном env

  • Структурированный логгер JSON/текст, [REDACTED] для authorization, apiKey, token (src/utils/logger.ts:24)

  • Возобновляемость InMemoryEventStore (src/utils/eventStore.ts:1) + карта сессий с сохранением состояния, когда RESUMABILITY_ENABLED=true (повтор через Last-Event-ID, GET /mcp поток, DELETE закрытие)

  • Укрепление Docker непривилегированный appuser + HEALTHCHECK (Dockerfile:1)

  • Тесты: 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 тестов → 130 всего с Фазой 5, 90.89% покрытие

🔗 Интеграции (Фаза 4)

  • Кэш MemoryCache TTL (src/utils/cache.ts:1) — defaultCache для web/github, SimpleQueue (src/utils/queue.ts:1)

  • RAG локальный вектор (hash-эмбеддинг 128-мерный, косинус, чанк 500/50) в src/tools/rag.tool.ts:1 — rag_ingest (чанки + sendResourceListChanged), rag_search (topK, threshold), rag_list, rag_clear + ресурс docs://{id}

  • Web src/tools/web.tool.ts:1 — brave_search (мок, если нет BRAVE_API_KEY), tavily_search (мок), web_fetch (кэшируется через defaultCache, CACHE_TTL_MS)

  • GitHub src/tools/github.tool.ts:1 — github_search_repos, github_get_repo, github_get_issue (кэшируется, GITHUB_TOKEN для лимита скорости)

  • Стек docker-compose.yml:1 (app + redis:7 + postgres:16 + qdrant:v1.12.4) с healthcheck

  • Демо rag_ingest → rag_search → docs:// E2E проверено в tests/integrations.test.ts:1 (21 тест)

🏢 Масштабирование и корпоративное использование (Фаза 5 — v3.0) — НОВОЕ

  • Мультитенантность src/middleware/tenant.ts:1 — заголовок X-Tenant-Id (или ?tenant=), tenantMiddleware возвращает 400, когда TENANT_REQUIRED=true и заголовок отсутствует, память с изоляцией тенантов getTenantMemory(tid) (изолированные хранилища), пространства имён для ключей кэша tenant:{id}:key, реестр createTenant/deleteTenant

  • SSO OIDC src/middleware/auth.ts:1 — AUTH_MODE=oidc: структурная проверка Bearer JWT (3 части, exp, iss против OIDC_ISSUER, aud против OIDC_AUDIENCE), claims прикрепляются к req.oidcClaims; в production подключается проверка подписи JWKS

  • Плоскость управления src/routes/controlplane.ts:1 — CRUD /admin/tenants (POST/GET/PATCH/DELETE + 409 дубликат/400 неверный id), POST /admin/tenants/:id/rotate-key, GET /admin/tenants/:id/store проверка изоляции; защищено admin-токеном

  • Масштабирование в рантайме src/utils/cluster.ts:1 — initCluster() создаёт CLUSTER_WORKERS (по умолчанию CPU-1), автоматический перезапуск при завершении воркера, CLUSTER_MODE=true; без состояния + RedisEventStore для настоящего горизонтального масштабирования

  • Стек мониторинга docker-compose.override.yml:1 — Prometheus (prometheus.yml собирает метрики с app:3000/metrics) на :9090 + Grafana на :3001

  • Тесты tests/v3_0.test.ts:1 (15 тестов: извлечение тенанта/изоляция/required-400, проверка OIDC-токена + issuer/audience + HTTP 401/200, жизненный цикл control plane 201/409/400/404/rotate-key/проверка хранилища/disabled-404, кластер no-op, сервисы compose) — всего 178

🔌 Экосистема и DX (Фаза 5 — v2.2)

  • Plugin SDK src/plugin/index.ts:1 — definePlugin({name, version, register}), registerPlugin(server, plugin) (устойчив к дубликатам), getRegisteredPlugins(), автоматические уведомления sendToolListChanged

  • Интеграции src/integrations/ — slackPlugin (list/post/search), notionPlugin (search/get/create), linearPlugin (list/create/get) — все замоканы без токенов (SLACK_TOKEN, NOTION_TOKEN); автоматически регистрируются в src/server.ts:1

  • Реестр smithery.yaml:1 — конфигурация Smithery + имя MCP Registry io.github.ahmedalbanna/mcp-server-base, поля mcpName/files в package.json:1

  • Гибридный RAG src/tools/rag.tool.ts:1 — режимы rag_search vector|bm25|hybrid (по умолчанию hybrid, alpha 0.5), BM25 (k1=1.5, b=0.75) нормализован + повторное ранжирование по косинусу; набор для оценки tests/eval/rag-eval.json (20 вопросов/ответов) с p@5 ≥0.8, проверено в tests/v2_2.test.ts:1

  • Песочница промптов src/routes/admin.ts:1 — POST /admin/prompts/:name/preview рендерит промпты на стороне сервера; UI песочницы в дашборде /admin

  • Тесты tests/v2_2.test.ts:1 (16 тестов: Plugin SDK define/register/dup/вызов инструментов, файлы реестра, гибридные режимы, eval p@5, предпросмотр/UI/счётчик) — всего 163

📈 Масштабирование и эксплуатация (Фаза 5 — v2.0)

  • Версионированный MCP v2.0.0 (package.json:1, config.MCP_SERVER_VERSION) с инструкциями для каждой минорной версии (src/server.ts:1)

  • OTEL трассировка/метрики (src/utils/otel.ts:1) — createSpan/withSpan, incrementCounter/recordHistogram, getMetrics/getSpans, заглушка JSON-экспорта для OTEL_EXPORTER_OTLP_ENDPOINT, флаг OTEL_ENABLED

  • RedisEventStore (src/utils/redisEventStore.ts:1) — реализация EventStore с storeEvent/replayEventsAfter, запасной вариант в памяти, eventStoreFactory.create() для горизонтального масштабирования (EVENT_STORE_TYPE=memory|redis, REDIS_URL)

  • Админ-интерфейс (src/routes/admin.ts:1) — GET /admin (HTML-дашборд), /admin/tools|resources|prompts|metrics|spans|stores|health (JSON), защищён через ADMIN_TOKEN (X-Admin-Token), флаг ADMIN_ENABLED

  • Задачи (src/tools/tasks.tool.ts:1) — экспериментальный delay_task (если доступны SDK-задачи) + запасные create_task/get_task/get_task_result (в памяти, опрос), инфраструктура SimpleQueue/MemoryCache

  • Бенчмарк k6/load.js:1 — http_req_duration p(95)<100ms, stages 10→50 VUs, checks >99%, npm run bench / bench:local

  • Compose docker-compose.yml:1 уже включает redis/postgres/qdrant для масштабирования

  • Тесты: tests/scale.test.ts:1 (OTEL spans/metrics, RedisEventStore replay, TTL кэша, очередь, admin HTML/metrics/token/ready, задачи create/poll, версия, k6-скрипт) — всего 130 (теперь 147 с v2.1)

  • Деплой готов для Fly.io/Cloud Run (без состояния + RedisEventStore), GHCR через release.yml, npm 2.0.0

🔒 Укрепление и наблюдаемость (Фаза 5 — v2.1) — НОВОЕ

  • OTEL Real src/observability/otel-real.ts:1 — initOtel() динамический импорт @opentelemetry/sdk-node + OTLPTraceExporter (запасной вариант — консоль), OTEL_ENABLED + OTEL_EXPORTER_OTLP_ENDPOINT, корректное завершение shutdown по SIGTERM

  • SLO src/observability/slo.ts:1 — checkSlo() (память/rag/кэш/аптайм, latencyMs), GET /health → {status, checks, uptime, version, otel, eventStore} + GET /ready → 503, если не ok, GET /metrics → Prometheus text/plain через prom-client (mcp_http_requests_total, mcp_http_request_duration_ms, mcp_sessions_active)

  • RBAC src/middleware/rbac.ts:1 — reader < writer < admin (заголовок X-Role, заглушка JWT), карта TOOL_ROLES (31 инструмент), mcpRbacMiddleware проверяет тело tools/call → 403, если reader пытается вызвать write_file/shell_execute, GET /admin → требуется admin

  • Резервное копирование src/utils/persistence.ts:1 — saveBackup()/loadBackup()/scheduleSave() (дебаунс 500 мс) в ALLOWED_ROOT/.backup.json (динамический getBackupFile()), логирует заглушку синхронизации Redis при установленном REDIS_URL, loadBackup() при запуске в src/index.ts:1

  • Метрики src/utils/metrics.ts:1 — prom-client Registry + collectDefaultMetrics, httpRequestsTotal/httpRequestDuration/mcpToolCallsTotal/mcpSessionsActive, обработчик GET /metrics

  • Тесты tests/v2_1.test.ts:1 (13 тестов: проверки SLO, RBAC hasRole/X-Role 403/200, SLO health/metrics 200 + текст Prometheus, OTEL span, резервное копирование save/load + scheduleSave через memory_set, initOtel выключен/включён) + tests/unit/rbac.test.ts:1 (4 теста) — всего 147

  • Логгер безопасен для stderr, никогда не логирует секреты (редактирование)

  • Zod → JSON Schema через SDK (src/types.ts:1, src/tools/*.tool.ts)

  • Таймаут на fetch (10 с) + структурированные ошибки

  • Корректное завершение (SIGINT/SIGTERM)

  • Health (GET /health) и ready (GET /ready) отдельно от MCP

  • Без состояния по умолчанию (sessionIdGenerator: undefined), с состоянием при RESUMABILITY_ENABLED=true (src/index.ts:22)

  • Type-safe, строгий TS + ESLint flat + Prettier + husky + lint-staged

  • Покрытие 85% строк / 70% веток enforced (vitest.config.ts:1), 178 тестов: unit + e2e HTTP/security/capabilities/integrations/scale/v2.1/v2.2/v3.0

📚 Документация

Полная документация в docs/:

🤝 Вклад

См. CONTRIBUTING.md — nvm use, npm test, добавьте инструмент/ресурс/промпт, убедитесь, что lint/typecheck/test проходят. См. CODE_OF_CONDUCT.md.


📚 MCP Документация

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    A 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.
    6
    2 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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
  • A
    license
    B
    quality
    C
    maintenance
    Enables running a Model Context Protocol server with a validated echo tool over stdio or Streamable HTTP, including strict schemas, tests, and hardened container deployment.
    1
    1
    MIT