Package Exports
- mcp-ts-template
Readme
MCP TypeScript Template 🚀
Jumpstart your Model Context Protocol (MCP) Client & Server development with this TypeScript Repo Template!
This template provides a solid, beginner-friendly foundation for building robust MCP servers and clients, adhering to the MCP 2025-03-26 specification. It includes production-ready utilities, a well-structured codebase, working examples, and clear documentation to get you up and running quickly.
Whether you're creating a new MCP server to extend an AI's capabilities or integrating MCP client features into your application, this template is your starting point.
✨ Key Features
Feature Area | Description | Key Components / Location |
---|---|---|
🔌 MCP Server | Functional server with example tools (EchoTool , CatFactFetcher for async/Promise API example) and an EchoResource . Supports stdio and Streamable HTTP transports. |
src/mcp-server/ |
💻 MCP Client | Working client aligned with MCP 2025-03-26 spec. Connects via mcp-config.json . Includes detailed comments. |
src/mcp-client/ |
🚀 Production Utilities | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization. | src/utils/ |
🔒 Type Safety/Security | Strong type checking via TypeScript & Zod validation. Built-in security utilities (sanitization, auth middleware stub for HTTP). | Throughout, src/utils/security/ , src/mcp-server/transports/authentication/ |
⚙️ Error Handling | Consistent error categorization (BaseErrorCode ), detailed logging, centralized handling (ErrorHandler ). |
src/utils/internal/errorHandler.ts , src/types-global/ |
📚 Documentation | Comprehensive README.md , structured JSDoc comments, API references |
README.md , Codebase, tsdoc.json , docs/api-references/ |
🤖 Agent Ready | Includes a .clinerules developer cheatsheet tailored for LLM coding agents. | .clinerules |
🛠️ Utility Scripts | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs. | scripts/ |
🧩 Services | Reusable modules for LLM (OpenRouter) and data storage (DuckDB) integration, with examples. | src/services/ , src/storage/duckdbExample.ts , ` |
For a more granular breakdown, see the Detailed Features Table below.
🚀 Projects Using This Template
This template is already powering several MCP servers, demonstrating its flexibility and robustness:
Project | Description | Status / Notes |
---|---|---|
pubmed-mcp-server | MCP server for PubMed, enabling AI agents to search, retrieve, analyze, and visualize biomedical literature via NCBI E-utilities. Features advanced research workflow capabilities. | Actively using this template. |
git-mcp-server | Provides an enterprise-ready MCP interface for Git operations. Allows LLM agents to initialize, clone, branch, commit, and manage repositories via STDIO & Streamable HTTP. | Actively using this template. |
obsidian-mcp-server | Enables LLMs to interact securely with Obsidian vaults via MCP. Offers token-aware tools for searching, navigating, and updating Obsidian notes, facilitating seamless knowledge base management with Properties management. | Refactor in progress using this template (see branch). |
atlas-mcp-server | Advanced task and knowledge management system with Neo4j backend, enabling structured data organization and complex querying for AI agents. | Aligned with this template (as of v2.8.8). |
filesystem-mcp-server | Offers platform-agnostic file system capabilities for AI agents via MCP. Enables reading, writing, updating, and managing files/directories, featuring advanced search/replace and directory traversal. | Actively using this template. |
Note: toolkit-mcp-server was initially built using an older version of this template and is pending updates to the latest structure.
You can also see my GitHub profile for additional MCP servers I've created, many of which are planned to be migrated to or built upon this template in the future.
📋 Table of Contents
✨ Key Features | 🚀 Projects Using This Template | 🚀 Quick Start | ⚙️ Configuration | Server Configuration | Client Configuration | 🏗️ Project Structure | 🧩 Adding Tools/Resources | 🌍 More MCP Resources | 📜 License | Detailed Features
Quick Start
Get the example server running in minutes:
Clone the repository:
git clone https://github.com/cyanheads/mcp-ts-template.git cd mcp-ts-template
Install dependencies:
npm install
Build the project:
npm run build # Or use 'npm run rebuild' for a clean install (deletes node_modules, logs, dist)
Format the code (Optional but Recommended):
npm run format
Run the Example Server:
- Via Stdio (Default): Many MCP host applications will run this automatically using
stdio
. To run manually for testing:npm start # or 'npm run start:stdio'
- Via Streamable HTTP:This starts a Streamable HTTP server (default:
npm run start:http
http://127.0.0.1:3010
) which uses Server-Sent Events for the server-to-client streaming component. The port, host, and allowed origins are configurable via environment variables (see Configuration).
- Via Stdio (Default): Many MCP host applications will run this automatically using
⚙️ Configuration
Server Configuration (Environment Variables)
Configure the MCP server's behavior using these environment variables:
Variable | Description | Default |
---|---|---|
MCP_TRANSPORT_TYPE |
Server transport: stdio or http . |
stdio |
MCP_HTTP_PORT |
Port for the HTTP server (if MCP_TRANSPORT_TYPE=http ). |
3010 |
MCP_HTTP_HOST |
Host address for the HTTP server (if MCP_TRANSPORT_TYPE=http ). |
127.0.0.1 |
MCP_ALLOWED_ORIGINS |
Comma-separated allowed origins for CORS (if MCP_TRANSPORT_TYPE=http ). |
(none) |
MCP_SERVER_NAME |
Optional server name (used in MCP initialization). | (from package.json) |
MCP_SERVER_VERSION |
Optional server version (used in MCP initialization). | (from package.json) |
MCP_LOG_LEVEL |
Server logging level (debug , info , warning , error , etc.). |
debug |
LOGS_DIR |
Directory for log files. | logs/ (in project root) |
NODE_ENV |
Runtime environment (development , production ). |
development |
MCP_AUTH_SECRET_KEY |
Required for HTTP transport. Secret key (min 32 chars) for signing/verifying auth tokens (JWT). | (none - MUST be set in production) |
OPENROUTER_APP_URL |
URL of the application (used by OpenRouter service for HTTP Referer). | http://localhost:3000 |
OPENROUTER_APP_NAME |
Name of the application (used by OpenRouter service for X-Title header). | 'mcp-ts-template' |
OPENROUTER_API_KEY |
API key for OpenRouter.ai service. Optional, but service will be unconfigured without it. | (none) |
LLM_DEFAULT_MODEL |
Default model to use for LLM calls via OpenRouter. | google/gemini-2.5-flash-preview-05-20 |
LLM_DEFAULT_TEMPERATURE |
Default temperature for LLM calls (0-2). Optional. | (none) |
LLM_DEFAULT_TOP_P |
Default top_p for LLM calls (0-1). Optional. | (none) |
LLM_DEFAULT_MAX_TOKENS |
Default max_tokens for LLM calls. Optional. | (none) |
LLM_DEFAULT_TOP_K |
Default top_k for LLM calls (non-negative integer). Optional. | (none) |
LLM_DEFAULT_MIN_P |
Default min_p for LLM calls (0-1). Optional. | (none) |
Note on HTTP Port Retries: If the MCP_HTTP_PORT
is busy, the server automatically tries the next port (up to 15 times).
Security Note for HTTP Transport: When using MCP_TRANSPORT_TYPE=http
, authentication is mandatory as per the MCP specification. This template includes JWT-based authentication middleware (src/mcp-server/transports/authentication/authMiddleware.ts
). You MUST set a strong, unique MCP_AUTH_SECRET_KEY
in your production environment for this security mechanism to function correctly. Failure to do so will result in bypassed authentication checks in development and fatal errors in production.
Client Configuration (src/mcp-client/client-config/mcp-config.json
)
Configure the connections for the built-in MCP client using src/mcp-client/client-config/mcp-config.json
. If this file is missing, it falls back to src/mcp-client/client-config/mcp-config.json.example
.
This file defines external MCP servers the client can connect to. The client implementation adheres to the MCP 2025-03-26 specification.
Example mcp-config.json
(see src/mcp-client/client-config/mcp-config.json.example
for the full version):
{
"mcpServers": {
"my-stdio-server": {
"command": "node", // Command or executable
"args": ["/path/to/my-server/index.js"], // Arguments for stdio
"env": { "LOG_LEVEL": "debug" }, // Optional environment variables
"transportType": "stdio" // Explicitly stdio (or omit for default)
},
"my-http-server": {
"command": "http://localhost:8080", // Base URL for HTTP
"args": [], // Not used for HTTP
"env": {}, // Not used for HTTP
"transportType": "http" // Explicitly http
}
// ... add other servers
}
}
command
: Executable path (stdio
) or Base URL (http
).args
: Array of arguments (required forstdio
).env
: Optional environment variables to set for the server process (stdio
).transportType
:stdio
(default) orhttp
.
See src/mcp-client/client-config/configLoader.ts
for the Zod validation schema and src/mcp-client/client-config/mcp-config.json.example
for a complete example.
🏗️ Project Structure
The src/
directory is organized for clarity:
config/
: Loads environment variables and package info.mcp-client/
: Logic for the client connecting to external MCP servers (updated to MCP 2025-03-26 spec).client-config/
: Handles loading and validation ofmcp-config.json
.configLoader.ts
: Loads and validates server configurations.mcp-config.json.example
: Example configuration file.
core/
: Core client logic including connection management and caching.clientManager.ts
: Manages client instances and their lifecycle.clientConnectionLogic.ts
: Handles the details of connecting and initializing with servers.clientCache.ts
: Caches active client connections.
transports/
: Manages different communication transports (Stdio, HTTP).transportFactory.ts
: Creates appropriate transport instances.stdioClientTransport.ts
: Implements Stdio transport.httpClientTransport.ts
: Implements HTTP transport.
index.ts
: Barrel file exporting key client functionalities.
mcp-server/
: Logic for the MCP server provided by this template.server.ts
: Initializes the server, registers tools/resources.resources/
: Example resource implementations (e.g.,EchoResource
).tools/
: Example tool implementations (e.g.,EchoTool
, andCatFactFetcher
demonstrating async/Promise API calls).transports/
: Handlesstdio
andhttp
communication for the server.
services/
: Contains service integrations.duck-db/
: Service for interacting with DuckDB, an in-process analytical data management system.duckDBConnectionManager.ts
: Manages DuckDB instance and connection lifecycle.duckDBQueryExecutor.ts
: Executes SQL queries and manages transactions.duckDBService.ts
: Main service class for DuckDB interaction.types.ts
: TypeScript types and interfaces for the DuckDB service.
llm-providers/
: API Providers for Large Language Models.openRouter/
: OpenRouter provider implementation.llmFactory.ts
: Factory for creating LLM provider clients.index.ts
: Barrel file for all LLM providers.
index.ts
: Barrel file for services.
storage/
: Example usage of services, e.g.,duckdbExample.ts
.types-global/
: Shared TypeScript definitions (Errors, MCP types).utils/
: Reusable utilities (logging, errors, security, parsing, etc.). Exported viaindex.ts
.
Explore the structure yourself:
See the current file tree in docs/tree.md or generate it dynamically:
npm run tree
(This uses scripts/tree.ts
to generate a current file tree.)
🧩 Adding Your Own Tools & Resources
This template is designed for extension! Follow the high-level SDK patterns:
- Create Directories: Add new directories under
src/mcp-server/tools/yourToolName/
orsrc/mcp-server/resources/yourResourceName/
. - Implement Logic (
logic.ts
): Define Zod schemas for inputs/outputs and write your core processing function. - Register (
registration.ts
):- Tools: Use
server.tool(name, description, zodSchemaShape, handler)
(SDK v1.10.2+). This handles schema generation, validation, and routing. Remember to add relevant annotations (readOnlyHint
,destructiveHint
, etc.) as untrusted hints. - Resources: Use
server.resource(regName, template, metadata, handler)
. - Wrap logic in
ErrorHandler.tryCatch
for robust error handling.
- Tools: Use
- Export & Import: Export the registration function from your new directory's
index.ts
and call it withincreateMcpServerInstance
insrc/mcp-server/server.ts
.
Refer to the included EchoTool
and EchoResource
examples and the .clinerules cheatsheet for detailed patterns.
For an example of a tool that performs asynchronous operations, such as making an external API call, see the get_random_cat_fact
tool located in src/mcp-server/tools/catFactFetcher/
. This tool demonstrates how to use async/await
within your tool's logic and handler, manage Promises, and integrate external data sources.
🌍 Explore More MCP Resources
Looking for more examples, guides, and pre-built MCP servers? Check out the companion repository:
➡️ cyanheads/model-context-protocol-resources
This collection includes servers for Filesystem, Obsidian, Git, GitHub, Perplexity, Atlas, Ntfy, and more, along with in-depth guides based on my real-world MCP development.
📜 License
This project is licensed under the Apache License 2.0. See the LICENSE file for details.
Detailed Features Table
Category | Feature | Description | Location(s) |
---|---|---|---|
Core Components | MCP Server | Core server logic, tool/resource registration, transport handling. Includes Echo Tool & Resource examples. | src/mcp-server/ |
MCP Client | Logic for connecting to external MCP servers (updated to MCP 2025-03-26 spec). Refactored for modularity. | src/mcp-client/ (see subdirs: core/ , client-config/ , transports/ ) |
|
Configuration | Environment-aware settings with Zod validation. | src/config/ , src/mcp-client/client-config/configLoader.ts |
|
Streamable HTTP Transport | Express-based server implementing the MCP Streamable HTTP transport (utilizing Server-Sent Events for server-to-client streaming), with session management, CORS, and port retries. | src/mcp-server/transports/httpTransport.ts |
|
Stdio Transport | Handles MCP communication over standard input/output. | src/mcp-server/transports/stdioTransport.ts |
|
Utilities (Core) | Logger | Structured, context-aware logging (files with rotation & MCP notifications). | src/utils/internal/logger.ts |
ErrorHandler | Centralized error processing, classification, and logging. | src/utils/internal/errorHandler.ts |
|
RequestContext | Request/operation tracking and correlation. | src/utils/internal/requestContext.ts |
|
Utilities (Metrics) | TokenCounter | Estimates token counts using tiktoken . |
src/utils/metrics/tokenCounter.ts |
Utilities (Parsing) | DateParser | Parses natural language date strings using chrono-node . |
src/utils/parsing/dateParser.ts |
JsonParser | Parses potentially partial JSON, handles <think> blocks. |
src/utils/parsing/jsonParser.ts |
|
Utilities (Security) | IdGenerator | Generates unique IDs (prefixed or UUIDs). | src/utils/security/idGenerator.ts |
RateLimiter | Request throttling based on keys. | src/utils/security/rateLimiter.ts |
|
Sanitization | Input validation/cleaning (HTML, paths, URLs, numbers, JSON) & log redaction (validator , sanitize-html ). |
src/utils/security/sanitization.ts |
|
Services | DuckDB Integration | Reusable module for in-process analytical data management using DuckDB. A storage layer that runs on the same level as the application. Includes connection management, query execution, and example usage. Integrated with our utils (logger, etc.) | src/services/duck-db/ , src/storage/duckdbExample.ts |
OpenRouter LLM Integration | Reusable module for interacting with various LLMs via the OpenRouter API (OpenAI SDK compatible). Includes a factory for client instantiation. Integrated with our utils (logger, etc.) | src/services/llm-providers/openRouter/ , src/services/llm-providers/llmFactory.ts |
|
Type Safety | Global Types | Shared TypeScript definitions for consistent interfaces (Errors, MCP types). | src/types-global/ |
Zod Schemas | Used for robust validation of configuration files and tool/resource inputs. | Throughout (config , mcp-client , tools, etc.) |
|
Error Handling | Pattern-Based Classification | Automatically categorize errors based on message patterns. | src/utils/internal/errorHandler.ts |
Consistent Formatting | Standardized error responses with additional context. | src/utils/internal/errorHandler.ts |
|
Safe Try/Catch Patterns | Centralized error processing helpers (ErrorHandler.tryCatch ). |
src/utils/internal/errorHandler.ts |
|
Client/Transport Error Handling | Specific handlers for MCP client and transport error handling. | src/mcp-client/core/ , src/mcp-client/transports/ |
|
Security | Input Validation | Using validator and zod for various data type checks. |
src/utils/security/sanitization.ts , etc. |
Input Sanitization | Using sanitize-html to prevent injection attacks. |
src/utils/security/sanitization.ts |
|
Sensitive Data Redaction | Automatic redaction in logs. | src/utils/security/sanitization.ts |
|
Configuration Fallback | Safely falls back to mcp-config.json.example if primary client config is missing. |
src/mcp-client/client-config/configLoader.ts |
|
Scripts | Clean Script | Removes dist and logs directories (or custom targets). |
scripts/clean.ts |
Make Executable Script | Sets executable permissions (chmod +x ) on specified files (Unix-like only). |
scripts/make-executable.ts |
|
Tree Script | Generates a directory structure tree, respecting .gitignore . |
scripts/tree.ts |
|
Fetch OpenAPI Spec Script | Fetches an OpenAPI spec (YAML/JSON) from a URL with fallbacks, saves locally. | scripts/fetch-openapi-spec.ts |