1. What Is MCP and Why Anthropic's "USB-C for AI" Analogy Is Exactly Right

The Model Context Protocol (MCP) is an open standard created by Anthropic that gives AI agents a single, standardized way to connect to external data sources and tools — files, databases, APIs, web scrapers, calendar systems, CRMs, anything.

Before MCP existed, every AI integration was its own one-off project. You wanted your agent to read from a Postgres database? Custom code. You wanted it to call a Slack API? More custom code. You wanted it to read a local file system? Even more custom code. And none of it was reusable across different agents or models.

MCP solves this with a universal interface. The USB-C analogy is apt: just like USB-C let one cable handle power, data, and video, MCP lets one protocol handle tool access, resource reading, and prompt injection — regardless of which AI model or application is on the other end.

Official Definition

MCP is "an open protocol that standardizes how applications provide context to LLMs." It separates the concern of what tools exist from how an AI model uses them.

The protocol was released publicly in late 2024 and has grown rapidly. By 2026, MCP has become the de facto standard for AI tool connectivity. Major integrations — Slack, GitHub, Notion, Google Drive, Postgres — all have community-maintained MCP servers. When you learn MCP, you're not learning a niche trick; you're learning the foundational layer of modern AI agent architecture.

2. How MCP Works: The Architecture in Plain English

MCP has three components you need to understand before writing any code:

MCP Host

The host is the AI application that wants to use tools. This could be Claude.ai, Claude Code, or any application built on the Claude API. The host initiates connections to MCP servers and uses their capabilities.

MCP Client

The client is a protocol layer embedded inside the host. When Claude Code needs to talk to an MCP server, it uses its built-in MCP client. You don't write the client — it's part of the AI application you're using.

MCP Server

The server is what you build. It's a lightweight process — typically a Python or TypeScript script — that exposes capabilities to the AI. An MCP server can expose three types of things:

  • Tools — Functions the AI can call (e.g., read_file, query_database, send_email)
  • Resources — Data the AI can read (e.g., files, database rows, API responses)
  • Prompts — Pre-built prompt templates the AI can invoke

The communication between client and server happens over a transport layer. The two supported transports are:

  • stdio — The server runs as a subprocess; the host communicates via standard input/output. Best for local development and Claude Code integration.
  • HTTP + SSE — The server runs as a web service; the host communicates via HTTP with Server-Sent Events for streaming. Best for production deployments and remote servers.

Start with stdio

For local development and Claude Code integration, stdio is simpler and requires zero networking setup. Switch to HTTP+SSE when you need to share an MCP server across multiple machines.

3. MCP vs. Function Calling: When to Use Each

If you've worked with the Anthropic API before, you know about tool use (function calling). You might be wondering: why do I need MCP if I can already define tools in my API calls? The answer comes down to architecture and reuse.

Dimension Function Calling (Tool Use) MCP
Scope Defined per API request Defined once, available to any host
Reusability Low — rebuild per project High — write once, use everywhere
Session state Stateless by default Server can maintain state across calls
Best for Simple, one-off tool definitions Production agents, shared tooling
Claude Code support Indirect Native
Learning curve Lower Slightly higher, worth it

Rule of thumb: use function calling for quick prototypes where you control the entire stack. Use MCP when you want Claude Code to access your tools natively, when you're building tooling that will be shared across projects, or when you're building an agent for a client who needs a clean separation between the AI layer and the data layer.

4. Setting Up Your First MCP Server: Step-by-Step

This section walks through the initial setup. You will need Node.js 18+ or Python 3.10+ depending on which SDK you use. Both are covered below.

1

Install the MCP SDK

Anthropic provides official SDKs for Python and TypeScript. Install the one that matches your preferred language.

2

Define your tools

Decide what capabilities your agent needs. Start with one or two tools — you can always add more later.

3

Write the server

Implement the server using the SDK. The boilerplate is minimal — the SDK handles all protocol-level communication.

4

Register in Claude Code

Add your server to ~/.claude/settings.json so Claude Code can discover and use it automatically.

5

Test in an agentic session

Open Claude Code, ask it to use one of your tools, and watch MCP in action.

5. Building an MCP Server in Python

This is a complete, working example. The server exposes two tools: one that reads a file by path, and one that lists files in a directory. These are simple but immediately useful — and they illustrate every concept you need to build more complex tools.

terminal
# Install the MCP Python SDK
pip install mcp
mcp_server.py
import asyncio
import os
from pathlib import Path
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent

# Create the MCP server instance
app = Server("file-tools")

# Declare available tools
@app.list_tools()
async def list_tools():
    return [
        Tool(
            name="read_file",
            description="Read the contents of a file at a given path",
            inputSchema={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Absolute or relative path to the file"
                    }
                },
                "required": ["path"]
            }
        ),
        Tool(
            name="list_directory",
            description="List all files in a directory",
            inputSchema={
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "Directory path to list"
                    }
                },
                "required": ["path"]
            }
        )
    ]

# Handle tool calls
@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "read_file":
        file_path = Path(arguments["path"])
        if not file_path.exists():
            return [TextContent(type="text", text=f"Error: File not found: {file_path}")]
        content = file_path.read_text(encoding="utf-8")
        return [TextContent(type="text", text=content)]

    elif name == "list_directory":
        dir_path = Path(arguments["path"])
        if not dir_path.is_dir():
            return [TextContent(type="text", text=f"Error: Not a directory: {dir_path}")]
        files = [str(f) for f in dir_path.iterdir()]
        return [TextContent(type="text", text="\n".join(files))]

    return [TextContent(type="text", text=f"Unknown tool: {name}")]

# Run the server over stdio
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await app.run(read_stream, write_stream, app.create_initialization_options())

if __name__ == "__main__":
    asyncio.run(main())

That is a fully functional MCP server. When Claude calls read_file or list_directory, this server handles the request and returns structured results. Notice how the SDK handles all the JSON-RPC protocol layer — you only write the business logic.

6. Building an MCP Server in TypeScript

If your project is Node.js-based, the TypeScript SDK is the better fit. The structure mirrors the Python version closely.

terminal
# Initialize project and install SDK
npm init -y
npm install @modelcontextprotocol/sdk
npm install -D typescript @types/node tsx
src/mcp-server.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 { readFileSync, readdirSync, existsSync } from "fs";

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

// List available tools
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "read_file",
      description: "Read the contents of a file at a given path",
      inputSchema: {
        type: "object",
        properties: {
          path: { type: "string", description: "Path to the file" },
        },
        required: ["path"],
      },
    },
    {
      name: "list_directory",
      description: "List files in a directory",
      inputSchema: {
        type: "object",
        properties: {
          path: { type: "string", description: "Directory path" },
        },
        required: ["path"],
      },
    },
  ],
}));

// Handle tool calls
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const { name, arguments: args } = request.params;

  if (name === "read_file") {
    const filePath = args?.path as string;
    if (!existsSync(filePath)) {
      return { content: [{ type: "text", text: `File not found: ${filePath}` }] };
    }
    const content = readFileSync(filePath, "utf-8");
    return { content: [{ type: "text", text: content }] };
  }

  if (name === "list_directory") {
    const dirPath = args?.path as string;
    const files = readdirSync(dirPath).join("\n");
    return { content: [{ type: "text", text: files }] };
  }

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

// Start server over stdio transport
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
}

main().catch(console.error);

7. Connecting Your MCP Server to Claude Code

Once your server is written, registering it with Claude Code takes under two minutes. Claude Code reads MCP server definitions from ~/.claude/settings.json.

~/.claude/settings.json
{
  "mcpServers": {
    "file-tools": {
      "command": "python",
      "args": ["/absolute/path/to/mcp_server.py"],
      "env": {}
    }
  }
}

For the TypeScript version, replace "python" with "npx" and pass "tsx" plus the path as args:

~/.claude/settings.json (TypeScript variant)
{
  "mcpServers": {
    "file-tools": {
      "command": "npx",
      "args": ["tsx", "/absolute/path/to/src/mcp-server.ts"],
      "env": {}
    }
  }
}

After saving the file, start a new Claude Code session. Claude will discover the server and list the available tools automatically. You can verify it worked by asking: "What MCP tools do you have available?" Claude will list read_file and list_directory.

Use absolute paths

Always use absolute paths in your MCP server configuration. Relative paths can cause the server to fail silently depending on where Claude Code is launched from.

8. Connecting Your Agent to Real Tools: Files, APIs, Databases

The file server above is a foundation. In production, you will want to connect to databases, third-party APIs, and internal systems. Here is how each category works.

Connecting to a REST API

Add an HTTP call inside your tool handler. The example below exposes a get_weather tool that calls an external weather API:

mcp_server.py — API tool example
import httpx

# Inside your call_tool handler:
if name == "get_weather":
    city = arguments["city"]
    api_key = os.environ["WEATHER_API_KEY"]  # from env, never hardcoded
    async with httpx.AsyncClient() as client:
        resp = await client.get(
            f"https://api.weatherapi.com/v1/current.json",
            params={"key": api_key, "q": city}
        )
        data = resp.json()
        result = f"Temp: {data['current']['temp_c']}°C, {data['current']['condition']['text']}"
        return [TextContent(type="text", text=result)]

Connecting to a Database (PostgreSQL)

For database access, install asyncpg and add a query_database tool. Always parameterize queries — never interpolate user input directly into SQL.

mcp_server.py — Database tool example
import asyncpg

DB_URL = os.environ["DATABASE_URL"]

if name == "query_database":
    query = arguments["query"]
    conn = await asyncpg.connect(DB_URL)
    try:
        rows = await conn.fetch(query)
        result = "\n".join([str(dict(row)) for row in rows])
        return [TextContent(type="text", text=result)]
    finally:
        await conn.close()

Security note

Never give an MCP server unrestricted write access to your production database on first setup. Scope permissions to read-only first, then add write tools after you have tested the agent thoroughly in a staging environment.

9. Three Practical MCP Use Cases That Businesses Will Pay For

Building an MCP server is a skill. Knowing which MCP servers to build for clients is the business. Here are three use cases where the ROI is clear enough that a client will write a check.

Use Case 1: The AI Operations Agent

A small business runs its operations across three tools: a CRM (HubSpot), an email platform (Mailchimp), and a spreadsheet for reporting. Every Monday, someone manually copies data between them for two hours.

You build an MCP server with three tools: get_crm_deals, update_email_list, and write_report. The AI agent runs the workflow automatically. The client saves 8 hours per month. At their hourly rate, you can charge $150/month maintenance and they are still ahead. Multiply across 10 clients and you have a business.

Use Case 2: The Internal Knowledge Agent

A company has 200+ internal documents — SOPs, product specs, HR policies — in a shared drive that nobody reads because searching is slow. You build an MCP server with a search_documents tool backed by vector embeddings. Employees ask questions in plain English and get cited answers in seconds. This is a $3,000–$5,000 project with a monthly maintenance retainer.

Use Case 3: The Client Reporting Agent

A marketing agency sends weekly reports to 20 clients. Each report requires pulling data from Google Analytics, Google Ads, and Meta Ads, then formatting it into a PDF. You build an MCP server that connects to all three APIs. The agent generates all 20 reports in under 10 minutes. The agency saves 15 hours per week. This is worth $200–$500/month in recurring revenue per client it serves.

10. MCP in Production: What You Need to Know

Moving from a working dev server to a production MCP deployment requires thinking about four things.

Error handling and resilience

Your tools should never crash the server process. Wrap all tool logic in try/except blocks and return descriptive error messages as TextContent rather than raising exceptions. An agent that gets a clear error message can self-correct; one that crashes gets stuck.

Authentication and secrets

Never hardcode API keys in your MCP server. Always read from environment variables. When running via Claude Code's MCP config, use the "env" field in settings.json to pass secrets:

~/.claude/settings.json — passing secrets safely
{
  "mcpServers": {
    "my-api-server": {
      "command": "python",
      "args": ["/path/to/server.py"],
      "env": {
        "OPENAI_API_KEY": "sk-...",
        "DATABASE_URL": "postgresql://..."
      }
    }
  }
}

Logging and observability

Add structured logging to every tool call. You want to know which tool was called, what arguments it received, and how long it took. This is essential for debugging agents in production where the AI's decision-making is opaque.

Transport for remote deployments

If your MCP server needs to run on a cloud VM rather than locally, switch from stdio to HTTP+SSE transport. The MCP SDK supports this with HttpServerTransport in TypeScript and sse_server in Python. Add authentication headers to prevent unauthorized access.

Want to go deeper on production MCP deployments? The free Module 0 of AgentForge covers the foundational architecture — including how to structure a production agent project from day one — and you can get full access to all 9 modules for a one-time payment.

Build MCP-Powered Agents From Scratch

AgentForge teaches you the full stack: MCP servers, Claude Agent SDK, deployment, and how to sell what you build to real clients. Module 0 is free.

Frequently Asked Questions About MCP Protocol

MCP (Model Context Protocol) is an open standard created by Anthropic that lets AI agents securely connect to external data sources and tools — files, databases, APIs, and more — through a unified interface. Think of it as USB-C for AI: one standard that works everywhere. It separates the concern of what tools exist from how an AI model uses them, making integrations reusable and portable across projects and models.
You can use either. Anthropic provides official MCP SDKs for both Python and TypeScript. Python is slightly faster to prototype with — pip install mcp and you are ready in minutes. TypeScript is the better choice if you are integrating with an existing Node.js stack or want full static typing. Both are covered in detail in this tutorial with complete, working code examples.
Function calling (tool use) is a per-request mechanism: you define tools inline on every API call. MCP is a persistent, reusable protocol: you define tools once in a running server, and any MCP-compatible host (including Claude Code) discovers and uses them across sessions. MCP is designed for production agents where tooling is shared across projects. Function calling is faster for one-off prototypes. For anything you plan to ship to a client or reuse across multiple agents, MCP is the right choice.
Yes. Claude Code has native MCP support built in. You configure MCP servers in your ~/.claude/settings.json file under the "mcpServers" key. When you start a new Claude Code session, it automatically discovers all configured servers, connects to them, and makes their tools available for use in agentic workflows — no manual wiring required. This is one of the most powerful features of Claude Code for building real-world automation agents.
MCP is an open standard. While Anthropic created it and Claude has first-class native support, the spec is fully public and model-agnostic. By 2026, multiple open-source frameworks and third-party AI tools have added MCP compatibility. Learning MCP now means your integrations are not locked to any single model — a meaningful advantage as the AI landscape continues to evolve rapidly.

Continue Learning

AF

AgentForge Team

AgentForge is a hands-on course teaching developers to build, deploy, and monetize AI agents using Claude Code, the Agent SDK, and MCP Protocol. 9 modules, 52 lessons, real code throughout. Module 0 is free.

Disclaimer: Results vary based on individual effort. The use cases and revenue figures mentioned in this article are examples based on market rates for AI automation services as of 2026. They do not represent guarantees of income. Building and selling AI agents requires learning, practice, and business development effort.