L1
·
Quiz
·
Lab
L2
·
Quiz
·
Lab
L3
·
Quiz
·
Lab
L4
·
Quiz
·
Lab
Module Test
🎯 Advanced · Lesson 1 of 4

MCP Architecture

Understanding the Model Context Protocol — how it standardizes tool communication between AI models and external services.

In November 2024, Anthropic released the Model Context Protocol (MCP) as an open standard, publishing a full specification and reference implementations in Python and TypeScript. Within weeks, companies including Block (formerly Square), Apollo, and Zed had announced integrations. The core problem MCP solved was one that every enterprise AI team had hit independently: every tool integration required custom glue code, and none of it was reusable across models. A filesystem connector built for Claude couldn't be used with GPT-4 without a complete rewrite. MCP changed that by defining a single protocol that any client and any server could implement once.

By Q1 2025, over 1,000 open-source MCP servers had been published on GitHub. The Anthropic-maintained model-context-protocol organization hosted reference servers for filesystem access, Git, databases, web search, and cloud APIs — all interoperable with any compliant MCP host.

What MCP Is and Why It Exists

The Model Context Protocol is a client-server protocol that standardizes how AI models request and receive context from external data sources and tools. Before MCP, every AI application that needed to call a tool — search a database, read a file, call an API — had to implement a bespoke integration. This created what Anthropic called the "M×N problem": M different models times N different tools meant M×N unique integrations to build and maintain.

MCP collapses this to M+N. Any MCP-compliant client (a model host like Claude Desktop, or a custom application) can connect to any MCP-compliant server (a tool provider) without custom code. The protocol defines three core primitives that servers can expose: Tools (callable functions the model can invoke), Resources (data the model can read), and Prompts (pre-defined prompt templates). This separation of concerns is fundamental — a server decides what it exposes; the client decides how to present those capabilities to the model.

Core Insight

MCP is architecturally similar to the Language Server Protocol (LSP) that standardized IDE integrations for programming languages in 2016. LSP eliminated the "every editor needs a plugin for every language" problem. MCP eliminates the equivalent problem for AI tool use. Both protocols succeeded for the same reason: they defined a minimal, transport-agnostic interface that was easy to implement on both sides.

The protocol operates over a transport layer — currently either stdio (standard input/output, for local processes) or HTTP with Server-Sent Events (SSE, for remote services). The transport choice is an implementation detail; the message format and capability negotiation are the same regardless. This design means an MCP server written as a local Python script can be deployed as a remote HTTPS service with only transport-layer changes.

The Three-Layer Architecture

MCP defines three distinct roles in every interaction. Understanding these roles precisely is essential before building anything.

  • MCP Host: The application that contains or manages the AI model. Claude Desktop is the canonical example. The host is responsible for managing connections to one or more MCP servers and deciding how to present server capabilities to the model. The host controls security boundaries — it decides which servers the model can access and what permissions apply.
  • MCP Client: A component within the host that maintains a one-to-one connection with a single MCP server. Each server connection is managed by a dedicated client instance. The client handles the protocol handshake, capability negotiation, and message routing. In the Claude Desktop implementation, the client is embedded in the application; in custom implementations, you build it yourself.
  • MCP Server: A lightweight program that exposes specific capabilities — tools, resources, or prompts — through the MCP protocol. Servers are intentionally scoped: the filesystem server handles file operations; the database server handles queries. This scoping makes servers easier to build, audit, and secure.

The lifecycle of an MCP connection follows a defined sequence: the client initiates a connection and sends an initialize request containing its protocol version and capabilities. The server responds with its own version and the capabilities it supports. After this handshake, the client sends an initialized notification and the connection is live. From this point, the model can request a list of available tools, call those tools with arguments, and receive structured results.

Architecture Note

MCP uses JSON-RPC 2.0 as its message format. Every request has a method name, an optional params object, and an id for correlation. Responses carry either a result or an error. Notifications (messages without an id) are fire-and-forget. If you've worked with JSON-RPC before, the message format will be immediately familiar; MCP's contribution is the specific methods and capability negotiation on top of it.

Tools, Resources, and Prompts in Detail

Each of MCP's three server-side primitives serves a distinct purpose in how the model interacts with the external world.

Tools are the most action-oriented primitive. A tool has a name, a description (which the model reads to decide whether to call it), and a JSON Schema defining its input parameters. When the model calls a tool, the server executes the corresponding logic — running a shell command, querying a database, calling an external API — and returns a result. Tools are the mechanism behind statements like "I'll search the web for that" or "Let me check the current stock price."

Resources represent data that the model can read but not necessarily modify. A resource has a URI (like file:///home/user/notes.txt or postgres://localhost/mydb/tables/users), a MIME type, and content. Resources can be static (a fixed file) or dynamic (a live query result). The host decides which resources to inject into the model's context and when.

Prompts are pre-defined prompt templates that servers can expose. This is less commonly discussed but powerful: a server can define a structured workflow — "analyze this codebase for security issues" or "summarize this document in three bullet points" — that users can invoke by name. Prompts can accept arguments that get interpolated into the template.

🎯 Advanced · Lesson 1 Quiz

MCP Architecture — Quiz

3 questions — free, untracked, retake anytime.

1. What problem does MCP primarily solve in AI tool integration?
✓ Correct — ✓ Correct. MCP collapses M×N custom integrations to M+N by defining a single protocol any client and server can implement once.
Not quite. MCP's core value is eliminating redundant integration work — any compliant client can connect to any compliant server without custom glue code.
2. Which MCP primitive represents data the model can read but not necessarily modify?
✓ Correct — ✓ Correct. Resources have a URI, MIME type, and content — they represent readable data like files or database query results.
Not quite. Resources are the read-oriented primitive. Tools are for callable actions; Prompts are pre-defined templates.
3. What message format does MCP use for all communication?
✓ Correct — ✓ Correct. MCP uses JSON-RPC 2.0 — every request has a method, optional params, and an id for correlation.
Not quite. MCP uses JSON-RPC 2.0 as its message format, regardless of whether the underlying transport is stdio or HTTP+SSE.
🎯 Advanced · Lesson 1 Lab

MCP Architecture Lab

Explore MCP's three-layer architecture and primitive types with a live AI tutor.

Lab: Mapping MCP Architecture

In this lab you'll work through concrete architectural questions about MCP. The AI tutor will open with a design scenario — respond with your analysis, then continue the conversation to deepen your understanding.

  1. Read the tutor's opening scenario carefully and identify which MCP roles and primitives are involved.
  2. Ask follow-up questions about transport layer choices, capability negotiation, or the JSON-RPC message structure.
  3. Challenge the tutor to describe what an initialize request and response look like in practice.
Try: "Walk me through the full lifecycle of an MCP connection from the first byte to the first tool call."
🤖 MCP Architecture Tutor Advanced · L1
🎯 Advanced · Lesson 2 of 4

Setting Up MCP

Installing, configuring, and connecting MCP servers to Claude Desktop and custom hosts — from first install to verified tool call.

In early 2025, the engineering team at Sourcegraph documented their MCP integration publicly. They connected their Cody AI assistant to an MCP server exposing code search and repository navigation tools. The setup took one afternoon: they wrote a server in TypeScript using the official MCP SDK, registered it in Claude Desktop's claude_desktop_config.json, and immediately had a working integration. Their blog post noted that the same server configuration worked without modification when they later wired it into their own custom host application — exactly the portability MCP was designed to deliver.

The contrast with their previous approach was stark: their prior Cody tool integration required about 800 lines of bespoke adapter code per model provider. The MCP server was 200 lines total and connected to four different host applications.

Installing the MCP SDK and Dev Environment

Anthropic maintains official MCP SDKs for Python and TypeScript. Both are available on their respective package registries and follow the same API conventions. For Python: pip install mcp. For TypeScript/Node: npm install @modelcontextprotocol/sdk. The minimum viable development environment is a Python 3.10+ or Node 18+ installation, the SDK, and Claude Desktop (for testing via stdio transport).

Development Tip

The MCP Inspector — available via npx @modelcontextprotocol/inspector — is the fastest way to debug a server without involving a full host application. It provides a web UI where you can directly call tools, list resources, and inspect the raw JSON-RPC messages in both directions. Use it before you ever open Claude Desktop.

The Python SDK uses a decorator-based API that makes tool registration concise. A minimal server that exposes one tool looks like this conceptually: import FastMCP, instantiate it with a name, decorate a function with @mcp.tool(), and call mcp.run(). FastMCP (now part of the official SDK) infers the tool's JSON Schema from the function's type annotations — you don't write schemas by hand for basic cases.

Configuring Claude Desktop as an MCP Host

Claude Desktop reads MCP server configurations from a JSON file at a platform-specific location. On macOS this is ~/Library/Application Support/Claude/claude_desktop_config.json; on Windows it is %APPDATA%\Claude\claude_desktop_config.json. The configuration structure is straightforward: a top-level mcpServers object where each key is the server's display name and each value contains the command to launch it.

A typical entry for a Python server named "my-tools" running via uv (the fast Python package manager) looks like: {"command": "uv", "args": ["run", "my_server.py"]}. For a Node server: {"command": "node", "args": ["/absolute/path/to/server.js"]}. Restart Claude Desktop after editing the config file. In the Claude Desktop UI, click the hammer icon (🔨) to verify the server connected and its tools are listed.

Common Pitfall

Claude Desktop launches servers using the system PATH at the time it starts — not the PATH in your terminal session. If your server depends on a virtual environment or a locally-installed tool, use absolute paths in the config and specify the full path to the Python or Node executable. This is the most common cause of "server failed to start" errors in first-time setups.

Environment variables can be passed to server processes via an env object in the server config. This is the standard way to pass API keys and database credentials. Never hardcode secrets in your server source code — put them in the Claude Desktop config's env section for local development, and use proper secrets management for production deployments.

Verifying the Connection and Testing Tools

After connecting a server, there are three verification steps practitioners use. First, check the Claude Desktop logs — on macOS, these are at ~/Library/Logs/Claude/mcp*.log. Each server gets its own log file. Look for the initialized notification in the log to confirm the handshake completed.

Second, open a conversation in Claude Desktop and ask Claude what tools it has available. Claude will list the tools from all connected servers by name and description. If your tool appears, the connection is working. Third, ask Claude to call the tool with a simple input and observe the result. This end-to-end test confirms the tool's execution logic is reachable from the model.

  • Log location (macOS): ~/Library/Logs/Claude/mcp-server-{name}.log
  • Log location (Windows): %APPDATA%\Claude\logs\mcp-server-{name}.log
  • Inspector: Run npx @modelcontextprotocol/inspector python my_server.py for real-time message inspection
  • Health check: Add a simple ping tool that returns "pong" — the fastest way to confirm end-to-end connectivity during development
🎯 Advanced · Lesson 2 Quiz

Setting Up MCP — Quiz

3 questions — free, untracked, retake anytime.

1. Where does Claude Desktop read its MCP server configurations on macOS?
✓ Correct — ✓ Correct. Claude Desktop reads its MCP server configuration from that path on macOS. On Windows it's in %APPDATA%\Claude\.
Not quite. On macOS, the config is at ~/Library/Application Support/Claude/claude_desktop_config.json.
2. What is the MCP Inspector primarily used for?
✓ Correct — ✓ Correct. The MCP Inspector provides a web UI to call tools, list resources, and see raw JSON-RPC traffic — essential for debugging before involving a full host.
Not quite. The Inspector is a development debugging tool that lets you interact with a server directly and inspect all JSON-RPC messages.
3. What is the most common cause of "server failed to start" errors in Claude Desktop MCP setups?
✓ Correct — ✓ Correct. Claude Desktop launches servers using the system PATH, not your terminal's PATH. Using absolute paths in the config fixes this.
Not quite. The most common issue is that Claude Desktop can't find the Python or Node executable because it uses the system PATH, not your shell's PATH.
🎯 Advanced · Lesson 2 Lab

MCP Setup Lab

Walk through a real MCP server setup with a tutor that knows every config detail.

Lab: Configuring Your First MCP Server

In this lab the tutor will immediately present a realistic setup scenario — a partially broken MCP configuration — and guide you through diagnosing it. Use this to internalize the debugging workflow.

  1. Read the tutor's scenario and identify what's wrong with the configuration.
  2. Ask the tutor to show you what the corrected config and log output should look like.
  3. Explore edge cases: what happens if the server crashes mid-conversation? How does Claude Desktop recover?
Try: "Show me a minimal working claude_desktop_config.json for a Python MCP server that needs a POSTGRES_URL environment variable."
🔧 MCP Setup Tutor Advanced · L2
🎯 Advanced · Lesson 3 of 4

Building MCP Tools

Writing production-quality MCP tools — schema design, error handling, input validation, and building tools the model can actually use reliably.

In March 2025, the team behind the open-source MCP server mcp-server-kubernetes published a retrospective on their tool design decisions. Their initial implementation returned raw Kubernetes API responses — complete JSON objects with dozens of fields. Claude would reliably use the tools but produce responses that were too verbose because the model was processing unnecessary data. They rewrote the tool responses to return only the fields relevant to the operation (pod name, status, restart count, node) and documented that token-efficient tool responses directly improved the quality of the model's reasoning about Kubernetes state. The lesson they highlighted: tool output is part of the model's context window; every byte matters.

Designing Tool Schemas That Models Use Correctly

A tool's JSON Schema definition does double duty: it tells the MCP client what parameters are valid (for validation), and it tells the model what parameters are available and what they mean (for decision-making). Writing good schemas is the single highest-leverage activity in MCP tool development, because a well-described tool gets called correctly and a poorly-described one gets called wrong.

The description field on the tool itself should answer: when should I call this? Be specific about preconditions and side effects. "Reads the contents of a file" is good. "Use this tool when you need to read a file" is worse (circular). "Reads the text content of a local file at the given absolute path. Returns an error if the file does not exist or is binary." is better — it specifies the input type, the failure modes, and the output type.

Schema Design Rule

Each parameter's description field in your JSON Schema is read by the model. Include the expected format, units, valid ranges, and any constraints. For a date parameter, write "ISO 8601 date string, e.g. 2024-03-15" not just "a date". The model will produce correctly-formatted arguments more reliably when the description is precise.

Use enum constraints wherever possible. If a parameter only accepts "read", "write", or "append", define it as an enum — not a free-form string with examples. Enums constrain the model's output space and eliminate an entire class of invalid tool calls. Similarly, use minimum/maximum for numeric ranges and pattern for string formats like UUIDs or file extensions.

Error Handling and Return Values

MCP tools can return two types of results: a successful content array, or a tool error. The distinction matters for how the model handles the response. A successful result with an error message embedded in the text is ambiguous — the model may not recognize it as an error. A proper tool error (setting isError: true in the response) signals clearly that the tool call failed and the model should reason about why and potentially retry with different arguments or take a different approach.

There are three categories of errors to handle explicitly. First, expected errors: a file doesn't exist, a query returns no results, an API rate limit is hit. These should be returned as tool errors with a specific, actionable message. Second, validation errors: the model passed an argument with the wrong type or an out-of-range value. Return these as tool errors immediately, before any side effects occur. Third, unexpected errors: crashes, network failures, unhandled exceptions. Catch these at the top level of your tool handler and return a sanitized error message — never let the raw exception propagate to the protocol layer.

  • Content types: Tools return content arrays with items of type text, image, or resource
  • Text responses: Prefer structured text (JSON or Markdown) over raw prose for data the model needs to parse
  • Image responses: Return base64-encoded image data with a MIME type for visual content
  • Error flag: Set isError: true at the response level, not just in the text content
Production Pattern

In Python with the official MCP SDK, wrap your tool handler body in a try/except. On success, return [TextContent(type="text", text=result)]. On a known error, raise McpError with an appropriate error code. On an unexpected exception, log it server-side and return a generic error to the model — don't expose internal stack traces or sensitive configuration details in tool error messages.

Input Validation and Security Boundaries

MCP servers are trusted components that execute with real system privileges — they can write files, query databases, call external APIs. This means input validation is a security requirement, not just good practice. Treat every tool call argument as untrusted input, even though it comes from the model. The model's arguments can be influenced by adversarial content in the data the model was given — a technique called prompt injection. A malicious document could instruct the model to call a tool with arguments like ../../../etc/passwd or ; rm -rf /.

The standard defensive patterns apply: validate and sanitize all path arguments (resolve and confirm they're within allowed directories), use parameterized queries for all database operations (never string-interpolate model-provided values into SQL), and apply allowlists rather than blocklists for permitted operations. The Anthropic documentation explicitly warns about prompt injection in MCP server design — it's a first-class concern, not an edge case.

For filesystem tools specifically: resolve the absolute path of any user-provided path argument and confirm it is a child of an explicitly permitted base directory before any file operation. For shell execution tools: avoid them entirely if possible; if you must have them, use a subprocess with a fixed command template and only allow model-controlled values for a small set of pre-validated arguments.

Lesson 3 Quiz

Test your understanding of Lesson 3
What is the central theme of Lesson 3 in this module?
✓ Correct — Correct.
Review Lesson 3 for the core concepts.
Why is practical application important alongside theoretical understanding?
✓ Correct — Correct. Practice reveals complexities beyond theoretical models.
Theory and practice complement each other — practice reveals real-world constraints.
What distinguishes effective practitioners in this field?
✓ Correct — Correct.
Critical thinking matters more than tools or experience alone.
🎯 Advanced · Lesson 3 Lab

Lab: Explore Lesson 3 Concepts

Apply what you learned in Lesson 3 through guided AI conversation

Your Task

Use the AI below to explore Lesson 3 concepts in depth. Challenge assumptions and work through scenarios.

Try asking about a specific concept from Lesson 3 and how it applies in practice.
🤖 AESOP Lab Assistant Lesson 3 Lab
Building AI Agents III — Tools · Module 6 · Lesson 4

L4: MCP-Compatible Agents

Advanced concepts, real-world applications, and practical implications
Core Concepts

This lesson explores l4: mcp-compatible agents — examining the key principles, real-world applications, and implications for practitioners working in this domain.

Understanding this topic requires both theoretical grounding and practical awareness of how these concepts manifest in deployed systems. The frameworks covered in earlier lessons provide the foundation; this lesson connects them to implementation reality.

Practical Applications

The transition from theory to practice reveals challenges that pure conceptual frameworks don't capture. Real-world deployment introduces constraints, trade-offs, and edge cases that demand nuanced judgment rather than rigid rule-following.

Effective practitioners in this space develop the ability to reason across multiple frameworks simultaneously, recognizing when different perspectives apply and how to resolve conflicts between competing priorities.

Looking Forward

As this field continues to evolve, the principles covered in this module will remain foundational even as specific technologies and implementations change. The ability to think critically about these topics — rather than simply memorizing current best practices — is what separates effective practitioners from those who merely follow checklists.

Lesson 4 Quiz

L4: MCP-Compatible Agents
What is the primary focus of L4: MCP-Compatible Agents?
✓ Correct — Correct. This lesson bridges theory and practice, focusing on real-world implementation.
Review the lesson — the focus is on connecting frameworks to practical reality.
Why does real-world deployment introduce challenges that pure theory doesn't capture?
✓ Correct — Correct. Real deployment requires judgment, not just framework application.
Practice doesn't invalidate theory — it reveals complexities that require nuanced application of theoretical principles.
What separates effective practitioners from those who merely follow checklists?
✓ Correct — Correct. Critical thinking and adaptability matter more than memorized procedures.
The key differentiator is critical thinking ability, not experience or resources alone.
🎯 Advanced · Lesson 4 Lab

Lab: Apply What You've Learned

Synthesize concepts from L4: MCP-Compatible Agents through guided AI conversation

Your Task

Use the AI below to explore the concepts from Lesson 4 in depth. Ask questions, challenge assumptions, and work through practical scenarios related to l4: mcp-compatible agents.

Try: "How would the concepts from this lesson apply to a real-world scenario in this field?"
🤖 AESOP Lab Assistant Lesson 4 Lab

Module 6 Test

MCP Integration · 15 Questions · 70% to Pass
Score: 0/15
1. What is the core objective of MCP Integration?
2. How should practitioners approach applying concepts from this module?
3. Which best describes the relationship between theory and practice in Building AI Agents III — Tools?
4. What distinguishes expert practitioners from novices in this field?
5. How does MCP Integration build on previous modules?
6. What role do constraints play in practical implementation?
7. When applying frameworks from this module, what is most important?
8. How should practitioners handle conflicting perspectives in this field?
9. What makes the concepts in MCP Integration relevant beyond their immediate context?
10. How should practitioners continue developing expertise after completing this module?
11. What is the relationship between understanding Building AI Agents III — Tools concepts and making decisions?
12. How do the lessons from this module apply to novel situations?
13. What is the value of understanding multiple perspectives on {course_title}?
14. How should practitioners evaluate new information or developments in this field?
15. What is the ultimate goal of learning MCP Integration?