Skip to content

Survey Tools — MCP Tool Reference

Survey tools handle the survey execution lifecycle: creating survey sessions, navigating questionnaire flows, submitting responses, and generating synthetic test data. Comment items are automatically skipped — callers never receive them.

list_surveys

List surveys, optionally filtered by campaign or respondent.

Parameter Type Required Default Description
campaign_id string No Filter by campaign ID
respondent_id string No Filter by respondent ID
status string No Filter: "pending", "in_progress", or "completed"
limit integer No 100 Maximum results to return

Returns: { items: [...], count, limit }


create_survey

Create a new survey for a respondent.

Parameter Type Required Default Description
questionnaire_id string Yes Questionnaire to use
respondent_id string Yes Respondent UUID
interviewer_user_id string No For phone/in-person interviews. Omit for self-completion
campaign_id string No Associate with a campaign

Returns: { id, questionnaire_id, interviewer_user_id, respondent_id, campaign_id, mode }


bulk_create_surveys

Create surveys for all respondents in a campaign's assigned pool. Skips respondents who already have surveys.

Parameter Type Required Default Description
campaign_id string Yes Campaign UUID

Returns:

{
  "status": "success",
  "campaign_id": "...",
  "created_count": 45,
  "skipped_count": 5,
  "surveys": [{"id": "...", "respondent_id": "..."}]
}

Requires: Campaign must have both a questionnaire and a respondent pool assigned.


get_survey_current_item

Get the current question in a survey. Initializes the survey state on first call.

Parameter Type Required Default Description
survey_id string Yes Survey UUID

Returns (question):

{
  "survey_id": "...",
  "id": "q_age",
  "text": "What is your age?",
  "kind": "Question",
  "input": {"control": "slider", "min": 18, "max": 99},
  "required": true,
  "isLast": false,
  "visited": false
}

Returns (complete): { status: "complete", survey_id, message: "Survey completed" }

Auto-Comment Skipping

Comment items (informational text) are transparently skipped — up to 50 consecutive Comments are auto-processed. Callers only receive actionable items (Question, QuestionGroup, MatrixQuestion).


get_question_options

Get the available response options for a question. Useful for understanding what values to submit.

Parameter Type Required Default Description
survey_id string Yes Survey UUID
item_id string No Specific item ID. If omitted, uses current item

Returns (choice control):

{
  "survey_id": "...",
  "item_id": "q_gender",
  "question_text": "What is your gender?",
  "control_type": "radio",
  "options": [
    {"value": "male", "text": "Male"},
    {"value": "female", "text": "Female"},
    {"value": "other", "text": "Other"}
  ],
  "required": true
}

Returns (range control):

{
  "control_type": "range",
  "options": [{"type": "range", "min": 18, "max": 99, "step": 1}]
}

Control types: radio, dropdown, checkbox, slider, switch, editbox, textarea. Text controls return empty options.


submit_survey_response

Submit an answer for the current question and advance to the next item.

Parameter Type Required Default Description
survey_id string Yes Survey UUID
item_id string Yes Item ID being answered
outcome any Yes Response value (type depends on control)

Returns:

{
  "status": "success",
  "survey_id": "...",
  "output": { },
  "survey_status": "completed"
}

The survey_status field only appears when the survey completes after this response. Trailing Comment items are auto-processed after each submission.

Call get_survey_current_item first

The survey must be initialized before submitting responses. If not initialized, returns: {"error": "Survey not initialized. Call get_survey_current_item first."}


finish_survey

Explicitly mark a survey as completed. Use for edge cases where auto-completion doesn't trigger.

Parameter Type Required Default Description
survey_id string Yes Survey UUID

Returns: { status: "success" | "already_complete", survey_id, message }.


mass_fill_surveys

Fill all pending surveys in a campaign with synthetic test responses. Do not use on campaigns with real respondent data.

Parameter Type Required Default Description
campaign_id string Yes Campaign UUID
distribution string No "realistic" Strategy: "realistic", "random", "stratified", or "llm"
max_surveys integer No Limit surveys to fill. null = all pending
profiles string[] No ["random"] Persona profiles, assigned round-robin

Returns:

{
  "status": "success",
  "campaign_id": "...",
  "completed": 48,
  "failed": 2,
  "total_responses": 480,
  "total_surveys": 50,
  "already_completed": 0,
  "distribution": "realistic",
  "profiles_used": ["young_single", "retired"],
  "failed_surveys": [{"survey_id": "...", "error": "..."}]
}

Distribution Modes

Mode Engine Speed Description
realistic Weighted random Fast Profile-aware demographic weighting (default)
random Uniform random Fast Pure random, no demographic influence
stratified Demographic strata Fast Quota-balanced responses
llm Claude Haiku API ~1s/question AI-generated, persona-consistent responses. Requires ANTHROPIC_API_KEY

Persona Profiles

Assigned round-robin to respondents. Available profiles:

Profile Age Income Behavior
young_single 25–35 $65k Progressive, tech-savvy, favors middle options
married_family 30–50 $80k Practical, value-oriented
retired 65+ $55k Conservative, favors early/traditional options
high_income 45 $150k+ Quality-focused, favors premium options
random 40 $70k No particular bias

Item Kind Handling

Item Kind Outcome Format Example
Comment null (auto-skipped) Informational text
Question Single value "option_a", 42, true
QuestionGroup List of values ["val1", "val2", "val3"]
MatrixQuestion Dict with _row_col keys {"_0_0": "val", "_0_1": "val"}

Error Handling

Common Errors

Scenario Response
Survey not found {"error": "Survey {id} not found"}
Campaign not found {"error": "Campaign {id} not found"}
Questionnaire not found {"error": "Questionnaire {id} not found"}
Survey not initialized {"error": "Survey not initialized. Call get_survey_current_item first."}
No pool assigned {"error": "Campaign has no respondent pool assigned"}
No incomplete surveys {"status": "no_surveys", "message": "No incomplete surveys found in campaign"}

Survey State Machine

[Not Started] → get_survey_current_item → [In Progress]
[In Progress] → submit_survey_response → [In Progress | Completed]
[In Progress] → finish_survey → [Completed]
  • Initialization: First call to get_survey_current_item loads the QML and creates the survey state
  • Auto-completion: Surveys complete automatically when the last item is answered
  • Comment skipping: Comment items are transparently processed (up to 50 consecutive) — callers never receive them
  • Persistence: Every response is immediately persisted to the database