tutorials2026-01-084 min read

The Definitive Guide to Building MCP Servers for Claude & Cursor

Learn how to build production-ready MCP servers that integrate with Claude Desktop and Cursor. We cover authentication, error handling, and best practices.

E

Emcy Team

Engineering

Code editor showing MCP server implementation with Claude Desktop configuration

The Model Context Protocol (MCP) is rapidly becoming the standard for connecting AI assistants to external tools and data sources. In this guide, we'll walk through building production-ready MCP servers that work seamlessly with Claude Desktop and Cursor.

What is MCP?

MCP (Model Context Protocol) is an open protocol that enables AI assistants to interact with external systems through a standardized interface. Instead of building custom integrations for each AI platform, you build one MCP server that works everywhere.

Why MCP Matters

Traditional AI integrations require:

  • Custom API wrappers for each AI platform
  • Complex authentication flows
  • Manual tool definition maintenance
  • Platform-specific error handling

MCP solves this by providing:

  • A single protocol that works with Claude, ChatGPT, Cursor, and more
  • Standardized tool definitions
  • Built-in authentication patterns
  • Consistent error handling

Getting Started

The fastest way to create an MCP server is using our open-source @emcy/openapi-to-mcp package:

npx @emcy/openapi-to-mcp generate --url https://api.example.com/openapi.json

This generates a complete TypeScript project with:

  • Tool definitions from your OpenAPI spec
  • Support for both Stdio and HTTP transports
  • Authentication configuration
  • Environment variable management

Project Structure

After generation, your project looks like this:

my-mcp-server/
├── src/
│   ├── index.ts        # Main entry point
│   └── transport.ts    # Transport configuration
├── package.json
├── tsconfig.json
├── .env.example
└── README.md

Transport Types

MCP supports two transport mechanisms:

Stdio Transport (Claude Desktop, Cursor)

Best for local development and desktop applications:

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const transport = new StdioServerTransport();
await server.connect(transport);

HTTP Transport (ChatGPT, Web Apps)

Best for production deployments and web-based clients:

import { StreamableHTTPServerTransport } from "./transport.js";

const transport = new StreamableHTTPServerTransport({
  sessionIdGenerator: () => crypto.randomUUID(),
});

Authentication Best Practices

API Key Authentication

For simple use cases, pass API keys via environment variables:

const headers = {
  "Authorization": `Bearer ${process.env.API_KEY}`,
  "Content-Type": "application/json",
};

OAuth 2.0

For production systems, implement proper OAuth flows:

const getAccessToken = async () => {
  const response = await fetch(tokenEndpoint, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "client_credentials",
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET,
    }),
  });
  return response.json();
};

Error Handling

Implement robust error handling to provide meaningful feedback to AI assistants:

try {
  const response = await fetch(url, options);
  if (!response.ok) {
    throw new Error(`API error: ${response.status} ${response.statusText}`);
  }
  return await response.json();
} catch (error) {
  return {
    error: true,
    message: error instanceof Error ? error.message : "Unknown error",
  };
}

Connecting to Claude Desktop

Add your server to Claude Desktop's configuration:

{
  "mcpServers": {
    "my-api": {
      "command": "node",
      "args": ["/path/to/my-mcp-server/dist/index.js"],
      "env": {
        "API_KEY": "your-api-key"
      }
    }
  }
}

Adding Telemetry

Track tool invocations with the @emcy/sdk:

import { EmcyTelemetry } from "@emcy/sdk";

const telemetry = new EmcyTelemetry({
  apiKey: process.env.EMCY_API_KEY,
  serverName: "my-api",
});

// Wrap tool handlers
const result = await telemetry.trace("get_users", async () => {
  return await fetchUsers();
});

Production Checklist

Before deploying to production, ensure you have:

  • Proper error handling for all API calls
  • Rate limiting to prevent abuse
  • Input validation on all parameters
  • Logging for debugging and monitoring
  • Health check endpoint for HTTP transport
  • Environment variable validation at startup

Conclusion

Building MCP servers doesn't have to be complex. With the right tools and patterns, you can expose your API to AI assistants in minutes. Start with @emcy/openapi-to-mcp for quick prototyping, then customize as needed.

Ready to get started? Try our wizard to generate your first MCP server in seconds.

Tags
MCP
Claude
Cursor
OpenAPI
tutorial