Skip to main content
Glama
nickytonline

MCP TypeScript Template

by nickytonline

MCP TypeScript Template

A TypeScript template for building remote Model Context Protocol (MCP) servers with modern tooling and best practices while leveraging the MCP TypeScript SDK.

Features

This template provides:

  • TypeScript 7 - Native compiler with strict configuration; TypeScript 6 remains available as tsc6

  • Effect - Typed configuration, validation, logging, error handling, and async workflows

  • Vite+ - Build, test, lint, and format through the vp CLI (Vite, Vitest, Oxlint, and Oxfmt). npm script names stay the same

  • Express - Fast, unopinionated web framework for HTTP server

  • Oxlint anti-slop rules - Vendored custom plugins in tools/oxlint/anti-slop, loaded by Vite+

  • Docker - Containerization support

  • Example Tools - echo and elicit_echo tools demonstrating tool implementation, structured output, annotations, and MCP elicitation

  • Example Agent Skill - example-server published through the MCP Skills extension (skills/list, skills/get, and resources/read)

Related MCP server: MCP Server Boilerplate

Getting Started

The easiest way to get started is using degit:

  1. Create a new project from this template

    npx degit nickytonline/mcp-typescript-template my-mcp-server
    cd my-mcp-server
  2. Install dependencies

    npm install
  3. Build the project

    npm run build
  4. Start the server

    npm start

The server will be available at http://localhost:3000 for MCP connections.

Alternative: Using GitHub Template

You can also click the "Use this template" button on GitHub to create a new repository, then clone it:

git clone <your-repo-url>
cd my-mcp-server
npm install

Development

Node.js 24.11 or newer. Vite+ does not run on earlier Node 24 releases. npm start still runs node dist/index.js, and the bundle target stays Node 24.

mise users get that runtime from mise.toml (node = "24"). Vite+ does not read mise.toml. The project-local vp binary uses the Node already on PATH; a global vp install is not required.

Type checking

npm run typecheck uses the TypeScript 7 compiler. The typescript package remains an npm alias for the TypeScript 6 compatibility package and is available as tsc6 when needed.

Watch mode for development (with hot reloading)

npm run dev

Build the project

npm run build

Linting

  • Lint the project

npm run lint
  • Fix all auto-fixable lint errors

npm run lint:fix

Formatting

  • Format files in the project

npm run format
  • Check formatting

npm run format:check

Testing Your MCP Server

You can test your MCP server using the MCP Inspector:

npx @modelcontextprotocol/inspector

This will launch a web interface that allows you to:

  • Connect to your MCP server

  • Test your tools interactively

  • View request/response messages

  • Debug your MCP implementation

Make sure your server is running (using npm start or npm run dev) before connecting with the inspector.

Available Tools

The template includes two example tools:

echo

Echoes back the provided message - a simple example to demonstrate MCP tool implementation.

Parameters:

  • message (string) - The message to echo back

elicit_echo

Demonstrates MCP elicitation: the tool takes no input, asks the connected client to prompt the user for a message, then echoes it back. Handles all three elicitation outcomes (accept, decline, cancel) and errors when the client doesn't support elicitation.

Both tools declare an outputSchema and return structuredContent alongside the text result, and carry annotations (readOnlyHint, idempotentHint, openWorldHint) describing their safety profile.

Agent skill

The template bundles an example Agent Skill that tells a client how to use echo and elicit_echo, and how to replace that guidance. On protocol revision 2026-07-28 or later, server/discover advertises io.modelcontextprotocol/skills. Clients that support the extension call skills/list or skills/get for skill://example-server/SKILL.md, then read the same bytes with resources/read. The listing includes a file manifest with SHA-256 digests and byte sizes, plus ttlMs and cacheScope freshness hints. Directory reads are left unimplemented.

Add another skill by creating skills/<name>/SKILL.md whose frontmatter name matches <name>. The server publishes valid, non-hidden skill directories under skills/. Coding skills in .agents/skills/ stay local to this repository and are separate from the skills the running server publishes.

A digest match checks that fetched bytes match the server's manifest. Reading a resource returns those bytes; the host decides whether to verify, approve, and load the skill. See docs/AGENT_SKILLS.md.

Customizing Your MCP Server

  1. Update package.json - Change name, version, description, and keywords. The MCP server name and version are read from name and version unless SERVER_NAME or SERVER_VERSION is set

  2. Modify src/tools.ts - Replace the echo / elicit_echo tools with your custom tools

  3. Replace skills/example-server - Add your own skills/<name>/SKILL.md and remove the example once it no longer describes the server. Delete every skill directory, leaving skills/ in place, to publish none

  4. Add your logic - Create additional TypeScript files for your business logic

  5. Update README - Document your specific MCP server functionality

Docker

Build and run using Docker:

  • Build the Docker image

docker build -t my-mcp-server .
  • Run the container

docker run -p 3000:3000 my-mcp-server

Docker Compose

A docker-compose.yml is included with a health check pre-configured:

docker compose up --build

Project Structure

mcp-typescript-template/
├── src/
│   ├── app.ts            # Express app and MCP Node adapter wiring
│   ├── app.test.ts       # HTTP boundary integration tests
│   ├── index.ts          # Effect startup and shutdown
│   ├── tools.ts          # Tool registration (registerTools) and logic
│   ├── tools.test.ts     # Integration tests (in-memory client/server)
│   ├── skills.ts         # Bundled Agent Skills and MCP Skills extension
│   ├── skills.test.ts    # Skill discovery, manifest, and resource tests
│   ├── config.ts         # Env var loading and validation (Effect Config)
│   ├── logger.ts         # Effect structured logging
│   └── lib/
│       ├── utils.ts      # MCP response helpers
│       ├── mcp-schema.ts  # Effect Schema → MCP Standard Schema adapter
│       ├── utils.test.ts # Unit tests
│       └── mcp-schema.test.ts # Schema adapter and dialect tests
├── skills/
│   └── example-server/SKILL.md  # Example Agent Skill published by the server
├── docs/AGENT_SKILLS.md  # Discovery, security, packaging, and compatibility
├── dist/                 # Built output (generated)
├── tsconfig.json         # TypeScript configuration
├── vite.config.ts        # Vite+ build, lint, and format configuration
├── mise.toml             # Node 24 pin for mise
├── Dockerfile            # Docker configuration
└── package.json          # Dependencies and scripts

Architecture

This template follows a simple architecture:

  • HTTP Transport - Uses Express with createMcpHandler (@modelcontextprotocol/server) for remote MCP connections

  • Stateless - Per the MCP 2026-07-28 spec: no session handshake or session ID; the app creates a fresh server per request and supports older clients through the SDK fallback

  • Tool Registration - registerTools(server) in src/tools.ts is the single source of truth for tool wiring; getServer() and the tests both use it

  • Agent Skills - registerSkills(server) in src/skills.ts publishes skills/ through MCP resources and the io.modelcontextprotocol/skills extension

  • Typed I/O - Effect Schema inputSchema/outputSchema values adapted to MCP Standard Schema, plus structuredContent for typed results

  • JSON Schema Dialects - The adapter supports both MCP-requested draft-07 and draft-2020-12 output

  • Error Handling - Genuine tool execution failures return isError: true via createErrorResult rather than being thrown; protocol, transport, and capability failures (e.g. an unsupported elicitation) can still reject the client call

  • Health Check - GET /health is a plain liveness endpoint (used by the Docker health check); GET /mcp is routed to the MCP handler itself

Example: Adding a New Tool

Add the registration inside registerTools() in src/tools.ts. See the create-mcp-tool skill (.agents/skills/create-mcp-tool) for the full walkthrough.

import type {
  CallToolResult,
  ServerContext,
} from "@modelcontextprotocol/server";
import { Effect, Schema } from "effect";
import { toMcpSchema } from "./lib/mcp-schema.ts";
import { createTextResult, runMcpEffect } from "./lib/utils.ts";

server.registerTool(
  "my_tool",
  {
    title: "My Custom Tool",
    description: "Description of what this tool does",
    inputSchema: toMcpSchema(
      Schema.Struct({
        param1: Schema.String,
        param2: Schema.optional(Schema.Number),
      }),
    ),
    outputSchema: toMcpSchema(Schema.Struct({ output: Schema.String })),
    annotations: { readOnlyHint: true, openWorldHint: false },
  },
  (args, ctx) => runMcpEffect(myTool(args, ctx)),
);

function myTool(
  args: { param1: string; param2?: number },
  _ctx: ServerContext,
): Effect.Effect<CallToolResult> {
  return Effect.succeed(createTextResult({ output: args.param1 }));
}

Keep the tool workflow in Effect and use runMcpEffect() only where it crosses back into the MCP SDK callback API. For asynchronous work, use Effect.tryPromise; for independent parallel work, use Effect.all with explicit concurrency.

Why Express?

This template uses Express for the HTTP server, which provides:

  • MCP SDK Compatibility - Full compatibility with @modelcontextprotocol/server's createMcpHandler, adapted to Node/Express via @modelcontextprotocol/node's toNodeHandler

  • Mature & Stable - Battle-tested HTTP server with extensive ecosystem

  • TypeScript Support - Excellent TypeScript support with comprehensive type definitions

  • Middleware Ecosystem - Rich ecosystem of middleware for common tasks

  • Documentation - Comprehensive documentation and community support

  • Reliability - Proven reliability for production applications

Repository Guidelines

Contributors should review AGENTS.md for project structure, coding standards, and pull request expectations before opening changes.

Related MCP Connectors

Related MCP Servers

  • F
    license
    D
    quality
    D
    maintenance
    A basic TypeScript starter template for building Model Context Protocol (MCP) servers with example function implementation and development tooling.
    1
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    A template project for quickly building Model Context Protocol (MCP) servers using TypeScript and the official SDK. It includes pre-configured examples for tools and resources to help developers jumpstart their custom MCP server development.
    30 npm
    -
  • F
    license
    A
    quality
    D
    maintenance
    A starter project for rapidly developing Model Context Protocol servers using TypeScript and the official SDK. It includes pre-implemented examples of tools and resources to help developers jumpstart their custom MCP server development.
    6
    -