Skip to content
reaatechREAATECH

@reaatech/mcp-server-engine

npm v1.0.0

Provides a pre-configured Express 5 application and server runner for building Model Context Protocol (MCP) servers with built-in middleware for authentication, rate limiting, and observability. It exposes functions to create an Express instance or start a server that automatically handles dual-transport (HTTP/SSE) routing, tool discovery, and graceful shutdowns.

@reaatech/mcp-server-engine

npm version License: MIT CI

Status: Pre-1.0 — APIs may change in minor versions. Pin to a specific version in production.

MCP server framework built on Express 5 with a composable middleware pipeline, tool orchestration, and dual-transport support. This is the top-level package that ties together the @reaatech/mcp-server-* ecosystem.

Installation

terminal
npm install @reaatech/mcp-server-engine
# or
pnpm add @reaatech/mcp-server-engine

Feature Overview

  • Express 5 server — Helmet security headers, CORS with configurable origins, 10 MB JSON body parsing
  • Middleware pipeline — Auth → Rate limit → Idempotency → Sanitization, in order
  • Dual transports — Streamable HTTP (primary) + SSE (legacy), mounted automatically
  • Tool orchestration — Auto-discovers .tool.ts files, registers them, traces execution
  • Health endpoints/health (full diagnostics), /ready (readiness), /live (liveness)
  • Observability — OpenTelemetry tracing on every tool call, Pino structured logging
  • Graceful shutdown — SIGTERM/SIGINT handlers drain connections within a configurable timeout
  • Environment-validated — All configuration validated at startup via Zod; fails fast on misconfiguration

Quick Start

Start a Server (30 seconds)

typescript
import { startServer } from '@reaatech/mcp-server-engine';
 
// Built-in echo and health-check tools are available
// Transport, auth, rate limiting, idempotency, and sanitization are all configured
startServer();
terminal
PORT=8080 pnpm dev
code
✅ GET  /health        → { status: "healthy", version: "1.0.0", ... }
✅ POST /mcp           → MCP messages (Streamable HTTP)
✅ GET  /mcp/sse       → SSE stream
✅ POST /mcp/messages  → SSE message handling

Customize the App

typescript
import { createApp } from '@reaatech/mcp-server-engine';
 
const app = await createApp();
 
// Add custom routes, middleware, or error handlers
app.get('/custom', (req, res) => {
  res.json({ custom: true });
});
 
app.listen(8080);

API Reference

createApp(): Promise<Express>

Builds and returns a fully configured Express application.

typescript
const app = await createApp();
app.listen(8080);

Steps performed:

  1. Initializes OpenTelemetry (tracing + metrics)
  2. Discovers and registers tools via @reaatech/mcp-server-tools
  3. Mounts security middleware (Helmet, CORS, JSON body parsing)
  4. Registers request ID generation
  5. Adds health/readiness/liveness endpoints
  6. Applies the middleware pipeline (auth → rate-limit → idempotency → sanitization)
  7. Mounts Streamable HTTP and SSE transports
  8. Adds 404 handler and centralized error handler

startServer(): Promise<void>

Creates the app, listens on the configured PORT, and registers SIGTERM/SIGINT graceful shutdown handlers.

typescript
startServer();
// Server listens on envConfig.PORT (default 8080)
// Graceful shutdown: drains connections within 30 seconds

createMcpServer(tools: ToolDefinition[]): McpServer

Creates an MCP server instance with the given tools. Each tool is registered with the MCP SDK’s server.tool() method. Tool execution is wrapped in OpenTelemetry spans and emits metrics.

typescript
import { createMcpServer } from '@reaatech/mcp-server-engine';
import { getTools } from '@reaatech/mcp-server-tools';
 
const server = createMcpServer(getTools());

Middleware Components

Each middleware function returns an Express middleware:

typescript
import {
  rateLimitMiddleware,
  idempotencyMiddleware,
  sanitizationMiddleware,
} from '@reaatech/mcp-server-engine';
 
app.use(rateLimitMiddleware());
app.use(idempotencyMiddleware());
app.use(sanitizationMiddleware());

Utility Functions

ExportReturnsDescription
getServerVersion()stringCurrent server version
getServerName()stringServer name (mcp-server-starter-ts)
clearRateLimitStore()voidClear rate limit state (for testing)
clearIdempotencyCache()voidClear idempotency cache (for testing)
getIdempotencyCacheSize()numberCurrent cache entry count
sanitizeString(input, patterns?){ sanitized, stripped }Sanitize a string
sanitizeObject(obj, patterns){ sanitized, stripped }Recursively sanitize an object

Middleware Pipeline

OrderMiddlewareDescription
1AuthValidates API key or Bearer token. Attaches RequestContext to req. Skips in dev when no key configured.
2Rate LimitToken bucket per client (keyed by hashed API key or IP). Returns 429 with Retry-After.
3IdempotencyDeduplicates requests with Idempotency-Key header. Returns cached response for duplicates within TTL.
4SanitizationStrips known prompt-injection patterns from request bodies. Logs sanitization events.

Configuration

All configuration is read from @reaatech/mcp-server-core’s validated environment:

VariableDefaultDescription
PORT8080Server port
NODE_ENVdevelopmentEnvironment
CORS_ORIGIN*CORS allowed origin(s)
API_KEYShared secret for auth (required in production)
AUTH_MODEapi-keyapi-key or bearer
AUTH_BYPASS_IN_DEVtrueSkip auth in dev when no key configured
RATE_LIMIT_RPM60Requests per minute per client
IDEMPOTENCY_TTL_MS300000Cache TTL for idempotent requests
SESSION_TIMEOUT_MS1800000Session expiry
LOG_LEVELinfodebug, info, warn, or error
OTEL_EXPORTER_OTLP_ENDPOINTOTLP collector URL
OTEL_SERVICE_NAMEmcp-serverService name for OTel
SANITIZATION_DENY_PATTERNSExtra patterns for sanitization

Health Endpoints

EndpointResponseDescription
GET /health{ status, version, environment, uptime, timestamp, checks: { readiness, liveness, memory } }Full diagnostics
GET /ready{ status: "ready" }Readiness probe for orchestrators
GET /live{ status: "alive" }Liveness probe for orchestrators

Error Handling

The server includes a centralized error handler:

  • 404 responses: { error: "Not Found", message: "Endpoint not found" }
  • Unhandled errors: { error: "Internal Server Error", message } — error details are hidden in production

License

MIT