DEV Community

Cover image for Build a Production-Ready MCP Server in TypeScript
Shola Jegede
Shola Jegede Subscriber

Posted on

Build a Production-Ready MCP Server in TypeScript

What is the Model Context Protocol (MCP)?

The Model Context Protocol (MCP) is a framework that allows AI assistants like Cursor or Claude to interact with external tools, APIs, and databases. Think of it as a bridge that lets your AI assistant actually do things in the real world: fetch data, update records, process payments, or manage authentication.

With MCP servers, you can:

  • Handle user authentication and sessions
  • Work with databases (queries, migrations, CRUD)
  • Manage billing flows (free tiers, upgrades, subscriptions)
  • Connect to external APIs (emails, third-party data, integrations)
  • Bundle multiple tools into a single AI-accessible server

Why Use the MCP Starter Kit?

Building an MCP server from scratch means setting up all of the above — authentication, database connections, billing, APIs, error handling, and deployment pipelines. That’s a lot of moving parts.

The MCP Starter Kit simplifies the process by giving you:

Instant Setup

  • One command bootstraps an MCP server
  • Preconfigured authentication with Kinde
  • Database setup via Neon PostgreSQL
  • Built-in billing system
  • Multiple ready-to-go templates (blog, ecommerce, CRM, todo)

Production-Ready Features

  • Secure auth flows
  • Database migrations & schema management
  • Error handling and logging
  • Rate limiting & security headers

  • Testing setup out of the box

Developer Experience

  • TypeScript support
  • Hot reloading for dev
  • Cursor AI integration
  • Deployment-ready config

What You'll Build

By the end of this tutorial, you'll create a complete MCP application with:

  • Authentication System → User login, registration, and session management
  • Database Integration → PostgreSQL with automatic schema setup
  • CRUD Operations → Create, read, update, and delete functionality
  • Billing System → Freemium model with upgrade flows
  • AI Integration → Seamless Cursor AI integration
  • Production Deployment → Ready-to-deploy application

Prerequisites

Before starting, ensure you have:

  • Node.js 18+ (download)
  • npm or yarn
  • Cursor IDE (download)
  • Git
  • Basic TypeScript knowledge (helpful but optional)

Setting Up Your Development Environment

Step 1: Install Node.js and npm

node --version
npm --version
Enter fullscreen mode Exit fullscreen mode

If missing, download and install from nodejs.org.

Step 2: Install Cursor IDE

  • Visit cursor.sh
  • Download and install Cursor
  • Sign up for a free account

Step 3: Create Development Accounts

You'll need accounts for:

Neon Database (Free Tier)

  • Visit neon.tech
  • Sign up for a free account
  • Create a new database
  • Copy your connection string

Kinde.com (Free Tier)

  • Visit kinde.com
  • Sign up for a free account
  • Create a new application
  • Note your client credentials

Creating Your First MCP Application

Step 1: Generate Your Application

npx mcp-starter-kit
Enter fullscreen mode Exit fullscreen mode

You'll see an interactive prompt:

🚀 MCP Starter Kit
Create MCP applications with authentication, database, and billing

📝 What would you like to name your application? my-awesome-app
📋 Choose your template:
  1. blog      - Blog management system (posts, comments)
  2. ecommerce - E-commerce system (products, orders)
  3. crm       - Customer relationship management (contacts, deals, tasks)
  4. todo      - Simple todo management system

🎯 Enter your choice (1-4): 1
🚀 Creating my-awesome-app with blog template...
✅ Application created successfully!
Enter fullscreen mode Exit fullscreen mode

Step 2: Install Dependencies

npm install
Enter fullscreen mode Exit fullscreen mode

Step3: Understand the Project Structure

Your generated project will have this structure:

my-awesome-app/
├── package.json              # Dependencies and scripts
├── tsconfig.json             # TypeScript configuration
├── .env.example              # Environment template
├── README.md                 # Project documentation
└── src/
    ├── app-config.ts         # Application configuration
    ├── universal-server.ts   # Main MCP server
    ├── setup-db.ts          # Database setup script
    ├── kinde-auth-server.ts  # Authentication server
    └── core/                 # Core MCP modules
        ├── auth/             # Authentication manager
        ├── database/         # Database manager
        ├── server/           # MCP server core
        └── tools/            # Tool factory
Enter fullscreen mode Exit fullscreen mode

A brief explanation of key files:

  • universal-server.ts → your main MCP server that handles all AI interactions
  • kinde-auth-server.ts → authentication server for user login/logout
  • setup-db.ts → database schema creation and migration script
  • app-config.ts → configuration for your specific application template
  • core/ → MCP modules

Configuring Authentication with Kinde

Step 1: Set Up Kinde Application

  1. Log into your Kinde dashboard
  2. Create a new application (if you haven’t)
  3. Configure the following settings:
  • Application Name: Your MCP App
  • Redirect URLs: http://localhost:3000/callback
  • Logout URLs: http://localhost:3000

Step 2: Configure Environment Variables

cp .env.example .env
Enter fullscreen mode Exit fullscreen mode

Edit your .env file:

# Kinde Authentication
KINDE_ISSUER_URL=https://your-domain.kinde.com
KINDE_CLIENT_ID=your_client_id
KINDE_CLIENT_SECRET=your_client_secret
JWT_SECRET=super_secret
Enter fullscreen mode Exit fullscreen mode

Setting Up Your Database with Neon

Step 1: Update your .env file

Grab the with the connection string you copied from your Neon console and paste it in your .env file:

# Database Configuration
DATABASE_URL=postgresql://username:password@host:port/database
Enter fullscreen mode Exit fullscreen mode

Your complete .env file should look like this:

# Database Configuration
DATABASE_URL=postgresql://username:password@host:port/database

# Kinde Authentication
KINDE_ISSUER_URL=https://your-domain.kinde.com
KINDE_CLIENT_ID=your_client_id
KINDE_CLIENT_SECRET=your_client_secret

# JWT Configuration
JWT_SECRET=your_super_secret_jwt_key_here

# Server Configuration
NODE_ENV=development
PORT=3000
Enter fullscreen mode Exit fullscreen mode

Step 2: Initialize Database Schema

npm run setup-db
Enter fullscreen mode Exit fullscreen mode

This command will:

  • Connect to your Neon database
  • Create all necessary tables
  • Set up indexes and relationships

Building Your MCP Server

Step 1: Start the server:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Step 2: Start the authentication server:

npm run auth-server
Enter fullscreen mode Exit fullscreen mode

Visit http://localhost:3000 to test the login flow.

Step 3: Understand the MCP Tools

Your MCP server provides these tools:

Authentication Tools:

  • login → Get authentication URL
  • save_token → Save authentication token
  • logout → Log out current user
  • refresh_billing_status → Check billing status

CRUD Tools (Blog Template):

  • create_post → Create new blog post
  • list_posts → List all blog posts
  • get_post → Get specific blog post
  • update_post → Update existing post
  • delete_post → Delete blog post
  • create_comment → Add comment to post
  • list_comments → List post comments

Step 4: Integrating with Cursor AI

Create or edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "my-awesome-app": {
      "command": "node",
      "args": ["dist/universal-server.js"],
      "cwd": "/path/to/your/my-awesome-app",
      "env": {
        "DATABASE_URL": "your_database_url",
        "KINDE_ISSUER_URL": "your_kinde_issuer_url",
        "KINDE_CLIENT_ID": "your_kinde_client_id",
        "KINDE_CLIENT_SECRET": "your_kinde_client_secret",
        "JWT_SECRET": "your_jwt_secret"
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

After configuring MCP settings, restart Cursor to load the new configuration.

Step 5: Test AI Integration

In Cursor, you can now use natural language to interact with your MCP application:

"Create a new blog post titled 'Getting Started with MCP' with content about building AI applications"
"List all my blog posts"
"Update the post with ID 1 to change the title to 'Advanced MCP Techniques'"
Enter fullscreen mode Exit fullscreen mode

Understanding the Billing System

The MCP Starter Kit includes a comprehensive billing system:

Free Tier Limits

Each template has configurable free tier limits:

Blog Template:

  • 10 posts (free tier)
  • 50 comments (free tier)
  • Unlimited reads

E-commerce Template:

  • 5 products (free tier)
  • 10 orders (free tier)
  • Unlimited customers

Upgrade Flow

  • Usage Tracking → Automatic tracking of free tier usage
  • Limit Warnings → Notifications when approaching limits
  • Upgrade Prompts → Seamless redirect to billing portal
  • Plan Management → Check current plan and usage

Billing Integration

// Check billing status
const billingStatus = await checkBillingStatus(userId);

// Redirect to upgrade
if (billingStatus.needsUpgrade) {
  return redirectToBillingPortal(userId);
}
Enter fullscreen mode Exit fullscreen mode

Available Templates Deep Dive

Blog Template

Perfect for content creators and writers:

Entities:

  • Posts - Title, content, author, published date
  • Comments - Text, author, post relationship

Features:

  • Rich text content support
  • Comment moderation
  • Author management
  • Publication scheduling

Use Cases:

  • Personal blogs
  • Company blogs
  • Documentation sites
  • News websites

E-commerce Template

Ideal for online stores and marketplaces:

Entities:

  • Products - Name, description, price, inventory
  • Orders - Customer, items, total, status
  • Order Items - Product, quantity, price

Features:

  • Inventory management
  • Order tracking
  • Customer management
  • Payment integration

Use Cases:

  • Online stores
  • Digital marketplaces
  • Subscription services
  • Product catalogs

CRM Template

Perfect for sales teams and businesses:

Entities:

  • Contacts - Name, email, company, status
  • Deals - Title, value, stage, contact
  • Tasks - Description, due date, contact

Features:

  • Lead management
  • Sales pipeline
  • Task automation
  • Contact segmentation

Use Cases:

  • Sales teams
  • Customer support
  • Lead generation
  • Business development

Todo Template

Great for personal productivity and task management:

Entities:

  • Todos - Title, description, completed, due date

Features:

  • Task prioritization
  • Due date management
  • Completion tracking
  • Category organization

Use Cases:

  • Personal productivity
  • Project management
  • Team coordination
  • Goal tracking

Advanced Features and Customization

Custom Entity Creation

You can extend any template with custom entities:

// Add a new entity to your template
const customEntity = {
  name: 'custom_entity',
  fields: {
    title: 'string',
    description: 'text',
    created_at: 'timestamp'
  },
  relationships: {
    user_id: 'users.id'
  }
};
Enter fullscreen mode Exit fullscreen mode

Custom MCP Tools

Create custom tools for your specific needs:

// Custom tool example
const customTool = {
  name: 'send_email',
  description: 'Send email to user',
  parameters: {
    to: 'string',
    subject: 'string',
    body: 'string'
  },
  handler: async (params) => {
    // Your custom logic here
    return { success: true };
  }
};
Enter fullscreen mode Exit fullscreen mode

API Rate Limiting

Configure rate limiting for your MCP server:

// Rate limiting configuration
const rateLimitConfig = {
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: 'Too many requests from this IP'
};
Enter fullscreen mode Exit fullscreen mode

Deployment and Production Considerations

Once your MCP server is running locally, the next step is to think about deploying it in a secure and production-ready way. Here are the key areas to cover:

Environment Configuration

Keep separate environment files for development and production.

Development (.env.local):

NODE_ENV=development
DATABASE_URL=your_dev_database_url
KINDE_ISSUER_URL=your_dev_kinde_url
Enter fullscreen mode Exit fullscreen mode

Production (.env):

NODE_ENV=production
DATABASE_URL=your_prod_database_url
KINDE_ISSUER_URL=your_prod_kinde_url
Enter fullscreen mode Exit fullscreen mode

Security Considerations

When moving to production, follow these best practices:

  1. Environment Variables → Never commit secrets or .env files to version control.
  2. HTTPS → Always serve your app over HTTPS in production.
  3. CORS → Configure CORS to only allow requests from your domain.
  4. Rate Limiting → Protect your endpoints from abuse with rate limiting.
  5. Input Validation → Validate all incoming requests to prevent injection attacks.

Deployment Options

There are several ways to host your MCP server. Here are three common approaches:

1. Vercel (Recommended)
Vercel makes deployment easy with automatic builds and scaling.

# Install Vercel CLI
npm i -g vercel

# Deploy your application
vercel --prod
Enter fullscreen mode Exit fullscreen mode

2. Railway
Railway provides a simple GitHub integration:

# Connect your GitHub repository
# Railway will automatically build and deploy your app
Enter fullscreen mode Exit fullscreen mode

3. Docker
For more control, you can containerize your app with Docker:

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

Which One Should You Choose?

Option Pros Cons
Vercel Zero-config, fast deploys, free tier, great for TypeScript apps Less control over server environment
Railway Easy GitHub integration, supports background jobs Free tier more limited than Vercel
Docker Full control, portable across any cloud provider More setup and maintenance required

For most developers, Vercel is the fastest way to go live. If you want more flexibility or need background jobs, Railway is a good choice. For enterprise-grade control, Docker is the way forward.

Troubleshooting Common Issues

MCP Server Not Detected in Cursor

Symptoms:

  • Cursor doesn't recognize your MCP server
  • Tools don't appear in Cursor interface

Solutions:

  • Check ~/.cursor/mcp.json syntax
  • Verify environment variables are set
  • Restart Cursor completely
  • Ensure MCP server is running
  • Check Cursor logs for errors

Authentication Issues

Symptoms:

  • Login redirects fail
  • Tokens not being saved
  • Authentication errors

Solutions:

  • Verify Kinde credentials in .env
  • Check redirect URLs in Kinde dashboard
  • Ensure auth server is running on port 3000
  • Clear browser cookies and try again
  • Check JWT secret is set correctly

Database Connection Issues

Symptoms:

  • Database connection errors
  • Schema creation fails
  • Query timeouts

Solutions:

  • Verify Neon database URL
  • Check database permissions
  • Run npm run setup-db to create schema
  • Test connection with npm run test-db
  • Check network connectivity

Performance Issues

Symptoms:

  • Slow response times
  • High memory usage
  • Timeout errors

Solutions:

  • Optimize database queries
  • Add database indexes
  • Implement caching
  • Use connection pooling
  • Monitor resource usage

Best Practices and Tips

Development Workflow

  • Use Version Control → Always use Git for your projects
  • Environment Management → Use different environments for dev/staging/prod
  • Testing → Write tests for your MCP tools
  • Documentation → Document your custom tools and configurations
  • Monitoring → Set up logging and monitoring

Security Best Practices

  • Secrets Management → Use environment variables for all secrets
  • Input Validation → Validate all inputs from AI and users
  • Rate Limiting → Implement rate limiting to prevent abuse
  • Authentication → Always verify user authentication
  • HTTPS → Use HTTPS in production

Performance Optimization

  • Database Indexing → Add indexes for frequently queried fields
  • Connection Pooling → Use connection pooling for database connections
  • Caching → Implement caching for frequently accessed data
  • Lazy Loading → Load data only when needed
  • Monitoring → Monitor performance metrics

AI Integration Tips

  • Clear Descriptions → Write clear descriptions for your MCP tools
  • Error Handling → Provide meaningful error messages
  • Context → Include relevant context in responses
  • Validation → Validate AI inputs before processing
  • Logging → Log all AI interactions for debugging

Conclusion and Next Steps

You’ve just built a production-ready AI-Native MCP server in TypeScript using a Starter Kit. Along the way, you added authentication, database integration, billing, and even connected it to Cursor AI.

With this foundation, you can now extend your server with custom tools, new entities, and additional integrations to fit your use case.

Ready to build your own MCP application? Run:

npx mcp-starter-kit
Enter fullscreen mode Exit fullscreen mode

and start experimenting today.

If you found this guide helpful, I’d love your support, check out the MCP Starter Kit GitHub repo and give it a ⭐.

Every star helps others discover the project and keeps me motivated to build more resources for the community.

Top comments (0)