A complete boilerplate for creating Model Context Protocol (MCP) servers and clients in TypeScript.
- Node.js 18+ (recommended: latest LTS)
- npm or yarn package manager
-
Clone or download this boilerplate
git clone https://github.com/RishabhKodes/tsMCP.git cd tsMCP -
Install dependencies
npm install
-
Build the project
npm run build
-
Run the server
npm run start:server
-
Test with the client (in a new terminal)
npm run start:client
src/
├── server.ts # MCP server implementation
├── client.ts # Example MCP client
└── types/ # Custom type definitions (if needed)
build/ # Compiled JavaScript output
package.json # Dependencies and scripts
tsconfig.json # TypeScript configuration
README.md # This file
npm run build- Compile TypeScript to JavaScriptnpm run start:server- Start the MCP servernpm run start:client- Run the example clientnpm run dev:server- Build and run server in one commandnpm run dev:client- Build and run client in one commandnpm run clean- Remove build directory
The example server includes:
- calculate - Perform basic arithmetic operations (add, subtract, multiply, divide)
- echo - Echo back the provided text
- get_memory - Retrieve values from the in-memory store
- set_memory - Store values in the in-memory store
- memory://config - Configuration settings
- memory://data - Sample application data
The server is built using the official MCP SDK and includes:
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = new Server({
name: 'tsMCP',
version: '1.0.0',
}, {
capabilities: {
resources: {},
tools: {},
},
});To add a new tool, implement these handler functions:
- List the tool in
ListToolsRequestSchemahandler:
{
name: 'my_new_tool',
description: 'Description of what the tool does',
inputSchema: {
type: 'object',
properties: {
input: { type: 'string', description: 'Input parameter' }
},
required: ['input']
}
}- Handle tool execution in
CallToolRequestSchemahandler:
case 'my_new_tool': {
const input = args?.input;
// Your tool logic here
return {
content: [{
type: 'text',
text: `Result: ${result}`
}]
};
}- List the resource in
ListResourcesRequestSchemahandler:
{
uri: 'custom://my-resource',
mimeType: 'application/json',
name: 'My Resource',
description: 'Description of the resource'
}- Handle resource reading in
ReadResourceRequestSchemahandler:
if (uri === 'custom://my-resource') {
return {
contents: [{
uri,
mimeType: 'application/json',
text: JSON.stringify(myData, null, 2)
}]
};
}The example client demonstrates how to:
- Connect to an MCP server
- List available tools and resources
- Call tools with parameters
- Read resources
- Handle errors and cleanup
To integrate your MCP server with Claude Desktop, add this configuration to your claude_desktop_config.json:
{
"mcpServers": {
"tsMCP": {
"command": "node",
"args": ["/path/to/your/project/build/server.js"]
}
}
}To integrate your MCP server with Cursor, add this configuration to your MCP settings:
{
"mcpServers": {
"tsMCP": {
"command": "node",
"args": ["/path/to/your/project/build/server.js"]
}
}
}The server communicates over stdio, making it compatible with any MCP client that supports the stdio transport.
The boilerplate includes comprehensive error handling:
- Input validation using Zod schemas
- Proper MCP error codes and messages
- Graceful cleanup on shutdown
- Type-safe parameter handling
Create a .env file for environment-specific configuration:
# Server configuration
MCP_SERVER_NAME=my-custom-server
MCP_SERVER_VERSION=1.0.0
# Application-specific settings
LOG_LEVEL=infoYou can implement custom transports beyond stdio:
import { WebSocketServerTransport } from '@modelcontextprotocol/sdk/server/websocket.js';
const transport = new WebSocketServerTransport({
port: 8080
});Extend the server with custom middleware:
server.setRequestHandler(MyCustomRequestSchema, async (request) => {
// Custom handling logic
});