Template for building custom MCP (Model Context Protocol) servers with TypeScript
- Add TypeScript strict args validation - Update CHANGELOG with latest changes - Fix browser-mcp DOM types and deprecated APIs - Ensure all MCPs compile successfully 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> |
||
|---|---|---|
| src | ||
| .gitignore | ||
| .mcp.json.example | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| QUICKSTART.md | ||
| README.md | ||
| tsconfig.json | ||
MCP Server Template
A template for building custom MCP (Model Context Protocol) servers with TypeScript. This template provides a solid foundation for creating your own MCP servers with tools, resources, and prompts.
🚀 Features
- TypeScript: Fully typed with TypeScript 5.7+
- Example Tools: Calculator and example tool implementations
- Resources: Sample resource provider
- Prompts: Template for custom prompts
- MCP SDK: Built on official @modelcontextprotocol/sdk
- Ready to Use: Complete setup with build scripts
📋 Prerequisites
- Node.js 18.0.0 or higher
- npm or yarn
🛠️ Installation
# Clone the repository
git clone https://git.customable.host/customable-mcp/mcp-server-template.git
cd mcp-server-template
# Install dependencies
npm install
# Build the project
npm run build
🎯 Usage
Running the Server
# Start the server
npm start
# Or run in development mode with auto-rebuild
npm run dev
Testing with Claude Code
Add this server to your Claude Code configuration (.mcp.json):
{
"mcpServers": {
"custom-server": {
"command": "node",
"args": ["/path/to/mcp-server-template/dist/index.js"],
"env": {}
}
}
}
📚 Project Structure
mcp-server-template/
├── src/
│ ├── index.ts # Main server entry point
│ ├── tools/ # Tool implementations
│ │ ├── example.ts # Example tool
│ │ └── calculator.ts # Calculator tool
│ ├── resources/ # Resource providers
│ │ └── example.ts # Example resource
│ └── prompts/ # Prompt templates
│ └── example.ts # Example prompt
├── dist/ # Compiled JavaScript (generated)
├── package.json
├── tsconfig.json
└── README.md
🔧 Available Tools
1. Example Tool
A simple tool that processes text messages.
Parameters:
message(string, required): The message to processuppercase(boolean, optional): Convert to uppercase
Example:
{
"message": "Hello World",
"uppercase": true
}
2. Calculator
Perform basic arithmetic operations.
Parameters:
operation(string, required): One of: add, subtract, multiply, dividea(number, required): First numberb(number, required): Second number
Example:
{
"operation": "add",
"a": 10,
"b": 5
}
📦 Available Resources
Example Data
URI: example://data
Provides sample user data in JSON format.
📝 Available Prompts
Example Prompt
A customizable prompt template for writing about a topic.
Arguments:
topic(required): The topic to write aboutstyle(optional): Writing style (formal, casual, technical)
🔨 Development
Building
npm run build
Type Checking
npm run typecheck
Cleaning Build Output
npm run clean
➕ Adding New Features
Adding a New Tool
- Create a new file in
src/tools/, e.g.,myTool.ts:
export async function myTool(args: any) {
const { param1, param2 } = args;
// Your logic here
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: true,
result: 'your result',
}, null, 2),
},
],
};
}
- Import and register in
src/index.ts:
import { myTool } from './tools/myTool.js';
// In ListToolsRequestSchema handler:
{
name: 'my_tool',
description: 'Description of my tool',
inputSchema: {
type: 'object',
properties: {
param1: { type: 'string', description: 'Parameter 1' },
param2: { type: 'number', description: 'Parameter 2' },
},
required: ['param1'],
},
}
// In CallToolRequestSchema handler:
case 'my_tool':
return myTool(args);
Adding a New Resource
- Create a new file in
src/resources/, e.g.,myResource.ts:
export async function myResource() {
return {
contents: [
{
uri: 'custom://my-resource',
mimeType: 'application/json',
text: JSON.stringify({ data: 'your data' }, null, 2),
},
],
};
}
- Import and register in
src/index.ts:
import { myResource } from './resources/myResource.js';
// In ListResourcesRequestSchema handler:
{
uri: 'custom://my-resource',
name: 'My Resource',
description: 'Description of my resource',
mimeType: 'application/json',
}
// In ReadResourceRequestSchema handler:
case 'custom://my-resource':
return myResource();
Adding a New Prompt
- Create a new file in
src/prompts/, e.g.,myPrompt.ts:
export async function myPrompt(args: any) {
const { argument1 } = args;
return {
messages: [
{
role: 'user',
content: {
type: 'text',
text: `Your prompt text with ${argument1}`,
},
},
],
};
}
- Import and register in
src/index.ts.
🤝 Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
📄 License
MIT License - See LICENSE file for details
🔗 Resources
💡 Examples
Check out our other MCP servers for inspiration:
- Browser Automation MCP - Universal browser automation with Playwright