Forms & quizzes
Forms, quizzes, questions, and interview dispatch. The former interview MCP has been folded into quiz — its quizzes / questions / dispatch tools live here (the event-guest tools moved to events).
| Endpoint | https://quiz.mcp.devfellowship.com/mcp |
|---|---|
| Tools | 19 in 4 groups |
| Package | packages/dfl-mcp-quiz |
| Auth |
Your dfl-auth login token as Authorization: Bearer <token>. Every call runs as
you, under RLS. See Auth & security.
|
{ "mcpServers": { "dfl-quiz": { "type": "http", "url": "https://quiz.mcp.devfellowship.com/mcp", "headers": { "Authorization": "Bearer YOUR_ACCESS_TOKEN" } } }}Other clients (Cursor, VS Code, codex, the Anthropic SDK): see Getting started, step 3.
| Backing data | quiz forms, quizzes, questions, and interview dispatch/responses; Discord id resolution for dispatch. |
Shareable forms: create them, read the answers, archive them.
create_form
Create a shareable batch-answer form on the quiz app.
create_formCreate Form
Create a shareable batch-answer form on the quiz app. Each item becomes one free-text question; an optional external_ref is stashed per item so responses map back to the source (e.g. a YouTube comment id). Returns { form_id, slug, shared_url }. Admin/super_admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | yes | Form title shown to responders. |
description | string | no | Intro/description shown above the items. |
welcome_cta | string | no | Call-to-action label on the welcome screen (default "Responder"). |
slug | string | no | Optional custom URL slug. Auto-generated if omitted. |
slug_prefix | string | no | Prefix for the auto-generated slug (default "form"; the skill uses "yt"). |
items | object[] | yes | The items to answer (e.g. one per YouTube comment). |
get_form
Get a form by id or slug: metadata + its items (questions and decoded external_ref).
get_formGet Form
Get a form by id or slug: metadata + its items (questions and decoded external_ref). Admin/super_admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_id | string | yes | Form UUID or slug. |
list_forms
List forms (newest first).
list_formsList Forms
List forms (newest first). Soft-archived forms are hidden by default — pass include_archived=true to include them. Optional slug_prefix filter (e.g. "yt"). Admin/super_admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug_prefix | string | no | Only return forms whose slug starts with this prefix. |
include_archived | boolean | no | Include soft-archived (is_active=false) forms. Default false. |
limit | number | no | Max rows (default 50). |
get_form_responses
Read submitted batch answers for a form (by id or slug), mapped back to each item via external_ref.
get_form_responsesGet Form Responses
Read submitted batch answers for a form (by id or slug), mapped back to each item via external_ref. Defaults to the most recent submission; pass all_responses=true for every submission. Admin/super_admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_id | string | yes | Form UUID or slug. |
all_responses | boolean | no | Include answers from every submission (default false = latest only). |
archive_form
Soft-archive a form (sets is_active=false) by id or slug.
archive_formArchive Form
Soft-archive a form (sets is_active=false) by id or slug. Does NOT delete — preserves questions and responses; restore with unarchive_form. Archived forms are hidden from list_forms by default and stop rendering at /shared/<slug>. Admin/super_admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_id | string | yes | Form UUID or slug. |
unarchive_form
Restore a soft-archived form (sets is_active=true) by id or slug.
unarchive_formUnarchive Form
Restore a soft-archived form (sets is_active=true) by id or slug. Inverse of archive_form. Admin/super_admin only.
| Parameter | Type | Required | Description |
|---|---|---|---|
form_id | string | yes | Form UUID or slug. |
Quizzes
Section titled “Quizzes”Quizzes and interviews: create, edit and read them.
create_quiz
Create a quiz/interview definition in quiz.quizzes (slug, title, description, welcome_message, and the per-interview agent_context / guardrails / business_unit_id).
create_quizCreate Quiz
Create a quiz/interview definition in quiz.quizzes (slug, title, description, welcome_message, and the per-interview agent_context / guardrails / business_unit_id). Add questions afterwards with add_quiz_question, or use create_interview_quiz to do both in one call.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Unique URL slug, e.g. "whatsapp-demo". |
title | string | yes | Quiz title. |
description | string | no | Quiz description. |
welcome_message | string | no | Intro message shown before the first question. |
welcome_cta | string | no | Call-to-action label for the welcome screen (default "Começar") |
completion_redirect_url | string | no | Where to redirect after completion. |
is_active | boolean | no | Whether the quiz is active (default true) |
agent_context | string | no | Injected per-interview context for the AI interviewer: company, the interview's purpose, the event, and tone. Combined at runtime with the engine hard-coded base guardrails. Plain text. |
guardrails | string | no | Optional per-interview extra rules layered on top of the engine base anti-injection guardrails (e.g. "stay strictly on the event-feedback topic; refuse off-topic questions politely"). Plain text. |
business_unit_id | string | no | Optional strategy.business_units id to inherit/share context across a BU. Per-interview agent_context/guardrails override the BU default. |
update_quiz
Update an existing quiz (by id OR slug): title, description, welcome_message, welcome_cta, completion_redirect_url, is_active, and the per-interview agent_context / guardrails / business_unit_id.
update_quizUpdate Quiz
Update an existing quiz (by id OR slug): title, description, welcome_message, welcome_cta, completion_redirect_url, is_active, and the per-interview agent_context / guardrails / business_unit_id. Only the fields you pass are changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | no | Quiz UUID (provide id OR slug) |
slug | string | no | Quiz slug (provide id OR slug) |
title | string | no | New title. |
description | string | no | New description (null to clear) |
welcome_message | string | no | New intro message (null to clear) |
welcome_cta | string | no | New CTA label (null to clear) |
completion_redirect_url | string | no | New completion redirect URL (null to clear) |
is_active | boolean | no | Active flag. |
agent_context | string | no | Injected per-interview context for the AI interviewer: company, the interview's purpose, the event, and tone. Combined at runtime with the engine hard-coded base guardrails. Plain text. |
guardrails | string | no | Optional per-interview extra rules layered on top of the engine base anti-injection guardrails (e.g. "stay strictly on the event-feedback topic; refuse off-topic questions politely"). Plain text. |
business_unit_id | string | no | Optional strategy.business_units id to inherit/share context across a BU. Per-interview agent_context/guardrails override the BU default. |
list_quizzes
List quiz/interview definitions from quiz.quizzes.
list_quizzesList Quizzes
List quiz/interview definitions from quiz.quizzes.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | no | Max quizzes to return (default 50, max 100) |
offset | number | no | Number of quizzes to skip (pagination) |
is_active | boolean | no | Filter by active flag. |
search | string | no | Search by title (ilike) |
get_quiz
Get a quiz by id or slug, including its ordered questions and each question's options.
get_quizGet Quiz
Get a quiz by id or slug, including its ordered questions and each question's options.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | no | Quiz UUID (provide id OR slug) |
slug | string | no | Quiz slug (provide id OR slug) |
Questions
Section titled “Questions”Add, edit and delete the questions of a quiz.
add_quiz_question
Add a question (and its options for choice types) to a quiz.
add_quiz_questionAdd Quiz Question
Add a question (and its options for choice types) to a quiz. Resolve the quiz by quiz_id OR quiz_slug. type: open | rating | multiple_choice | single | multi. Options apply to choice types; rating auto-generates a 0–N scale; "open" is a free-text turn.
| Parameter | Type | Required | Description |
|---|---|---|---|
quiz_id | string | no | Quiz UUID (provide quiz_id OR quiz_slug) |
quiz_slug | string | no | Quiz slug (provide quiz_id OR quiz_slug) |
text | string | yes | Question text, e.g. "Qual o seu nome?". |
type | enum | no | open | rating | multiple_choice | single | multi (open = free-text reply) One of: single, multi, multiple, multiple_choice, horizontal, open, rating. Default: "open". |
position | number | no | Display order (1-based). If omitted, appended. |
is_required | boolean | no | Whether an answer is required (default true) |
options | string[] | no | Option labels for choice types (ignored for open; overrides rating scale) |
rating_max | number | no | For type=rating: scale ceiling (default 5 → labels "0".."5") |
cohort_tag | string | no | Cohort-only branch tag (e.g. "lideres"). Encodes a [cohort:<tag>] marker + is_required=false. |
update_quiz_question
Edit an existing question in place by question_id — change text, position, type, is_required, and/or its options — WITHOUT deactivating the quiz or re-authoring a new slug.
update_quiz_questionUpdate Quiz Question (in place)
Edit an existing question in place by question_id — change text, position, type, is_required, and/or its options — WITHOUT deactivating the quiz or re-authoring a new slug. type: open | rating | multiple_choice | single | multi. Pass the FULL ordered option list to set options (diffed against current: upsert by position, delete removed); omit options to leave them untouched; pass [] to clear them.
| Parameter | Type | Required | Description |
|---|---|---|---|
question_id | string | yes | UUID of the quiz.questions row to edit. |
text | string | no | New question text. |
position | number | no | New 1-based display order. |
type | enum | no | New type: open | rating | multiple_choice | single | multi. One of: single, multi, multiple, multiple_choice, horizontal, open, rating. |
is_required | boolean | no | Whether an answer is required. |
options | string[] | no | FULL ordered desired option labels (index 0 → position 1 → letter A). Diffed vs current. Omit to leave options untouched; [] clears all options. |
rating_max | number | no | For type=rating with no explicit options: scale ceiling (default 5 → labels "0".."5") |
delete_quiz_question
Hard-delete a question (and its options) by question_id.
delete_quiz_questionDelete Quiz Question
Hard-delete a question (and its options) by question_id. Refuses if the question has collected answers unless force=true (to preserve session history). Use this to cleanly remove a question instead of cohort-gating it with an inert marker.
| Parameter | Type | Required | Description |
|---|---|---|---|
question_id | string | yes | UUID of the quiz.questions row to delete. |
force | boolean | no | Delete even if the question has collected answers (those answers will be orphaned). Default false → refuse when answers exist. |
create_interview_quiz
Create a quiz (with per-interview agent_context / guardrails / business_unit_id) and all its questions in one call.
create_interview_quizCreate Interview Quiz (quiz + questions)
Create a quiz (with per-interview agent_context / guardrails / business_unit_id) and all its questions in one call. Each question: { text, type (open|rating|multiple_choice|single|multi), options?[], rating_max?, is_required?, cohort_tag? }. Returns the created quiz with its questions.
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | string | yes | Unique URL slug, e.g. "whatsapp-demo". |
title | string | yes | Quiz title. |
description | string | no | Quiz description. |
welcome_message | string | no | Intro message before the first question. |
is_active | boolean | no | Active flag (default true) |
agent_context | string | no | Injected per-interview context for the AI interviewer: company, the interview's purpose, the event, and tone. Combined at runtime with the engine hard-coded base guardrails. Plain text. |
guardrails | string | no | Optional per-interview extra rules layered on top of the engine base anti-injection guardrails (e.g. "stay strictly on the event-feedback topic; refuse off-topic questions politely"). Plain text. |
business_unit_id | string | no | Optional strategy.business_units id to inherit/share context across a BU. Per-interview agent_context/guardrails override the BU default. |
questions | object[] | yes | Ordered list of questions to create. |
Dispatch
Section titled “Dispatch”Send an interview over WhatsApp or Discord, and follow who answered and what they said.
dispatch_interview
Send a quiz/interview to a list of recipients via the interview engine over WhatsApp (phone) or Discord.
dispatch_interviewDispatch Interview (WhatsApp / Discord)
Send a quiz/interview to a list of recipients via the interview engine over WhatsApp (phone) or Discord. For Discord, supply discord_id directly, or a guest_id / member_id to resolve it server-side (precedence: guest override > member→profile > skip). Returns sent/failed counts, per-recipient dispatch ids, and any skipped recipients with no Discord identity.
| Parameter | Type | Required | Description |
|---|---|---|---|
quiz_slug | string | yes | Slug of the quiz to send (must exist in quiz.quizzes) |
channel | enum | no | Delivery channel. whatsapp → recipients need phone; discord → discord_id (or guest_id/member_id to resolve). One of: whatsapp, discord. Default: "whatsapp". |
recipients | object[] | yes | Send-list (1–200 recipients) |
list_dispatches
List interview dispatch rows (who received which quiz, channel, status, timestamps).
list_dispatchesList Interview Dispatches
List interview dispatch rows (who received which quiz, channel, status, timestamps). Filter by quiz_slug, status, or recipient_phone.
| Parameter | Type | Required | Description |
|---|---|---|---|
quiz_slug | string | no | Filter by quiz slug. |
status | enum | no | Filter by dispatch status. One of: pending, sent, in_progress, completed, timed_out, opted_out. |
recipient_phone | string | no | Filter by recipient phone. |
limit | number | no | Max rows (default 50, max 200) |
offset | number | no | Rows to skip (pagination) |
get_interview_status
Track one interview: the dispatch row (status, timestamps), its session, and answers collected so far.
get_interview_statusGet Interview Status
Track one interview: the dispatch row (status, timestamps), its session, and answers collected so far. Provide dispatch_id OR (recipient_phone + quiz_slug).
| Parameter | Type | Required | Description |
|---|---|---|---|
dispatch_id | string | no | Dispatch UUID. |
recipient_phone | string | no | Recipient phone (with quiz_slug) |
quiz_slug | string | no | Quiz slug (with recipient_phone) |
list_answers
List the answers (per-question transcript) for a session.
list_answersList Answers
List the answers (per-question transcript) for a session. Provide response_id OR dispatch_id.
| Parameter | Type | Required | Description |
|---|---|---|---|
response_id | string | no | Response (session) UUID. |
dispatch_id | string | no | Dispatch UUID (resolves its response_id) |
list_responses
List response (session) rows for a quiz — one per interview session, with completion status.
list_responsesList Responses
List response (session) rows for a quiz — one per interview session, with completion status. Filter by quiz_slug and/or completed. Pair with list_answers for the per-question transcript.
| Parameter | Type | Required | Description |
|---|---|---|---|
quiz_slug | string | no | Filter by quiz slug. |
quiz_id | string | no | Filter by quiz id (alternative to quiz_slug) |
completed | boolean | no | true → only completed sessions; false → only in-progress. |
limit | number | no | Max rows (default 50, max 200) |
offset | number | no | Rows to skip (pagination) |
Deprecated names
Section titled “Deprecated names”These old names still answer until the date shown. Call the new name.
| Deprecated name | Use instead | Removed after |
|---|---|---|
add_question | add_quiz_question | 2026-12-04 |
update_question | update_quiz_question | 2026-12-04 |
delete_question | delete_quiz_question | 2026-12-04 |