MCP Server Template
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Server Template show me the available tools"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 inspectorProject 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 definitionsConfiguration
Environment variables (prefix with MCP_SERVER_):
Variable | Default | Description |
|
| Server name |
|
| Server version |
|
| Log level: debug, info, warning, error |
|
| SQLite database path |
|
| Enable/disable caching |
|
| Default cache TTL (seconds) |
|
| Request timeout (ms) |
|
| Transport: |
|
| HTTP port (when transport=http) |
|
| HTTP host (when transport=http) |
| - | Sentry DSN for error tracking |
|
| Enable OpenTelemetry tracing |
| - | OTLP collector endpoint |
|
| 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 startAdd to Claude Desktop config:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["/path/to/dist/index.js"]
}
}
}HTTP
For cloud deployment:
MCP_SERVER_TRANSPORT=http npm startEndpoints:
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 startOpenTelemetry
Distributed tracing:
OTEL_ENABLED=true \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
npm startUse 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 validateMCP 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-resourceBearer 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
bearerAuthMiddlewareAdd JWKS fetching and caching
Configure scopes per tool
See MCP Authorization Spec for details.
License
MIT
References
Available Tools
4 toolsaddA
Add two numbers together
Inputs: a (required), b (required).
cacheB
Get or set a cached value. Provide only key to get, provide key and value to set.
Inputs: key (required), value, ttlSeconds.
echoC
Echo a message back, optionally in uppercase
Inputs: message (required), uppercase.
statusB
Get server status and cache statistics
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: add performs arithmetic, cache handles key-value storage, echo returns input with optional transformation, and status provides server metadata. There is no overlap or ambiguity between these functions.
All tool names follow a consistent, simple verb-based pattern (add, cache, echo, status) without mixing conventions like snake_case or camelCase. This uniformity makes the set predictable and easy to understand.
With 4 tools, the count is reasonable for a template server, covering basic utilities like arithmetic, caching, echoing, and status checks. It's slightly minimal but well-scoped for demonstration purposes, lacking only minor expansions.
As a template server, it covers fundamental operations but has notable gaps for a more robust utility set, such as missing tools for deletion, advanced caching operations, or error handling. However, it provides a complete basic workflow for its intended scope.
Related MCP Connectors
A simple Typescript MCP server built using the official MCP Typescript SDK and smithery/cli. This…
Kickstart development with a customizable TypeScript template featuring sample tools for greeting,…
A TypeScript MCP server for Home Assistant, enabling programmatic management of entities, automati…
Primarily to be used as a template repository for developing MCP servers with FastMCP in Python, P…