How-To Guides · Certification Study Guide · 2026-07-10
Linux Foundation · AI & ML Track · Beginner
Model Context Protocol Associate — a visual-first study guide
Everything on the official blueprint, sized to the exam weights, verified against the live MCP specification — stable 2025-11-25 as the exam baseline, with the incoming 2026-07-28 revision flagged throughout.
Spec currency check — read this first. The current stable protocol revision is 2025-11-25 — treat this as your exam baseline (it's what the exam tests today). The remote transport you must know is Streamable HTTP (2025-03-26); the old HTTP+SSE (2024-11-05) is deprecated; authorization is OAuth 2.1.
A big revision is imminent. 2026-07-28 is a locked Release Candidate (final 28 Jul 2026) — the largest change since launch. It makes MCP stateless: the initialize handshake and Mcp-Session-Id are removed; Tasks & MCP Apps become extensions; Roots/Sampling/Logging are deprecated; resource-not-found moves -32002 → -32602. Throughout this guide, an 2026-07-28 RC flag marks each baseline answer that flips in the new revision. See Spec Watch.
Where the exam weight lives — study time should mirror this
A major new revision was about to land when this guide was written. Here's exactly where things stood as of 11 Jul 2026, and what to do about it. Update: 2026-07-28 shipped as a final release on 28 July 2026. The MCP Goes Stateless guide covers the final delta.
How to use this on the exam. The MCPA blueprint is written against the current stable spec (2025-11-25), so if a question turns on the handshake, sessions, or the -32002 code, answer per the baseline. But the 2026-07-28 RC is public and finalizes in weeks — a refreshed exam could adopt it. When a question's wording sounds "stateless / _meta / server/discover / extension," it's testing the new revision. The flags below tell you which is which.
| Area | 2025-11-25 (baseline) | 2026-07-28 RC |
|---|---|---|
| Handshake | initialize → result → initialized | Removed. Stateless: version + clientInfo + capabilities ride in _meta on every request; new server/discover RPC advertises capabilities |
| Sessions | Mcp-Session-Id header | Removed. Any request lands on any instance; carry state via server-minted handles passed as tool args |
| Server→client calls | Server-initiated sampling/createMessage, elicitation/create, roots/list | Replaced by Multi Round-Trip Requests: server returns InputRequiredResult (resultType:"input_required"); client retries with inputResponses |
| Deprecations | Roots, Sampling, Logging all active | All three deprecated (SEP-2577). Roots→tool params/URIs; Sampling→direct LLM APIs; Logging→stderr / OpenTelemetry |
| Tasks | Experimental core feature | Graduated to an official extension (tasks/get polling, tasks/update; tasks/list removed) |
| Extensions | — | New extensions framework (reverse-DNS IDs, extensions capability map). Official: MCP Apps (sandboxed HTML UIs), Tasks |
| Change notices | GET SSE stream; resources/subscribe | Single subscriptions/listen stream + cache hints (ttlMs, cacheScope) on list/read results |
| Routing headers | — | Required Mcp-Method + Mcp-Name headers (route without body inspection) |
| Error code | Resource not found = -32002 | Changes to -32602 (Invalid Params). MCP reserves -32020…-32099 |
| Tool schemas | 2020-12; structuredContent = object | Full 2020-12 (oneOf/anyOf/$ref); structuredContent = any JSON value |
| Auth | OAuth 2.1 + DCR / Client ID Metadata Docs | Same base, hardened: validate iss (RFC 9207), issuer-bound creds; DCR now deprecated in favor of Client ID Metadata Documents |
Unchanged and safe to over-learn: the host/client/server model, the three server primitives and their control model, tool-invocation flow, OAuth 2.1 fundamentals (PKCE, resource indicators, audience validation, no token passthrough), and the whole security threat model. The RC re-plumbs transport & lifecycle, not MCP's core value or its trust model.
No prerequisites are required, but the blueprint recommends this foundation. Every item below shows up indirectly on the exam. Skim if you know it; drill the JSON-RPC and OAuth pieces if you don't.
MCP is JSON-RPC 2.0 over a transport. Every message is one of three shapes. All must be UTF-8.
Has id + method (+ optional params). Expects a matching response.
Has the same id and either a result or an error — never both.
Has method but no id → fire-and-forget, no response expected (e.g. notifications/initialized).
// Request
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": { "name": "get_weather", "arguments": { "location": "NYC" } } }
// Success response // Error response
{ "jsonrpc":"2.0","id":1, { "jsonrpc":"2.0","id":1,
"result": { ... } } "error": { "code":-32602, "message":"..." } }
// Notification (no id → no reply)
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
Remember: id present ⇒ a response is owed. id absent ⇒ it's a notification, no response. A response carries either result or error.
Authorization: Bearer <token> on every request. Never in a URL query string.An MCP server advertises what it can do during the initialize handshake and via */list calls. Being able to read a tool definition — name, description, inputSchema (JSON Schema), optional outputSchema and annotations — is an explicit exam skill.
Purpose & scope · core concepts · interoperability & value
The Model Context Protocol is an open standard that gives AI applications a uniform way to connect models to external tools, data, and context. Anthropic introduced it in November 2024; it is now community-governed. The canonical framing:
The "USB-C for AI" analogy. Before MCP, every model-to-tool connection was a bespoke integration — an M × N problem (M apps × N tools). MCP turns it into M + N: build a server once, and any MCP-compatible client can use it. One standard port, many peripherals.
What they'll test. The M×N → M+N reframing; that MCP is an open protocol not a product; that its job is standardizing context/tool access; and the vocabulary of hosts/clients/servers and the three primitives. Expect "which of these is a benefit of MCP?" and "what problem does MCP solve?" style items.
Schemas & structured data · hosts / clients / servers · model interaction flow
Host / Client / Server — the participant model
The user-facing app that contains the LLM (e.g. Claude Desktop, an IDE, an agent). Owns the model, the UI, user consent, and the security policy. Spawns one client per server connection.
Exposes tools, resources, and prompts. Runs locally (stdio) or remotely (Streamable HTTP). Holds its own credentials to the systems behind it.
Databases, SaaS APIs, filesystems, the web. The server brokers access to these — the client/model never touches them directly.
inputSchema) and optional outputs (outputSchema) are described with JSON Schema. As of 2025-11-25 the default dialect is JSON Schema 2020-12.structuredContent object (validated against outputSchema) in addition to human-readable content blocks.capabilities object at initialize time (see Domain 3).What they'll test. Which role does what — especially that the host holds the model and consent, the client is 1:1 with a server and isolated, and the server exposes capabilities. Also: schemas are JSON Schema; a server can be local or remote.
interaction patterns & response handling · error handling · tool invocation lifecycle · protocol primitives
Initialize handshake & capability negotiation
initialize request — sends its protocolVersion, capabilities (roots, sampling, elicitation), and clientInfo.initialize result — echoes an agreed protocolVersion, its own capabilities (tools, resources, prompts, logging, completions), serverInfo, optional instructions.notifications/initialized — a notification (no id). Only now may normal operations begin.ping (and server logging) may be sent.2026-07-28 RC The handshake is removed — MCP becomes stateless. There is no initialize/initialized exchange; every request instead carries its protocol version, clientInfo, and capabilities in _meta (keys like io.modelcontextprotocol/protocolVersion). Servers must implement server/discover to advertise versions & capabilities; a version mismatch returns UnsupportedProtocolVersionError. Baseline answer for the exam today: the handshake still exists.
| Phase | Purpose | Key messages |
|---|---|---|
| Initialization | Agree protocol version; negotiate capabilities; exchange identity | initialize req/resp, then notifications/initialized |
| Operation | Normal work using only negotiated capabilities | tools/*, resources/*, prompts/*, notifications |
| Shutdown | Clean close — no MCP message, done at transport level | stdio: close stdin → SIGTERM → SIGKILL · HTTP: close connection |
Discovery → selection → invocation → result
tools/list; server returns tool definitions (name, description, inputSchema). Supports pagination via cursor.tools/call with name + arguments (validated against the schema).content[] (text/image/audio/resource_link/embedded resource) and/or structuredContent, plus isError.listChanged, it can emit notifications/tools/list_changed; the client re-lists.Three server primitives, distinguished by who controls them. This "who controls what" mental model is the single most-tested idea in this domain.
| Primitive | Controlled by | Discover / use | Purpose | Analogy |
|---|---|---|---|---|
| Tools | Model (AI decides) | tools/list → tools/call | Take actions / cause effects | Function call · POST |
| Resources | Application (host decides) | resources/list → resources/read | Supply read-only context/data | File / GET |
| Prompts | User (person selects) | prompts/list → prompts/get | Reusable templated workflows | Slash command |
MCP also defines client primitives — capabilities a server can call back into the client (declared by the client at initialize):
| Capability | What it does | Human in loop? |
|---|---|---|
| Roots | Client tells the server which filesystem/URI boundaries it may operate within | Configured by host |
| Sampling | Server asks the client's LLM to generate a completion (2025-11-25 adds tool-calling to sampling) | Yes — user approves |
| Elicitation | Server asks the user for structured input mid-flow (2025-11-25 adds URL-mode + richer enums) | Yes — user provides |
2026-07-28 RC Roots and Sampling are deprecated (along with Logging). And server-initiated callbacks disappear: instead of the server calling the client (sampling/createMessage, elicitation/create, roots/list), the server returns an InputRequiredResult and the client retries the original request with inputResponses — the Multi Round-Trip Request (MRTR) pattern, which keeps everything stateless. Baseline exam answer: these are still live server→client requests.
The #1 gotcha in this domain. MCP separates protocol errors from tool execution errors. They live in different parts of the message and behave differently.
error objectTransport/protocol-level failures: unknown method, malformed request, unknown tool name, server crash. Returned as { "error": { "code": -32602, ... } }. The model does not see this as a tool result.
result with isError: trueThe tool ran but failed its job: API rate-limited, bad business data, etc. Returned inside a normal result so the model can see it and self-correct. As of 2025-11-25, input-validation errors should also be returned this way (not as protocol errors) to let the model retry.
// Protocol error — unknown tool
{ "jsonrpc":"2.0","id":3, "error":{ "code":-32602, "message":"Unknown tool: foo" } }
// Tool execution error — tool ran, but failed (model sees this)
{ "jsonrpc":"2.0","id":4, "result":{
"content":[{ "type":"text","text":"API rate limit exceeded" }],
"isError": true } }
2026-07-28 RC The protocol-error vs isError split is unchanged, but two details move: resource-not-found changes from -32002 to -32602 (Invalid Params), and MCP now reserves the -32020…-32099 band for spec-defined codes. The isError:true convention for tool-execution failures stays exactly the same.
What they'll test (heavily). The initialize handshake order (init → result → initialized notification); who controls tools vs resources vs prompts; the tool-call lifecycle; and protocol-error vs isError tool-execution-error. Know the standard error codes (see cheat sheet) and that unknown-tool = -32602 protocol error, while a failed tool run = isError:true.
trust boundaries · permissions & consent · risk & safety controls · auditability & observability
Where trust changes hands — each boundary is a control point
The host must obtain informed consent and present clear UI: which tools are exposed, visual indicators when a tool runs, confirmation prompts for sensitive actions.
Each server is isolated behind its own client. The client must treat server-supplied content (descriptions, tool annotations) as untrusted unless the server is trusted. Capabilities gate what's even possible.
The server uses its own credentials/token for downstream systems. It must not pass the client's token through to the API (see confused deputy / token passthrough).
The spec's trust-&-safety principles: user consent and control, data privacy, tool safety (treat descriptions as untrusted; confirm before running), and LLM sampling controls (user approves what the model is asked to generate).
Authorization is optional and applies to HTTP-based transports. stdio servers use environment credentials instead. When present, the MCP server is an OAuth 2.1 Resource Server; a separate Authorization Server issues tokens.
Discovery & token flow (abridged)
401 Unauthorized + WWW-Authenticate header pointing at resource metadata.Authorization: Bearer <token> on every request — never in the query string. Server validates the audience before acting.WWW-Authenticate — the client starts least-privilege and elevates only when a privileged op is attempted.2026-07-28 RC Still OAuth 2.1 — the fundamentals below don't change — but hardened: clients must validate the iss parameter (RFC 9207) before redeeming a code, credentials are bound to their issuing authorization server, and clients declare an application_type at registration. Note Dynamic Client Registration is now deprecated in favor of Client ID Metadata Documents.
| Threat | What happens | Mitigation |
|---|---|---|
| Token passthrough | Server forwards the client's token to a downstream API unchanged | Forbidden. Server validates token audience = itself; uses its own token downstream |
| Confused deputy | Proxy with static client ID + DCR + consent cookie lets an attacker skip consent | Per-client consent before forwarding to 3rd-party auth; validate exact redirect_uri |
| Session hijacking | Guessable/reused Mcp-Session-Id lets an attacker impersonate | Non-deterministic IDs; bind to user (user:session); never use sessions for auth |
| SSRF | Malicious server's metadata URLs point at internal / cloud-metadata endpoints | HTTPS only; block private IP ranges; validate redirects; egress proxy |
| Prompt injection | Untrusted content steers the model into unwanted tool calls | Human-in-loop deny; show tool inputs; annotations untrusted unless server trusted |
| Malicious local server | Poisoned startup command runs arbitrary code with client privileges | Show exact command + consent before run; sandbox; prefer stdio isolation |
| Malicious OAuth URL | javascript:/data: scheme in an auth URL → XSS/RCE | Allowlist http(s) only; no shell execution to open URLs |
notifications/message) at standard severity levels.CancelledNotification.2026-07-28 RC The logging capability is deprecated — servers log to stderr (stdio) or emit OpenTelemetry instead, with W3C trace context (traceparent/tracestate/baggage) carried in _meta. The consent, audit-logging, and human-in-the-loop principles are unchanged; only the built-in logging mechanism moves.
What they'll test (heavily). Token passthrough is forbidden and why (breaks audience/audit/trust). OAuth 2.1 = mandatory PKCE + resource indicators + audience validation; bearer token in header not query string; stdio uses env creds. The consent/human-in-loop principles. Session IDs must not be used for auth. Match each named attack to its mitigation.
roles / responsibilities / adoption · operational use cases · ecosystem & portability
server.json format helps discovery and distribution of servers.YYYY-MM-DD), incremented only on backwards-incompatible change.What they'll test. Matching responsibilities to roles; recognizing realistic MCP use cases vs things MCP doesn't do; and the portability/interop value proposition (one server → many hosts/models). Light on trivia, heavy on "which scenario fits MCP."
| Code | Name | When |
|---|---|---|
| -32700 | Parse error | Invalid JSON received |
| -32600 | Invalid Request | Not a valid JSON-RPC envelope |
| -32601 | Method not found | Unknown/unsupported method |
| -32602 | Invalid params | Bad args, missing required, unknown tool name |
| -32603 | Internal error | Generic server-side failure |
| -32002 | Resource not found | MCP-specific: resources/read on missing URI |
| -32000 to -32099 | Server error | Reserved for implementation-defined errors |
Remember: a tool that runs but fails is not a code above — it's a normal result with isError:true.
2026-07-28 RC Resource-not-found moves from -32002 to -32602; the MCP spec reserves -32020…-32099 for its own codes (-32000…-32019 stays implementation-defined). The generic JSON-RPC codes above are unchanged.
| stdio | Streamable HTTP | HTTP+SSE | |
|---|---|---|---|
| Status | Current | Current (remote) | Deprecated |
| Introduced | Original | 2025-03-26 | 2024-11-05 |
| Topology | Local subprocess | Remote, multi-client | Remote |
| Channel | stdin / stdout (newline-delimited) | One endpoint: POST + optional GET/SSE | Two endpoints |
| Session | Process lifetime | Mcp-Session-Id header | — |
| Auth | Env variables | OAuth 2.1 + Bearer | — |
| Version hdr | n/a | MCP-Protocol-Version | n/a |
Streamable HTTP security must-knows: validate Origin (return 403 if bad, per 2025-11-25), bind to localhost when local, use HTTPS — to stop DNS-rebinding.
2026-07-28 RC Streamable HTTP goes stateless: the Mcp-Session-Id header and SSE resumability (Last-Event-ID) are removed; POSTs must carry Mcp-Method + Mcp-Name routing headers; list/read results gain ttlMs + cacheScope cache hints; and change notices use one subscriptions/listen stream. HTTP+SSE is now formally reclassified Deprecated under the lifecycle policy.
| Primitive | Who controls | Methods |
|---|---|---|
| Tools | Model | tools/list, tools/call |
| Resources | Application | resources/list, resources/read, resources/subscribe |
| Prompts | User | prompts/list, prompts/get |
| Roots | Client | declared capability; roots/list |
| Sampling | Client (user-approved) | sampling/createMessage |
| Elicitation | Client (user-provided) | elicitation/create |
22 items, deliberately over-weighted to Domains 3 (26%) and 4 (24%), with two on the incoming 2026-07-28 revision. Tap Show answer to reveal the explanation. Try to answer before revealing.
A client calls a tool that doesn't exist on the server. How does the server respond?
result with isError: trueerror with code -32602notifications/tools/list_changedB. An unknown tool name is a protocol error → JSON-RPC error, code -32602 (Invalid params). It is not a tool execution error, because the tool never ran. isError:true is only for a tool that ran and failed.
Which message correctly ends the initialization phase and permits normal operations?
initialize resultinitialize requestnotifications/initializedping from either sideC. Order is: client initialize request → server initialize result → client notifications/initialized (a notification, no id). Only after that notification may non-ping operations begin.
Tools, resources, and prompts differ chiefly by who controls them. Match correctly.
B. Tools = model-controlled (AI decides to call), Resources = application-controlled (host decides what context to include), Prompts = user-controlled (person selects, e.g. a slash command).
A tool executes but the downstream API is rate-limited. The best-practice response is:
error with code -32603result with content describing the failure and isError: trueB. The tool ran but failed its job → a tool execution error reported in the result with isError:true, so the model can see it and self-correct/retry.
Which is a client primitive (a capability a server can invoke on the client)?
D. Sampling (plus roots and elicitation) is a client primitive — the server asks the client's LLM to generate, subject to user approval. Tools/resources/prompts are server primitives.
A message has a method but no id. It is a:
C. No id ⇒ notification (fire-and-forget, no response expected), e.g. notifications/initialized or list_changed.
How does a server tell clients that its available tools have changed at runtime?
notifications/tools/list_changed (if it declared listChanged)isError:trueB. If the server declared the listChanged capability, it emits notifications/tools/list_changed; the client then re-issues tools/list.
Which best describes structured tool output in the current spec?
structuredContent validated against an outputSchemacontent entirelyB. A tool may declare an outputSchema and return a typed structuredContent object; for backwards compatibility it should also mirror it as serialized JSON text in a content block.
An MCP server receives a client token and forwards it unchanged to a downstream API. This is:
B. Token passthrough is forbidden. It breaks audience validation, corrupts the audit trail, and violates trust boundaries. The server must validate the token's audience is itself, and obtain its own token for the downstream API.
MCP authorization is based on which standard, and where does it apply?
C. OAuth 2.1, for HTTP-based transports. stdio servers should not use this flow — they take credentials from the environment.
Which is mandatory for MCP OAuth clients to prevent authorization-code interception?
A. PKCE is mandatory (OAuth 2.1). Tokens go in the Authorization header, never the query string; access tokens should be short-lived.
What does the resource parameter (RFC 8707) accomplish in MCP auth?
B. Resource indicators name the target server so the issued token is audience-bound — it can't be replayed against a different service. Servers must validate they are the intended audience.
Because tools are model-controlled, the primary safety backstop against prompt-injection-driven tool calls is:
B. The spec says there should always be a human in the loop with the ability to deny tool invocations, plus clear UI showing which tools are exposed and what inputs are sent.
A confused-deputy attack on an MCP proxy is prevented primarily by:
C. The proxy must obtain per-client consent and validate the exact redirect_uri before initiating the third-party flow — so a leftover consent cookie can't be abused.
Which statement about MCP session IDs is correct?
C. Use secure, non-deterministic IDs; bind them to the user (user:session); and never use sessions for authentication — verify every inbound request.
A malicious server returns metadata URLs pointing at http://169.254.169.254/. This targets:
B. That's the link-local cloud metadata address — a classic SSRF target. Mitigate by requiring HTTPS, blocking private/reserved IP ranges, and validating redirects.
Why must clients treat tool annotations (like readOnlyHint) with caution?
B. Annotations are server-supplied hints; a malicious server could lie. Clients must consider them untrusted unless they come from a trusted server — never let a hint bypass consent.
The clearest statement of MCP's core value is:
B. One standard connection layer means a server built once works with any compliant host/model — M×N → M+N. It's a protocol, not a model or an HTTP replacement.
In MCP's participant model, the relationship between clients and servers is:
B. The host spawns one client per server, each isolated (1:1). This isolation is a security boundary as well as an architectural one.
Which scenario is the best fit for MCP?
B. MCP standardizes how a host/model reaches external tools and data with negotiated capabilities and consent — exactly the DB + ticketing integration case. It doesn't train models or serve websites.
In the 2026-07-28 revision, how does a client learn a server's protocol version and capabilities, given the initialize handshake was removed?
_meta, and the server implements a server/discover RPCMcp-Session-Id headerB. The RC makes MCP stateless: version, clientInfo, and capabilities travel in _meta on every request, and servers must implement server/discover for up-front capability/version discovery. There is no handshake and no Mcp-Session-Id. (On today's stable exam, the answer would instead be the initialize handshake.)
Which set of features does the 2026-07-28 revision deprecate?
B. Roots, Sampling, and Logging are deprecated (SEP-2577) — migrate to tool params/resource URIs, direct LLM-provider APIs, and stderr/OpenTelemetry respectively. They remain functional for 12+ months. The core primitives and the OAuth 2.1 mechanics are not deprecated.
A focused 7-day pass, front-loading the two heavy domains. Adjust to your pace; the ordering (weight-first) is the point.
| Day | Focus | Do |
|---|---|---|
| 1 | Fundamentals + Architecture (30%) | Read the spec overview + architecture; draw the host/client/server diagram from memory |
| 2–3 | Interactions & Execution (26%) | Lifecycle, primitives control matrix, error handling; hand-trace an initialize + tools/call |
| 4–5 | Security & Governance (24%) | OAuth 2.1 flow, trust boundaries, the threat→mitigation table; explain token passthrough out loud |
| 6 | Use Cases & Ecosystem (20%) | Roles, use cases, portability; skim SDKs + registry + governance |
| 7 | Review + drill | Redo all 20 practice Qs cold; re-read every "What they'll test" box; memorize error codes + transports |
isError:true tool execution error, with examples.Mcp-Session-Id), MRTR, Tasks/MCP-Apps as extensions, Roots/Sampling/Logging deprecated, -32002→-32602.Before you sit: run the proctor's system check ahead of time, clear your desk, have government ID ready, and confirm a stable connection. Verify current price, question count, and passing score on the official LF exam page (they can change and aren't always published).
All links verified against live pages on 2026-07-10. The specification is the authoritative source; study it directly.
How-To Guides · Published 10 July 2026
Built from public sources. Plans, prices and versions change: check the linked sources before you rely on them.
Get new guides by emailOne short note when a new How-To Guide lands. Free.
Get new guides by emailBrowse all guides