mcp-server-template

chris-quintin/mcp-server-template

3.2

If you are the rightful owner of mcp-server-template and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

This document provides a structured overview of a Model Context Protocol (MCP) server template designed for building robust MCP servers using TypeScript and Node.js.

Tools
1
Resources
0
Prompts
0

MCP Server Template

A comprehensive template for building Model Context Protocol (MCP) servers using TypeScript and Node.js.

Features

  • 🛠️ Complete MCP Implementation: Tools, Resources, and Prompts
  • 🔄 Dual Transport Support: STDIO (local) + HTTP (web/cloud) modes
  • 📦 TypeScript: Full type safety and modern JavaScript features
  • 🔧 Example Tools: Sample implementations to get you started
  • 📚 Resource Management: File-like data exposure
  • 💬 Prompt Templates: Reusable AI interaction templates
  • 🚀 Development Ready: Hot reload, linting, and build scripts
  • ☁️ Cloud Ready: Railway, Docker, and multi-platform deployment
  • 📖 Well Documented: Comprehensive examples and comments

Prerequisites

  • Node.js v18.0.0 or higher
  • npm or yarn package manager

Quick Start

  1. Clone and Setup

    git clone <your-repo-url> my-mcp-server
    cd my-mcp-server
    npm install
    
  2. Configure Environment

    cp .env.example .env
    # Edit .env with your configuration
    
  3. Development Mode

    npm run dev
    
  4. Build for Production

    npm run build
    npm start        # STDIO mode
    npm start:http   # HTTP mode
    

🔄 Transport Modes

This template supports two transport modes with identical MCP functionality:

📱 STDIO Mode (Local MCP Clients)

Perfect for local MCP clients like Claude Desktop, Cursor, or other desktop applications.

# Development
npm run dev

# Production
npm run build
npm start

Use STDIO when:

  • ✅ Integrating with Claude Desktop
  • ✅ Running locally for development
  • ✅ Building desktop MCP integrations
  • ✅ Working with process-based MCP clients

Client Configuration Example (Claude Desktop):

{
  "mcp-server-template": {
    "command": "node",
    "args": ["/path/to/your/dist/index.js"]
  }
}

🌐 HTTP Mode (Web/Cloud Deployment)

Ideal for web applications, cloud deployment, and remote MCP access.

# Development  
npm run dev:http

# Production
npm run build
npm start:http

Use HTTP when:

  • ✅ Deploying to Railway, Render, or other cloud platforms
  • ✅ Building web-based MCP integrations
  • ✅ Need HTTP endpoints for health checks
  • ✅ Require remote access to your MCP server

Endpoints:

  • Health Check: GET /health
  • SSE Connection: GET /sse
  • MCP Messages: POST /message

📊 Mode Comparison

FeatureSTDIO ModeHTTP Mode
Transportstdin/stdoutSSE over HTTP
Use CaseLocal clientsWeb/Cloud deployment
Health Checks/health endpoint
Remote Access✅ HTTPS support
Cloud Deploy✅ Railway, Render, etc.
Desktop Clients✅ Claude Desktop
Same MCP Features

Both modes implement the exact same MCP functionality - tools, resources, and prompts are identical. Choose based on your deployment needs!

Project Structure

mcp-server-template/
├── src/
│   └── index.ts          # Main server implementation
├── dist/                 # Compiled JavaScript (generated)
├── package.json          # Dependencies and scripts
├── tsconfig.json         # TypeScript configuration
├── .eslintrc.json        # ESLint configuration
├── .env.example          # Environment variables template
├── .gitignore           # Git ignore rules
└── README.md            # This file

Core Concepts

Tools

Tools are functions that can be called by MCP clients. They accept structured input and return structured output.

// Example tool registration
{
  name: 'search_data',
  description: 'Search for data using a query string',
  inputSchema: {
    type: 'object',
    properties: {
      query: { type: 'string', description: 'The search query' }
    },
    required: ['query']
  }
}

Resources

Resources expose data in a file-like manner. They have URIs and can be read by clients.

// Example resource
{
  uri: 'config://server',
  mimeType: 'application/json',
  name: 'Server Configuration',
  description: 'Current server configuration and settings'
}

Prompts

Prompts are reusable templates for AI interactions with parameterization support.

// Example prompt
{
  name: 'analyze_data',
  description: 'Analyze data and provide insights',
  arguments: [
    { name: 'data', description: 'The data to analyze', required: true }
  ]
}

Customization

Adding New Tools

  1. Define the tool schema in the ListToolsRequestSchema handler:

    tools.push({
      name: 'my_tool',
      description: 'Description of what the tool does',
      inputSchema: {
        type: 'object',
        properties: {
          param1: { type: 'string', description: 'First parameter' }
        },
        required: ['param1']
      }
    });
    
  2. Implement the tool logic in the CallToolRequestSchema handler:

    case 'my_tool': {
      const { param1 } = args as { param1: string };
      const result = await myService.doSomething(param1);
      return {
        content: [{ type: 'text', text: result }]
      };
    }
    

Adding New Resources

  1. Register the resource in the ListResourcesRequestSchema handler
  2. Implement the read logic in the ReadResourceRequestSchema handler

Adding New Prompts

  1. Register the prompt in the ListPromptsRequestSchema handler
  2. Implement the prompt logic in the GetPromptRequestSchema handler

Development Scripts

  • npm run dev - Start development server with hot reload
  • npm run build - Build for production
  • npm start - Start production server
  • npm run watch - Watch mode for development
  • npm run lint - Run ESLint
  • npm run lint:fix - Fix ESLint issues automatically
  • npm run clean - Clean build directory

Environment Variables

Copy .env.example to .env and configure:

  • NODE_ENV - Environment (development/production)
  • API_KEY - Your API key (if using external services)
  • DATABASE_URL - Database connection string (if needed)
  • LOG_LEVEL - Logging level (debug/info/warn/error)

Error Handling

The template includes comprehensive error handling:

  • Tool Errors: Caught and returned as error responses
  • Resource Errors: Proper error messages for missing resources
  • Server Errors: Logged to stderr (never stdout)
  • Graceful Shutdown: Handles SIGINT for clean shutdown

Best Practices

  1. Never write to stdout - Use stderr for logging
  2. Validate inputs - Use Zod schemas for input validation
  3. Handle errors gracefully - Return meaningful error messages
  4. Use TypeScript - Leverage type safety throughout
  5. Document your tools - Provide clear descriptions and examples
  6. Test thoroughly - Test all tools, resources, and prompts

Deployment

Local Development

STDIO Mode (for local MCP clients):

npm run dev

HTTP Mode (for web/remote access):

npm run dev:http

Production Build

npm run build
npm start        # STDIO mode
npm start:http   # HTTP mode

Railway Deployment

Railway is a great platform for deploying MCP servers with automatic HTTPS and scaling.

1. One-Click Deploy

Deploy on Railway

2. Manual Deployment
  1. Install Railway CLI:

    npm install -g @railway/cli
    
  2. Login and Initialize:

    railway login
    railway init
    
  3. Configure Environment Variables:

    railway variables set NODE_ENV=production
    railway variables set API_KEY=your-api-key
    railway variables set PORT=3000
    
  4. Deploy:

    railway up
    
3. GitHub Integration
  1. Push your code to GitHub
  2. Visit Railway
  3. Click "New Project" → "Deploy from GitHub repo"
  4. Select your repository
  5. Railway will automatically detect the configuration and deploy

Railway Configuration Files:

  • railway.json - Railway deployment settings
  • nixpacks.toml - Build configuration
  • Environment variables set via Railway dashboard

Railway Features:

  • ✅ Automatic HTTPS with custom domains
  • ✅ Zero-downtime deployments
  • ✅ Auto-scaling based on traffic
  • ✅ Built-in monitoring and logs
  • ✅ Environment variable management
  • ✅ GitHub/GitLab integration
4. Accessing Your Deployed Server

After deployment, Railway provides:

  • Public URL: https://your-app.railway.app
  • Health check: https://your-app.railway.app/health
  • MCP endpoint: https://your-app.railway.app/message

Docker Deployment

Create a Dockerfile:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
EXPOSE 3000
CMD ["npm", "run", "start:http"]

Build and run:

docker build -t mcp-server .
docker run -p 3000:3000 mcp-server

Other Cloud Platforms

Render
  1. Connect GitHub repository
  2. Set build command: npm run build
  3. Set start command: npm run start:http
  4. Add environment variables
Fly.io
fly launch
fly deploy
Google Cloud Run
gcloud run deploy --source .
Vercel (Serverless)

Add vercel.json:

{
  "builds": [{ "src": "dist/http-server.js", "use": "@vercel/node" }],
  "routes": [{ "src": "/(.*)", "dest": "/dist/http-server.js" }]
}

Troubleshooting

Common Issues

  1. Module not found errors

    • Ensure all dependencies are installed: npm install
    • Check TypeScript compilation: npm run build
  2. Server not responding

    • Check that the server is running on stdio transport
    • Verify no stdout pollution (use stderr for logging)
  3. Type errors

    • Run TypeScript compiler: npx tsc --noEmit
    • Check tsconfig.json configuration

Debug Mode

Enable debug logging by setting environment variable:

LOG_LEVEL=debug npm run dev

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Make your changes
  4. Run tests and linting: npm run lint
  5. Build the project: npm run build
  6. Commit your changes: git commit -am 'Add feature'
  7. Push to the branch: git push origin feature-name
  8. Create a Pull Request

License

MIT License - see LICENSE file for details.

Resources

Support

If you encounter issues or need help:

  1. Check the MCP Documentation
  2. Review the example implementations in src/index.ts
  3. Open an issue in this repository
  4. Join the MCP community discussions