Skip to main content
Glama
ljutreras
by ljutreras

MCP Server Template

Template hexagonal para crear MCP servers en Node.js/TypeScript. Objetivo: agregar un nuevo tool = crear 1 archivo + 1 línea.

Estructura

src/
├── index.ts                     ← entrypoint (3 líneas)
│
├── core/
│   ├── registry.ts              ← ToolRegistry: registro + dispatcher automático
│   ├── server.ts                ← factory de instancias McpServer
│   └── run.ts                   ← transporte dual stdio/HTTP
│
├── tools/
│   ├── index.ts                 ← ← ← ÚNICO ARCHIVO QUE EDITAS AL AGREGAR TOOLS
│   └── examples/
│       └── es-search.tool.ts    ← ejemplo completo (patrón a seguir)
│
├── infra/
│   ├── clients/
│   │   └── elasticsearch.client.ts   ← singleton de ES
│   └── formatters/
│       └── result.formatter.ts       ← limpieza de resultados para el LLM
│
├── config/
│   ├── env.ts                   ← variables de entorno validadas con Zod
│   └── logger.ts                ← pino → stderr (MCP-safe)
│
└── shared/
    ├── types/
    │   └── tool.types.ts        ← ToolDefinition interface
    └── errors/
        └── mcp.error.ts         ← toMcpError / toMcpSuccess helpers

Related MCP server: MCP Base Server

Agregar un nuevo tool (3 pasos)

Paso 1 — Crea src/tools/mi-feature.tool.ts

import { z } from "zod";
import { ToolDefinition } from "../shared/types/tool.types.js";
import { toMcpSuccess } from "../shared/errors/mcp.error.js";

const MiInput = z.object({
  param: z.string().describe("Descripción para el LLM"),
});

async function miHandler(input: z.infer<typeof MiInput>) {
  // tu lógica aquí
  return toMcpSuccess({ resultado: input.param });
}

export const miTool: ToolDefinition<z.infer<typeof MiInput>> = {
  name: "mi_tool",
  description: "Descripción para el LLM",
  inputSchema: MiInput,
  handler: miHandler,
};

Paso 2 — Regístralo en src/tools/index.ts

import { miTool } from "./mi-feature.tool.js";

export function registerAllTools(registry: ToolRegistry): void {
  registry
    .register(esSearchKeywordTool)
    .register(miTool);  // ← esta línea
}

Paso 3 — Listo. El dispatcher, JSON Schema y listado MCP se actualizan solos.

Variables de entorno

SERVER_NAME=mi-mcp-server
SERVER_VERSION=1.0.0
MCP_TRANSPORT=stdio          # stdio | http
PORT=3001
ELASTICSEARCH_URL=http://localhost:9200
LOG_LEVEL=info

Comandos

npm install
npm run dev           # dev stdio
npm run dev:http      # dev MCP over HTTP
npm run prod          # prod MCP over HTTP

Regla de oro del MCP logging

Nunca uses console.log en un MCP server en modo stdio. stdout es el canal del protocolo. Un console.log rompe el handshake. Usa siempre logger.info(...) de config/logger.ts — escribe a stderr.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A TypeScript-based template for rapidly developing MCP servers with modular tool architecture, built-in validation using Zod schemas, and comprehensive error handling.
    4 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Node.js template for building stateful MCP servers with streamable HTTP transport, featuring modular tools and resources for easy extension and integration.
    3 npm
    2
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides a starting template for building MCP servers with TypeScript, including examples of tools and resources to accelerate development.
    -