What MCP Is — and What It Isn't

MCP is a protocol — a standardized communication contract between an AI host application and external capability providers. It is not a library, a cloud service, or a specific tool. Think of it as USB-C for AI: a single standard connector that lets any compliant tool plug into any compliant AI host, regardless of who built either side.

Before MCP, every AI integration was bespoke. You wanted Claude to read your database? Write a custom integration in the host app. You wanted Cursor to access your internal docs? Another bespoke solution. MCP collapses all of this into one protocol: build an MCP server once, and it works with every MCP-compatible host — Claude Desktop, Cursor, VS Code extensions, custom agents, and any application built with the Anthropic SDK.

Architecture: Three Roles

MCP defines three distinct roles in every interaction:

Host
MCP Host
The AI-powered application the user directly uses. Examples: Claude Desktop, Cursor, custom agent apps. The host manages the AI model and decides which MCP servers to connect.
Client
MCP Client
The component inside the host that speaks the MCP protocol to servers. Each host-server connection has one client. Handles the wire protocol, request/response lifecycle, and capability negotiation.
Server
MCP Server
A lightweight process you build that exposes capabilities to the AI. Can be a local process (stdio) or a remote service (HTTP+SSE). This is what you write when you "build with MCP."

What an MCP Server Can Expose

MCP servers can expose three categories of capability to the AI:

  • Toolsfunctions the AI can call to take actions or retrieve data (search the web, query a database, send an email)
  • Resourcesread-only data the AI can access (files, database rows, API responses, live documentation)
  • Promptsreusable prompt templates with arguments (useful for standardizing how tasks are requested across a team)

Building an MCP Server in TypeScript

The official MCP SDK for TypeScript is the easiest starting point. This example creates a server with one tool that fetches weather data:

# Initialize project
mkdir my-mcp-server && cd my-mcp-server
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node tsx
// src/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 1. Create the server
const server = new McpServer({
  name: "weather-server",
  version: "1.0.0",
});

// 2. Register a tool
server.tool(
  "get_weather",
  "Get current weather for a city",
  { city: z.string().describe("City name") },
  async ({ city }) => {
    // Replace with real API call
    const data = await fetch(
      `https://api.example.com/weather?q=${city}`
    ).then(r => r.json());

    return {
      content: [{
        type: "text",
        text: `${city}: ${data.temp}°C, ${data.condition}`,
      }],
    };
  }
);

// 3. Register a resource (read-only data)
server.resource(
  "config",
  "app://config",
  async () => ({
    contents: [{
      uri: "app://config",
      text: JSON.stringify({ version: "1.0", env: "production" }),
    }],
  })
);

// 4. Connect via stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP server running"); // stderr only — stdout is the protocol
# Run the server
npx tsx src/index.ts

Building an MCP Server in Python

The Python SDK uses a decorator pattern that keeps server code readable:

# Install
pip install mcp
# server.py
from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("weather-server")

# Tool — AI can call this
@mcp.tool()
async def get_weather(city: str) -> str:
    """Get current weather for a city."""
    async with httpx.AsyncClient() as client:
        r = await client.get(f"https://api.example.com/weather?q={city}")
        data = r.json()
    return f"{city}: {data['temp']}°C, {data['condition']}"

# Resource — AI can read this
@mcp.resource("docs://readme")
def get_readme() -> str:
    """Project README."""
    with open("README.md") as f:
        return f.read()

# Prompt template
@mcp.prompt()
def analyze_weather(city: str) -> str:
    return f"Fetch weather for {city} and summarize in one sentence."

if __name__ == "__main__":
    mcp.run()  # stdio transport by default

Connecting to Claude Desktop

Add your server to Claude Desktop's config file. The location varies by OS:

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

# Windows
%APPDATA%\Claude\claude_desktop_config.json
// claude_desktop_config.json
{
  "mcpServers": {
    "weather": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/src/index.ts"]
    },
    "weather-python": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"],
      "env": {
        "API_KEY": "your-key-here"
      }
    }
  }
}

Restart Claude Desktop after editing. The AI will now see your tools listed in the tool picker and can call them during any conversation. No further configuration needed — the AI discovers available tools automatically at connection time.

"MCP is plumbing. It doesn't tell the AI what to do — it gives the AI the pipes to reach things it couldn't reach before. What the AI does with those pipes is determined by Skills, prompts, and the task at hand."

MCP vs Skills: Where the Boundary Is

Aspect MCP Skills
What it is Protocol for external connectivity Packaged AI workflows / slash commands
Layer Infrastructure (how AI accesses tools) Behavior (what the AI does)
Triggered by AI autonomously, based on task needs User explicitly (/command) or AI matching
Built with TypeScript / Python server code Markdown prompts, CLAUDE.md, config files
Use when AI needs to reach external systems You want repeatable, named workflows

MCP and Skills are complementary, not competing. A Skill can invoke MCP tools internally. An MCP server doesn't know or care what Skill triggered the tool call. The right mental model: MCP is the toolbox, Skills are the instructions for how to use the tools on a specific job. For a deeper look at Skills and how to build them, see the companion article.