A production-ready template for building Model Context Protocol (MCP) servers in TypeScript. Fork this to quickly spin up a new MCP server for any business domain — database tools, API integrations, document workflows, or custom AI capabilities.
- All three MCP primitives: Tools, Resources, and Prompts with working examples
- Three transports: stdio (Claude Desktop), Streamable HTTP, and Vercel serverless
- TypeScript with strict mode, ESM, and full type safety
- Zod schemas for runtime argument validation
- Unit tests (Vitest) + smoke tests for all transports
- ESLint + Prettier for consistent code quality
- CI/CD ready with GitHub Actions workflow
- Docker support with multi-stage builds
- Structured logging with sensitive-field redaction
- MIT licensed — use freely for any purpose
# Clone and enter
git clone <your-repo-url> my-mcp-server
cd my-mcp-server
# Install
npm ci
# Build
npm run build
# Run (HTTP transport)
npm run start:http
# → http://127.0.0.1:3000/mcp
# → http://127.0.0.1:3000/health
# Run (stdio transport — for Claude Desktop)
npm run start:stdio
# Test
npm test # unit tests
npm run test:smoke # stdio smoke test
npm run lint # code qualitySee TEMPLATE.md for a step-by-step guide to adapting this template for your business needs. The key steps are:
- Update
package.json(name, description, bin) - Update
src/server.ts(server identity and instructions) - Replace example tools in
src/tools.ts - Replace example resources in
src/resources.ts - Replace example prompts in
src/prompts.ts - Update tests to match your new capabilities
- Update the banner and README
Search for TODO(template) comments throughout the codebase — they mark every customization point.
├── src/
│ ├── server.ts # Transport-agnostic server factory
│ ├── tools.ts # Tool definitions (AI-callable functions)
│ ├── resources.ts # Resource definitions (URI-addressable data)
│ ├── prompts.ts # Prompt definitions (reusable templates)
│ ├── banner.ts # Startup banner printer
│ ├── logging.ts # Structured HTTP request/response logger
│ ├── stdio.ts # stdio transport entry point
│ └── http.ts # Streamable HTTP transport entry point
├── api/
│ ├── mcp.ts # Vercel serverless handler
│ └── health.ts # Health check endpoint
├── tests/
│ ├── tools.test.ts # Unit tests for tools
│ ├── resources.test.ts
│ └── prompts.test.ts
├── scripts/
│ ├── smoke.mjs # stdio smoke test
│ └── smoke-vercel.ts # Vercel smoke test
├── index.ts # HTTP server entry (dev/Vercel compat)
├── Dockerfile
├── .github/workflows/ci.yml
└── TEMPLATE.md # Customization guide
This template ships with example tools, resources, and prompts to demonstrate the patterns:
| Type | Examples |
|---|---|
| Tools | echo, calculate, current_time, random_number, summarize_list |
| Resources | config://app, docs://about, users://{id}, greeting://{name} |
| Prompts | summarize, code_review, brainstorm |
Replace all of these with your business logic. See TEMPLATE.md for guidance.
Used by desktop MCP clients (Claude Desktop, MCP Inspector). The client spawns this server as a child process and communicates via stdin/stdout.
Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/dist/stdio.js"]
}
}
}Used by web-based clients. Start with npm run start:http.
# Initialize a session
curl -X POST http://127.0.0.1:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'Deploy to Vercel with zero configuration. The api/mcp.ts handler is stateless — each request creates a fresh server+transport pair.
| Script | Description |
|---|---|
npm run build |
Compile TypeScript → dist/ |
npm start |
Start HTTP transport |
npm run start:stdio |
Start stdio transport |
npm run dev:stdio |
Watch mode for stdio |
npm run dev:http |
Watch mode for HTTP |
npm test |
Run unit tests (Vitest) |
npm run test:smoke |
stdio integration smoke test |
npm run test:vercel |
Vercel integration smoke test |
npm run lint |
ESLint check |
npm run format |
Prettier format |
npm run typecheck |
TypeScript type check (no emit) |
npm run inspect |
Open MCP Inspector |
See .env.example for all options.
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
HTTP server port |
HOST |
127.0.0.1 |
HTTP bind address |
MCP_LOG_BODY_LIMIT |
4000 |
Max chars in log body capture |
CORS_ORIGIN |
* |
CORS origin for Vercel handler |
- Node.js >= 18
- npm >= 9
MIT — see LICENSE.