Click on "Install 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 Templateshow 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