Skip to main content
Creating Your First MCP Server
Documentation

Creating Your First MCP Server

Learn how to extend Claude with custom tools and capabilities by building your own Model Context Protocol server

5 min read View on GitHub

Imagine giving Claude the ability to interact with your internal systems, query your databases, or control your smart home devices. With the Model Context Protocol (MCP), this vision becomes reality. MCP transforms Claude from a powerful conversational AI into an extensible platform that can integrate seamlessly with any system you build.

This guide will walk you through creating your first MCP server, unlocking the potential to extend Claude’s capabilities in ways that matter to you and your users.

What is the Model Context Protocol?

The Model Context Protocol is an open standard that enables AI assistants like Claude to connect with external tools, data sources, and services. Think of it as a universal adapter that lets Claude communicate with the world beyond its training data.

An MCP server exposes tools (functions that Claude can call), resources (data that Claude can access), and prompts (reusable templates) through a standardized interface. When you build an MCP server, you’re essentially teaching Claude new skills specific to your domain.

The protocol handles all the complexity of communication, authentication, and error handling, letting you focus on building the functionality that matters.

Prerequisites

Before diving in, make sure you have:

  • Node.js 18+ or Python 3.10+ installed
  • Claude Desktop or access to Claude Code (MCP client)
  • Basic familiarity with TypeScript/JavaScript or Python
  • A text editor or IDE of your choice

This tutorial uses TypeScript, but the concepts apply equally to Python or any language with an MCP SDK.

Building Your First Server

Let’s build a simple weather server that gives Claude the ability to fetch weather information for any city. This example demonstrates the core concepts you’ll use in any MCP server.

Step 1: Set Up Your Project

Create a new directory and initialize your project:

mkdir weather-mcp-server
cd weather-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node

Create a tsconfig.json file:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true
  }
}

Step 2: Create Your Server

Create src/index.ts and start with the basic server structure:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
  {
    name: "weather-server",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

Step 3: Define Your Tools

Add a tool handler that implements the weather lookup functionality:

server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "get_weather",
        description: "Get current weather for a city",
        inputSchema: {
          type: "object",
          properties: {
            city: {
              type: "string",
              description: "City name",
            },
            units: {
              type: "string",
              enum: ["celsius", "fahrenheit"],
              description: "Temperature units",
            },
          },
          required: ["city"],
        },
      },
    ],
  };
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "get_weather") {
    const city = request.params.arguments?.city;
    const units = request.params.arguments?.units || "celsius";

    // In a real server, you'd call a weather API here
    const weatherData = {
      city,
      temperature: units === "celsius" ? 22 : 72,
      condition: "Sunny",
      humidity: 65,
    };

    return {
      content: [
        {
          type: "text",
          text: `Weather in ${city}: ${weatherData.temperature}°${
            units === "celsius" ? "C" : "F"
          }, ${weatherData.condition}, ${weatherData.humidity}% humidity`,
        },
      ],
    };
  }

  throw new Error(`Unknown tool: ${request.params.name}`);
});

Step 4: Start the Server

Add the transport layer to handle communication:

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Weather MCP Server running on stdio");
}

main().catch((error) => {
  console.error("Server error:", error);
  process.exit(1);
});

Build your server:

npx tsc

Connecting to Claude

Now that your server is built, let’s connect it to Claude Desktop.

Register Your Server

Edit your Claude Desktop configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add your server to the configuration:

{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": ["/absolute/path/to/weather-mcp-server/build/index.js"]
    }
  }
}

Restart Claude Desktop. Your server is now available to Claude.

Test Your Server

Open a conversation with Claude and try:

“What’s the weather like in San Francisco?”

Claude will automatically call your get_weather tool and provide the response. You’ve just extended Claude’s capabilities with your custom integration.

Advanced Ideas

Now that you’ve built your first MCP server, here are some powerful ideas to explore:

Database Integration: Create a server that lets Claude query your application database, making it easy to answer questions about your data without writing SQL.

API Gateway: Build a server that wraps your internal APIs, giving Claude controlled access to trigger workflows, create records, or fetch system status.

File Operations: Develop a server that provides specialized file handling, like parsing configuration files, analyzing logs, or transforming data formats.

Multi-Tool Workflows: Combine multiple tools in a single server to enable complex operations, like fetching data from one system, transforming it, and sending it to another.

Smart Home Control: Create a server that interfaces with IoT platforms, letting Claude control lights, thermostats, and other devices through natural conversation.

Next Steps

The Model Context Protocol opens up endless possibilities for extending Claude. Your first server is just the beginning. As you build more sophisticated integrations, you’ll discover that MCP’s flexibility makes it easy to evolve your tools alongside your needs.

Explore the official MCP documentation for advanced features like resource providers, prompt templates, and authentication patterns. Join the MCP community to share your creations and learn from other builders.

The future of AI integration is open, interoperable, and in your hands. What will you build next?

Share:

Learn, Contribute & Share

This guide has a companion repository with working examples and code samples.