Pillar 4 · Knowledge · Advanced

MCP Advanced: Sampling, Notifications, Roots, Transports.

This course extends the MCP foundations with the capabilities production servers actually need: sampling (server asks the client to call the model), log and progress notifications (server streams updates), roots (server reads files only inside client-allowed boundaries), and the two transports (stdio for local subprocesses and streamable-http for remote, multi-client deployments). You also dig into the JSON message types underneath so you can debug at the wire level. Finish here and you can ship an MCP server that handles long-running work, respects security boundaries, and runs at scale.

15 Skilljar lessons·~95 min on Skilljar·D2 + D3

Mirrors Anthropic's Model Context Protocol: Advanced Topics course on Skilljar.

Original course15 lessons · ~95 min
Model Context Protocol: Advanced Topics
Take it on Anthropic Skilljar ↗
MCP Advanced: Sampling, Notifications, Roots, Transports, painterly hero showing the course's central concept with the Loop mascot as guide.
01 · What you'll learn

You'll walk away with

  1. How sampling lets a server delegate LLM calls back to the client (and why that beats putting an API key on the server)
  2. How to emit log and progress notifications during long-running tool calls so the client can render real-time feedback
  3. What roots are, why they matter for filesystem security, and how a server enumerates and respects them
  4. The full JSON-RPC 2.0 message vocabulary MCP uses (request, response, notification, error)
  5. When to choose stdio vs streamable-http transport, and how state and reconnection differ between them
  6. How session state works in streamable-http and the failure modes to design around
02 · Prerequisites

Read these first

03 · The course mirror

Lesson outline

Every lesson from Model Context Protocol: Advanced Topics with our one-line simplification. The Skilljar course is the source; we summarize.

#Skilljar lessonOur simplification
1Let's get started!Course framing: the four advanced surfaces are sampling, notifications, roots, and transports. Each fixes a real production gap.
2SamplingSampling lets a server ask the client to make an LLM call on its behalf, so secrets and model choice stay on the client.
3Sampling walkthroughEnd-to-end: server requests sampling/createMessage, client prompts user (optional), invokes model, returns the completion.
4Log and progress notificationsNotifications are one-way messages: notifications/message for logs, notifications/progress for percent-complete on long calls.
5Notifications walkthroughHands-on: emit progress with a token from the request, stream log lines, watch them surface in the client UI.
6RootsRoots are filesystem boundaries the client publishes; the server enumerates them via roots/list and stays inside them.
7Roots walkthroughWire a server that respects roots, listens for roots/list_changed, and refuses access outside the published set.
8SurveyMid-course feedback checkpoint; no technical content.
9JSON message typesMCP rides JSON-RPC 2.0: requests have id and expect a response, notifications have no id and never get one.
10The STDIO transportstdio is the default for local servers: client spawns the server as a subprocess, messages flow over stdin/stdout, length-prefixed.
11The StreamableHTTP transportstreamable-http is the remote transport: HTTP POST for requests, optional SSE for server-to-client streaming, sessions over Mcp-Session-Id header.
12StreamableHTTP in depthWalk through the headers, session lifecycle, GET-for-stream pattern, and resume tokens; this is the layer to debug when production breaks.
13State and the StreamableHTTP transportSessions are sticky to a server instance; for horizontal scaling either pin sessions or externalize state to Redis or similar.
14Assessment on MCP conceptsFinal assessment covering all four advanced surfaces.
15Wrapping upRecap and pointers: combine these surfaces to ship a production-ready MCP server with security and observability.
04 · Our simplification

The course in 7 paragraphs

MCP Foundations gave you tools, resources, and prompts. That gets you a working server. Production servers need four more capabilities, and this course is built around them: sampling, notifications, roots, and the two transports. Each one solves a problem you hit the moment a real team starts using your server. Skip them and your server breaks the first time a tool call takes 30 seconds, or the moment your security review asks where the LLM API key lives.

Sampling is the most counterintuitive of the four. It lets the server ask the *client* to make an LLM call on the server's behalf. That sounds backwards until you realize it solves a real problem: the client already has an API key, model preference, and rate limits configured. Putting another LLM key on the server doubles the surface area of secrets and model-version drift. With sampling, the server requests sampling/createMessage, the client (optionally) shows the user what's about to be sent, the client invokes the model, and the response comes back. Common use case: a database-querying server that wants to summarize a result in natural language without ever holding an Anthropic key.

Log and progress notifications are the streaming layer. A long-running tool call (a 30-second build, a multi-step research task) needs to give the client feedback or the user thinks the system has hung. MCP defines two notification flavors: notifications/message for log lines (with severity levels) and notifications/progress for percent-complete updates tied to a progress token included in the original request. The notifications are one-way: the client doesn't ack them, and the server doesn't expect a response. The Python SDK exposes ctx.report_progress() and ctx.log() so you don't write JSON-RPC by hand.

Roots are the security boundary the spec adds for filesystem access. A client publishes a list of roots, meaning directories the server is allowed to read. The server queries them with roots/list and listens for roots/list_changed to react to live changes. This is the spec's answer to "how do I let an MCP filesystem server work without giving it /". The server still implements its own enforcement (the spec is advisory at the protocol layer), but a well-behaved server treats roots as a hard fence and rejects paths that fall outside. Expect exam questions on which side enforces the boundary (server) vs which side declares it (client).

Underneath all four surfaces is JSON-RPC 2.0. MCP uses three message shapes: requests (have id, expect a response), responses (carry the matching id, return result or error), and notifications (no id, no response, fire-and-forget). Knowing this saves you when a server appears hung. Odds are you sent a notification when a request was needed, or vice versa. The Inspector and most SDKs hide the JSON, but when production breaks at 2 a.m., you read the raw frames and you need to know which is which.

Transport is the choice you make first and rarely revisit. `stdio` is the local default: the client spawns the server as a subprocess, messages flow over stdin/stdout with length prefixes, the connection lives as long as the subprocess does. Simple, secure (no network), but single-client. `streamable-http` is the remote transport: HTTP POST carries requests, optional Server-Sent Events stream server-to-client messages, and an Mcp-Session-Id header tracks per-client session state. It is the right choice for shared SaaS-style MCP servers but introduces session-stickiness, reconnection, and horizontal-scaling concerns that stdio doesn't have.

The takeaway: combine these four surfaces with the foundation primitives and you have an MCP server that can run long jobs, stream feedback, respect security boundaries, delegate model calls cleanly, and scale horizontally. Most production MCP outages trace to one of these four surfaces being skipped or misconfigured. The exam knows this; questions around "which surface fixes problem X" are reliable territory. When in doubt, run the heuristic: long-running work means notifications, server-side LLM calls means sampling, filesystem access means roots, deployment shape means transport choice. The other heuristic the exam loves is the control point. Sampling is server-requested but client-executed. Notifications are server-emitted with no client response. Roots are client-declared and server-enforced. Transport is client-chosen at connection time. Every advanced MCP question can be answered by figuring out which side owns the decision. Combine this with the foundation course's tools-resources-prompts breakdown, and you have a complete mental model of the protocol.

05 · Listicle pattern

The 4 advanced MCP surfaces and what each fixes

Every advanced MCP feature solves a specific production problem. Memorize the failure mode each one prevents.

  1. Sampling: the server delegates LLM calls

    Server calls sampling/createMessage; client invokes the model and returns the completion. Use when the server needs LLM output but you do not want to put another API key on it. Keeps model choice and secrets on the client.

    Concept: mcp
  2. Notifications: server streams progress and logs

    notifications/progress (with a token from the request) and notifications/message (with a severity level). One-way; no ack. Use for any tool call longer than a few seconds so the client UI can render feedback.

    Concept: streaming
  3. Roots: filesystem security boundary

    Client publishes a list of allowed directories. Server reads via roots/list, listens for roots/list_changed, and refuses access outside. The client declares; the server enforces. Always assume the spec is advisory and write a hard check.

    Concept: mcp
  4. Transport: `stdio` vs `streamable-http`

    stdio is local subprocess, single-client, simplest. streamable-http is remote, multi-client, with session IDs and optional SSE streaming. Pick streamable-http when many clients share one server; pick stdio for everything else.

    Concept: mcp
06 · Listicle pattern

3 transport pitfalls in production

When streamable-http MCP servers fail in production, it is almost always one of these three.

  1. Session affinity not enforced

    Mcp-Session-Id ties a client to a specific server instance's in-memory state. Without sticky routing at the load balancer, the next request hits a server that has never seen this session and 404s. Pin sessions or externalize state.

    Concept: session-state
  2. SSE connection dropped without resume

    Long-lived SSE streams die at proxies, load balancers, and on flaky mobile networks. The spec supports resume tokens; if you do not implement them, the client loses notifications on every reconnect.

    Concept: streaming
  3. Treating `stdio` like a daemon

    stdio servers live and die with the client subprocess; they do not persist. Storing in-memory state and assuming the next session will see it is wrong. Persist to disk, or accept session-scoped state.

    Concept: session-state
07 · Key takeaways

6 takeaways with cross-pillar bridges

Sampling lets the server request LLM completions through the client, keeping API keys and model choice on the client side.

Use notifications/progress with a token from the request and notifications/message for logs whenever a tool call takes more than a few seconds.

Roots are the filesystem boundary the client publishes and the server is expected to enforce; never trust the spec alone, write a hard path check.

MCP rides JSON-RPC 2.0 with three message shapes: requests carry an id, responses match by id, notifications have no id and never get a response.

Choose stdio for local single-client servers and streamable-http only when multiple clients share one server; the latter introduces session-stickiness and reconnection.

streamable-http sessions are pinned to a specific server instance via Mcp-Session-Id; horizontal scaling requires sticky routing or externalized session state.

08 · Exam mapping

How this maps to the CCA-F exam

Domains
D2 Tool Design + Integration · D3 Agent Operations
Blueprint
20% (D3) + 18% (D2)
What it advances
Direct prep for D3 task statements on production integration patterns and D2 questions on tool surface design under operational constraints. Advanced MCP topics surface in the agentic-tool-design scenario, in long-running server discussions, and in any item that contrasts stdio vs remote HTTP deployments.
09 · Curated supplementary sources

3 hand-picked extras

These amplify the Skilljar course beyond what the course itself covers. Each was picked for a specific reason.

10 · Concepts wired

Concepts in this course

11 · Scenarios in play

Where you'll see this in production

12 · Sibling Knowledge

Other course mirrors you may want next

13 · AEO FAQ

8 questions answered

Phrased as the way real students search. Tagged by intent so you can scan to what you actually need.

DefinitionWhat is MCP sampling and when should I use it?
Sampling is when an MCP server asks the client to make an LLM call on the server's behalf via sampling/createMessage. Use it when your server needs natural-language output but you do not want to put a separate Anthropic key, model preference, and rate limit on it. The client owns the model decision; the server just describes what it needs.
How-toHow do I show progress for a long-running MCP tool call?
Include a progressToken in the original request, then have the server emit notifications/progress updates with that token and a percent-complete value. Pair with notifications/message for log lines. The Python SDK exposes ctx.report_progress(progress, total) so you do not write JSON-RPC frames by hand.
DefinitionWhat are MCP roots and who enforces them?
Roots are filesystem directories the client publishes as the boundary the server is allowed to read inside. The server queries them via roots/list and reacts to roots/list_changed. The client declares; the server enforces. Treat the spec as advisory and write a hard path check, because clients vary in how strictly they police access.
ComparisonShould I use stdio or streamable-http transport for my MCP server?
Use `stdio` for local single-client servers (simplest, no network, lifetime tied to the subprocess). Use `streamable-http` when many clients share one server (Slack-team-wide deployments, hosted SaaS). The latter introduces session-stickiness, reconnection, and horizontal-scaling concerns that stdio does not have.
TroubleshootWhy is my streamable-http MCP server losing sessions when scaled to multiple instances?
Mcp-Session-Id is pinned to a specific server instance's in-memory session state. Without sticky routing at your load balancer, the next request lands on an instance that has never seen the session and returns 404. Either configure session affinity at the proxy or externalize session state to Redis or a similar shared store.
ComparisonHow is an MCP notification different from a request?
A request has an id and the receiver must respond (success or error). A notification has no `id` and the receiver must never respond. Notifications are fire-and-forget. Mixing these up is the most common source of MCP bugs at the wire level: a missing response on what you thought was a notification will hang the client forever.
ScopeDoes streamable-http require Server-Sent Events?
Not for every interaction. Requests flow over standard HTTP POST. SSE is the optional upgrade path when the server needs to stream messages to the client (notifications, sampling requests, async results). The client opens the SSE stream with a GET; the server pushes events when it has them. Without SSE you can still do request-response, just no server-initiated traffic.
How-toHow do I test the advanced MCP features without writing a full client?
Use the MCP Inspector. Run mcp dev <server-file> and the Inspector launches a local web UI that supports sampling (it will prompt you for completions), notifications (you see them stream in), roots (you can publish test roots), and both transports. It is the curl-equivalent for the protocol and the fastest way to isolate bugs.
Last reviewed: 2026-05-06·Refresh cadence: 60 days; faster when MCP spec ships a breaking version (transport changes are most likely)·View on Skilljar ↗
K · Advanced · D3 · Agent Operations

MCP Advanced: Sampling, Notifications, Roots, Transports, complete.

You've covered the full ten-section breakdown for this primitive, definition, mechanics, code, false positives, comparison, decision tree, exam patterns, and FAQ. One technical primitive down on the path to CCA-F.

Share your win →