mcp-server-base
MCP Server Base v2.0 — Escala y Operabilidad (2026)
Servidor moderno Model Context Protocol que usa el stack más actual:
MCP SDK
1.12+— API de alto nivelMcpServer+StreamableHTTPServerTransport(nuevo) yStdioServerTransportTypeScript 5.7 ESM + módulo
NodeNextValidación Zod → JSON Schema automático + validación de entorno (
src/config.ts:1)Express 4 + helmet + allowlist de CORS + límite de peticiones + health/ready + Admin UI
Doble transporte: STDIO (local, Claude Desktop) y Streamable HTTP (remoto, especificación 2025-03, sin estado + reanudación con estado vía RedisEventStore)
Módulos estructurados de herramientas/recursos/prompts + integraciones RAG (vectorial local), Web (caché), GitHub
OTEL trazado/métricas (
src/utils/otel.ts:1), Tareas (experimental +create_task), pruebas de carga k6tsxwatch,tsxwatch,vitest(130 pruebas, 91 % de cobertura), apagado ordenado,docker-compose(redis, postgres, qdrant)
🚀 Inicio rápido
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/healthRelated MCP server: MCP Server
Desarrollo
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 se ejecuta en push/PR a main con la matriz Node 20+22: lint, format:check, typecheck, test:coverage, build, docker build.
🔌 Transportes
Transporte | Uso | Comando |
STDIO | Clientes locales (Claude Desktop) |
|
Streamable HTTP | Remoto / Docker / Cloud |
|
Streamable HTTP es el nuevo estándar que reemplaza a SSE (obsoleto desde marzo de 2025).
🧰 Herramientas (31)
Herramienta | Descripción | Entrada |
| Devuelve un mensaje |
|
| Suma/resta/multiplicación/división |
|
| Hora actual |
|
| Obtiene una URL |
|
| Lista archivos bajo ALLOWED_ROOT |
|
| Lee un archivo (límite 1MB) |
|
| Escribir archivo y avisar de cambio del recurso |
|
| Busca texto dentro de archivos |
|
| Establece KV en memoria |
|
| Obtiene KV |
|
| Elimina KV |
|
| Lista las KV | — |
| Borra todo | — |
| SQL mediante alasql (users, notes) |
|
| Lista tablas con recuentos de filas | — |
| Shell (allowlist, deshabilitado por defecto) |
|
| Demo de elicitación (contacto/preferencias) |
|
| Demo de muestreo (LLM) |
|
| Ingesta de texto (fragmentado, con embeddings) |
|
| Búsqueda vectorial (coseno) |
|
| Lista documentos | — |
| Vacía el almacén vectorial | — |
| API de Brave (mock si no hay clave) |
|
| API de Tavily (mock si no hay clave) |
|
| Obtención web con caché |
|
| Busca repositorios en GitHub |
|
| Obtiene el repo de GitHub |
|
| Obtiene el issue de GitHub |
|
| Crea tarea en segundo plano |
|
| Obtiene estado de la tarea |
|
| Obtiene resultado de la tarea |
|
📦 Recursos (6)
config://server-info— metadatos del servidor (JSON, ahora incluyefeatures)greeting://{name}— plantilla de saludo dinámicafile:///{+path}— archivo en espacio aislado (ALLOWED_ROOT), listar y completar,file:///notes.txtmemory://{key}: KV en memoria, listar y completardb://{table}/{id}— fila de la demo DB (users/notes), listar y completardocs://{id}— fragmento RAG (ingerido conrag_ingest), listar y completar
💬 Prompts (4)
Argumentos | |
|
|
|
|
|
|
|
|
⚙️ Configuración del cliente
Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"mcp-server-base": {
"command": "node",
"args": ["/absolute/path/to/mcp-server/dist/index.js"]
}
}
}Cliente 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 :6333Demo RAG (ingestión → búsqueda → 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📁 Estructura
src/
├── index.ts # entry: stdio + http (helmet/cors/rateLimit/auth/resumability)
├── server.ts # createMcpServer() factory
├── config.ts # zod env (AUTH, CORS, rateLimit, RAG, cache, integrations)
├── types.ts # Zod schemas
├── middleware/auth.ts # AUTH_MODE none|apiKey|bearer
├── middleware/rateLimit.ts
├── middleware/requestId.ts
├── utils/logger.ts # stderr, JSON/text, redaction, child(requestId)
├── utils/eventStore.ts # InMemoryEventStore for Last-Event-ID
├── utils/cache.ts # MemoryCache (TTL) + defaultCache
├── utils/queue.ts # SimpleQueue
├── tools/ # 31 tools: echo, fs, memory, db, shell, rag, 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
├── resources/ # 6 resources: config, greeting, file, memory, db, docs
├── routes/admin.ts # Admin UI + metrics + spans
└── prompts/ # 4 prompts: code-review, explain-concept, summarize, researchPara añadir una herramienta: crea src/tools/my.tool.ts → exporta registerMyTool(server) → añade en src/tools/index.ts.
🔐 Seguridad (Fase 2)
Cabeceras Helmet (
x-dns-prefetch-control,x-frame-options,x-content-type-options, etc.) mediantehelmet@7(src/index.ts:1)Allowlist CORS (
CORS_ORIGIN=*o lista separada por comas) con credencialescors(src/config.ts:60)Autenticación
AUTH_MODE=none|apiKey|bearerensrc/middleware/auth.ts:1—401sinX-API-KeyoAuthorization: Bearerválidos (health/ready y OPTIONS excluidos)Límite de peticiones
express-rate-limit(por defecto 100/15min) sobre/mcp—429 Too Many Requests(src/middleware/rateLimit.ts:1)RequestId (
X-Request-IdrandomUUID, cabecera de eco, correlación del logger hijo) (src/middleware/requestId.ts:1)Validación de entorno con Zod (
src/config.ts:1) —parseEnv()validaPORT,AUTH_MODE,API_KEYde forma cruzada y falla rápido si los valores no son válidosLogger estructurado JSON/texto,
[REDACTED]sobreauthorization,apiKey,token(src/utils/logger.ts:24)Reanudabilidad
InMemoryEventStore(src/utils/eventStore.ts:1) + mapa de sesiones con estado cuando.teariaRESUMABILITY_ENABLED=true(replay es medianteLast-Event-ID,GET /mcpstream,DELETEclose)Refuerzo Docker no root
appuser+HEALTHCHECK(Dockerfile:1)Pruebas:
tests/unit/auth.test.ts,tests/unit/logger.test.ts,tests/unit/eventStore.test.ts,tests/e2e/security.test.ts(helmet/auth/rateLimit/reanudabilidad) — 67 pruebas → 130 en total con la Fase 5, 90.89 % cobertura
🔗 Integraciones (Fase 4)
Caché
MemoryCachecon TTL (src/utils/cache.ts:1) —defaultCachepara web/github,SimpleQueue(src/utils/queue.ts:1)RAG vectorial local (embedding hash de 128, coseno, chunk 500/50) en
src/utils/rag.tool.ts:1—rag_ingest(fragmentado +sendResourceListChanged),rag_search(topK, threshold),rag_list,rag_clear+ recursodocs://{id}Web en
src/tools/web.tool.ts:1—brave_search(mock si no hayBRAVE_API_KEY),tavily_search(mock),web_fetch(caché concacheyCACHE_TTL_MS)GitHub en
src/tools/github.tool.ts:1—github_search_repos,github_get_repo,github_get_issue(caché,GITHUB_TOKENpara límite de peticiones)Stack
docker-compose.yml:1(app + redis:7 + postgres:16 + qdrant:v1.12.4) con healthchecksDemo
rag_ingest → rag_search → docs://verificado E2E entests/integrations.test.ts:1(21 pruebas)
📈 Escala y Operabilidad (Fase 5 — v2.0)
Versiones MCP
v2.0.0(package.json:1,config.MCP_SERVER_VERSION) con instrucciones por minor (src/server.ts:1)OTEL seguimiento/métricas (
src/utils/otel.ts:1) —createSpan/withSpan,incrementCounter/recordHistogram,getMetrics/getSpans, export JSON stub paraOTEL_EXPORTER_OTLP_ENDPOINT, flagOTEL_ENABLEDRedisEventStore (
src/utils/redisEventStore.ts:1) — implementaciónEventStoreconstoreEvent/replayEventsAfter, fallback en memoria,eventStoreFactory.create()para escala horizontal (EVENT_STORE_TYPE=memory|redis,REDIS_URL)Admin UI (
src/routes/admin.ts:1) — api (dashboard HTML),/admin/tools|resourcespromps,/admin/metrics|resources|metrics|spans|stores|health(JSON), protegido conADMIN_TOKEN(X-Admin-Token),ADMIN_ENABLED`Tareas (
src/tools/tasks.tool.ts:1) — experimentaldelay_task(si hay SDK tasks) + fallbackcreate_task/get_task/get_task_result(en memoria, polling), infraSimpleQueue/MemoryCacheBench
k6/load.js:1— ``http_req_duration p(95)<100ms,stages10→50 VUs,checks >99 %,npm run bench/bench:local`Compose en
docker-compose.yml:1ya incluye redis/postgres/qdrant para escalaPruebas:
tests/scale.test.ts:1(OTEL spans/metrics, replay de RedisEventStore, TTL de caché, cola, admin HTML/métricas/token/ready, tareas create/poll, versión, script k6) — 130 en totalDespliegue listo para Fly.io/Cloud Runestado (stateless + RedisEventStore), GHCR vía
release.yml, npm2.0.0Logger safe para stderr, nunca registra secretos (redacción)
Zod → JSON Schema vía SDK (
src/types.ts:1,src/tools/*.tool.ts)Timeout en fetch (10 s) + errores estructurados
Apagado ordenado (
SIGINT/SIGTERM)Health (
GET /health) y ready (GET /ready) separados de MCPSin estado por defecto (
sessionIdGenerator: undefined), con estado cuandoRESUMABILITY_ENABLED=true(src/index.ts:22)Seguridad de tipos, TypeScript estricto + ESLint flat + Prettier + husky + lint-staged
Cobertura 85 % de líneas / 70 % de ramas obligatoria (
vitest.config.ts:1), 130 pruebas: unitarias + e2e HTTP/seguridad/capabilities/integraciones/escala
🤝 Contribuciones
Ver CONTRIBUTING.md — nvm use, npm test, añade herramienta/recurso/prompt, garantiza que lint/typecheck/test pasen. Ver CODE_OF_CONDUCT.md.
📚 Documentación MCP
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server that supports STDIO, SSE and Streamable HTTP protocols for AI model interactions.131MIT
- AlicenseNot gradedqualityFmaintenanceA robust server implementing the Model Context Protocol with SSE and STDIO transport, enabling real-time communication and extensible tooling for AI models.3813MIT
- 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.6111MIT
- AlicenseNot gradedqualityCmaintenanceA 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
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
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ahmedalbanna/mcp-server-base'
If you have feedback or need assistance with the MCP directory API, please join our Discord server