A callback is supposed to be a doorway, not a courier.
That distinction keeps getting lost because the doorway looks like a URL and URLs are very good at pretending they are harmless. A redirect arrives with a code, a state value, a path, a host, maybe a fragment nobody meant to expose, maybe a token someone was in a hurry to pass along. The handler receives a string and the system has to decide whether this is consent, debris, or a leak wearing a success shape.
The dangerous version is the helpful one.
It says yes because the host is familiar. It says yes because the route exists. It says yes because some OAuth thing happened upstream and the handler would like to be done with ceremony. Then the MCP server, the tool bridge, or the agent surface inherits a secret it was never supposed to see. The receipt becomes a payload. The proof becomes luggage. The boundary becomes gossip.
Remote agent interfaces cannot afford that kind of friendliness.
A good auth boundary is almost boring. HTTPS only. Exact redirect only. Exact state only. Authorization code present. No access token in the query. No refresh token in the query. No ID token in the query. No fragment full of accidental authority. The receipt records that a code existed and hashes the state. It does not preserve the code. It does not preserve the state. It does not smuggle the thing it was meant to protect into the logs that prove protection happened.
This feels small because the fix is small. A parser. A few named refusals. A test that proves the wrong path is wrong. Another test that proves a token-shaped shortcut dies before any MCP handler runs. Documentation that refuses to pretend the stdio server magically gained OAuth because a remote deployment wanted browser-shaped convenience.
Small is where most safety actually lives.
The large architecture words arrive later: consent, delegation, protected resource metadata, bearer credentials, remote MCP clients. They matter. They also hide the first job, which is to keep the wrong bytes from crossing the seam. If a callback can carry raw authority into the agent runtime, the rest of the architecture is already negotiating with a spill.
Agents make this sharper because they read receipts as instructions. A human sees a messy callback and thinks something broke. An agent sees a successful response and may build a plan on top of it. It may cache the wrong conclusion, retry the wrong credential, or teach the next call that secrets travel through visible strings. The first mistake becomes a style guide.
So the callback should stay empty of authority.
Not empty of meaning. It can still prove shape. It can still prove state. It can still prove that an authorization code was delivered to the proxy that knows what to do next. But the MCP handler does not need the token. The model does not need the token. The trace does not need the token. The public receipt does not need the token.
This is the recurring lesson under different masks. A manifest should not make the consumer eat an infinite schema. A payment failure should not degrade into a free answer. A tools list should not export networks the provider cannot serve. A callback should not carry secrets across the boundary just because the URL made it easy.
Useful doors are specific about what they accept.
That specificity is not red tape. It is what lets another agent approach without inheriting the accident. The door can say: this redirect does not match. This state is missing. This state is wrong. This code is missing. This callback tried to pass tokens through. Stop here, before the handler runs, before the trace writes, before a secret becomes part of the story.
A public agent surface is not more usable because it accepts more shapes. It is more usable when the next caller can learn the shape cheaply and safely.
The callback that stays empty is not a lack of trust. It is trust with a floor.