Inside MCP
The Model Context Protocol from the wire up: who the roles are, every JSON-RPC message in both protocol eras, stdio and HTTP, OAuth, running behind a load balancer, what tools cost in context, how servers get attacked, and when a skill or a CLI is the better choice.
17 lessons in 6 modules, about three and a half hours. Each has animated diagrams, something to try, and a quick check. Checked against specification revision 2026-07-28.
How each lesson works
The course follows one loop: see it, run it, break it, explain it.
- See itAnimated diagrams you can play, pause and step.
- Run itReal lab code that prints every byte on the wire.
- Break itFaults and attacks on purpose, predicted first.
- Explain itA quick check, then a paragraph in your own words.
Lessons
- Host, client and server
- What the node command does
- Not OAuth, not quite REST
- Two eras: legacy and modern
- The lifecycle, step by step
- When the server needs input
- stdio and Streamable HTTP
- The OAuth flow for remote servers
- Threats: poisoning and friends
- A package or a URL
- Stateless behind a load balancer
- One flat list of tools
- Servers come and go
- The context bill
- MCP, a skill, or a CLI?
- Why use an SDK
- Run, break, explain: the labs
Also: the course roadmap (where the hands-on phases stand), the glossary, and sources and credits.
Questions asked along the way
These came up while the course was being written. Each short answer links to the lesson that answers it properly.
Is MCP like OAuth 2.0 with PKCE?
No. They sit at different layers. MCP is an application protocol: JSON-RPC 2.0 messages for tools, resources and prompts, closest in spirit to the Language Server Protocol. OAuth 2.1 with PKCE is MCP's authorization layer, and it applies only to the HTTP transport. A local stdio server takes credentials from its environment instead.
What does Claude do with the node command in my config?
It starts that program as a child process on your machine, wires its stdin and stdout to an MCP client, asks it what it offers, puts the tool descriptions in the model's prompt, and writes a tools/call line whenever the model chooses a tool. Closing stdin shuts it down. Adding a local server means running that program with your own permissions.
Isn't it just a REST API with a spec?
Half right: JSON over HTTP POST, bearer tokens, and a stateless server in the current revision. But the consumer is a language model that discovers tools at run time and reads their descriptions as instructions; it is one RPC endpoint rather than resources and verbs; the server can ask the client for user input or a model completion; versions and capabilities ride on every request; and server text lands inside the model's prompt, which creates a trust problem REST never had.
Ship a package people install, or host a URL?
Host a URL for anything that touches company data or a SaaS API: one deployment, central OAuth, audit and revocation, nothing executing on laptops. Ship a stdio package only when the server must reach the user's own machine: files, the IDE, a local browser or database. With the SDK both can come from the same factory.
Behind a load balancer, how does the server know who I am?
From the request itself. Every POST carries the bearer token; the server validates it and hands the principal to the handler. No replica remembers you between requests, so no sticky routing is needed. Your application data lives in your database, and a half-finished interaction travels with the client as a signed requestState.
Does an agent notice a server appearing, failing or coming back?
Only through the host. The protocol never announces new servers: the host is told by config or a gateway, connects, and the model sees the new tools on its next turn. A server can change its own tools live through a subscriptions/listen stream. When one dies, calls to it fail as tool errors and the conversation carries on; when it returns there is no session to rebuild, so the client just re-listens and re-lists.
Why use an MCP library at all?
It is the plumbing: framing, id correlation, server/discover, version errors, schema validation, header checks, streaming, cancellation, the input-required round trip and both protocol eras. You write tool logic. It does not validate tokens, judge tool descriptions or protect requestState unless you ask it to.
When is a skill better than an MCP server?
Use MCP when the agent must reach something: a live system, a write action, per-user authorization. Use a skill when it must know how to do something: a procedure, a house style. Use a CLI with a short skill when a good command-line tool already exists. Most teams use both, often a skill that teaches the agent how to use a server well.
What is a stdio server, and what does "packaging" one mean?
A stdio server is an MCP server that runs as a program on your own machine. The host (Claude Desktop, Claude Code, an IDE) starts it as a child process and talks to it through its standard input and output, one JSON-RPC message per line. You never start it yourself; the host does, from a config entry like "command": "node", "args": ["server.js"].
"Packaging" means publishing that program to a registry such as npm, so other people can use it without cloning your code: their config says "command": "npx", "args": ["-y", "your-server"] and the host downloads and starts it. The other way to share a server is to host it at a URL over HTTP, with nothing to install.