📖 Lecture — Agents, ReAct, and the Model Context Protocol

For nine weeks you've been assembling the pieces of a production AI system: containers, cloud deployment, CI/CD, inference serving, fine-tuning, and RAG. This week those pieces gain a new capability — the ability to act. Instead of a model that only answers questions, you'll give your capstone an agent that can decide, on its own, which tool to call, when to call it, and what to do with the result. That's a meaningful jump in both power and risk, so we'll cover the mental model, the protocol that standardizes tool access, and the guardrails that keep it safe. From chatbot to agent. An LLM agent uses the model as a reasoning and planning engine rather than just a text generator. The core loop looks like this: Goal → Perception → Reasoning → Planning → Action → Observation → Memory update → repeat The agent starts with a goal (e.g., "find the customer's order status"). It perceives its environment (the user's message, any prior context). It reasons about what it knows and doesn't know. It plans a next step. It acts — usually by calling a tool. It observes the result. It updates its memory/state. Then it loops again, deciding whether it has enough information to answer or needs another action. This loop is what separates an agent from a single-shot prompt: the model is making a sequence of autonomous decisions, not just producing one output. ReAct: reasoning and acting, out loud. A naive agent implementation might ask the model to silently pick a tool and return only the result. The ReAct pattern (Reasoning + Acting) instead has the agent alternate explicit "Thought" steps with concrete "Action" steps, visible in the transcript:

Step type What it contains Why it matters
Thought The model's stated reasoning about what it knows and what to do next Makes the agent's decision-making inspectable and debuggable
Action A specific tool call with parameters Grounds the agent's intent in a concrete, checkable operation
Observation The real result returned by the tool Feeds ground truth back into the next reasoning step

Because ReAct plans one step at a time instead of committing to a fixed upfront plan, it's more robust when a tool call fails, returns unexpected data, or reveals that the original plan was wrong — the agent re-reasons at every step rather than blindly executing a script. When you build your capstone's agent, log the full Thought/Action/Observation trace; it's the single best debugging tool you'll have when the agent misbehaves. The N × M problem and why MCP exists. Before the Model Context Protocol (introduced by Anthropic on November 25, 2024), connecting N different AI applications to M different tools/data sources meant writing roughly N×M custom integrations — every model-to-tool pairing needed its own glue code. MCP is an open standard that collapses this to N+M: a data or tool provider builds one MCP server that exposes its capabilities in a standard way, and any MCP-compatible AI application acts as an MCP client that can talk to any MCP server. Communication runs over JSON-RPC 2.0, and servers expose capabilities through three primitives:

Primitive What it is Capstone example
Tools Callable functions the model can invoke to take action get_order_status(order_id), run_query(sql)
Resources Read-only data the client can attach as context A file, a database schema, a document
Prompts Reusable, parameterized prompt templates the server offers A "summarize this ticket" template

Building and testing a server. The Python SDK (FastMCP) lets you turn an ordinary function into an MCP tool with a single @mcp.tool() decorator, then run the server over stdio transport so any MCP host can launch and talk to it as a subprocess. Critically, you don't have to wire it into a full agent to test it — the standalone MCP Inspector (npx @modelcontextprotocol/inspector) connects directly to your server, lists its tools/resources/prompts, and lets you invoke them by hand. Get the server working and verified in the Inspector before you connect it to a real agent; it isolates protocol/server bugs from agent-reasoning bugs. Agentic RAG. Plain RAG is a fixed pipeline: retrieve, then generate. LangGraph (now stable at v1.0) supports stateful, cyclic agent workflows, which lets you build Agentic RAG — a loop where the agent decides at each step whether to retrieve, re-query with a refined question, or answer directly. This is a direct application of the agent loop above: the retrieval step becomes just another tool the agent chooses to call, as many times as needed. Correcting three misconceptions.

  1. "The agent will just do the right thing." It won't, reliably. Agents hallucinate tool names and parameters, call the wrong tool, and can believe a step succeeded when it silently failed. Treat every tool result as untrusted input: validate it, and require explicit confirmation before any consequential action (deleting data, sending money, modifying production state).
  2. "More MCP servers connected means more capability, with no downside." Every tool definition and every tool result consumes tokens. Connect five MCP servers with ten tools each and you may burn a large share of your context budget on tool schemas before the agent has even seen the user's question. Expose only the tools your capstone actually needs, and scope each tool narrowly.
  3. "MCP is a safe, closed protocol because Anthropic built it." It is an open protocol, and its openness is the point — but that means anyone can write a malicious or careless MCP server. Documented risks include malicious code execution, credential theft, and weak/absent authentication on servers. Scope permissions tightly, sandbox tool execution, and never point a general-purpose agent at an MCP server you haven't reviewed.

By the end of this week, your capstone should have at least one real MCP tool that an agent can call, tested end-to-end, with a guardrail you can point to and explain.