Turning Point Academy · MCP Engineering

OAuth for MCP — Solved exercises

Curso MCP Engineering · M3


Conceptual exercises to solidify the OAuth 2.1 flow in remote MCP servers. There's no need to write code: it's about understanding the journey and why each step is where it is. Solve them on your own first; each exercise has a detailed solution further down.

Remember the map before you begin: 401 → discovery → token → validate. The client asks without credentials, the server responds 401 with a clue (WWW-Authenticate), the client does discovery, gets a JWT from the authorization server, and retries with Authorization: Bearer <token>; the server validates issuer, audience, and scope.

Exercise 1 — Order the flow

These five moments are out of order. Number them 1 to 5 in the correct order:

Exercise 2 — The missing step

A developer describes their flow like this: "The client asks, receives a 401, and then the client retries the same request expecting to be let through the second time." What essential step did they skip? Why will the retry, as described, not work?

Exercise 3 — Open discovery

The /.well-known/oauth-protected-resource endpoint responds without asking for credentials. A colleague says: "That's a security hole: anyone can query it." Are they right? Explain why that endpoint must stay open and what information it hands out (and what it does not).

Exercise 4 — Validating the JWT

Your server receives a request with a Bearer <token>. The token is correctly signed and hasn't expired. Even so, your server rejects it. Name two reasons why a well-signed and valid token can, correctly, be rejected. (Hint: think about the three fields the server validates.)

Exercise 5 — Local or remote?

For each case, decide whether it needs OAuth 2.1 (yes / no) and justify it in one line:

Exercise 6 — Translate the header

A client receives this response from the server:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://api.ejemplo.com/.well-known/oauth-protected-resource"

What should the client do next, and why did the server send it that URL instead of simply saying "no"?

Exercise 7 — The stolen token from next door

Your MCP server is api.miapp.com. An attacker got hold of a legitimate and valid JWT that another service, api.otracosa.com, issued to a real user. The attacker presents it at your server with Authorization: Bearer <that-token>. Which JWT field stops this attack, and how?

Exercise 8 — Who issues and who validates?

Complete the sentence with the correct actors (client, MCP server, authorization server): "The ______ issues the JWT; the ______ presents the JWT on each request; the ______ validates the JWT before responding." Then, explain why the MCP server can validate the token without calling the authorization server on every request.


Solutions

1 — Correct order.

  1. The client sends the first request, without credentials.
  2. The server responds 401 Unauthorized with WWW-Authenticate.
  3. The client does discovery and obtains the token from the authorization server.
  4. The client retries with Authorization: Bearer <token>.
  5. The server validates the JWT (issuer, audience, scope).

Notice that discovery and obtaining the token live together in step 3: they're the bridge between receiving the 401 and being able to retry with something in hand.

2 — The missing step. Between the 401 and the retry, the client has to obtain a token. The 401 does not mean "try again": it means "you need credentials, and here's the clue (WWW-Authenticate) to get them." Without doing discovery and obtaining the JWT from the authorization server, the retry arrives just as empty and gets 401 again. Repeating the same request without credentials is repeating the same mistake: nothing changed between the first attempt and the second.

3 — Open discovery. The colleague is not right. That endpoint must stay open precisely so a new client can get started (bootstrap) without knowing anything in advance. It only hands out metadata about where to ask for the token (who the authorization server is) — it does not hand out protected data or tokens. Knowing which door to knock on doesn't let you in: for that you still need a valid JWT. It's like having the "reception, ground floor" sign: it tells you where to go, but it doesn't open any office for you.

4 — Rejection of a signed, valid token. Either of these two reasons is enough:

The correct signature and validity are necessary but not sufficient: they say "this token is real and hasn't expired," not "this token works here and for this."

5 — Local or remote.

6 — Translate the header. The client should follow that discovery URL (/.well-known/oauth-protected-resource) to find out which authorization server to ask for the token, obtain the JWT, and retry the original request with Authorization: Bearer <token>. The server sends the URL instead of a curt "no" because the 401 is designed to be actionable: it gives the client the map to get permission on its own, without human intervention. A bare "no" would leave the client not knowing where to go.

7 — The stolen token from next door. The audience (aud) field stops it. That token was issued for api.otracosa.com, so its aud points to that service. When it reaches your server, your validation asks "was this token issued for me?" and the answer is no → you reject it. That's why validating aud is not optional: without that check, any legitimate token from any service would work in yours. The correct signature isn't enough: the token is real, but it's not for you.

8 — Who issues and who validates. "The authorization server issues the JWT; the client presents the JWT on each request; the MCP server validates the JWT before responding." The MCP server can validate without calling the authorization server because the JWT is self-verifiable: it carries the information inside and a signature that the server checks with the authorization server's public key. Like an event wristband: the security guard looks at the seal and decides on the spot, without phoning the organization. That makes validation fast and means the server doesn't have to keep a copy of every issued token.

To remember

  1. The flow is always 401 → discovery → token → validate.
  2. A 401 asks you to get credentials, not to repeat the empty request.
  3. Discovery stays open on purpose: it hands out the map, not the key.
  4. Correct signature + not expired isn't enough: the server validates issuer, audience, and scope.
  5. Audience is what keeps a token from another service from working in yours.
  6. The JWT is self-verifiable: the server validates with the signature, without calling anyone.

Turning Point Academy · MCP Engineering Course · Module 3 · OAuth exercises