AI Learning Hub
advanced

Model Context Protocol (MCP)

An open standard that lets any AI client connect to any tool or data source through a uniform interface. "USB-C for AI tools."

What MCP actually does

The Model Context Protocol is a standard way for AI apps to plug into tools and data sources. Without it, every app — Claude Desktop, Cursor, ChatGPT — rebuilds its own integrations to Postgres, GitHub, Slack, your filesystem, every internal service. With it, you build the integration once as an MCP server, and every MCP-aware client can use it.

The model is still doing tool calling under the hood. MCP doesn't replace that — it standardises the cable between the AI app and whatever the tool is. Anthropic open-sourced it in late 2024; OpenAI, Google, and most of the ecosystem have adopted it.

That's the whole concept. Below: the three primitives MCP defines (tools, resources, prompts), what differs from raw tool calling, and what an MCP server looks like in code.

When you'd reach for it

MCP earns its keep when you want AI to reach beyond the prompt:

  • Connecting Claude Desktop or Cursor to your filesystem, databases, or internal services without writing client-specific glue.
  • Letting non-developers add tools — a single MCP server config gets shared across users.
  • Building a tool surface once for an internal app and exposing it across multiple AI products.
  • Adopting community servers (Postgres, GitHub, Linear, Slack) instead of writing your own.

You wouldn't reach for MCP when you're building a self-contained app where the model only needs functions you've already wired into your own backend — raw tool calling is simpler.

How it's actually built

Without MCP, every AI app reinvents tool integration. With MCP, there's a standard protocol between clients (the AI app) and servers (the tool/data provider):

MCP is the cable: any client speaks to any server through one shared protocol.

Anthropic open-sourced MCP in late 2024; OpenAI, Google, and the broader ecosystem have since adopted it.

How MCP differs from raw tool calling

Raw tool callingMCP
Tools defined per-app, per-callTools live in independent servers; clients discover them
Each integration is bespokeEach MCP server is reusable across all MCP clients
No standard for resources or promptsResources and prompts are first-class
Authentication is your problemOAuth flow is part of the spec

Plus protocol-level features: tool listing, capability negotiation, streaming, structured errors. Anthropic open-sourced MCP in late 2024; OpenAI, Google, and the broader ecosystem have since adopted it.

Where it bites in real life

Under the hood (optional)

Two examples of what an MCP server looks like in code: a trivial weather server (~10 lines) and a more realistic read-only Postgres server (~20 lines). Skip if you don't code — what matters is that one server file exposes tools to any MCP-aware client.

Show example code (Python + JSON, ~40 lines across two examples)click to expand

A minimal Python MCP server:

from mcp.server.fastmcp import FastMCP
 
mcp = FastMCP("weather")
 
@mcp.tool()
def get_weather(city: str) -> dict:
    """Get current weather for a city."""
    return {"city": city, "temp_c": 14, "condition": "rain"}
 
if __name__ == "__main__":
    mcp.run()

Add this to Claude Desktop's config:

{
  "mcpServers": {
    "weather": { "command": "python", "args": ["/path/to/server.py"] }
  }
}

Restart Claude. The get_weather tool is available with full schema discovery.

A read-only Postgres MCP server (more realistic):

from mcp.server.fastmcp import FastMCP
import psycopg
 
mcp = FastMCP("postgres-readonly")
conn = psycopg.connect(os.environ["DATABASE_URL"])
 
@mcp.tool()
def query(sql: str) -> list[dict]:
    """Run a read-only SQL query against the production database. SELECT only."""
    if not sql.strip().lower().startswith("select"):
        raise ValueError("Only SELECT statements are allowed")
    with conn.cursor(row_factory=psycopg.rows.dict_row) as cur:
        cur.execute(sql)
        return cur.fetchall()
 
@mcp.resource("schema://tables")
def schema() -> str:
    with conn.cursor() as cur:
        cur.execute("SELECT table_name FROM information_schema.tables WHERE table_schema='public'")
        return "\n".join(r[0] for r in cur.fetchall())

Now any MCP-aware client can ask "what tables exist?" (resource) and "select all users created today" (tool).

Check your understanding

  1. 1. What problem does MCP primarily solve?
  2. 2. Which is NOT one of MCP's three primitives?
  3. 3. How does MCP relate to raw tool calling?

Found this useful? Share it with someone learning AI.

Further reading

Related lessons in this track