Add stateless MCP elicitation support - #328
Draft
pushpak1300 wants to merge 18 commits into
Draft
Conversation
pushpak1300
force-pushed
the
feat/elicitation
branch
3 times, most recently
from
August 19, 2026 04:58
a4a8ada to
e8c28f7
Compare
Drops elicitUrl() and the url client capability, leaving form mode only. Fixes found while reviewing: - Merge input responses with array_replace so numeric keys survive - Key default elicitations per call site, stable across replays - Throw when reading content off a declined or cancelled response - Report boolean client capabilities as declared - Serialize empty input request params as an object - Forward input responses to nested catalog tools - Keep cache hints off input required results - Surface the capability error for prompts and resources - Set APP_KEY for the test suite so the request state can be encrypted Adds the four missing conformance fixtures, which empties the input required section of the expected failures baseline.
Reads the input requests through typed accessors instead of repeating the result lookup, and swaps the manual search in assertElicits for a collection contains.
Adds ElicitationAction for the three actions the specification defines and reads the response action through it, so accepted, declined and cancelled compare enum cases instead of repeating string literals.
ElicitResponse now takes the action and content it holds rather than the raw response array, with a from factory parsing the wire shape once at the boundary instead of on every accessor call.
pushpak1300
force-pushed
the
feat/elicitation
branch
from
August 19, 2026 06:01
e8c28f7 to
c2d31fa
Compare
pushpak1300
marked this pull request as ready for review
August 19, 2026 08:14
pushpak1300
marked this pull request as draft
August 19, 2026 09:27
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Asking the user something mid-request used to need a live bidirectional session, and we don't have one — every request is handled on its own.
Elicitation in revision 2026-07-28 is stateless. The server answers with
resultType: input_required, the client collects the answer, then retries the same call with it. Two plain requests.So a handler can now ask for something:
What
$githubisAn
ElicitResponsewrapping the client's reply — an action, plus content matching the schema you asked for:{"action": "accept", "content": {"name": "octocat"}}It is read only, and reading content when the action is not
acceptthrows.Ask more than once and each answer arrives in turn:
An
ask()with no answer yet ends the request and asks the client. The handler re-runs from the top on the retry with the earlier answers already filled in, so$nameis populated by the time the second round reaches$colour. Anything before anask()runs on every round — keep it idempotent.Works in tools, prompts, resources and generator tools. Reading a declined or cancelled response throws, so check
accepted()ordeclined()first.Not supported through tool search. A catalog tool reached via
execute_toolsthat callsask()fails withTool [name] requested user input, which is not supported through tool search.— a batch has no way to replay the calls that already completed, so a round trip would re-run their side effects.Testing: