cameronsjo/mcp-server-template
If you are the rightful owner of mcp-server-template and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
This template provides a comprehensive setup for building Model Context Protocol (MCP) servers using TypeScript, designed for both local and cloud environments.
MCP Server Template
A production-ready template for building Model Context Protocol (MCP) servers with TypeScript.
Features
- MCP SDK 1.24.3 - Latest SDK with 2025-11-25 spec support
- Dual Transport - Stdio (Claude Desktop) and HTTP (cloud deployment)
- OAuth 2.1 Foundations - Protected resource metadata, bearer token structure
- SQLite Caching - TTL-based caching with sql.js (WebAssembly)
- Observability - Sentry error tracking + OpenTelemetry tracing
- Security - PII sanitization, rate limiting, DNS rebinding protection
- Type Safety - Strict TypeScript with Zod validation
Quick Start
# Clone and install
git clone <this-repo> my-mcp-server
cd my-mcp-server
npm install
# Development mode (hot reload)
npm run dev
# Build and run
npm run build
npm start
# Test with MCP Inspector
npm run inspector
Project Structure
src/
├── index.ts # CLI entry point
├── server.ts # MCP server implementation
├── instrumentation.ts # Sentry + OpenTelemetry setup
├── config/
│ └── index.ts # Environment configuration
├── db/
│ ├── database.ts # SQLite connection (sql.js)
│ └── cache.ts # TTL-based caching
├── tools/
│ ├── registry.ts # Tool registration pattern
│ └── examples.ts # Example tool implementations
├── transport/
│ └── http-transport.ts # HTTP with OAuth foundations
├── shared/
│ ├── logger.ts # Structured logging
│ ├── errors.ts # Custom error classes
│ ├── rate-limiter.ts # Per-source rate limiting
│ ├── pii-sanitizer.ts # PII detection/removal
│ └── tracing.ts # OpenTelemetry utilities
└── types/
└── index.ts # TypeScript type definitions
Configuration
Environment variables (prefix with MCP_SERVER_):
| Variable | Default | Description |
|---|---|---|
MCP_SERVER_NAME | mcp-server-template | Server name |
MCP_SERVER_VERSION | 0.1.0 | Server version |
MCP_SERVER_LOG_LEVEL | info | Log level: debug, info, warning, error |
MCP_SERVER_DB_PATH | .data/cache.db | SQLite database path |
MCP_SERVER_CACHE_ENABLED | true | Enable/disable caching |
MCP_SERVER_CACHE_TTL | 3600 | Default cache TTL (seconds) |
MCP_SERVER_TIMEOUT | 30000 | Request timeout (ms) |
MCP_SERVER_TRANSPORT | stdio | Transport: stdio or http |
MCP_SERVER_PORT | 3000 | HTTP port (when transport=http) |
MCP_SERVER_HOST | 127.0.0.1 | HTTP host (when transport=http) |
MCP_SERVER_SENTRY_DSN | - | Sentry DSN for error tracking |
OTEL_ENABLED | false | Enable OpenTelemetry tracing |
OTEL_EXPORTER_OTLP_ENDPOINT | - | OTLP collector endpoint |
MCP_SERVER_DEBUG | false | Debug mode (skips auth) |
Creating Tools
Tools are registered with the ToolRegistry using Zod schemas:
import { z } from 'zod';
import { getToolRegistry } from './tools/registry.js';
// Define input schema
const MyToolInputSchema = z.object({
query: z.string().min(1).describe('Search query'),
limit: z.number().positive().optional().default(10),
});
type MyToolInput = z.infer<typeof MyToolInputSchema>;
// Implement handler
async function myToolHandler(input: MyToolInput) {
// Your implementation here
return {
success: true,
data: { results: [] },
};
}
// Register tool
const registry = getToolRegistry();
registry.register(
'my_tool',
'Description of what this tool does',
MyToolInputSchema,
myToolHandler
);
Transport Modes
Stdio (Default)
For Claude Desktop and local integrations:
npm start
Add to Claude Desktop config:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/dist/index.js"]
}
}
}
HTTP
For cloud deployment:
MCP_SERVER_TRANSPORT=http npm start
Endpoints:
GET /health- Health checkGET /.well-known/mcp- MCP server metadataGET /.well-known/oauth-protected-resource- OAuth metadata (RFC 9728)GET /mcp- SSE stream for server eventsPOST /mcp- JSON-RPC requestsDELETE /mcp- Close session
Security Features
PII Sanitization
Automatically detects and masks sensitive data:
import { sanitizePii } from './shared/pii-sanitizer.js';
const safe = sanitizePii('Contact: user@example.com');
// Output: "Contact: [EMAIL]"
Rate Limiting
Per-source rate limiting with exponential backoff:
import { getRateLimiter } from './shared/rate-limiter.js';
const limiter = getRateLimiter();
limiter.configure('external-api', {
requestsPerWindow: 100,
windowMs: 60000,
});
await limiter.waitForSlot('external-api');
// Make request...
DNS Rebinding Protection
HTTP transport validates Host headers against allowlist.
Observability
Sentry
Error tracking with PII filtering:
MCP_SERVER_SENTRY_DSN=https://xxx@sentry.io/xxx npm start
OpenTelemetry
Distributed tracing:
OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
npm start
Use tracing utilities:
import { withSpan, createApiSpan } from './shared/tracing.js';
const result = await withSpan('my-operation', async (span) => {
span.setAttribute('custom.attr', 'value');
return doWork();
});
Development
# Type check
npm run check
# Lint
npm run lint
npm run lint:fix
# Format
npm run format
# Test
npm test
npm run test:coverage
# Validate (all checks)
npm run validate
MCP 2025-11-25 Spec Compliance
| Feature | Status |
|---|---|
| Tools | ✅ Implemented |
| Resources | 📝 Scaffolded |
| Prompts | 📝 Scaffolded |
| Streamable HTTP | ✅ Implemented |
| .well-known/mcp | ✅ Implemented |
| OAuth 2.1 Foundations | ✅ Scaffolded |
| Tasks | ❌ Not yet |
| Elicitation | ❌ Not yet |
OAuth 2.1 Implementation
The template includes foundations for OAuth 2.1 per the MCP spec:
- Protected Resource Metadata (RFC 9728) at
/.well-known/oauth-protected-resource - Bearer token middleware structure (implement JWT validation)
- WWW-Authenticate headers with resource_metadata reference
- Scope checking structure for tool authorization
To complete OAuth integration:
- Choose an authorization server (Auth0, Logto, etc.)
- Implement JWT validation in
bearerAuthMiddleware - Add JWKS fetching and caching
- Configure scopes per tool
See MCP Authorization Spec for details.
License
MIT