Skip to main content
Glama
cameronsjo

MCP Server Template

by cameronsjo
README.md7 kB
# 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 ```bash # 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: ```typescript 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: ```bash npm start ``` Add to Claude Desktop config: ```json { "mcpServers": { "my-server": { "command": "node", "args": ["/path/to/dist/index.js"] } } } ``` ### HTTP For cloud deployment: ```bash MCP_SERVER_TRANSPORT=http npm start ``` Endpoints: - `GET /health` - Health check - `GET /.well-known/mcp` - MCP server metadata - `GET /.well-known/oauth-protected-resource` - OAuth metadata (RFC 9728) - `GET /mcp` - SSE stream for server events - `POST /mcp` - JSON-RPC requests - `DELETE /mcp` - Close session ## Security Features ### PII Sanitization Automatically detects and masks sensitive data: ```typescript 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: ```typescript 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: ```bash MCP_SERVER_SENTRY_DSN=https://xxx@sentry.io/xxx npm start ``` ### OpenTelemetry Distributed tracing: ```bash OTEL_ENABLED=true \ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \ npm start ``` Use tracing utilities: ```typescript import { withSpan, createApiSpan } from './shared/tracing.js'; const result = await withSpan('my-operation', async (span) => { span.setAttribute('custom.attr', 'value'); return doWork(); }); ``` ## Development ```bash # 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: 1. **Protected Resource Metadata** (RFC 9728) at `/.well-known/oauth-protected-resource` 2. **Bearer token middleware** structure (implement JWT validation) 3. **WWW-Authenticate** headers with resource_metadata reference 4. **Scope checking** structure for tool authorization To complete OAuth integration: 1. Choose an authorization server (Auth0, Logto, etc.) 2. Implement JWT validation in `bearerAuthMiddleware` 3. Add JWKS fetching and caching 4. Configure scopes per tool See [MCP Authorization Spec](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization) for details. ## License MIT ## References - [MCP Specification](https://modelcontextprotocol.io/specification/2025-11-25) - [MCP SDK](https://www.npmjs.com/package/@modelcontextprotocol/sdk) - [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk)

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/cameronsjo/mcp-server-template'

If you have feedback or need assistance with the MCP directory API, please join our Discord server