Module 5: Multi-Agent & MCP Standards · 7.5h
01 · UNDERSTAND
Day 26 Theory — MCP Architecture and the 2026-07-28 Protocol Model
Why MCP exists
AI applications often need access to external capabilities: ticket systems, databases, files, internal APIs, search services and automation tools.
Without a shared protocol, every AI host could invent a different integration contract for each capability. That creates duplicated adapters and makes tools difficult to move between applications.
The Model Context Protocol (MCP) defines a common protocol boundary between an AI application and capability providers.
MCP does not make an LLM smarter. It standardizes how compatible applications discover and invoke capabilities through a shared protocol.
The three roles: host, client and server
Keep these roles separate.
Host
The host is the application that owns the AI experience.
Examples include an IDE assistant, desktop agent application, or our Service Desk runtime.
The host owns product concerns such as:
- user identity,
- authorization policy,
- model selection,
- conversation/product state,
- UI and approvals.
Client
The client is the protocol component inside the host that communicates with one MCP server.
A host can have multiple MCP clients connected to different servers.
Server
The server exposes capabilities using MCP-defined messages and schemas.
For example, one server may expose ticketing tools while another exposes approved knowledge resources.
Service Desk host
|
+-- MCP client A ----> Ticketing MCP server
|
+-- MCP client B ----> Knowledge MCP server
The model does not directly “talk to MCP.” Application code mediates model decisions and protocol calls.
Protocol is not transport
A common beginner confusion is to equate MCP with HTTP.
MCP defines protocol semantics: methods, parameters, results, metadata and capability contracts.
Those protocol messages can travel over supported transports such as:
- STDIO for local process integration,
- Streamable HTTP for remote service integration.
Think of it as:
MCP semantics
|
+---- STDIO transport
|
+---- Streamable HTTP transport
The transport changes how bytes move. It does not change the fundamental responsibility of the MCP method being invoked.
JSON-RPC request/response mental model
MCP uses JSON-RPC 2.0 message patterns for protocol operations.
A request identifies the operation and includes an ID so the response can be correlated.
Conceptually:
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "get_ticket",
"arguments": {"ticket_id": "INC-42"}
}
}
The response carries the same request ID.
Notifications are different: they do not expect a response.
Understanding this distinction is valuable when you inspect protocol traces rather than relying only on SDK abstractions.
The important 2026-07-28 change: no mandatory handshake or protocol session
Older MCP examples commonly begin with an initialize / initialized exchange and may depend on an Mcp-Session-Id for Streamable HTTP.
The 2026-07-28 specification changes that model.
The core protocol is now stateless at the protocol layer:
- the old
initialize/initializedhandshake is retired, - the protocol-level
Mcp-Session-Idis retired, - requests are self-describing,
- an HTTP request can be handled by any compatible server instance without sticky protocol-session routing.
A simplified mental model is:
Older HTTP lifecycle
client -> initialize -> session id -> later protocol requests tied to session
2026-07-28 core
client -> self-contained request -> any compatible server instance
This is why copying old MCP tutorials without checking their specification version is dangerous.
Stateless protocol does not mean stateless application
This distinction matters enormously.
The protocol no longer requires hidden transport-level conversation state, but your application may still need persistent state.
For example, a browser automation server might create a browser session and return:
browser_id = "br_7842"
The caller can pass that explicit handle back on later tool calls.
The state is now visible in the application contract instead of being an invisible requirement of the transport session.
Therefore:
Stateless protocol core ≠ databases forbidden, caches forbidden, or application sessions forbidden.
It means the core protocol request should not rely on mandatory hidden session state that the transport must preserve.
Self-describing requests and _meta
In the current model, protocol/client information that previously lived mainly in the initialization exchange can travel with requests in metadata.
This supports horizontally scalable server deployments because a fresh server instance can understand a request without first reconstructing a protocol session.
Header-based routing
For Streamable HTTP in the current specification, request metadata such as:
Mcp-MethodMcp-Name
can make the operation visible to gateways and policy layers.
That matters operationally.
A gateway can reason about:
tools/list
versus:
tools/call + privileged_reset_password
without parsing arbitrary model prose.
Protocol-visible routing metadata can improve authorization, observability and infrastructure routing—but the header itself does not authorize the action.
Optional discovery with server/discover
A client does not need the old initialization handshake simply to begin using the protocol.
If it wants server capabilities up front, the current model provides optional server discovery.
Treat discovery as:
“What does this server advertise?”
not:
“I am now permitted to call everything it advertises.”
Discovery and authorization are different concerns.
Multi Round-Trip Requests (MRTR)
Some operations need additional information after the server has begun processing a request.
For example:
Client -> call privileged operation
Server -> input_required: user approval needed
Client -> obtain approval
Client -> retry/continue with input response
Server -> final result
This is the idea behind Multi Round-Trip Requests (MRTR).
MRTR enables richer interaction without returning to a permanently open bidirectional protocol session.
Do not interpret MRTR as “the server secretly stores an unlimited conversation.” It is a defined multi-exchange protocol pattern.
Tools, resources and prompts are different capability types
Students often reduce MCP to “tool calling.” Tools are important, but MCP can describe different capability surfaces.
At a high level:
- tools expose executable operations,
- resources expose retrievable context/data,
- prompts expose reusable prompt-related capability where supported by the protocol/version.
The security profile is different. Reading a resource and executing a privileged side-effecting tool should not receive identical policy merely because both came from one MCP server.
MCP does not solve authorization
Protocol interoperability is not a security decision.
Before executing a tool, the application still needs deterministic controls such as:
authenticated user
|
v
authorization policy
|
v
allowed MCP server/tool?
|
v
validate arguments
|
v
execute with least-privilege credentials
|
v
audit result
The model may suggest an action. The application decides whether that action is allowed.
Capability descriptions are untrusted input
An MCP server can expose tool names, descriptions and schemas that influence model behavior.
That metadata should not automatically be trusted simply because it conforms to MCP.
Later we will examine tool poisoning and supply-chain risk. For now remember:
A standard schema can make untrusted content easier to exchange; it does not make the content trustworthy.
Migration mindset
When reading MCP examples, always identify the protocol generation.
Questions to ask:
- Which MCP specification version does this example target?
- Does it depend on
initializeorMcp-Session-Id? - Is the SDK example newer or older than the protocol semantics being taught?
- Is the example local STDIO or remote Streamable HTTP?
- Which responsibility belongs to the protocol, and which belongs to the application?
This prevents accidental mixing of old lifecycle assumptions with the 2026-07-28 model.
Service Desk connection
Previously, the Service Desk called capabilities through custom Python interfaces. Today we introduce an interoperable protocol boundary.
Before
------
Service Desk -> custom Python adapter -> ticket API
After
-----
Service Desk host
-> MCP client
-> MCP server
-> ticket capability
We gain a standard capability contract, but we do not outsource product security or workflow correctness to MCP.
The principle is:
MCP standardizes capability exchange. The 2026-07-28 core removes mandatory handshake/session coupling, but application state, identity, authorization, trust and side-effect safety remain explicit engineering responsibilities.
02 · APPLY
Lesson goal
Today we apply the 2026-07-28 Model Context Protocol (MCP) mental model to the Service Desk.
By the end of the lesson you should be able to:
- distinguish host, client and server responsibilities,
- separate MCP protocol semantics from transport,
- explain why the old
initialize/initializedhandshake is no longer part of the 2026-07-28 core, - explain why
Mcp-Session-Idis no longer a mandatory protocol session mechanism, - construct a self-contained Streamable HTTP tool request,
- explain
Mcp-Method,Mcp-Nameand request_meta, - explain optional
server/discover, - describe Multi Round-Trip Requests (MRTR),
- keep authorization and application state outside “protocol magic.”
What changed in the Service Desk today?
Previously, the Service Desk reached capabilities through application-specific Python interfaces.
Today we introduce a standards-based boundary:
Service Desk Host
|
| MCP client behavior
v
MCP protocol boundary
|
v
Capability server
|
+-- tools
+-- resources
+-- other supported MCP capability surfaces
The protocol standardizes capability exchange. The Service Desk still owns user identity, permissions and product policy.
Architecture: 2026-07-28 Streamable HTTP
graph LR
Host[Service Desk Host] -->|POST /mcp\nself-contained request| Gateway[HTTP Gateway]
Gateway -->|Mcp-Method / Mcp-Name| ServerA[MCP Server Instance A]
Gateway --> ServerB[MCP Server Instance B]
ServerA -->|JSON-RPC response| Host
ServerB -->|JSON-RPC response| Host
The important production consequence is that a request does not need to be pinned to the server instance that previously created a protocol session.
First: identify the protocol generation
Older MCP material commonly shows:
initialize
↓
initialized
↓
Mcp-Session-Id
↓
later requests
That is not the 2026-07-28 core lifecycle.
For the version taught in this course:
self-contained request
↓
server handles request
↓
response
If discovery is needed first, server/discover is available as an optional RPC. It is not a mandatory replacement handshake.
A self-contained tool call
The official 2026-07-28 model makes important routing information explicit on the HTTP request.
A representative request looks like:
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search_kb
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_kb",
"arguments": {
"query": "VPN certificate renewal"
},
"_meta": {
"io.modelcontextprotocol/clientInfo": {
"name": "service-desk",
"version": "1.0.0"
}
}
}
}
What the headers are doing
MCP-Protocol-Version
: Identifies the MCP protocol version used by the request.
Mcp-Method
: Makes the protocol method visible to HTTP infrastructure.
Mcp-Name
: Makes a relevant capability name visible for operations such as tool calls.
This allows gateways and policy systems to reason about protocol operations without inferring intent from model-generated prose.
The same idea in Python
The goal of this example is to make the HTTP contract visible. Production applications may use the current MCP SDK rather than constructing every request manually.
import httpx
MCP_URL = "https://mcp.internal.example/mcp"
async def call_search_kb(query: str) -> dict:
payload = {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_kb",
"arguments": {"query": query},
"_meta": {
"io.modelcontextprotocol/clientInfo": {
"name": "service-desk",
"version": "1.0.0",
}
},
},
}
headers = {
"MCP-Protocol-Version": "2026-07-28",
"Mcp-Method": "tools/call",
"Mcp-Name": "search_kb",
}
async with httpx.AsyncClient(timeout=15.0) as client:
response = await client.post(MCP_URL, json=payload, headers=headers)
response.raise_for_status()
result = response.json()
if result.get("jsonrpc") != "2.0" or result.get("id") != 1:
raise ValueError("Unexpected MCP JSON-RPC response")
return result
Do not memorize the timeout value. It is an example. Production timeout policy belongs to the application and dependency contract.
Why removing the protocol session matters
Imagine three identical MCP server instances behind a load balancer.
Older session-coupled thinking often creates pressure for:
client -> instance A
|
+-- session state
future client call must somehow reach A again
With the stateless 2026-07-28 core:
request 1 -> instance A
request 2 -> instance C
request 3 -> instance B
Each request contains enough protocol context to be handled independently.
This simplifies ordinary horizontal scaling and reduces hidden transport-session coupling.
Stateless protocol does not ban stateful applications
Suppose a tool starts a browser session and returns:
{
"browser_id": "browser_427"
}
A later tool call may include that handle explicitly:
{
"name": "browser_click",
"arguments": {
"browser_id": "browser_427",
"selector": "#submit"
}
}
The application is stateful, but the state dependency is explicit in the application/tool contract.
Do not teach:
“MCP servers cannot store state.”
Teach:
“The 2026-07-28 core does not require a hidden protocol-level session.”
Optional discovery
A client may want to learn server capabilities before making other calls.
The current protocol provides optional server/discover behavior for that purpose.
Conceptually:
Client -> server/discover
Server -> advertised capabilities
Discovery answers what the server advertises.
It does not answer whether the current user is authorized to invoke every advertised operation.
List results and caching
The 2026-07-28 direction also improves cacheability of list-style capability results.
Why does that matter?
A large tool catalog does not need to be rediscovered and injected repeatedly when the server indicates it can be cached appropriately.
Benefits can include:
- lower latency,
- fewer repeated protocol calls,
- more stable upstream prompt/context construction.
Caching still needs invalidation semantics. Never assume a tool catalog is valid forever.
Multi Round-Trip Requests (MRTR)
Some logical operations require additional input after work has started.
Example:
Service Desk -> call privileged remediation tool
MCP server -> input_required: approval needed
Service Desk -> obtain approved human input
Service Desk -> continue/retry operation with inputResponses
MCP server -> result
MRTR allows this without reintroducing a mandatory long-lived bidirectional protocol session.
MRTR means Multi Round-Trip Requests. It does not mean arbitrary hidden conversation state.
MCP is not authorization
Suppose the model requests:
reset_password(user="ceo")
MCP can standardize how that tool call is represented and transported.
It does not prove the current caller is allowed to perform it.
The application security path should still look like:
authenticated caller
|
v
authorization policy
|
v
allowed server + tool?
|
v
validate arguments
|
v
execute using least privilege
|
v
audit outcome
The model proposes. Deterministic application policy decides.
Capability metadata is also input
Tool names, descriptions and schemas can influence model behavior.
Treat capability metadata from an external server as data crossing a trust boundary.
A valid MCP schema does not prove that:
- the server is trusted,
- the tool implementation is safe,
- the description is honest,
- the caller should be allowed to invoke it.
We will explore this security problem in depth on Day 29.
Migration exercise: identify outdated assumptions
For each statement, decide whether it belongs to the old lifecycle or the 2026-07-28 core.
Statement A
Every client must call
initialize()before calling a tool.
Answer: Old lifecycle assumption. Not part of the 2026-07-28 stateless core.
Statement B
Every later HTTP request must carry
Mcp-Session-Id.
Answer: Old lifecycle assumption. The protocol-level session header is retired in the 2026-07-28 core.
Statement C
An MCP application may still use a database or explicit application handle across calls.
Answer: Correct. Stateless protocol does not forbid stateful application behavior.
Statement D
A client may optionally discover server capabilities before making other calls.
Answer: Correct. Discovery is optional rather than a mandatory initialization handshake.
Debugging a 2026-07-28 HTTP request
When a call fails, inspect the protocol boundary systematically.
- Is
MCP-Protocol-Versionthe expected value? - Does
Mcp-Methodmatch the JSON-RPC method? - Does
Mcp-Namematch the named capability where required? - Does the JSON-RPC request have a valid
id,methodandparamsshape? - Is client metadata present as required by the current contract?
- Did authentication/authorization reject the request before tool execution?
- Is the server returning a protocol error or an HTTP infrastructure error?
- Are you accidentally reading documentation for a previous MCP version?
Common mistakes
- Mixing
2025-11-25handshake examples into a2026-07-28lesson. - Saying stateless protocol means the application cannot persist state.
- Treating
server/discoveras mandatory initialization. - Treating discovery as authorization.
- Using a discovered tool description as trusted policy.
- Assuming a protocol standard automatically provides safe credentials or least privilege.
Practical lab
Work in:
service-desk-day-26/
Task A — find protocol-generation assumptions
Inspect the Day 26 implementation and tests for any use of:
initialize
initialized
Mcp-Session-Id
For material labelled 2026-07-28, explain whether each occurrence is valid, migration comparison material, or stale code that should be removed.
Task B — inspect a self-contained request
Trace one tools/call request and identify:
- HTTP routing headers,
- JSON-RPC request ID,
- method,
- tool name,
- arguments,
- client metadata.
Task C — separate protocol and security
For a privileged Service Desk tool, write down:
what MCP validates/transports
versus:
what the Service Desk authorization layer must decide
Task D — explain state explicitly
Design a two-call workflow that returns an explicit handle on call 1 and requires that handle on call 2.
Explain why this is compatible with a stateless protocol core.
Task E — run tests
cd service-desk-day-26
PYTHONPATH=. pytest -q
If tests encode the old mandatory initialization/session model, treat that as a course bug—not as evidence that the old model is current.
Knowledge check
1. What was removed from the 2026-07-28 core lifecycle?
The mandatory initialize / initialized handshake and protocol-level Mcp-Session-Id session model were retired.
2. Does that mean every MCP server must be application-stateless?
No. Application state may be persisted and referenced explicitly through tool arguments/handles or other application mechanisms.
3. Why are Mcp-Method and Mcp-Name useful?
They make protocol operation metadata visible to HTTP routing, policy and observability infrastructure.
4. Is server/discover mandatory?
No. It is an optional way to learn server capabilities before other calls.
5. What does MCP not decide?
It does not decide whether the authenticated user is authorized to perform a business action, whether a server is trusted, or whether a side effect is safe for the product.
Scenario
A team migrates to MCP 2026-07-28 but keeps sticky load-balancer routing because “the client must return to the server that initialized its session.”
What is wrong?
Answer: That assumption belongs to the older protocol session lifecycle. The 2026-07-28 core is designed around self-contained requests without the retired mandatory protocol session. Application-specific state may still exist, but it should not be confused with the old transport-level session requirement.
Key takeaways
- Always identify the MCP specification version before copying examples.
- MCP 2026-07-28 uses a stateless protocol core with self-contained requests.
- The old mandatory
initializehandshake andMcp-Session-Idmodel are retired. server/discoveris optional.- MRTR supports defined multi-exchange interactions without requiring a permanent bidirectional protocol session.
- Protocol interoperability does not replace authentication, authorization, trust policy or side-effect safety.
Official references
- MCP 2026-07-28 release explanation: https://blog.modelcontextprotocol.io/posts/2026-07-28/
- Model Context Protocol specification site: https://modelcontextprotocol.io/
- MCP Python SDK: https://github.com/modelcontextprotocol/python-sdk
03 · EXPLAIN
Interview checkpoint
Explain one design decision from this lesson, the alternative you rejected, and the failure mode or evidence that justified your choice.