Model Context Protocol (MCP): The Universal Standard for AI Tool Integration



Remember when every device needed a different cable? Then USB came along. Model Context Protocol (MCP) is doing the same thing for AI tools—creating a universal way for AI models to interact with external systems.

Network connections Photo by NASA on Unsplash

What is MCP?

Model Context Protocol is an open standard that defines how AI models communicate with external tools, data sources, and services. Instead of building custom integrations for every AI provider, you build one MCP server and it works everywhere.

┌─────────────┐     MCP      ┌─────────────┐
│   Claude    │◄────────────►│  Your Tool  │
└─────────────┘              └─────────────┘
       │                            │
       │         MCP                │
       ▼                            ▼
┌─────────────┐              ┌─────────────┐
│   GPT-4     │              │  Database   │
└─────────────┘              └─────────────┘

Why MCP Matters

Before MCP, integrating AI with your systems meant:

  1. Writing custom code for each AI provider
  2. Managing multiple authentication schemes
  3. Handling different context formats
  4. Maintaining separate tooling definitions

With MCP:

  1. Write one integration
  2. Works with any MCP-compatible AI
  3. Standardized authentication
  4. Universal tool definitions

Building Your First MCP Server

Let’s build a simple MCP server that provides weather data:

// weather-mcp-server.ts
import { MCPServer, Tool, Resource } from '@modelcontextprotocol/sdk';

const server = new MCPServer({
  name: 'weather-service',
  version: '1.0.0',
});

// Define a tool
server.addTool({
  name: 'get_weather',
  description: 'Get current weather for a location',
  inputSchema: {
    type: 'object',
    properties: {
      city: { type: 'string', description: 'City name' },
      units: { 
        type: 'string', 
        enum: ['celsius', 'fahrenheit'],
        default: 'celsius'
      }
    },
    required: ['city']
  },
  handler: async ({ city, units }) => {
    const weather = await fetchWeather(city, units);
    return {
      temperature: weather.temp,
      conditions: weather.conditions,
      humidity: weather.humidity
    };
  }
});

// Define a resource (data the AI can read)
server.addResource({
  uri: 'weather://forecast/weekly',
  name: 'Weekly Forecast',
  description: '7-day weather forecast',
  mimeType: 'application/json',
  handler: async () => {
    return await getWeeklyForecast();
  }
});

server.start();

MCP Architecture Deep Dive

MCP defines three core primitives:

1. Tools

Functions the AI can call to take actions:

interface Tool {
  name: string;
  description: string;
  inputSchema: JSONSchema;
  handler: (input: any) => Promise<any>;
}

2. Resources

Data sources the AI can read:

interface Resource {
  uri: string;
  name: string;
  description: string;
  mimeType: string;
  handler: () => Promise<string | Buffer>;
}

3. Prompts

Pre-defined prompt templates:

interface Prompt {
  name: string;
  description: string;
  arguments: PromptArgument[];
  template: string;
}

Data flow diagram Photo by Markus Spiske on Unsplash

Real-World MCP Implementation

Here’s a production-ready MCP server for a database:

// database-mcp-server.ts
import { MCPServer } from '@modelcontextprotocol/sdk';
import { Pool } from 'pg';

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

const server = new MCPServer({
  name: 'database-service',
  version: '1.0.0',
  capabilities: {
    tools: true,
    resources: true,
    prompts: true
  }
});

// Query tool with safety checks
server.addTool({
  name: 'query_database',
  description: 'Execute a read-only SQL query',
  inputSchema: {
    type: 'object',
    properties: {
      query: { 
        type: 'string',
        description: 'SQL SELECT query'
      },
      limit: {
        type: 'number',
        default: 100,
        maximum: 1000
      }
    },
    required: ['query']
  },
  handler: async ({ query, limit = 100 }) => {
    // Safety: Only allow SELECT queries
    if (!query.trim().toLowerCase().startsWith('select')) {
      throw new Error('Only SELECT queries are allowed');
    }
    
    // Add limit if not present
    const limitedQuery = query.includes('limit') 
      ? query 
      : `${query} LIMIT ${limit}`;
    
    const result = await pool.query(limitedQuery);
    return {
      rows: result.rows,
      rowCount: result.rowCount,
      fields: result.fields.map(f => f.name)
    };
  }
});

// Schema resource
server.addResource({
  uri: 'database://schema',
  name: 'Database Schema',
  description: 'Current database table schemas',
  mimeType: 'application/json',
  handler: async () => {
    const result = await pool.query(`
      SELECT table_name, column_name, data_type 
      FROM information_schema.columns 
      WHERE table_schema = 'public'
      ORDER BY table_name, ordinal_position
    `);
    return JSON.stringify(result.rows, null, 2);
  }
});

server.start({ transport: 'stdio' });

Connecting MCP to Claude

Claude Desktop supports MCP natively. Configure it in claude_desktop_config.json:

{
  "mcpServers": {
    "weather": {
      "command": "node",
      "args": ["./weather-mcp-server.js"],
      "env": {
        "WEATHER_API_KEY": "your-key"
      }
    },
    "database": {
      "command": "node",
      "args": ["./database-mcp-server.js"],
      "env": {
        "DATABASE_URL": "postgresql://..."
      }
    }
  }
}

MCP vs Traditional APIs

FeatureTraditional APIMCP
AI IntegrationCustom per providerUniversal
DiscoveryManual documentationAutomatic
SchemaOpenAPI/GraphQLJSONSchema
StreamingVariesBuilt-in
AuthenticationCustomStandardized

Security Considerations

MCP servers handle AI-initiated requests. Security is critical:

// Security best practices
server.addTool({
  name: 'sensitive_operation',
  // 1. Rate limiting
  rateLimit: { requests: 10, window: '1m' },
  
  // 2. Input validation
  inputSchema: {
    type: 'object',
    properties: {
      userId: { 
        type: 'string',
        pattern: '^[a-zA-Z0-9-]+$'  // Strict pattern
      }
    },
    additionalProperties: false  // Reject unknown fields
  },
  
  handler: async (input, context) => {
    // 3. Check permissions
    if (!context.user.hasPermission('sensitive_op')) {
      throw new Error('Unauthorized');
    }
    
    // 4. Audit logging
    logger.info('Sensitive operation', { 
      user: context.user.id,
      input 
    });
    
    // 5. Sanitize output
    return sanitize(await performOperation(input));
  }
});

The MCP Ecosystem

The ecosystem is growing rapidly:

  • Official SDKs: TypeScript, Python, Rust
  • Community servers: GitHub, Slack, Notion, databases
  • IDE plugins: VS Code, Cursor, JetBrains
  • Cloud providers: AWS, GCP, Azure MCP connectors

Getting Started

  1. Install the SDK:
    npm install @modelcontextprotocol/sdk
    
  2. Create a server (see examples above)

  3. Test locally:
    npx @modelcontextprotocol/inspector ./your-server.js
    
  4. Connect to Claude Desktop or your preferred AI client

Conclusion

MCP is the missing standard that makes AI integration practical. Instead of maintaining dozens of custom integrations, you maintain one MCP server. The AI ecosystem benefits from interoperability, and developers benefit from reduced complexity.

If you’re building AI-powered applications, MCP should be on your radar. It’s not just another protocol—it’s the foundation for how AI will interact with the world.


Building an MCP server? I’d love to see what you create. Share your projects!

이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)