AI

CCA-F Study Day 8/20: MCP Architecture & Protocol

Domain 2: Tool Design & MCP Integration (~18-20% of exam)


πŸ“Œ Today's Focus

Today we dive into the Model Context Protocol (MCP) β€” the open standard that Anthropic created for connecting AI models to external tools and data sources. Think of it as "USB-C for AI." The exam tests your understanding of MCP's architectureprotocol layersthree core primitives, and lifecycle. This is a highly testable topic because the architecture has clean, distinct layers that lend themselves perfectly to multiple-choice distractor questions.

After yesterday's structured error responses, you know how tool results should be formatted. Today you'll learn the standardized protocol through which those tools are discovered, connected, and invoked at scale.


🧠 Core Concepts

1. What MCP Is (and Isn't)

MCP = Model Context Protocol β€” an open standard (originally open-sourced by Anthropic in November 2024, now governed by the Linux Foundation's Agentic AI Foundation) that defines how AI applications connect to external tools, data sources, and services.

The USB-C Analogy: Before MCP, every AI model Γ— tool combination needed custom integration code (NΓ—M problem). MCP provides one universal interface β€” build one MCP server and it works with any MCP-compatible client (Claude, Cursor, VS Code, etc.).

What MCP is NOT:

  • ❌ NOT a replacement for the Messages API or tool_use β€” it's a layer on top
  • ❌ NOT specific to Claude β€” it's model-agnostic (OpenAI, Google, Microsoft all support it)
  • ❌ NOT a cloud service β€” it's a protocol specification (like HTTP or LSP)

2. The Three-Layer Architecture

This is the most exam-testable concept today. MCP has three distinct architectural roles:


β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           MCP HOST                       β”‚
β”‚    (Claude Code, Claude Desktop,         β”‚
β”‚     your AI application)                 β”‚
β”‚                                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”‚
β”‚  β”‚MCP Clientβ”‚    β”‚MCP Clientβ”‚           β”‚
β”‚  β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                β”‚
    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
    β”‚MCP Serverβ”‚    β”‚MCP Serverβ”‚
    β”‚(Local)   β”‚    β”‚(Remote)  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Role What It Does Example
Host The AI application that coordinates MCP clients. Manages lifecycle, security, user consent. Claude Code, Claude Desktop, your custom app
Client Maintains a 1:1 connection to a single MCP server. Handles protocol negotiation. Internal component within the Host
Server Exposes tools, resources, and prompts via the MCP protocol. Each server is isolated (own process, own permissions). A GitHub MCP server, a database MCP server, a Slack MCP server

πŸ”‘ Key Exam Point: Each Client connects to exactly ONE Server (1:1 relationship). A Host can manage MULTIPLE Clients. Servers are isolated from each other β€” this is the security boundary.

3. Two Protocol Layers

MCP operates across two layers:

Layer Purpose Implementation
Data/Application Layer JSON-RPC 2.0 protocol β€” lifecycle management, primitives, capabilities negotiation, notifications Defines the "what" β€” what messages look like
Transport Layer How messages physically move between Client and Server STDIO (local) or Streamable HTTP (remote)

Transport Options:

Transport Use Case Communication
STDIO Local servers on same machine stdin/stdout streams (fast, no network)
Streamable HTTP Remote servers over network HTTP POST + Server-Sent Events (SSE)

4. Three Core Primitives

MCP servers expose exactly three types of things. This is critical to memorize:

Primitive Purpose Discovery Execution Analogy
Tools Executable functions the AI can invoke tools/list tools/call POST endpoints (actions)
Resources Data sources providing contextual information resources/list resources/read GET endpoints (data)
Prompts Reusable interaction templates prompts/list prompts/get Templates/macros

πŸ”‘ Key Distinctions (exam loves these):

  • Tools = things the AI does (side effects, actions, mutations)
  • Resources = things the AI reads (data, context, no side effects)
  • Prompts = pre-built interaction patterns (templates the user/system invokes)

5. MCP Lifecycle (Initialize β†’ Operate β†’ Shutdown)

The lifecycle follows a strict 5-step sequence:

  1. Initialize β€” Client sends initialize request with its capabilities and protocol version
  2. Capability Negotiation β€” Server responds with its capabilities (which primitives it supports)
  3. Initialized Notification β€” Client signals it's ready for normal operation
  4. Normal Operation β€” Tool discovery (tools/list), tool execution (tools/call), resource access
  5. Shutdown β€” Graceful connection termination
// Initialize Request (JSON-RPC 2.0)
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": { "elicitation": {} },
    "clientInfo": { "name": "example-client", "version": "1.0.0" }
  }
}

// Server Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": { "subscribe": true }
    },
    "serverInfo": { "name": "github-server", "version": "2.0.0" }
  }
}

6. MCP in Claude Code

In practice, you configure MCP servers in Claude Code like this:

# Add an MCP server to Claude Code
claude mcp add playwright -- npx @anthropic/mcp-playwright

# MCP tool naming convention:
# Pattern: mcp__<server_name>__<action>
# Example: mcp__playwright__browser_screenshot
# Example: mcp__github__create_pull_request

The naming convention mcp__<server>__<action> lets you instantly identify which server owns which tool β€” critical when an agent has access to multiple MCP servers.

7. Tool Search for Scale

When you have many MCP servers with many tools (10,000+ servers exist in public directories), you don't want to preload all tools into context. ToolSearch dynamically finds and loads tools on-demand based on the current task β€” preventing tool overload (remember Day 6: keep to 4-5 tools per agent).


⚠️ Anti-Patterns & Exam Traps

❌ Wrong Answer (Anti-Pattern) βœ… Correct Answer Why It's Wrong
"MCP Host connects directly to MCP Server" Host manages Clients; Clientsconnect to Servers (1:1) The Client is the protocol intermediary β€” the Host never bypasses it
"MCP uses REST/HTTP APIs" MCP uses JSON-RPC 2.0 over STDIO or Streamable HTTP It's not REST β€” it's a bidirectional RPC protocol
"Tools and Resources are the same thing" Tools = actions (side effects); Resources = data (read-only) Confusing these is a classic exam trap
"MCP servers share state with each other" Each server is isolated β€” own process, own permissions Isolation is a core security feature
"Load all available MCP tools into context" Use ToolSearch for dynamic discovery; keep 4-5 tools active per agent Overloading tools degrades selection accuracy
"MCP requires the Claude API" MCP is model-agnostic β€” works with any compatible client It's an open standard, not Claude-specific
"The Host handles protocol negotiation" The Client handles protocol negotiation with the Server The Host manages Clients, but Clients do the protocol work

πŸ’» Code Examples

Example 1: Simple MCP Server (Python SDK)

from mcp.server import Server
from mcp.types import Tool, TextContent

# Create an MCP server
server = Server("weather-server")

@server.list_tools()
async def list_tools():
    return [
        Tool(
            name="get_weather",
            description="Get current weather for a city. Returns temperature, conditions, and humidity.",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "City name (e.g., 'Seattle')"},
                    "units": {"type": "string", "enum": ["celsius", "fahrenheit"], "default": "fahrenheit"}
                },
                "required": ["city"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get_weather":
        city = arguments["city"]
        # In production, call a real weather API
        return [TextContent(
            type="text",
            text=f'{{"city": "{city}", "temp": 72, "conditions": "sunny", "humidity": 45}}'
        )]
    raise ValueError(f"Unknown tool: {name}")

# Run with STDIO transport (local)
if __name__ == "__main__":
    import asyncio
    from mcp.server.stdio import stdio_server
    asyncio.run(stdio_server(server))

Example 2: MCP Client Connection

from mcp.client import ClientSession
from mcp.client.stdio import stdio_client

async def connect_to_server():
    # Connect to local MCP server via STDIO
    async with stdio_client("python", "weather_server.py") as (read, write):
        async with ClientSession(read, write) as session:
            # Step 1: Initialize (capability negotiation)
            await session.initialize()
            
            # Step 2: Discover available tools
            tools = await session.list_tools()
            print(f"Available tools: {[t.name for t in tools]}")
            
            # Step 3: Call a tool
            result = await session.call_tool(
                "get_weather", 
                {"city": "Seattle", "units": "fahrenheit"}
            )
            print(f"Result: {result}")

Example 3: MCP Configuration in Claude Code

# .claude/mcp_servers.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@anthropic/mcp-github"],
      "env": {
        "GITHUB_TOKEN": "${GITHUB_TOKEN}"
      }
    },
    "postgres": {
      "command": "npx",  
      "args": ["-y", "@anthropic/mcp-postgres"],
      "env": {
        "DATABASE_URL": "${DATABASE_URL}"
      }
    },
    "remote-api": {
      "url": "https://api.example.com/mcp",
      "transport": "streamable-http"
    }
  }
}

🎬 Video to Watch

"Building Agents with Model Context Protocol - Full Workshop with Mahesh Murag of Anthropic" (AI Engineer Summit)

πŸ”— Search YouTube for: "Building Agents with Model Context Protocol Full Workshop Mahesh Murag Anthropic" (~1.5 hours, AI Engineer channel)

Mahesh Murag is on Anthropic's Applied AI team and directly developed MCP. This workshop covers:

  • 00:00 – 09:39 β€” What is MCP? (philosophy, motivation, the NΓ—M problem) ← most relevant for today
  • 09:39 – 26:25 β€” Building with MCP (practical implementation) ← watch this for hands-on context
  • 26:25 – 1:13:15 β€” MCP & Agents (patterns for agent integration)
  • 1:13:15+ β€” What's next for MCP? (roadmap, remote servers, registry)

Priority sections for today: the first 26 minutes cover architecture and building β€” exactly what the exam tests.


πŸ“– Reading


πŸ› οΈ Hands-On Exercise (20-30 minutes)

Draw the MCP Architecture from Memory

  1. On a blank sheet of paper (or whiteboard), draw the complete MCP architecture: 
    • Label Host, Client(s), Server(s)
    • Show the 1:1 Client↔Server relationship
    • Show the 1:many Host↔Client relationship
    • Label both protocol layers (Data/JSON-RPC + Transport/STDIO or HTTP)
  2. Next to each Server, list the three primitives (Tools, Resources, Prompts) with their discovery + execution methods
  3. Write out the 5-step lifecycle in order
  4. Finally: write one MCP tool name using the Claude Code naming convention (mcp__server__action)

If you can do all 4 from memory, you own this material.


πŸ“ Quick Quiz

Q1. In MCP architecture, which component maintains a direct 1:1 connection with an MCP Server?

A) The MCP Host B) The MCP Client C) The AI Model D) The Transport Layer

Q2. A developer needs to expose a read-only data feed (e.g., latest stock prices) to an AI agent via MCP. Which MCP primitive should they use?

A) Tools β€” because the agent needs to fetch the data B) Resources β€” because it's read-only contextual data C) Prompts β€” because it's a structured interaction D) Tools β€” with a readOnlyHint annotation

Q3. During MCP initialization, what does the Server's response to the initialize request communicate?

A) The list of all available tools and their schemas B) The Server's capabilities (which primitives it supports) C) Authentication credentials for the Client D) The full conversation history for context


Answers

Q1: B β€” The MCP Client maintains the 1:1 connection with a Server. The Host manages multiple Clients but doesn't connect to Servers directly.

Q2: B β€” Resources are for read-only data that provides context. Tools are for actions with side effects. Even though "fetching" data sounds like a tool, the key distinction is: no side effects = Resource.

Q3: B β€” Initialization is about capability negotiation, not tool discovery. The Server declares which primitives it supports (tools, resources, prompts) and what features are available. Tool listing happens during Normal Operation (step 4), not initialization.


πŸ‘€ Tomorrow's Preview

Day 9: Built-in Tools & Tool Distribution β€” You'll learn Claude's native built-in tools (Read, Write, Bash, Grep, Glob), how to distribute tools across agents for optimal selection, and the parallel vs. sequential execution rules. This completes Domain 2.