Elicitation Authoring Guide¶
Elicitation lets an interactive Guide entrypoint ask a connected MCP client for the values it needs before Guide renders the entrypoint. It is shared by command and skill entrypoints: define a form once in frontmatter and the same resolver handles URI values, modern multi-round input, and legacy sequential input.
Use this guide with Command Authoring or Skills Authoring. It describes only the shared input contract.
Where elicitation applies¶
Declare elicitation only on an interactive command or the selected SKILL.md entrypoint.
Guide resolves it before rendering the body. A command supports native command resources,
guide://_command resource reads, and underscore, colon, and semicolon prompt routes. A skill
supports its selected guide://$skill-name entrypoint.
Ordinary documents and non-entrypoint skill members do not elicit. An entrypoint may also compose
forms from partials explicitly named by its includes frontmatter. A listed partial may contribute
frontmatter-only forms; its body still appears only when the entrypoint renders the normal Mustache
partial. requires-* is evaluated before a partial contributes its forms.
Form identifiers and field names must be unique across the effective entrypoint and its contributing partials. Invalid frontmatter, duplicate identifiers or fields, self-references, and conditional cycles are authoring errors.
Form declaration¶
elicitation is a mapping from a local form identifier to a form declaration. Every form needs a
non-empty message and an object JSON Schema with a non-empty properties mapping.
elicitation:
review-target:
message: Choose what to review.
schema:
type: object
properties:
mode:
type: string
enum: [uncommitted, branch, pull-request]
description: Review target type.
required: [mode]
Supported property types are string, integer, number, and boolean. enum values and
defaults must use the declared primitive type. required must name properties in that same form.
The MCP client receives the schema unchanged, apart from command-only dynamic properties described
below, so descriptive property metadata such as a title or description may improve the UI when the
client supports it.
Command-only dynamic sources¶
Commands may use source: workflow-phases on a string property to derive an enum from the enabled
workflow phases before the form is delivered. The active phase is omitted from an interactive choice,
while an explicit positional or URI phase remains available for normal command validation. Guide
removes this command-only source marker before delivery. Skills do not perform command
specialisation and therefore must not use it.
An enum is the portable way to express a simple choice. A client may display it as a select,
radio group, or another suitable control; the precise visual presentation is client-specific and is
not a Guide contract. A free-text string remains a text field.
Typed fields and defaults¶
elicitation:
options:
message: Configure the run.
schema:
type: object
properties:
attempts:
type: integer
minimum: 1
default: 3
threshold:
type: number
default: 0.8
dry_run:
type: boolean
default: false
label:
type: string
required: [label]
Guide normalises supplied primitive values to the declared type and validates enums, numeric
minimum/maximum constraints, string pattern constraints, and defaults. A pattern is a
regular expression applied to the complete string value (Guide uses a full match); it is useful
for constraining free-text identifiers such as branch names. Patterns must be valid, non-empty
regular expressions and may only be declared on string properties.
For URI input, text is normalised only against the declared field: a string field can therefore
receive the literal text true or false, while a boolean field receives a boolean value.
URI keywords take precedence over elicited answers. false and 0 are values, not missing input;
only an omitted, null, or blank string required field is unresolved.
guide://_review?mode=uncommitted
guide://$workflow-review?mode=branch&reference=feature/example
Help and non-interactive clients¶
Guide resolves command help before elicitation. Asking for help must describe the command without opening an input request.
If elicitation is unavailable, every required field in a form may use a schema default. Guide
uses those defaults and exposes the state to Mustache under
elicitation.defaulted_forms.<form-name>. The form name defaulted remains valid because the
internal marker is defaulted_forms, not defaulted.
{{#elicitation.defaulted_forms.review-target}}
No target was supplied; using the documented default.
{{/elicitation.defaulted_forms.review-target}}
Alternatively, fallback: render lets the entrypoint render without unresolved values when it can
obtain the missing information in its own instructions. An explicit decline remains a decline; it
does not silently apply defaults. Without a complete default or fallback: render, Guide returns
a validation failure naming the URI keywords the caller must supply.
Branches and matching¶
Use when to create a conditional follow-up form. There is no separate match frontmatter key:
the when mapping is the match expression. Each key names an effective form property and each
value is one permitted primitive or a list of permitted primitives.
elicitation:
target:
message: Choose a target.
schema:
type: object
properties:
mode: {type: string, enum: [uncommitted, branch, pull-request]}
required: [mode]
reference:
message: Enter the selected branch or pull request.
when:
mode: [branch, pull-request]
schema:
type: object
properties:
reference: {type: string}
required: [reference]
when matches only when every condition matches. Values are compared after the supplying
field has been normalised to its declared primitive type. A condition that does not match makes the
form inapplicable. A condition whose value is not yet known makes the branch unresolved; Guide
first asks for the form that supplies that value, even if the supplier has no required fields.
Guide re-evaluates branches after each accepted answer, default, and cancellation. This supports multi-step flows without asking for a branch that no longer applies. A form cannot depend on itself or participate in a dependency cycle.
For an AND match, add more keys:
when:
mode: pull-request
scope: remote
Both mode and scope must match for the form to apply.
Protocol behaviour and continuation state¶
The declaration and rendered template context are the same for all clients. The input transport is different:
| Connection | Behaviour |
|---|---|
| Legacy MCP | Guide uses the legacy sequential elicitation request path and asks only the forms currently applicable. |
| MCP 2026-07-28 | Guide returns an input_required result containing the currently applicable forms. The client sends accepted responses on a later request. |
For the modern protocol, continuation state retains accepted values, completed forms, requested forms, the originating entrypoint, the original URI keywords, and command positional arguments. FastMCP seals this state before it reaches the client and unseals it before Guide receives the next request. A changed or cross-entrypoint state is rejected before its values are used.
This is a framework integrity boundary, not an author-facing encryption feature: authors should not place secrets in forms merely because continuation state is sealed. Treat all accepted values as ordinary user input and use only the declared, validated primitive fields.
Rendering accepted values¶
Accepted and normalised values are merged with command or skill keyword context. Use the ordinary Mustache keyword paths for the entrypoint type, for example:
Reviewing {{kwargs.mode}} {{kwargs.reference}}
The resolver never infers a form from an entrypoint name. It uses only the effective elicitation
frontmatter declared by the selected interactive entrypoint and its eligible partials.