Skip to main content
Glama

template-mcp

MCP (Model Context Protocol) server template with TypeScript, Zod validation, and dual transport support (stdio/HTTP). Compatible with any MCP client: Claude Code, Claude Desktop, Cursor, VS Code Copilot, Windsurf, Cline, and more.

Features

  • Dual transport: stdio (local) and Streamable HTTP (remote)

  • TypeScript strict with ESM modules

  • Zod validation for tool input schemas

  • Joi env validation (fail-fast on startup)

  • Pino logging to stderr (stdio-safe)

  • Modular architecture: tools, resources, and prompts as separate modules

  • Factory pattern: createServer() for testability

  • Full test suite with MCP SDK in-memory transport

  • Quality tooling: ESLint + Prettier + Husky + lint-staged

  • Docker ready: multi-stage build

  • CI/CD: GitHub Actions pipeline

Related MCP server: xmcp Application

Quick Start

pnpm install
pnpm dev

Scripts

Script

Description

pnpm dev

Start with hot reload (tsx watch)

pnpm build

Compile TypeScript + resolve aliases

pnpm start

Run compiled server

pnpm test

Run tests

pnpm lint

Lint source code

pnpm type-check

Type check without emit

Configuration

Copy .env.example to .env and adjust:

Variable

Default

Description

MCP_TRANSPORT

stdio

Transport: stdio or http

PORT

3000

HTTP port (only for http transport)

LOG_LEVEL

info

Pino log level

NODE_ENV

development

Environment

Project Structure

src/
├── main.ts              # Entrypoint: transport selection
├── server.ts            # createServer() factory
├── config/              # Env validation + constants
├── common/              # Logger, error helpers, types
├── tools/               # MCP tools (callable by LLMs)
├── resources/           # MCP resources (read-only data)
└── prompts/             # MCP prompts (reusable templates)

Adding a New Tool

  1. Create src/tools/my-tool.tool.ts:

import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';

export function registerMyTool(server: McpServer): void {
  server.registerTool(
    'my_tool',
    {
      title: 'My Tool',
      description: 'What this tool does',
      inputSchema: {
        param: z.string().describe('Parameter description'),
      },
      annotations: {
        readOnlyHint: true,
        destructiveHint: false,
        idempotentHint: true,
        openWorldHint: false,
      },
    },
    async ({ param }) => ({
      content: [{ type: 'text', text: `Result: ${param}` }],
    }),
  );
}
  1. Register in src/tools/index.ts:

import { registerMyTool } from './my-tool.tool.js';

export function registerTools(server: McpServer): void {
  registerGreetTool(server);
  registerMyTool(server); // add here
}
  1. Add tests in src/tools/__tests__/my-tool.tool.spec.ts

Client Configuration

Claude Code

Add to .claude/settings.json:

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

Claude Desktop

Add to claude_desktop_config.json:

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

Cursor

Add to Cursor Settings > MCP Servers:

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

VS Code (Copilot)

Add to .vscode/settings.json:

{
  "mcp": {
    "servers": {
      "template-mcp": {
        "command": "node",
        "args": ["/absolute/path/to/template-mcp/dist/main.js"]
      }
    }
  }
}

Docker

# Build
docker build -t template-mcp .

# Run (HTTP mode, used for remote access)
docker run -p 3000:3000 template-mcp

Tech Stack

  • Node.js 22 + TypeScript (strict, ESM)

  • MCP SDK v1 (@modelcontextprotocol/sdk)

  • Zod (tool input validation)

  • Joi (env validation)

  • Pino (stderr logging)

  • Vitest (testing)

  • ESLint + Prettier + Husky


Verificación

Todo lo siguiente está comprobado y funcionando al 100%.

Calidad de código

Check

Comando

Lint + formato

pnpm lint

Tipado estricto

pnpm type-check

Build (tsc + alias)

pnpm build

Tests unitarios (11/11)

pnpm test

Suite

Cubre

greet.tool.spec.ts (5)

Listado, estilos casual/formal/enthusiastic, rechazo de nombre vacío

server-info.resource.spec.ts (2)

Listado, campos JSON (name, version, uptime, timestamp)

summarize.prompt.spec.ts (4)

Listado, estilos brief/bullet-points, coerción numérica, defaults

Sin red ni puertos — usa InMemoryTransport del SDK.

Runtime — transporte stdio (modo por defecto)

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' \
  | MCP_TRANSPORT=stdio node dist/main.js

Respuesta JSON-RPC en stdout, logs en stderr.

Runtime — transporte HTTP

MCP_TRANSPORT=http PORT=3100 node dist/main.js &
# Initialize → capturar Mcp-Session-Id del header
# tools/list, resources/list, prompts/list, tools/call greet, resources/read info://server

Endpoint verificado

Resultado esperado

tools/call greet {"name":"Freddy","style":"casual"}

"Hey Freddy! How's it going?"

resources/read info://server

JSON con name, version, uptime, nodeVersion, timestamp

Docker

docker build -t template-mcp .  # multi-stage: base → deps → build → production
docker run -p 3000:3000 template-mcp  # arranca en HTTP mode

CI (GitHub Actions)

pnpm install → pnpm lint → pnpm build → pnpm test
Corre en cada push y PR a main/master.

Pipeline de commits (local)

git commit → husky → lint-staged → eslint --fix + prettier --write (solo archivos staged)

Gaps conocidos

  • HTTP transport sin tests automáticos (medio): los unit tests usan InMemoryTransport; el transporte HTTP (StreamableHTTPServerTransport) solo se verificó manualmente con curl. Para producción remota añadir tests de integración con sesión real

  • Integración con cliente MCP (medio): verificar manualmente agregando a .claude/settings.json o Cursor y confirmando que tools/resources/prompts aparecen en el cliente

  • Tool inputs extremos (bajo): strings muy largos, unicode malformado — Zod los rechaza pero el error response no está testeado vía HTTP

  • Sesiones concurrentes (bajo): fuera del scope de un template

Available Tools

1 tool
greetGreet UserA
Read-onlyIdempotent

Generates a personalized greeting message. Use this tool when you need to greet someone by name with an optional custom greeting style.

Inputs: name (required), style.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.8/5.0

    Scored across 1 tool

    Disambiguation5/5

    Only one tool exists, so there is no ambiguity in choosing between tools.

    Naming Consistency3/5

    With only one tool, consistency is not applicable, but the name 'greet' is clear and follows a common verb pattern.

    Tool Count2/5

    A single tool for a server called 'template-mcp' suggests an extremely narrow scope, which is likely insufficient for meaningful tasks.

    Completeness2/5

    The server only offers a greeting function, which is too limited for any substantial workflow; missing any broader functionality.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    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.
      5 npm
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      A Model Context Protocol (MCP) server template designed for building structured tools, prompts, and resources with built-in support for HTTP and STDIO transports. It provides a standardized framework for developers to create and deploy AI-driven services using TypeScript and Zod schema validation.
      4 npm
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      A minimal TypeScript MCP server template with example tool, Zod validation, stdio transport, and dotenv setup.
      23 npm
      MIT