How I Built a MCP Server Connected to Claude Desktop with Typescript

In this comprehensive guide, we'll walk through the process of building a TypeScript MCP server from scratch and connecting it to Claude Desktop.

Emmanuel Mumba

Emmanuel Mumba

9 April 2025

How I Built a MCP Server Connected to Claude Desktop with Typescript

The Model Context Protocol (MCP) represents a significant advancement in how AI assistants interact with external tools and data sources. Developed by Anthropic, MCP enables Claude to seamlessly communicate with custom servers, allowing it to access real-time information, execute complex workflows, and interact with APIs without leaving the conversation context. This capability transforms Claude from a standalone LLM into a versatile assistant that can leverage external functionality while maintaining conversation coherence.

In this comprehensive guide, we'll walk through the process of building a TypeScript MCP server from scratch and connecting it to Claude Desktop. By implementing this integration, you'll enable Claude to perform tasks like retrieving real-time data, executing computations, or interacting with your custom business logic directly within conversations.

Before diving into our MCP server implementation, it's worth mentioning that your choice of API development tool can significantly impact your workflow efficiency.

As we build our TypeScript MCP server, consider how Apidog's collaborative features and development-focused approach can enhance your team's productivity and ensure your APIs remain consistent, well-tested, and thoroughly documented throughout the process.

button

Understanding the Model Context Protocol

The Model Context Protocol defines a standardized way for Claude to communicate with external services. When Claude identifies that it needs information from an external source, it can invoke an MCP server through a specially formatted JSON request. The server processes this request and returns the requested data, which Claude can then incorporate into its response.

MCP offers several advantages over traditional AI integration approaches:

Prerequisites

Before we begin building our MCP server, ensure you have the following:

Setting Up Your TypeScript Project

Let's start by creating a new TypeScript project for our MCP server:

mkdir claude-mcp-server
cd claude-mcp-server
npm init -y
npm install typescript @types/node ts-node express @types/express cors @types/cors
npx tsc --init

Next, update your tsconfig.json to include these settings:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

Implementing the MCP Server

Create a new file called server.ts in your project root directory. This will be the entry point for our MCP server:

import express from 'express';
import cors from 'cors';
import { Request, Response } from 'express';

// Define types for the MCP protocol
interface MCPRequest {
  query: string;
  conversation_id: string;
  request_id: string;
  parameters?: Record<string, any>;
}

interface MCPResponse {
  response: string;
  status: 'success' | 'error';
  error?: string;
}

const app = express();
app.use(cors());
app.use(express.json());

// Health check endpoint
app.get('/health', (req: Request, res: Response) => {
  res.status(200).json({ status: 'healthy' });
});

// MCP endpoint
app.post('/mcp', (req: Request, res: Response) => {
  try {
    const mcpRequest = req.body as MCPRequest;
    console.log('Received MCP request:', JSON.stringify(mcpRequest, null, 2));

    // Process the request based on the query
    const response = processQuery(mcpRequest);
    
    res.status(200).json({
      status: 'success',
      response
    } as MCPResponse);
  } catch (error) {
    console.error('Error processing MCP request:', error);
    res.status(500).json({
      status: 'error',
      error: error instanceof Error ? error.message : 'Unknown error',
      response: 'Sorry, there was an error processing your request.'
    } as MCPResponse);
  }
});

// Function to process different query types
function processQuery(request: MCPRequest): string {
  const { query, parameters } = request;

  // Example query handling - customize this for your use case
  switch (query) {
    case 'getCurrentTime':
      return `The current time is ${new Date().toLocaleTimeString()}`;
    
    case 'getWeather':
      const location = parameters?.location || 'Unknown';
      // In a real app, you would call a weather API here
      return `The weather in ${location} is currently sunny and 72°F`;
    
    case 'calculateSum':
      if (parameters?.numbers && Array.isArray(parameters.numbers)) {
        const sum = parameters.numbers.reduce((a: number, b: number) => a + b, 0);
        return `The sum of the numbers is ${sum}`;
      }
      return 'Invalid parameters for sum calculation';

    default:
      return `Unrecognized query: ${query}`;
  }
}

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`MCP server running on port ${PORT}`);
});

Running Your MCP Server

To run your server, execute:

npx ts-node server.ts

Your MCP server should now be running on port 3000 (or your specified port).

Connecting to Claude Desktop

Now that your MCP server is running, you need to configure Claude Desktop to connect to it. Here's how:

  1. Open Claude Desktop application
  2. Go to Settings (usually in the top-right corner)
  3. Navigate to the "Experimental Features" section
  4. Enable the "Model Context Protocol" toggle
  5. Add a new MCP endpoint with the URL http://localhost:3000/mcp
  6. Save your settings

Claude Desktop will now be able to communicate with your custom MCP server.

Testing the Integration

To test your MCP server with Claude, try asking Claude questions that would trigger the specific queries you've implemented. For example:

When Claude recognizes that it needs external information to answer these questions, it will automatically send an MCP request to your server and incorporate the response into its answer.

Extending Your MCP Server

The basic server we've built is just a starting point. Here are some ideas for extending its functionality:

Add Authentication

To secure your MCP server, add authentication:

// Middleware for basic auth
const authenticateMCP = (req: Request, res: Response, next: Function) => {
  const apiKey = req.headers['x-api-key'];
  if (!apiKey || apiKey !== process.env.MCP_API_KEY) {
    return res.status(401).json({
      status: 'error',
      error: 'Unauthorized',
      response: 'Authentication failed'
    });
  }
  next();
};

// Apply middleware to MCP endpoint
app.post('/mcp', authenticateMCP, (req: Request, res: Response) => {
  // Existing handler code
});

Implement Database Integration

Connect your MCP server to a database to retrieve or store information:

import { MongoClient } from 'mongodb';

// Initialize database connection
const dbClient = new MongoClient('mongodb://localhost:27017');
let db: any;

async function connectToDb() {
  await dbClient.connect();
  db = dbClient.db('mcpDatabase');
  console.log('Connected to database');
}

connectToDb().catch(console.error);

// Add a query handler for database interactions
case 'getUserData':
  if (parameters?.userId) {
    const user = await db.collection('users').findOne({ id: parameters.userId });
    return user ? JSON.stringify(user) : 'User not found';
  }
  return 'Invalid user ID';

Add Webhook Support

Implement webhook functionality to notify external services:

case 'sendNotification':
  if (parameters?.message && parameters?.destination) {
    // Call external notification service
    await fetch('https://your-webhook-url.com', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message: parameters.message })
    });
    return `Notification sent to ${parameters.destination}`;
  }
  return 'Invalid notification parameters';

Best Practices for MCP Server Development

  1. Handle errors gracefully: Always catch exceptions and return informative error messages
  2. Implement logging: Log all requests and responses for debugging and auditing
  3. Use TypeScript interfaces: Define clear interfaces for all data structures
  4. Set timeouts: Implement request timeouts to prevent hanging operations
  5. Validate inputs: Carefully validate all input parameters before processing
  6. Add unit tests: Test your query handlers thoroughly to ensure reliability

Conclusion

Building a TypeScript MCP server opens up exciting possibilities for extending Claude's capabilities. By following this guide, you've created a foundation for integrating Claude with your own services and data. The Model Context Protocol enables a seamless user experience where Claude can access external information without breaking the conversation flow.

As MCP continues to evolve, we can expect even more sophisticated integrations between large language models and external systems. Whether you're building productivity tools, knowledge management systems, or custom business applications, MCP provides a powerful way to combine Claude's intelligence with your specialized functionality.

Start exploring the possibilities by extending your server with additional query handlers specific to your use cases, and share your experiences with the growing community of MCP developers.

Explore more

Apidog SEO Settings Explained: Maximize Your API Docs Visibility

Apidog SEO Settings Explained: Maximize Your API Docs Visibility

Discover how to supercharge your API documentation's visibility with Apidog's powerful SEO features. This comprehensive guide covers everything from page-level optimizations like custom URLs and meta tags to site-wide settings such as sitemaps and robots.txt.

18 June 2025

How to Protect API Specification from Unauthorized Users with Apidog

How to Protect API Specification from Unauthorized Users with Apidog

Learn how Apidog empowers you to protect API specification from unauthorized users. Explore advanced API documentation security, access controls, and sharing options for secure API development.

17 June 2025

How to Use the PostHog MCP Server?

How to Use the PostHog MCP Server?

Discover how to use the PostHog MCP server with this in-depth technical guide. Learn to install, configure, and optimize the server for seamless PostHog analytics integration using natural language. Includes practical use cases and troubleshooting.

16 June 2025

Practice API Design-first in Apidog

Discover an easier way to build and use APIs