Not OAuth, not quite REST
Two common first guesses: “MCP is an OAuth-style flow” and “MCP is just a REST API with a spec”. The first is wrong, the second half right. Sorting them out gives you the layer picture the rest of the course uses.
By the end of this lesson you can
- draw MCP, its authorization layer and its two transports as layers;
- say when OAuth applies and where a stdio server's credentials come from instead;
- compare MCP with a REST API on consumer, shape, direction, versioning, transports and trust;
- explain the LSP analogy and the M plus N argument.
Three layers
MCP is an application protocol: JSON-RPC 2.0 messages for tools, resources and prompts. OAuth sits at different layers: it is MCP's optional authorization layer, and it applies to one transport only.
The stack use the Show switch above to fade the other transport
- On top: MCP messages. The same JSON-RPC methods whatever carries them.
- Underneath: two transport bindings. stdio for a local subprocess, Streamable HTTP for a remote endpoint.
- Only above HTTP sits an authorization layer: OAuth 2.1 with PKCE, Protected Resource Metadata (RFC 9728) and the resource parameter (RFC 8707).
- A stdio server has no OAuth: it gets credentials from the environment the host passes it. stdio servers SHOULD NOT use OAuth.
- On HTTP the result of the OAuth flow, a bearer token, rides on every POST in the
Authorizationheader. Lesson 8 walks the whole flow.
| MCP | OAuth 2.1 with PKCE | |
|---|---|---|
| Kind | Application RPC protocol | Authorization framework |
| Closest relative | Language Server Protocol | Other delegated-access grants |
| Purpose | An AI application talking to tools and data | Getting a scoped access token for a user |
| Relationship | MCP uses OAuth as its authorization layer, on HTTP only. The full flow. | |
Which layer does that?
Sort each job into the layer responsible for it.
- Defines
tools/calland the shape of its result. That is the protocol itself: the same on stdio and HTTP. - Gets a token for one user, scoped to one MCP server. The OAuth flow, with the resource parameter naming the server.
- Frames each message as exactly one line on stdin. Framing is the stdio transport binding's job.
- Says an unsupported protocol version gets error
-32022. A protocol-level error, identical on both transports. - Uses a PKCE code verifier so a stolen authorization code is useless. PKCE is part of OAuth 2.1.
- Cancels a request by closing the HTTP response stream. How cancellation is signalled depends on the transport (on stdio it is a notification).
Not quite REST
“A way to talk to an external service with an agreed spec” is half right. In the current revision it is even JSON over HTTP POST, with bearer tokens and a stateless server. The differences are where the interesting engineering is.
| REST API | MCP | |
|---|---|---|
| Consumer | A developer who reads docs at build time | A model that discovers tools at run time and reads descriptions as instructions |
| Shape | Resources and verbs, many URLs | One endpoint, named methods (RPC) |
| Direction | Client asks, server answers | Server can ask the client for user input, a model completion or roots, inside its result |
| Versioning | In the URL or a header, chosen by you | Protocol version and client capabilities on every request |
| Transports | HTTP | stdio and HTTP, identical messages |
| Trust | Response data is data | Server-written text enters the model's prompt, so it can steer the model |
Common misconception
“MCP replaces my REST API.” Usually it wraps it. Your REST API sits behind the MCP server, which turns it into a handful of well-described tools a model can use.
The better analogy: LSP
MCP is a standard adapter that turns any API into function-calling tools, the way the Language Server Protocol turns any compiler into editor features. The specification names LSP as its inspiration. The payoff is the same: integrations add up instead of multiplying.
From M × N to M + N
- Without a shared protocol, every host writes its own integration for every service.
- Three hosts and three services: nine adapters, each maintained separately. M × N.
- With MCP, each host implements the client side once and each service exposes one server.
- Three plus three: six. Add a host or a service and you write one more, not three. M + N, exactly what LSP did for editors and languages.
Quick check
A local stdio server needs a GitHub token. How should it get one?
Which difference from REST creates a security problem REST never had?
Four hosts want to use five services. With MCP, roughly how many integrations are written?
Recap
- MCP is the message layer; OAuth is an optional authorization layer used only on Streamable HTTP; stdio takes credentials from the environment.
- MCP vs REST: a model as consumer, one RPC endpoint, the server can ask back, versions on every request, two transports, and server text in the prompt.
- The right analogy is LSP: a standard adapter, so integrations go from M × N to M + N.