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.

Architecture

flowchart TD
    Client["MCP client<br/>Claude Desktop · IDE · agent"] -->|JSON-RPC over stdio| Entry["index.ts<br/>load env · connect transport"]
    Entry --> Server["server.ts<br/>buildServer()"]
    Server --> Tools["tools/*<br/>name + zod schema + handler"]
    Tools --> Lib["lib/*<br/>logger · result · http · env"]

Construction is kept separate from transport, so the same server runs over stdio in production and over an in-memory transport in tests — no mocks. Full write-up in ARCHITECTURE.md.

Related MCP server: Antigravity MCP Server

Enterprise architecture

Pillar

How the template applies it

Resilience

a thrown tool handler is contained per call (returned as an error result) — one bad call never crashes the server

Observability

structured, leveled logging to stderr (stdout is reserved for the MCP protocol)

Reproducibility

committed lockfile + Node pinned via .nvmrc, and tests that run the real server over an in-memory transport — no mocks

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

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"]
    }
  }
}

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 Agyemang

Install Server
A
license - permissive license
A
quality
B
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