Skip to main content
Glama
EricAgyemang478

mcp-server-template

MCP Server Template

CI License: MIT Node

A production-ready starting point for a Model Context Protocol server: typed tools with schema-validated inputs, real tests, a multi-stage Docker image, and a CI pipeline โ€” the boring parts done right so the next MCP server starts at mile 10.

It ships with three example tools that cover the shapes you'll actually build: a pure tool, a networked tool, and a stateful tool.

Features

  • ๐Ÿงฉ Modular tools โ€” one file per tool group, registered in one place

  • โœ… Schema-validated inputs via zod โ€” bad calls fail fast

  • ๐Ÿงช Real tests โ€” an in-memory client/server harness, no mocks (node:test)

  • ๐Ÿณ Multi-stage Docker image that runs as a non-root user

  • ๐Ÿค– CI โ€” format, type-check, test, build, and a Docker build, on every push/PR

  • ๐Ÿ”‡ Protocol-safe logging โ€” stdout is reserved for MCP; logs go to stderr

  • ๐Ÿ”‘ No secrets in the repo โ€” config via env, with a .env.example

Related MCP server: TypeScript MCP Server Boilerplate

Quickstart

nvm use            # or Node 20+
npm install
npm run dev        # run the server over stdio (Ctrl-C to stop)
npm test           # run the test suite
npm run build      # compile to dist/

Example tools

Tool

Kind

What it shows

text_stats

pure

Validated input โ†’ structured output, no side effects

get_weather

networked

External API (Open-Meteo, no key), timeouts, error handling

note_set / note_get / note_list / note_delete

stateful

File-backed persistence shared across tools

Adding your own tool

This is the whole point of the template โ€” it's a three-step change:

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

    import { z } from "zod";
    import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
    import { text } from "../lib/result.js";
    
    export function registerMyThingTools(server: McpServer): void {
      server.tool(
        "greet",
        "Say hello to someone.",
        { name: z.string().describe("Who to greet") },
        async ({ name }) => text(`Hello, ${name}!`),
      );
    }
  2. Register it in src/tools/index.ts (one line).

  3. Done โ€” transport, validation, error handling, tests, and Docker need no changes.

Connect it to a client

Build first (npm run build), then point your MCP client at dist/index.js. Example config (e.g. Claude Desktop) in examples/mcp-config.json:

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

Architecture

A short, layered design โ€” entrypoint โ†’ server factory โ†’ tool groups โ†’ small shared libs. Construction is separate from transport, which is what makes it both testable and easy to extend. Full write-up with a request-lifecycle diagram in ARCHITECTURE.md.

Testing

npm test builds the real server, connects a real MCP client over an in-memory transport, and exercises tools end to end (schema validation included). Network tools aren't hit in CI โ€” tests stay fast and deterministic.

Docker

docker build -t mcp-server-template .
docker run --rm -i mcp-server-template   # -i: MCP talks over stdio

Project structure

src/
โ”œโ”€โ”€ index.ts          # entrypoint: load env, build server, connect stdio
โ”œโ”€โ”€ server.ts         # buildServer() โ€” construction, transport-agnostic
โ”œโ”€โ”€ lib/
โ”‚   โ”œโ”€โ”€ logger.ts     # stderr-only logging
โ”‚   โ”œโ”€โ”€ result.ts     # text() / errorResult() content helpers
โ”‚   โ”œโ”€โ”€ http.ts       # fetchJson() with timeout
โ”‚   โ””โ”€โ”€ env.ts        # minimal .env loader
โ””โ”€โ”€ tools/
    โ”œโ”€โ”€ index.ts      # registerAllTools() โ€” add new groups here
    โ”œโ”€โ”€ text.ts       # pure tool
    โ”œโ”€โ”€ weather.ts    # networked tool
    โ””โ”€โ”€ notes.ts      # stateful tool
test/                 # in-memory client/server tests

License

MIT ยฉ Eric Opoku

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

โ€“Maintainers
โ€“Response time
โ€“Release cycle
โ€“Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

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/EricAgyemang478/mcp-server-template'

If you have feedback or need assistance with the MCP directory API, please join our Discord server