In this first lesson, we start by getting students to load the agent code and take a look in their IDE. In our github folder we share a new folder "research_agent" with its code. In the first lesson of part 2B, students should clone that repo to see the structure of the full project, which is also explained in this lesson. We tell the user they will follow along to lessons in this part of the cours by  simply running isolated step of the workflow as requested for each lesson - Step one for the first lesson, step 2 for the second lesson, etc. We will also provide notebooks for students to test tweaking of specific parts of the code that we teach in each lesson. 

Following the intro to the full project We will lay the groundwork for our entire research agent by introducing the core concepts of the Model Context Protocol (MCP). We'll explore the roles of an MCP server, which exposes data and functionality, and an MCP client, the LLM application that consumes them. 

Focus on why we chose to use MCP in our agent system.

Explains the purpose and structure of Anthropic's Model Context Protocol (MCP) as an open standard for LLM-application interaction. Details its core primitives (Resources, Tools, Prompts) and communication flow (JSON-RPC). Discusses how MCP aims to standardize tool use and context management. Talk about MCP tools, MCP resources, and MCP prompts (in the research agent MCP server we mainly have MCP tools and an MCP prompt to setup the agentic workflow, and it also has a few MCP resources just for showing how to use them, even though they are not really used in the research workflow). Make sure to explain the use case of MCP prompts ([this video](https://www.youtube.com/watch?v=mKEq_YaJjPI) helped me understand it).

[https://seldonia.notion.site/Extending-LLM-Capabilities-with-Anthropic-s-Model-Context-Protocol-MCP-1d0f9b6f427080979515ec8c825622db?pvs=74](https://www.notion.so/Extending-LLM-Capabilities-with-Anthropic-s-Model-Context-Protocol-MCP-1d0f9b6f427080979515ec8c825622db?pvs=21)

https://decodingml.substack.com/p/why-mcp-breaks-old-enterprise-ai

**In-depth system design of the research agent** (system design of both agents in L14)**.** As a hands-on example of how to apply MCP to a concrete example, go in-depth into the research agent system design architecture built with MCP, along with expected inputs, outputs, components, etc.

[Refer to this doc for more on layering the system design teaching across multiple lessons.](https://www.notion.so/Plan-of-attack-for-the-system-design-syllabus-structure-and-storytelling-25df9b6f4270806e823dc3ff728281d7?pvs=21)

The primary framework for this will be the FastMCP library. We will set up our initial project structure, creating both the orchestrating agent (the client) and the MCP server. To simplify development, we will begin by using a single project where the MCP server runs as an "in-memory" server, allowing us to test the client and server interaction easily.

Related code files from the research agent code:

- `mcp_server/server.py`: the entrypoint of the MCP server. Show how tools, resources, and prompts endpoints are registered via `mcp_server/routers/tools.py` , `mcp_server/routers/resources.py`, and `mcp_server/routers/prompts.py` (show small parts of them, no need to show all the endpoints, it’s enough to show one tool endpoint, one for a resource, and one for a prompt). Explain the MCP server project structure. Show the content of the prompt in `mcp_server/prompts/research_instructions_prompt.py`, which describes the main agentic workflow of the research agent. Ideally, make a Mermaid diagram for it. By using this prompt, the MCP client is given the knowledge of how the tools of this MCP server are commonly use together, and it can start the workflow. It would start by asking the user for the research folder and for further optional instructions about how to run the workflow (try it in the terminal and show it in the article).
- `mcp_client/client.py`: the entrypoint for the MCP client. It can be run with `uv run -m src.client` (for in-memory MCP server) or `uv run -m src.client --transport stdio`  (for MCP server over stdio transport). Talk about the two ways of setting up the MCP server in it: the in-memory way, and the way with stdio as transport protocol (in this case, explain also how other popular MCP clients, like Cursor, use a configuration like the one that we have in the code to connect the MCP client to MCP servers). Highlight the result of the `get_capabilities_from_mcp_client` and `print_startup_info` functions, which list the available tools, resources, and prompts from the server. Then, briefly explain that the goal of `parse_user_input` is just to parse the user input, which could be a scripted command or a message for the agent. Show how the agent works in the terminal. Explain also what the `handle_user_message` function does. Quickly go over the purpose of every file in the `utils` folder (we don’t need to explain all the code here as it’s not strictly important to teach how AI agents work… just show the core of it, or show nothing). Briefly explain also the [`settings.py`](http://settings.py) file and the purpose of `pydantic_settings`. We won’t talk about the MCP client code anymore in the other lessons of this part 2B. Simply mention that Opik is used to monitor all LLM calls, but don’t delve into it as it’s a topic for part 3 of the course. Highlight how this is a general MCP client: it could connect to any MCP server, not just the one that we’ll create for the research workflow.

About other code to show, I’d stop here for now. In the next lessons of this part 2B we’ll show the implementation of some tools from `mcp_server/tools` in detail, as we’ll progressively show how the agent can do the full workflow and do some on-the-fly adaptation depending on the results of the MCP tools. We kept orchestration light and pushed heavy work into tools. The agent decides *what* to do; tools do the *work*. That cut tokens, reduced “lost-in-the-middle,” and made retries cheaper than re‑prompting the LLM with giant context.

I’d conclude this lesson by showing how the MCP client can be used in the terminal, by trying the commands which allow to manually trigger an MCP resource, or an MCP prompt. Use also the commands that list the available tools, resources, and prompts. Explain that the `/model-thinking-switch` command allow to switch between a reasoning model and a non-reasoning model.

Developer notes:

- At first we weren’t sure about how to structure the project, also considering that there are two projects: the research agent and the writer agent. There wasn’t any standard around as it’s a rather new field. So, we started the project with something very simple and unordered. Moreover, at first, we tried developing the research agent as a static workflow using LangGraph. After noticing that we needed something more adaptable, we decided to go with a MCP client/server architecture with it, and we switched to fastmcp. We started with an MCP client that contained the whole prompt of the agentic workflow in it from the start, and an MCP server with only MCP tools. Then, we learned more about the usecase of MCP prompts, and moved the prompt of the agentic workflow from the client to the server. We also structured the server more as a FastAPI project (with routers) as the project grew with many tools/resources/prompts. Finally, after studying several popular open-source MCP servers, we decided to have separate folders for tools/resources/prompts, and we got to the final project organization. We liked the organization of the final project as, while teaching MCP clients as well, it allows other popular MCP clients (e.g. Cursor) to connect to our MCP server and use it.