A Model Context Protocol (MCP) server template for Node.js with TypeScript support.
This is a comprehensive MCP server template that provides a robust foundation for building Model Context Protocol servers. It supports multiple transport modes: stdio, SSE (Server-Sent Events), and HTTP streams, making it suitable for various integration scenarios. The template includes authentication, logging, and a sample weather tool to demonstrate the MCP tool implementation pattern.
- Node.js 18+
- npm or pnpm
- TypeScript knowledge for customization
# Clone the repository
git clone https://github.com/pshaddel/mcp-template.git
cd mcp-template
# Install dependencies
npm install
# or
pnpm install
# Build the project
npm run buildCreate a .env file based on the sample provided:
cp .sample.env .envConfigure the following environment variables:
| Variable | Description | Default | Required |
|---|---|---|---|
MODE |
Transport mode: stdio, sse, or http-streams |
stdio |
Yes |
API_KEYS |
Comma-separated list of allowed API keys (SSE/HTTP streams mode only) | - | No (required for SSE/HTTP streams) |
APP_PORT |
Port for SSE/HTTP streams server | 3000 |
No |
For stdio mode (Claude Desktop):
MODE=stdioFor SSE mode (HTTP server):
MODE=sse
API_KEYS=your_api_key1,your_api_key2
APP_PORT=3000For HTTP streams mode (HTTP server with streaming):
MODE=http-streams
API_KEYS=your_api_key1,your_api_key2
APP_PORT=3000npm run dev
# or
npm run start:dev
# or with pnpm
pnpm devnpm start
# or with pnpm
pnpm startThe MCP Inspector is a powerful debugging tool that provides a web interface to test and interact with your MCP server tools during development.
npx @modelcontextprotocol/inspectorThis will start the inspector and open it in your browser (typically at http://localhost:5173).
The inspector supports different transport modes depending on how your MCP server is running:
When running your server in SSE mode:
- URL:
http://localhost:3000/sse(or your configured port) - Headers: Add the following header for authentication:
- Header Name:
x-api-key - Header Value: Your API key from the
.envfile
- Header Name:
When running your server in HTTP streams mode:
- URL:
http://localhost:3000/mcp(or your configured port) - Headers: Add the following header for authentication:
- Header Name:
x-api-key - Header Value: Your API key from the
.envfile
- Header Name:
- Start your MCP server first in either SSE or HTTP streams mode
- The inspector will automatically detect available tools and display their schemas
- You can test tools interactively and see real-time responses
- Use the inspector to validate your tool implementations before integrating with other clients
- Build the project:
npm run build- Add the following configuration to your Claude Desktop config file:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"mcp-template": {
"command": "node",
"args": [
"--env-file=/path/to/your/project/.env",
"/path/to/your/project/build/main.js"
]
}
}
}3.Then restart Claude Desktop. and you should see the MCP server listed in the settings.
-
Run the application in
sseorhttp-streamsmode. If running locally, usenpm run devornpm start.- For SSE mode: server will be available at
http://localhost:3000/sse - For HTTP streams mode: server will be available at
http://localhost:3000/mcp
If you are running n8n in a docker container, you cannot use
http://localhost:3000as the n8n container cannot access the host's localhost. Instead, you can usehttp://host.docker.internal:3000to access the host's services from within the n8n container, or you can run the n8n container with the--network="host"option to share the host's network stack. - For SSE mode: server will be available at
-
Run the n8n instance, if locally, use the following command:
docker run -it --rm \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8n-
Open n8n in your browser at
http://localhost:5678. -
Create a new workflow and add an AI Agent node.
-
In Tools section, add a MCP Client Tool node.
-
Configure the MCP Client Tool node with the following settings:
- Server URL:
- For SSE mode:
http://host.docker.internal:3000/sse - For HTTP streams mode:
http://host.docker.internal:3000/mcp
- For SSE mode:
- API Key: Add a custom header
x-api-keywith your API key from the.envfile.
- Server URL:
The Tools Should be available now.
When running in HTTP streams mode, the server provides streamable HTTP endpoints for MCP communication with session management:
Base URL: http://localhost:3000 (or your configured port)
Endpoints:
POST /mcp- Initialize session or send MCP messagesGET /mcp- Retrieve server-to-client notifications (requires session ID)DELETE /mcp- Terminate MCP sessionGET /health- Health check endpoint
Session Management:
HTTP streams mode uses session-based communication. Include the mcp-session-id header in requests after initialization:
# Initialize a new session
curl -X POST \
-H "x-api-key: your_api_key" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test-client","version":"1.0.0"}}}' \
http://localhost:3000/mcp
# Use the returned session ID in subsequent requests
curl -X POST \
-H "x-api-key: your_api_key" \
-H "mcp-session-id: your-session-id" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
http://localhost:3000/mcpAuthentication:
Set the x-api-key header with one of your configured API keys for all requests.
- Enable MCP support in VS Code in settings.
- Use it via VS Code by adding the following to your
.vscode/mcp.jsonfile:
{
"servers": {
"mcp-template": {
"type": "stdio",
"command": "node",
"args": [
"--env-file=/path/to/your/project/.env",
"/path/to/your/project/build/main.js"
]
}
},
"inputs": []
}- Start using it in VS Code by running the MCP commands in Copilot Chat(In Agent mode).
When running in SSE mode, the server provides HTTP endpoints for MCP communication:
Base URL: http://localhost:3000 (or your configured port)
Endpoints:
GET /sse- Establish SSE connectionPOST /messages- Send MCP messagesGET /health- Health check endpoint
Authentication:
Set the x-api-key header with one of your configured API keys:
curl -H "x-api-key: your_api_key" http://localhost:3000/sseFetches weather data from the Open Meteo API.
Input Parameters:
| Parameter | Type | Description | Example |
|---|---|---|---|
latitude |
string | Latitude of the location | "47.8095" |
longitude |
string | Longitude of the location | "13.0550" |
start_date |
string | Start date (YYYY-MM-DD) | "2025-07-25" |
end_date |
string | End date (YYYY-MM-DD) | "2025-07-25" |
timezone |
enum | Timezone | "Europe/London" |
Supported Timezones:
Europe/LondonAmerica/New_YorkAsia/Tokyo
Example Usage:
{
"latitude": "47.8095",
"longitude": "13.0550",
"start_date": "2025-07-25",
"end_date": "2025-07-25",
"timezone": "Europe/London"
}src/
βββ main.ts # Main server entry point
βββ tools/ # MCP tools directory
β βββ tool.interface.ts # Tool interface definition
β βββ weather.ts # Weather tool implementation
βββ tests/ # Test files
βββ weather.test.ts # Weather tool tests
- Create a new tool file in
src/tools/:
import { z } from 'zod';
import { Tool } from './tool.interface.js';
export const myTool: Tool = {
tool_name: 'my_tool',
description: 'Description of what your tool does',
inputSchema: {
// Define your input schema using zod validators
param1: z.string().describe('Parameter description'),
},
function: async (args) => {
// Implement your tool logic here
return {
content: [{
type: 'text',
text: 'Tool response'
}]
};
}
};- Register the tool in
src/main.ts:
import { myTool } from './tools/my-tool.js';
// Add this line after the existing tool registration
mcpServer.registerTool(myTool.tool_name, {
description: myTool.description,
inputSchema: myTool.inputSchema,
}, myTool.function);| Script | Description |
|---|---|
npm run build |
Compile TypeScript to JavaScript |
npm run dev |
Run in development mode with hot reload |
npm run start:dev |
Alternative development command |
npm start |
Run the built server |
npm run test:coverage |
Run tests with coverage report |
Build and run with Docker:
# Build the Docker image
docker build -t mcp-template .
# Run the container
docker run -p 3000:3000 --env-file .env mcp-templateRun tests to ensure everything works correctly:
npm test # Run tests
npm run test:coverage # Run tests with coverage
# or
pnpm test
pnpm run test:coverage"Transport not found" error in SSE/HTTP streams mode:
- Ensure the SSE connection is established before sending messages (SSE mode)
- Check that the sessionId is properly passed in requests (HTTP streams mode)
- Verify the correct endpoint is being used (
/ssefor SSE,/mcpfor HTTP streams)
Session management issues (HTTP streams mode):
- Ensure you initialize a session with the
initializemethod before other requests - Include the
mcp-session-idheader in all requests after initialization - Check that the session hasn't expired or been terminated
Permission errors:
- Verify the API key is correctly set in headers
- Check that the API key exists in your
API_KEYSenvironment variable
Build errors:
- Run
npm run buildto ensure TypeScript compilation succeeds - Check that all dependencies are installed
Enable detailed logging by setting the log level:
// In main.ts, modify the capabilities
capabilities: {
logging: {
level: 'debug', // Change from 'info' to 'debug'
format: 'json',
destination: 'stdout',
}
}Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Anthropic for the Model Context Protocol
- Open Meteo for the weather API used in the example tool

