Stateful Strategies
For complex models with many fields organized into sections, mcp-rune ships a stateful strategy that walks the agent through one section at a time, validating as it goes. Use this when a single-shot validation would overwhelm the LLM — typically 20+ fields, multiple required dependencies, or workflows where the user needs to see partial progress before committing.
This guide covers the configuration knobs, the validation flow, and the StatefulStrategy API. For the structure stateful strategies consume (sections + fieldGroups), see the Sections & Field Groups guide. For the comparison with stateless and hybrid, see the Prompt Creation guide.
Mode configuration
Stateful prompts support two interaction modes:
| Mode | Behavior | Use Case |
|---|---|---|
guided | Walk through each section interactively | Human interaction via MCP client |
quick | Minimize questions, infer values from context | Agentic workflows, automation |
Enabling mode selection
1. Add mode to static arguments
static arguments = [
{ name: 'mode', description: '"guided" (step-by-step) or "quick" (minimal interaction)', required: false },
// ... other prompt-specific arguments
]
2. Mode selection is automatic via BasePrompt
The generateStatefulGuidanceInstructions() method automatically includes mode selection instructions.
Structural overview
The Flow diagram (generated by .flowDiagram()) serves as the single structural overview. In guided mode, the LLM references this diagram rather than repeating section information.
Stateful prompt structure
import { BasePrompt } from './base_prompt.js'
export class ActivityPrompt extends BasePrompt {
// 1. Declare strategy
static strategy = 'stateful'
// 2. Define sections (user-facing workflow)
static sections = {
basics: {
title: 'Basic Information',
description: 'Title and description',
required: true,
groups: ['basics']
}
}
// 3. Define field groups (validation structure)
static fieldGroups = {
basics: {
fields: ['title', 'description'],
required: true
}
}
// 4. Schema derivation
static {
const schema = derivePromptSchema(Activity, {
fieldGroups: this.fieldGroups
})
this.fieldGroups = schema.fieldGroups
this.fieldDefinitions = schema.fieldDefinitions
}
// 5. MCP metadata
static title = 'Create Activity'
static modelName = 'activity'
// 6. Arguments with mode support
static arguments = [
{ name: 'mode', description: '"guided" or "quick"', required: false },
{ name: 'title', description: 'Activity title', required: false }
]
// 7. Generate description using BasePrompt helpers
static description = `${ActivityPrompt.getStrategyIntro()} activities.
**Field Groups:**
${ActivityPrompt.generateFieldGroupsList()}
${ActivityPrompt.generateFlowDiagramFromConfig()}`
// 8. Prompt content using PromptContentGenerator
get promptContent() {
return PromptContentGenerator.for(ActivityPrompt, 'activity')
.add(`# Activity Creation Guide\n\n...`)
.standard()
.add(this.generateToolUsageSection())
.attributeReference()
.build()
}
}
BasePrompt helpers
| Method | Purpose |
|---|---|
generateFieldGroupsList() | List field groups with fields and requirements |
generateFlowDiagramFromConfig() | Compact flow diagram from sections/fieldGroups |
generateStatefulGuidanceInstructions(modelName) | Full guidance instructions including mode selection |
generateSectionDocumentation(groupName, sectionNumber, modelName) | Per-section documentation |
generateToolExample(modelName, action, attributes) | Generate tool usage example |
getStrategyIntro() | Strategy-appropriate intro text |
getSectionFields(sectionName) | Get all fields for a section |
getSectionForGroup(groupName) | Get section for a fieldGroup |
getSectionFieldNames(sectionName) | Get all field names for a section |
getSectionNumber(sectionName) | Get 1-based section number |
Validation flow
Stateful prompts require validation after each section:
User provides section input
|
LLM calls validate_form(model, section, fields)
|
Server validates and returns errors/warnings
|
LLM proceeds to next section or asks for corrections
|
After all sections: validate_form(model, fields) for full validation
|
If ready_to_submit: true -> create_model()
StatefulStrategy API
The StatefulStrategy class handles stateful prompts with sections support.
getSections(promptClass)
Returns section metadata with aggregated fields from groups:
const sections = StatefulStrategy.getSections(ActivityPrompt)
// Returns:
[
{
name: 'basics',
title: 'Basic Information',
required: true,
fields: ['title', 'description'],
groups: ['basics'],
description: 'Title and description for the activity'
},
// ...
]
getProgress(promptClass, fields)
Returns completion progress by fieldGroup:
const progress = StatefulStrategy.getProgress(ActivityPrompt, fields)
// Returns:
{
sections: {
basics: {
applicable: true,
total_fields: 2,
filled_fields: 1,
complete: false,
partial: true,
required: true,
title: 'Basic Information'
}
},
overall: {
total_sections: 4,
completed_sections: 1,
required_complete: false,
percentage: 25
}
}
See also
- Sections & Field Groups guide — the structure stateful strategies consume.
- Prompt Creation guide — the broader strategy picture (stateless / hybrid / stateful).
- Strategy pattern internals:
src/mcp/prompts/strategies/README.md— implementation reference for strategy dispatching, tool integration, and logging.