Campaign Tools — MCP Tool Reference¶
Campaign tools manage the lifecycle of survey campaigns: creating campaigns, assigning interviewers and respondent pools, distributing workload, and sending invitations. Many operations use a batch response pattern with added/skipped/reasons fields.
list_campaigns¶
List all campaigns, optionally filtered by project, name, or status.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
project_id |
string |
No | — | Filter by project ID |
name |
string |
No | — | Filter by campaign name |
status |
string |
No | — | Filter by status |
limit |
integer |
No | 100 |
Maximum results to return |
Returns: { items: [...], count, limit }
get_campaign¶
Get a campaign by ID.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
Returns: Campaign object or { error }.
create_campaign¶
Create a new campaign. Campaign mode is automatically determined based on whether interviewers are assigned.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string |
Yes | — | Campaign display name |
project_id |
string |
Yes | — | Parent project ID |
questionnaire_id |
string |
Yes | — | Questionnaire to use |
status |
string |
No | "active" |
Initial status |
Returns: Created campaign object.
add_interviewers_to_campaign¶
Add interviewers (Users with interviewer role) to a campaign. Uses the batch response pattern.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
user_ids |
string[] |
Yes | — | List of user IDs to add as interviewers |
Returns:
{
"campaign_id": "...",
"added": ["uid1"],
"already_present": ["uid2"],
"skipped": [{"id": "uid3", "reason": "User not found"}],
"total_added": 1
}
Skip reasons: "User not found", "No interviewer role".
remove_interviewers_from_campaign¶
Remove interviewers from a campaign.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
user_ids |
string[] |
Yes | — | List of user IDs to remove |
Returns:
update_campaign_questionnaire¶
Change the questionnaire assigned to a campaign.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
questionnaire_id |
string |
Yes | — | New questionnaire UUID |
Returns:
{
"campaign_id": "...",
"old_questionnaire_id": "...",
"new_questionnaire_id": "...",
"success": true,
"warning": "Campaign has existing surveys — they reference the old questionnaire"
}
Existing Surveys
The warning field appears if the campaign already has surveys. Existing surveys retain references to the old questionnaire.
assign_respondents_to_interviewer¶
Assign specific respondents to a specific interviewer within a campaign for workload distribution.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
interviewer_id |
string |
Yes | — | Interviewer user UUID |
respondent_ids |
string[] |
Yes | — | List of respondent IDs to assign |
Returns:
unassign_respondents_from_interviewer¶
Remove respondents from an interviewer's assignment. Respondents remain in the campaign pool but become unassigned.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
interviewer_id |
string |
Yes | — | Interviewer user UUID |
respondent_ids |
string[] |
Yes | — | List of respondent IDs to unassign |
Returns:
get_interviewer_workload¶
Get the workload for a specific interviewer in a campaign — assigned respondents and survey completion status.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
interviewer_id |
string |
Yes | — | Interviewer user UUID |
Returns:
{
"campaign_id": "...",
"interviewer_id": "...",
"assigned_respondents": [
{"id": "...", "name": "...", "email": "...", "age": 35, "gender": "female", "location": "Berlin"}
],
"survey_status": {
"respondent_id": {"survey_id": "...", "status": "completed", "completed": true}
},
"statistics": {
"total_assigned": 10,
"completed": 3,
"in_progress": 2,
"not_started": 5,
"completion_rate": 0.3
}
}
get_unassigned_respondents¶
Get respondents in a campaign not yet assigned to any interviewer.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
Returns:
{
"campaign_id": "...",
"unassigned_count": 5,
"unassigned_respondents": [
{"id": "...", "name": "...", "email": "...", "age": 28, "gender": "male", "location": "Munich"}
]
}
assign_pool_to_campaign¶
Assign a respondent pool to a campaign. Links the pool so bulk_create_surveys can create surveys for all pool respondents.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
pool_id |
string |
Yes | — | Respondent pool UUID |
Returns:
{
"campaign_id": "...",
"pool_id": "...",
"pool_name": "Urban Millennials",
"respondent_count": 200,
"previous_pool_id": null
}
get_campaign_pool¶
Get the respondent pool assigned to a campaign.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
Returns (pool assigned):
{
"campaign_id": "...",
"pool_id": "...",
"pool_name": "...",
"pool_description": "...",
"respondent_count": 200,
"respondent_ids": ["..."],
"source_type": "strategy",
"source_strategy_id": "...",
"quality_score": 0.95,
"has_pool": true
}
Returns (no pool): { campaign_id, pool_id: null, has_pool: false, message: "..." }
send_campaign_invitations¶
Send survey invitation emails to campaign respondents. Sends real emails with magic link access.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
campaign_id |
string |
Yes | — | Campaign UUID |
respondent_ids |
string[] |
No | — | Specific respondents to invite |
send_to_all_uninvited |
boolean |
No | false |
Send to all uninvited respondents |
Real Emails
This tool sends actual emails. You must specify either respondent_ids or send_to_all_uninvited=true.
Returns:
{
"campaign_id": "...",
"results": {
"sent": [{"respondent_id": "...", "name": "...", "email": "...", "survey_id": "...", "survey_url": "..."}],
"skipped": [{"respondent_id": "...", "name": "...", "reason": "No email address"}],
"failed": [{"respondent_id": "...", "name": "...", "reason": "Email send failed: ..."}]
},
"summary": {"sent": 8, "skipped": 1, "failed": 1}
}
Eligibility requirements per respondent:
- Must have an email address
notification_preferencemust not be"none"- Survey must not be already completed or in progress
Skip reasons: "Respondent not found", "No email address", "Opted out of notifications", "Survey already completed", "Survey already in_progress".
Error Handling¶
Common Errors¶
| Scenario | Response |
|---|---|
| Campaign not found | {"error": "Campaign {id} not found"} |
| Interviewer not in campaign | {"error": "Interviewer {id} is not assigned to this campaign"} |
| No questionnaire/pool | {"error": "Campaign has no questionnaire assigned"} |
Batch Operation Pattern¶
Most campaign tools that accept lists of IDs return structured results rather than failing on individual items:
{
"added": ["id1"],
"already_present": ["id2"],
"skipped": [{"id": "id3", "reason": "User not found"}],
"total_added": 1
}
This pattern applies to: add_interviewers_to_campaign, remove_interviewers_from_campaign, assign_respondents_to_interviewer, unassign_respondents_from_interviewer, and send_campaign_invitations.
Each skipped/failed item includes a reason field explaining why it was excluded from the operation.