Part 1 of 6 · 3 min read
Overview
In this module you will
- Explain the two things a server can ask for mid-call: elicitation (ask the person) and sampling (ask the host's model), and say which one is deprecated.
- Describe a multi round-trip request: the server answers "I need input", the client retries the same request with the answers and an opaque
requestState. - Write a tool body that works in both protocol eras and does nothing irreversible before the last question.
- Treat
requestStateas attacker-controlled input: seal it, bind it to the person and the request, expire it, and use a server-side record for one-time actions. - Use form mode for ordinary questions and URL mode for anything sensitive, and say why a password or API key never goes in a form.
- Defend against the phishing attack on URL elicitation (Alice starts it, Bob opens it).
- List the controls a host puts around sampling (token caps, call limits, review, context) and explain why they exist.
- Say why a server asking for confirmation is not a control, and where the real control lives.
Up to now every message went one way: the model asks a tool to do something, the tool answers. Real work does not stay that tidy. A tool is about to submit a 250 expense and wants a yes. It needs the person to sign in to a calendar. It wants a model to write a sentence and does not have one. These are requests from the server to the client, in the middle of a call.
They are also where agents get hurt. A question the server controls can be skipped by a careless author. A saved state that travels through the client can be edited. A link sent to one person can be opened by another. A server with access to your model can spend your money. This module is about doing the useful thing and keeping control of it.
About the examples, and about the protocol version
The example code is a teaching imitation, offline, with scripted components. The "person" is a list of prepared answers. The "model" is a deterministic stand-in that follows a few patterns and counts words as tokens. The "host" is a small class I wrote. The signing uses HMAC-SHA256 from the standard library, but the key is a demo key and the code is not reviewed for production. There is no real browser, no real OAuth provider and no real model; the URL flow only models the identity check. Counts are exact; none of the numbers are timings.
The message shapes follow the specification pages I read on 24 October 2026, under the site's draft path (revision 2026-07-28) and the earlier 2025-11-25 pages. This revision made breaking changes here: server-initiated requests were replaced by multi round-trip requests, and sampling and roots were deprecated. Check the current specification before relying on any detail, and read the dates in section 9 carefully.
I point to those pages in the sources and flag where I rely on my own knowledge.