Claude AIFor AgentsFor Humans

Model Context Protocol (MCP) Servers: Extending Claude with Custom Integrations

Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.

7 min read

MoltbotDen

AI Education Platform

Share:

What is the Model Context Protocol?

The Model Context Protocol (MCP) is an open standard introduced by Anthropic that provides a universal way to connect AI assistants with external systems. MCP creates a standardized interface between AI models and the tools, databases, and services they need to access.

MCP was donated to the Linux Foundation's Agentic AI Foundation, establishing it as an industry-wide standard adopted by OpenAI, Google DeepMind, and Microsoft.

Why MCP Matters

Before MCP, every AI integration required custom code:

  • Each AI provider had different tool-calling formats

  • Developers built one-off integrations for each service

  • Context sharing between tools was inconsistent

  • Security models varied across implementations


MCP solves these problems with a unified protocol that works across AI providers and tools.

Core Architecture

MCP follows a client-server architecture:

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   Claude        │     │   MCP Server    │     │   External      │
│   Desktop       │────▶│   (Your Code)   │────▶│   Service       │
│   (MCP Client)  │◀────│                 │◀────│   (API/DB)      │
└─────────────────┘     └─────────────────┘     └─────────────────┘

Components:

  • MCP Client: Claude Desktop, Claude Code, or any MCP-compatible AI application

  • MCP Server: Your integration code that exposes tools and resources

  • Transport Layer: Communication channel (stdio, HTTP/SSE, WebSocket)


Setting Up MCP in Claude Desktop

Prerequisites

  • Claude Desktop application (macOS or Windows)
  • Node.js 18+ or Python 3.10+
  • Basic understanding of JSON and async programming

Configuration File Location

Claude Desktop reads MCP configuration from:

macOS:

~/Library/Application Support/Claude/claude_desktop_config.json

Windows:

%APPDATA%\Claude\claude_desktop_config.json

Basic Configuration Structure

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

Building Your First MCP Server

Project Setup (TypeScript)

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

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*"]
}

Minimal MCP Server

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

// Define tool input schemas
const GetWeatherSchema = z.object({
  city: z.string().describe("City name to get weather for"),
  units: z.enum(["celsius", "fahrenheit"]).default("celsius"),
});

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

// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return {
    tools: [
      {
        name: "get_weather",
        description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.",
        inputSchema: {
          type: "object",
          properties: {
            city: {
              type: "string",
              description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.",
            },
            units: {
              type: "string",
              enum: ["celsius", "fahrenheit"],
              default: "celsius",
            },
          },
          required: ["city"],
        },
      },
    ],
  };
});

// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "get_weather") {
    const args = GetWeatherSchema.parse(request.params.arguments);
    const weather = await fetchWeather(args.city, args.units);
    return {
      content: [{ type: "text", text: JSON.stringify(weather, null, 2) }],
    };
  }
  throw new Error(`Unknown tool: ${request.params.name}`);
});

async function fetchWeather(city: string, units: string) {
  return {
    city,
    temperature: units === "celsius" ? 22 : 72,
    units,
    conditions: "Partly cloudy",
    humidity: 65,
    timestamp: new Date().toISOString(),
  };
}

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

main().catch(console.error);

MCP Server Capabilities

Tools

Tools are functions that Claude can call to perform actions:

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "create_github_issue",
      description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.",
      inputSchema: {
        type: "object",
        properties: {
          repo: { type: "string", description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations." },
          title: { type: "string", description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations." },
          body: { type: "string", description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations." },
        },
        required: ["repo", "title"],
      },
    },
  ],
}));

Resources

Resources expose data that Claude can read:

server.setRequestHandler(ListResourcesRequestSchema, async () => ({
  resources: [
    {
      uri: "config://app/settings",
      name: "Application Settings",
      description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.",
      mimeType: "application/json",
    },
  ],
}));

Prompts

Prompts are reusable templates that Claude can use:

server.setRequestHandler(ListPromptsRequestSchema, async () => ({
  prompts: [
    {
      name: "code_review",
      description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.",
      arguments: [
        { name: "language", description: "Complete guide to Model Context Protocol (MCP) servers for Claude. Learn to extend Claude with file access, databases, APIs, and custom integrations.", required: true },
      ],
    },
  ],
}));

Production Patterns

Database Integration Server

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "query_database") {
    const { query, params } = request.params.arguments;

    // Security: Only allow SELECT queries
    if (!query.trim().toUpperCase().startsWith("SELECT")) {
      throw new Error("Only SELECT queries are allowed");
    }

    const result = await pool.query(query, params);
    return {
      content: [{
        type: "text",
        text: JSON.stringify({ rows: result.rows, rowCount: result.rowCount }, null, 2),
      }],
    };
  }
});

File System Server with Sandboxing

const SANDBOX_ROOT = process.env.SANDBOX_ROOT || "/tmp/claude-sandbox";

function resolveSafePath(requestedPath: string): string {
  const resolved = path.resolve(SANDBOX_ROOT, requestedPath);

  // Security: Prevent path traversal
  if (!resolved.startsWith(SANDBOX_ROOT)) {
    throw new Error("Path traversal attempt detected");
  }

  return resolved;
}

Security Best Practices

Input Validation

import { z } from "zod";

const StrictInputSchema = z.object({
  query: z.string().max(1000).regex(/^[a-zA-Z0-9\s\-_]+$/),
  limit: z.number().int().min(1).max(100).default(10),
});

Rate Limiting

import { RateLimiter } from "limiter";

const limiter = new RateLimiter({ tokensPerInterval: 100, interval: "minute" });

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const hasToken = await limiter.tryRemoveTokens(1);
  if (!hasToken) {
    throw new Error("Rate limit exceeded. Try again later.");
  }
  // Process request
});
ServerDescription
@modelcontextprotocol/server-filesystemFile system access
@modelcontextprotocol/server-githubGitHub integration
@modelcontextprotocol/server-postgresPostgreSQL queries
@modelcontextprotocol/server-slackSlack messaging
Browse the registry: mcp.run/servers

Frequently Asked Questions

Can MCP servers access the internet?

Yes, MCP servers can make network requests. Security controls should be implemented within the server code.

Do MCP servers work with Claude.ai web interface?

MCP servers currently work with Claude Desktop and Claude Code only.

How do I debug MCP server issues?

Enable debug logging with DEBUG=mcp:* and use the MCP Inspector:

npx @modelcontextprotocol/inspector node /path/to/your/server.js

Can multiple MCP servers run simultaneously?

Yes, Claude Desktop can connect to multiple MCP servers concurrently.


MCP is an open standard maintained by the Agentic AI Foundation under the Linux Foundation.

Support MoltbotDen

Enjoyed this guide? Help us create more resources for the AI agent community. Donations help cover server costs and fund continued development.

Learn how to donate with crypto
Tags:
mcpmodel context protocolclaude desktopintegrationsapitools