A beginner-friendly foundation for building Model Context Protocol (MCP) servers (and in the future also clients) with TypeScript. This template provides a comprehensive starting point with production-ready utilities, well-structured code, and working examples for building an MCP server.
Copy this repo to kickstart your own MCP server and set your vibe code session up for success!
.clinerules: This repository includes a .clinerules file that serves as a developer cheat sheet for your LLM coding agent with quick reference for the codebase patterns, file locations, and code snippets. When copying this template for your own project, be sure to update the cheat sheet to reflect your modifications and additions.
Model Context Protocol (MCP) is a framework that enables AI systems to interact with external tools and resources. It allows language models to:
This template gives you a head start in building MCP servers that can be used by AI systems to extend their capabilities.
The template follows a modular architecture designed for clarity and extensibility:
flowchart TB
subgraph API["API Layer"]
direction LR
MCP["MCP Protocol"]
Val["Validation"]
San["Sanitization"]
MCP --> Val --> San
end
subgraph Core["Core Components"]
direction LR
Config["Configuration"]
Logger["Logging System"]
Error["Error Handling"]
Server["MCP Server"]
Config --> Server
Logger --> Server
Error --> Server
end
subgraph Implementation["Implementation Layer"]
direction LR
Tool["Tools"]
Resource["Resources"]
Util["Utilities"]
Tool --> Server
Resource --> Server
Util --> Tool
Util --> Resource
end
San --> Config
San --> Server
classDef layer fill:#2d3748,stroke:#4299e1,stroke-width:3px,rx:5,color:#fff
classDef component fill:#1a202c,stroke:#a0aec0,stroke-width:2px,rx:3,color:#fff
class API,Core,Implementation layer
class MCP,Val,San,Config,Logger,Error,Server,Tool,Resource,Util component
Core Components:
validator
and sanitize-html
.validator
and sanitize-html
.validator
for various data type checks.sanitize-html
to prevent injection attacks.Clone this 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
Add to your MCP client settings:
{
"mcpServers": {
"atlas": {
"command": "node",
"args": ["/path/to/mcp-ts-template/dist/index.js"],
"env": {}
}
}
}
The configuration system provides a flexible way to manage settings:
The codebase follows a modular structure within the src/
directory, including configurations (config/
), MCP server logic (mcp-server/
with tools and resources), global types (types-global/
), and common utilities (utils/
).
For a detailed, up-to-date view of the project structure, run the following command:
npm run tree
This command executes the scripts/tree.ts
script, which generates a tree representation of the current project layout.
Tool | Description |
---|---|
Echo Tool | Formats and echoes messages with various options. Demonstrates input validation, error handling, and proper response formatting. |
See the Echo Tool implementation for detailed usage examples and implementation details.
Resource | Description |
---|---|
Echo Resource | Returns echo messages based on input parameters. Demonstrates resource registration, URI handling, and consistent response formatting. |
See the Echo Resource implementation for detailed usage examples and implementation details.
src/mcp-server/tools/
(e.g., src/mcp-server/tools/myNewTool/
).myNewToolLogic.ts
file:
validator
and manual checks).registration.ts
file:
McpServer
, ErrorHandler
, and logger
.async
function (e.g., registerMyNewTool
) that accepts the McpServer
instance.ErrorHandler.tryCatch
to wrap the server.tool()
call.server.tool()
with:
MyToolInputSchema.shape
).async
handler function that:
params
.ErrorHandler.tryCatch
to wrap the call to your core logic function.{ content: [{ type: "text", text: JSON.stringify(result) }] }
).index.ts
file within your tool's directory, export the registration function (e.g., export { registerMyNewTool } from './registration.js';
).src/mcp-server/server.ts
, import your registration function and call it, passing the server
instance (e.g., await registerMyNewTool(server);
).// In src/mcp-server/server.ts:
// import { registerMyNewTool } from './tools/myNewTool/index.js';
// ...
// await registerMyNewTool(server);
src/mcp-server/resources/
(e.g., src/mcp-server/resources/myNewResource/
).myNewResourceLogic.ts
file:
validator
and manual checks).uri
(URL object) and validated params
and returns the resource data.registration.ts
file:
McpServer
, ResourceTemplate
, ErrorHandler
, and logger
.async
function (e.g., registerMyNewResource
) that accepts the McpServer
instance.ErrorHandler.tryCatch
to wrap the registration process.ResourceTemplate
with the URI pattern and any list
or complete
operations.server.resource()
with:
ResourceTemplate
instance.async
handler function that:
uri
(URL) and validated params
.ErrorHandler.tryCatch
to wrap the call to your core logic function.{ contents: [{ uri: uri.href, text: JSON.stringify(result), mimeType: "application/json" }] }
).index.ts
file within your resource's directory, export the registration function (e.g., export { registerMyNewResource } from './registration.js';
).src/mcp-server/server.ts
, import your registration function and call it, passing the server
instance (e.g., await registerMyNewResource(server);
).Example registration.ts
structure
// In src/mcp-server/server.ts:
// import { registerMyNewResource } from './resources/myNewResource/index.js';
// ...
// await registerMyNewResource(server);
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
{
"mcpServers": {
"atlas": {
"env": {},
"args": [
"/path/to/mcp-ts-template/dist/index.js"
],
"command": "node"
}
}
}
Seamless access to top MCP servers powering the future of AI integration.