Table of Contents
- Module 1: Understanding the Model Context Protocol
- Module 2: Advantages of MCP
- Module 3: MCP in Action
- Summary
This course provides a conceptual, non-coding introduction to the Model Context Protocol (MCP). It assumes general familiarity with large language models (LLMs), but no prior knowledge of MCP. The goal is to build an accurate mental model of MCP’s terminology, architecture, and behavior so that it can be applied when building, integrating, or evaluating AI applications.
Module 1: Understanding the Model Context Protocol
What Is the Model Context Protocol?
The quality of an AI system’s output is only as good as its inputs — its context. When working with AI applications, it is not enough to rely on what is baked into a model’s training data. Real-world AI-powered applications typically need the AI to have access to additional information and abilities that go beyond that training data:
- If an AI should help a user understand what is on their calendar, it needs access to that calendar data.
- The same is true for information in a database, files in a file system, emails in an inbox, or virtually any other external source of information.
The core question becomes: how do we connect that external information to an AI in a standardized way? That is exactly the problem the Model Context Protocol (MCP) solves. MCP is best understood by breaking down its name:
| Term | Meaning in the context of MCP |
|---|---|
| Standard | A shared agreement on how something should work — one way everyone follows so things stay compatible. It is not a specific technology; it is an agreed-upon way of doing something. |
| Protocol | A set of rules for communication. A protocol defines the format, order, and meaning of the messages exchanged between parties. |
| Open (source) | Publicly available for anyone to use or build on. MCP was created by Anthropic, but the protocol itself is open — anyone can implement and use it. |
Putting this together, MCP is an open-source standard protocol for connecting AI applications to external tools and data. The rest of this course explores the details of that protocol and how tools and data are made available to an AI through it.
mindmap
root((Model Context Protocol))
Standard
Shared agreement
Compatibility across systems
Protocol
Format of messages
Order of messages
Meaning of messages
Open Source
Created by Anthropic
Publicly implementable
Anyone can build on it
MCP Participants: Hosts, Clients, and Servers
MCP defines three participants — the “players on the stage” of the protocol: hosts, clients, and servers.
| Participant | Role |
|---|---|
| Host | The application interfacing with the AI model, possibly presenting a UI to the user. Think of it as both a container and an orchestrator. Its ultimate goal is to get context to the LLM so that whatever the host is trying to accomplish can be carried out. |
| Client | A running program within the host. Its job is to go and retrieve information for the LLM. A host will typically instantiate more than one client, as needed, based on the activity it is trying to carry out. |
| Server | The source that actually provides context. It may be local (running on your own computer) or remote (elsewhere on the internet). It could expose calendar information, a local file system, a database, an email inbox, or virtually any other data source. |
The relationship is simple: the host instantiates one or more clients; each client connects to a server; the server supplies data that is treated as context for the LLM — as if that data had been typed directly into a prompt window.
flowchart LR
User(["User"]) -->|interacts with| Host["Host<br/>(AI application / container & orchestrator)"]
Host -->|instantiates| Client1["Client A"]
Host -->|instantiates| Client2["Client B"]
Client1 -->|connects to| Server1["Server<br/>(local or remote)"]
Client2 -->|connects to| Server2["Server<br/>(local or remote)"]
Server1 -->|provides context| Client1
Server2 -->|provides context| Client2
Client1 -->|delivers context| LLM["LLM"]
Client2 -->|delivers context| LLM
LLM -->|generates response| Host
Host -->|presents output| User
Concrete example: Visual Studio Code acts as the host — the AI application. It interfaces with an AI model to assist with coding, and it has the ability to instantiate MCP client objects. Those clients can connect to a server. For example, an Angular developer could install the Angular MCP server, which can:
- Pull information from the local file system (looking at code files).
- Search documentation and practical examples.
- Provide those examples and patterns for code generation, to be used by the LLM.
The LLM needs access to that documentation, and that access comes from instantiating an MCP client that connects to the Angular MCP server. In practice, a developer visits the framework’s own documentation (for example, angular.dev) to find MCP setup instructions for various hosts — such as Cursor, Gemini CLI, or Visual Studio Code. From the user’s perspective, what they experience is simply that the LLM’s output improves and becomes more accurate, because its context now includes up-to-date information thanks to the interaction between host, client, and server.
MCP Primitives: Tools, Resources, and Prompts
Understanding hosts, clients, and servers explains who is involved, but not what is actually communicated between them. The pieces of information exchanged are called primitives — the smallest building blocks of the system: the building blocks a server can provide, or the pieces of information exchanged between host/client and server.
There are three primary primitives:
| Primitive | Definition | Purpose | Example |
|---|---|---|---|
| Tool | An executable function on the server that performs actions. | Lets the AI ask the server to do something. The action may or may not return data. | Querying a database, calling an API, performing a calculation. |
| Resource | Contextual, read-only information for the AI. | Lets the AI ask the server for information. | The contents of files, a database schema. |
| Prompt | A reusable template designed to be selected and used by a user. | Guides the response the AI gives by providing structured prompt templates the user can fill in and submit. | A calendar-related prompt template that helps a user ask for information within a specific date range. |
In short: tools are about performing actions, resources are about providing information, and prompts are about guiding the interaction. All three are provided to the host and its clients by the server, and — critically — all of these concepts are part of the open standard protocol, meaning every MCP-compliant client and server implements them in a standardized way.
flowchart TB
Server["MCP Server"]
Server -->|"Tool<br/>(executable function / action)"| Tools["e.g. run a database query"]
Server -->|"Resource<br/>(read-only data)"| Resources["e.g. local files, DB schema"]
Server -->|"Prompt<br/>(reusable template)"| Prompts["e.g. calendar date-range template"]
How the Data Actually Moves
Beyond the three primitives, MCP defines how this data is transferred, using two layers:
| Layer | Role | Detail |
|---|---|---|
| Data layer | Defines the structure of the messages exchanged. | Uses JSON-RPC — information formatted in JSON describing what the server can do and what the client can do, in a standardized format. |
| Transport layer | Defines how the JSON is physically moved between participants. | Either standard I/O (local host, client, and server on the same machine) or HTTP (server is remote, elsewhere on the internet). |
flowchart LR
subgraph DataLayer["Data Layer"]
JSONRPC["JSON-RPC messages<br/>(tools, resources, prompts)"]
end
subgraph TransportLayer["Transport Layer"]
StdIO["Standard I/O<br/>(local host + server)"]
HTTP["HTTP<br/>(remote server)"]
end
JSONRPC --> StdIO
JSONRPC --> HTTP
Host, client, and server may all be local, or split with a remote server — either way, they exchange standardized JSON information over one of these two transports, allowing the primitives (tools, resources, prompts) to move between them.
Module 2: Advantages of MCP
The Integration Problem: Existing Alternatives
Before discussing why MCP is beneficial, it helps to understand the integration problem it solves. Integration, in this context, means connecting an application to something outside itself: a tool the application can use, data it can read, or a service it can interact with. This includes both:
- Connections to external information — APIs, components, and services.
- The connection to the AI model itself.
Each vendor and creator of an AI model may have its own approach or API for integrating with that model or connecting it to external information sources. This is similar to the problem of having many incompatible USB connectors: the more ways there are to connect, the more complicated the resulting code becomes. If an AI model is given access to a specific set of tools through a vendor-specific API, porting that integration to a different model often fails outright, because the new model is not designed to work at that same API level. Inflexible solutions create real problems whenever a project needs to move between models for different use cases or costs.
The transcript highlights three commonly used alternative approaches, each with a significant downside:
| Alternative Approach | Description | Key Limitation |
|---|---|---|
| Model-specific plugins | The model vendor allows you to add an integration/plug-in for specific functionality (e.g., integrating a particular calendar into a particular model). | Not portable. Moving to a different AI model from a different vendor means the plugin logic cannot simply be carried over. |
| Manual API integrations | The developer writes custom code for each specific API — one for the database, another for the calendar, another for the email inbox, and so on. | Does not scale. Every new capability requires a unique, hand-written integration, adding significant overhead as functionality expands. |
| Language-specific frameworks | A framework built for a specific programming language or runtime (e.g., something Python-specific or Java-specific). | Tied to a specific runtime. Reduces future flexibility because all code becomes dependent on a framework that only works in one programming language. |
flowchart TD
Problem["Integration Problem:<br/>Connecting AI to external tools & data"]
Problem --> A["Model-specific plugins"]
Problem --> B["Manual API integrations"]
Problem --> C["Language-specific frameworks"]
A --> A1["❌ Not portable across models"]
B --> B1["❌ Does not scale"]
C --> C1["❌ Tied to one runtime/language"]
What is needed instead is an approach that provides maximum flexibility, is portable, scalable, not tied to a specific programming language, and still capable of enhancing an LLM with capabilities and information.
Why MCP: Benefits over Alternatives
MCP is designed to be that one standard that can connect any AI application to any tool or data source. Its key benefits map directly onto the shortcomings of the alternatives:
| Benefit | Explanation |
|---|---|
| Open ecosystem of pre-built integrations | Because MCP is open, a wide variety of implementations and open-source solutions already exist. Makers of calendars, databases, email systems, and more can build integrations according to the open protocol, saving significant custom development work. |
| Standardized structure | Moving from project to project does not require relearning or rebuilding integration logic from scratch — MCP works the same way every time: there are tools (actions), resources (data), and possibly prompts (templates). |
| Client flexibility | If a project undergoes a fundamental architectural change, the MCP integration itself continues to work the same way, regardless of the host application (an IDE, an enterprise chat interface, or a custom app). |
| Reduced hallucinations | By making it easy to supply clear, relevant context to the LLM, MCP helps reduce incorrect or fabricated outputs. |
| Build once, use everywhere | As you move from model to model, the MCP integration itself does not change — every model receives the same kind of information in the same format. |
| Language agnostic | Nothing in the protocol is tied to a specific programming language. As long as MCP is followed, it does not matter what language the host, client, or server is written in. |
flowchart LR
subgraph Alternatives["Existing Alternatives"]
P1["Model-specific plugins<br/>❌ Not portable"]
P2["Manual API integrations<br/>❌ Doesn't scale"]
P3["Language-specific frameworks<br/>❌ Tied to one runtime"]
end
subgraph MCP["Model Context Protocol"]
M1["Open protocol<br/>✅ Portable across models"]
M2["Pre-built, standardized integrations<br/>✅ Scales"]
M3["Language agnostic<br/>✅ Any runtime"]
end
P1 -.solved by.-> M1
P2 -.solved by.-> M2
P3 -.solved by.-> M3
Why does reducing hallucinations matter so much? Models are not trained on your data — they are trained on a large corpus of general information that may not include your organization’s specifics. Without additional context, patterns, and vocabulary supplied through mechanisms like MCP, an LLM fills in gaps probabilistically based on its training data, which may or may not match the desired output. That guess can be confidently wrong — an LLM that hallucinates or confabulates can break an application and erode the trust of stakeholders and users.
By standardizing on MCP, applications connect models to real, current, live data — not just static training data. Returning to the Angular MCP server example: as the Angular framework adds new features, its MCP server can supply up-to-date examples for the LLM to follow when generating code. The same principle applies to a customer-facing chatbot, which should give answers that are accurate and consistent with what an organization actually wants to communicate. Grounded answers — answers based on true, current information — guide and constrain the pattern-matching behavior of the LLM.
Summarizing the direct mapping between limitations and MCP’s response:
| Limitation of Alternative | MCP’s Solution |
|---|---|
| Model-specific plugins are not portable | Open protocol — solution logic ports across models |
| Manual API integrations don’t scale | Standardized approach, many integrations pre-built by others |
| Language-specific frameworks are tied to a runtime | MCP is language agnostic |
Because MCP overcomes these limitations, it has been readily adopted across the industry, and it can be adopted for virtually any AI integration project.
Module 3: MCP in Action
Use Cases and the MCP Ecosystem
MCP’s core concept is to bring data and abilities to an LLM. There are many sources of data and a great deal of functionality an LLM could help automate, so MCP is the mechanism for bringing that data and those abilities into the LLM’s reach. Three common categories of use cases stand out:
| Use Case | What MCP Enables |
|---|---|
| Chatbots | Adds new functionality to a conversational interface — the same way a new button might add a capability to a graphical UI. |
| IDE assistants (e.g., Visual Studio Code, Cursor) | Augments developer tools with LLM capabilities while simultaneously augmenting the LLM’s knowledge with up-to-date documentation and standardized patterns. |
| AI agents | Increases reliability and capability of autonomous task execution. Because an LLM is inherently unreliable (it is probabilistic), MCP helps ground agent behavior in real data and available actions. |
Digging a bit deeper into each:
- Chatbots can answer questions using real data instead of guesses based on training data, look up information on demand to get the latest available data, and take actions on behalf of users (for example, scheduling a meeting through a “schedule a meeting” tool exposed by an MCP server).
- IDE assistants can read data outside the project’s own context (such as documentation and framework-specific examples), access general documentation to both generate code and answer developer questions about the codebase, and run commands and tools — expanding the IDE’s capability beyond plain text generation into executing other software.
- AI agents can access tools and data mid-task to ensure a workflow makes sense, adjust behavior on the fly based on real-time data, choose from available services exposed to the LLM, and gather context as a task is carried out. For example, an agent scheduling a calendar event and then sending a follow-up email could use MCP to retrieve an invitation link from the calendar tool and include that link in the email tool call — coordinating a multi-step process using real data.
mindmap
root((MCP Use Cases))
Chatbots
Answer with real data
Look up info on demand
Take actions for users
IDE Assistants
Read outside project context
Access documentation
Run commands and tools
AI Agents
Access tools/data mid-task
Adjust on the fly
Choose from available services
Gather context across steps
Real-World Hosts, Clients, and Servers
Recall that a host instantiates clients. The ecosystem already includes many concrete, real-world examples:
| Category | Examples |
|---|---|
| Hosts (AI applications that instantiate clients) | Claude Desktop (installed program running the LLM, expandable via MCP), the Cursor IDE, Amazon Q |
| Clients (components running inside a host) | Visual Studio Code extensions that augment Copilot, command-line interface tools, custom-built applications |
| Servers (sources of context) | Google Drive (file data), Slack (conversation summaries), GitHub (issues/commits analysis), PostgreSQL (database queries), local file systems, and many more |
Whatever the specific combination of host, client, and server, the underlying MCP structure and protocol remain the same — whether it is Claude Desktop summarizing local PDFs, Cursor analyzing changes in a GitHub branch, or a custom application pulling live data from a SQL database. Because the standard is open, the ecosystem of MCP-based functionality can continue to grow indefinitely.
flowchart TB
subgraph Hosts["Example Hosts"]
H1["Claude Desktop"]
H2["Cursor"]
H3["Amazon Q"]
end
subgraph Clients["Example Clients"]
C1["VS Code extension"]
C2["CLI tool"]
C3["Custom app"]
end
subgraph Servers["Example Servers"]
S1["Google Drive"]
S2["Slack"]
S3["GitHub"]
S4["PostgreSQL"]
S5["Local file system"]
end
H1 --> C1
H2 --> C2
H3 --> C3
C1 --> S1
C1 --> S3
C2 --> S3
C2 --> S4
C3 --> S2
C3 --> S5
The MCP Request-Response Flow
Understanding use cases explains why MCP matters; understanding the request-response flow explains what actually happens under the hood between a client and a server. This flow breaks down into three phases:
| Phase | What Happens |
|---|---|
| 1. Initialization | The client and server establish a connection and exchange information about capabilities. |
| 2. Operation | The client and server exchange messages; the client can call tools on the server. |
| 3. Shutdown | The connection between client and server is cleanly closed. |
sequenceDiagram
participant U as User
participant H as Host (AI Application)
participant C as MCP Client
participant S as MCP Server
participant L as LLM
Note over C,S: Phase 1 — Initialization
C->>S: Protocol version + client capabilities (e.g. roots, sampling)
S-->>C: Server capabilities (tools, resources, prompts) + server info
Note over C,S: Phase 2 — Operation
U->>H: Asks a question (e.g. "What issues are open in my repo?")
H->>L: Forwards question with available context
L->>C: Requests list of available tools
C->>S: list_tools()
S-->>C: [get_issues, search_files, send_message, ...]
L->>C: Chooses tool to call (e.g. get_issues)
C->>S: get_issues()
S-->>C: JSON result
C-->>H: Returns JSON as context
H->>L: Supplies tool result as context
L-->>H: Generates output using new context
H-->>U: Presents answer
Note over C,S: Phase 3 — Shutdown
H->>C: Close connection
C->>S: Terminate session
Initialization and Capability Negotiation
During initialization, information is exchanged via JSON-RPC over the transport layer (standard I/O locally, or HTTP remotely). The protocol version is specified, and the client’s capabilities are passed to the server, since the server may be able to take advantage of some of them. The server then responds with its own set of capabilities and information about itself. This exchange is called capability negotiation.
| Side | Capability | Description |
|---|---|---|
| Client | Roots | Where in the file system the application has permission to do its work — effectively, “work here.” |
| Client | Sampling | The client has access to the LLM; the server may need the LLM to do some work. The server can provide a prompt (possibly including server-side data), the client runs that prompt against the LLM, and sends the result back to the server. This lets the server prompt the client’s own LLM. |
| Server | Prompts | Standard prompt templates the user can select from. |
| Server | Resources | Data that can be retrieved from the server. |
| Server | Tools | Actions the LLM is able to call. |
flowchart LR
subgraph ClientCaps["Client Capabilities"]
Roots["Roots<br/>(file system permission scope)"]
Sampling["Sampling<br/>(server can prompt client's LLM)"]
end
subgraph ServerCaps["Server Capabilities"]
SPrompts["Prompts"]
SResources["Resources"]
STools["Tools"]
end
ClientCaps <-->|capability negotiation| ServerCaps
Operation Phase in Detail
Once initialization and capability negotiation are complete, the operation phase is where the real work happens:
- The LLM can request the list of tools available from the server.
- The server responds with that list — for example,
get_issuesfrom a code repository,search_filesfor a local file system, orsend_messagefor an email inbox. - The LLM reads this list as text and infers which tool it should call based on what it is trying to accomplish. This is not hard-coded logic calling a specific tool — the LLM uses its text-inference ability to choose, based on the context it has been given.
- The chosen tool call is executed on the server, which is coded to look up or perform the requested action and return JSON.
- That JSON is returned to the host and client, which the LLM then uses as context to generate its output for the user — for example, stating which issues are open and how many, potentially following an output template supplied by the host or server.
- When the interaction concludes, the host and client shut down the connection with the server.
This entire process is structured, predictable, and standardized — the mental model to keep whenever implementing MCP servers or clients, or simply using MCP-enabled AI applications.
The Lifecycle of Context
The entire purpose of MCP is to provide context and capability — and an LLM’s output is only as good as its context, since an LLM is fundamentally a pattern-matching, probabilistic engine. Generally, the better the patterns and information it is given, the better its output — though, as this section explains, there is a limit to that principle.
Each MCP primitive contributes context in a distinct way:
| Primitive | Contribution to Context |
|---|---|
| Tools | Knowing what tools are available, what they do, and why they might be used in a given situation helps the LLM make an accurate probabilistic guess about which tool to call. |
| Resources | The data supplied becomes part of what the LLM processes alongside the user’s next prompt — not just the raw prompt text. |
| Prompts | Well-designed templates help users write better prompts, which is itself a form of context. |
Mapping context growth onto the request-response flow:
- During initialization: context is provided through capability negotiation — the LLM becomes aware that tool definitions, resources, and prompt templates are available. This is context that begins slowly accumulating.
- During operation: once the host and client have the list of available tools, that list itself becomes added context. The actual data returned from tool calls is added as well. You can picture this as a continuously growing document being fed to the LLM.
- At output time: the LLM produces output that interacts with the user, using accumulated context to generate an improved, grounded response. Critically, that output itself becomes context too — the LLM’s own prior output becomes part of its ongoing contextual history.
flowchart TD
Init["Initialization:<br/>capability negotiation context"] --> Op["Operation:<br/>tool list + tool-call results added as context"]
Op --> Out["Output:<br/>LLM generates response using accumulated context"]
Out --> Hist["LLM's own output becomes part of future context"]
Hist --> Op
User(["User asks new question"]) --> Op
This back-and-forth — the LLM through the client to the server, and the LLM to the user through the host — is the context lifecycle. At every step, context keeps growing.
The Caution: Context Is Not Free
Filling the LLM’s context window does not necessarily make output better indefinitely. Known problems emerge as context grows too large:
| Risk | Description |
|---|---|
| Recency bias | The LLM tends to focus disproportionately on what appears most recently in its context. |
| Context rot | A very large amount of context can cause the LLM’s output to diverge from the intended goal. |
| Hallucinations | One possible consequence of context rot — output becomes inaccurate, sometimes no longer even referencing the real data retrieved through MCP. |
flowchart LR
Growing["Context Window Growing"] --> Check{"Too much context?"}
Check -- No --> Better["Improved, grounded output"]
Check -- Yes --> Risk["Recency bias / Context rot"]
Risk --> Hallucination["Hallucinations / divergence from intended output"]
Managing context therefore requires balance. MCP is not an automatic solution to the context problem — it supplies the mechanism for delivering context, but developers must still actively manage how much and which context is passed to the LLM to avoid overwhelming it. Achieving that balance while using MCP well is what enables genuinely reliable, accurate AI applications.
Summary
This course introduced the Model Context Protocol (MCP) as an open-source standard protocol for connecting AI applications to external tools and data. The key ideas to retain:
- Participants: a host (the AI application, acting as container and orchestrator) instantiates one or more clients, which connect to servers that supply context — locally or remotely.
- Primitives: servers expose tools (executable actions), resources (read-only data), and prompts (reusable templates) — all transmitted as JSON-RPC messages (data layer) over standard I/O or HTTP (transport layer).
- Advantages over alternatives: MCP replaces model-specific plugins (not portable), manual API integrations (don’t scale), and language-specific frameworks (tied to one runtime) with a single, open, language-agnostic, portable, and scalable standard.
- Use cases: chatbots, IDE assistants, and autonomous AI agents all benefit from MCP by gaining access to real, current data and callable actions instead of relying solely on static training data.
- Request-response flow: every MCP interaction follows three phases — initialization (capability negotiation), operation (tool discovery, tool calls, data exchange), and shutdown (clean connection close).
- Context lifecycle: every exchange — capability negotiation, tool lists, tool results, and even the LLM’s own prior output — becomes part of a continuously growing context. More context generally helps, but excessive context can cause recency bias, context rot, and hallucinations, so context must be actively managed.
Quick Reference
| Concept | One-line Definition |
|---|---|
| MCP | Open-source standard protocol for connecting AI applications to external tools and data |
| Host | The AI application; container and orchestrator that instantiates clients |
| Client | A component running inside the host that connects to a server |
| Server | The source of context — local or remote — providing tools, resources, and prompts |
| Tool | An executable server-side function that performs an action |
| Resource | Read-only contextual data provided by the server |
| Prompt | A reusable, user-selectable prompt template |
| Data layer | JSON-RPC message format |
| Transport layer | Standard I/O (local) or HTTP (remote) |
| Initialization phase | Connection setup and capability negotiation |
| Operation phase | Tool discovery, tool calls, and data exchange |
| Shutdown phase | Clean closure of the client-server connection |
| Context rot | Degraded output quality caused by excessive accumulated context |
Checklist for Applying MCP
- Identify what external data or actions your AI application actually needs (calendars, databases, file systems, APIs, etc.).
- Determine whether an existing MCP server already covers that data source before building a custom one.
- Confirm which host/client combination you are working with (IDE, chat interface, custom app) and how it instantiates MCP clients.
- Understand which primitives (tools, resources, prompts) the target server exposes.
- Choose the appropriate transport: standard I/O for local servers, HTTP for remote servers.
- Design for capability negotiation — know what your client needs to declare (roots, sampling) and what the server needs to declare (tools, resources, prompts).
- Monitor and manage context size to avoid recency bias, context rot, and hallucinations as the conversation or task grows.
- Treat MCP as the standardized transport for context — not a substitute for careful context engineering.
Search Terms
model · context · protocol · mcp · ai · agents · orchestration · artificial · intelligence · generative · alternatives · clients · hosts · servers