MCP Integration
RooQuiz ships an MCP (Model Context Protocol) server that lets AI clients — Claude Desktop, Claude Code, Cursor, Codex, and others — operate on quizzes inside your team. With natural language you can create quizzes, scorecards, and outcome quizzes, append questions, reorder items, and configure report dimensions or outcome types; you can also duplicate / delete quizzes, manage translations and examinees, and read submission records, stats and conversion funnels — instead of building everything by hand in the editor.
MCP is a feature for power users — you’ll need an AI client that supports MCP. For basic, visual quiz building we still recommend the editor.
How it works
- An AI client connects to RooQuiz’s MCP endpoint (
/api/mcp) using one of two auth methods: OAuth authorization (recommended — supported clients just sign in via the browser) or a personal API token. - Either way, the AI acts as you within the currently active team.
- Every action goes through the same access checks as the admin UI; write operations are also recorded in the audit log.
- So what the AI can do is bounded entirely by your role and permissions in that team — it can’t exceed them.
Option 1: OAuth authorization (recommended)
Clients that support MCP OAuth — claude.ai and Claude Code — need no manually created token. Just provide the endpoint URL: the client discovers the authorization server automatically and opens your browser, where you sign in to RooQuiz, pick the team to authorize, and click “Authorize”.
claude.ai (Web)
Open claude.ai’s Settings → Connectors → Add custom connector:
- Name it anything (e.g.
RooQuiz). - Use your endpoint (looks like
https://your-domain/api/mcp) as the remote MCP server URL. - Save and click “Connect” — your browser is redirected to the RooQuiz authorization page; sign in, pick a team, and click “Authorize”.
About OAuth connections:
- The team you pick during authorization becomes the initially active team; the AI can still switch later via
switch_active_tenant. - The connection shows up in the token list under Settings → MCP Integration (tagged OAuth); revoking it disconnects that client. It does not count toward the 5-token limit.
- Credentials renew automatically (the access token refreshes on a 1-hour rolling basis; the connection itself stays valid for 30 days and extends with use) — nothing to maintain by hand.
Option 2: Personal token (PAT)
For clients without OAuth support (Cursor, Codex CLI, Claude Desktop) or browserless environments like CI, connect with a personal API token.
Create a token
Go to Settings → MCP Integration and click “Create Token”:
- Give it a name (for recognition, e.g.
Cursor - my Mac). - Pick a default team — the token operates on this team by default, and the AI can later switch to any other team you belong to via the
switch_active_tenanttool. - After creation, a plaintext token starting with
rqp_live_is shown.
The plaintext token is shown only once. It cannot be retrieved after you leave the page. Copy it immediately; if lost, you must revoke it and create a new one.
Limits:
- Each user can hold at most 5 tokens (including revoked ones; OAuth connections don’t count). To create more, delete one to free a slot (“revoke” only deactivates — it does not free the slot).
- A token is a personal credential — never commit it to source control or share it publicly.
Configure your AI client
On the Settings → MCP Integration page you can copy ready-made config snippets for each client, along with your Endpoint URL (looks like https://your-domain/api/mcp). Replace rqp_live_xxx... in the snippet with the token you just generated.
Claude Code (CI)
For Claude Code, prefer the OAuth flow above; a token header is only needed in browserless environments like CI:
claude mcp add --transport http rooquiz https://your-domain/api/mcp \
--header "Authorization: Bearer rqp_live_xxx..."Available tools
Once connected, the AI assistant can call the tools below. They all act on the team the token is currently active in.
Team (Tenant)
| Tool | What it does |
|---|---|
list_my_tenants | List all teams you belong to, marking the currently active one. |
get_active_tenant | Return the team the token is currently active in; all writes default to it. |
switch_active_tenant | Switch the active team (persists across sessions; target must be a team you’ve joined). |
Form
| Tool | What it does |
|---|---|
create_form | Create a quiz (quiz exam, scorecard, or outcome typing quiz). Can take a questions array and report config in one call to avoid round trips. An outcome quiz must include report.outcomes (the list of result types) at creation, with every choice voting for types via outcomes. |
list_forms | List the current team’s quizzes, with optional scene or title filtering. |
get_form | View a quiz’s full details (the fields[] question list, report config, etc.); call this first to get each question’s code before editing — for outcome quizzes, the result-type codes live in report.outcomeAnalysis.outcomes. |
update_form | Update title, description, open/closed state, or merge-replace the report config by sub-key; for outcome quizzes, pass report.outcomes to merge-update result types by code (name/description/CTA; configured images are kept, and removing a type still referenced by question votes is rejected). Scene and language are locked after creation. |
delete_form | Move a quiz to the trash (soft delete): hidden from list_forms, recoverable for 5 days via restore_form (then permanently purged). Only the quiz owner / team owner can delete; submission records are kept until permanent purge. |
restore_form | Restore a quiz deleted by delete_form from the trash. Only the owner / team owner can restore; errors if it’s not in the trash. |
duplicate_form | Duplicate a quiz: clones its question structure, scoring, report, visuals and settings plus all language translations into a new quiz owned by you (with fresh links). Does not copy submission records, sharing, integrations or ban state. Optional newTitle. |
Question
| Tool | What it does |
|---|---|
add_question | Append an item to the end: a question (SingleCheck/MultiCheck/TrueFalse/FillBlank) or a page break (Breaker). In an outcome quiz, every choice must declare which result types it votes for (TrueFalse uses trueOutcomes / falseOutcomes). |
insert_question | Insert an item at a specific position, using after / before to reference an existing code. |
move_question | Move an existing question or page break to a new position by code. |
update_question | Update stem, note, explanation, required flag, score, correct answer, or FillBlank AI grading by code. Cannot change question type or choice content. |
delete_question | Delete a question or page break by code. |
Report dimensions
| Tool | What it does |
|---|---|
set_dimension_analysis | Set a quiz’s multi-dimension analysis (radar chart dimensions) as a whole; in quiz each dimension references question codes, in scorecard each uses a formula. Pass an empty array to clear. Not applicable to outcome quizzes (they have no dimensions — configure result types via report.outcomes instead). |
Translations (FormTranslation)
Offer a quiz in multiple languages: one source quiz (primary language) plus one translation per other language (same structure as the source, only the text is translated; submission records always anchor to the source quiz).
| Tool | What it does |
|---|---|
create_form_translation | Add a language version to a quiz, cloning the source copy as the initial draft (same codes, source-language text), and return that content to translate right away. The language must differ from the primary, at most one per language. |
list_form_translations | List a quiz’s existing language versions (language, active flag, public link, etc.). |
get_form_translation | Read one language version’s full content (including fields[] and report) to translate in place — every code must stay identical to the source. |
update_form_translation | Save a language version’s translated copy (title / description / fields / report / systemText), or pause it via isActive; the structure is fixed by the source, you only change text, and omitted fields count as partial translation. |
delete_form_translation | Delete one language version. |
Examinees
The people who take a quiz. Each examinee is bound to a single team; the tools return safe fields only — password, verification code, reset token and other sensitive fields are never exposed.
| Tool | What it does |
|---|---|
list_examinees | List the current team’s examinees, with optional fuzzy search by email / name and status (active / disabled) filtering. |
get_examinee | View an examinee’s detail (including custom customData) by its business ID examineeId (e.g. AB1234567890, shown in the list). |
update_examinee | Edit an examinee’s name / status / customData by examineeId (customData is validated against the team’s field definitions). Email and team cannot be changed. |
Records & Analytics
Read quiz performance, conversion funnels and leads so the AI can close the build → measure → iterate loop. The lead tools return respondent info (PII).
| Tool | What it does |
|---|---|
get_form_stats | Read a quiz’s stats over the last N days (default 30, max 180): KPI overview, daily trend, channels (utm_source), login types, devices, and per-question answer distributions. |
get_form_funnel | Read a quiz’s conversion funnel over the last N days: viewed → started → submitted → lead captured → report viewed → CTA clicked → shared, plus per-channel funnel and drop-off points. |
list_records | List the current team’s submission records (leads): examinee, answers, a compact report result and UTM; filter by quiz, report status and submitted time. |
get_record | View one record’s detail by its id (returned by list_records): full answers, report result and submission metadata. |
Image upload
| Tool | What it does |
|---|---|
prepare_image_upload | Step 1: issue a direct-upload URL for a cover/image (PUT the file to it). |
finalize_image_upload | Step 2: verify and record the image into the team media library, returning a media id; reference it via update_form’s flagImg / landingImage. |
Typical flows:
- Exam / scorecard:
create_formto create the quiz and get each question’scode→ useupdate_formorset_dimension_analysisto configure report formulas / dimensions bycode. - Outcome quiz:
create_formin one call withreport.outcomes(give each type a uniquecodeof your own, e.g.lion) plus each choice’s votes → after submission the type with the most votes wins (ties resolved by list order); fine-tune type copy / CTAs later viaupdate_form.
Current limitations
- Random Quiz is not supported: its questions live in the QuestionBank — manage them in the editor; MCP doesn’t cover them yet.
- Can’t change question type or choices directly: to switch type or edit choices,
delete_questionthenadd_questionto rebuild. The same applies to an outcome quiz’s choice-to-type vote mapping — to change votes, rebuild the question. - Scorecard choice scoring uses Option Scoring: in the scorecard scene
update_questionrejectsscore/correctAnswer/aiMatch. Edit choice scores in the admin UI, or delete and recreate. The outcome scene rejects those three parameters likewise (it decides by votes — there is no scoring). - Outcome quiz question types: voting questions are SingleCheck / MultiCheck / TrueFalse (FillBlank is not supported); result-type images can’t be uploaded via MCP yet — configure them in the editor (images already configured are kept when MCP updates
report.outcomes). - Scene and language are locked after creation and can’t be changed via MCP.
- Delete is a soft delete:
delete_formmoves to the trash (auto-purged after 5 days), not an immediate permanent delete; for permanent removal, delete again in the admin UI. - Duplicate copies no data:
duplicate_formclones structure and translations only — it does not copy submission records, sharing settings or integrations (which hold secrets); the new quiz starts clean. - Examinee identity fields are immutable:
update_examineecan’t change email, team, orexamineeId(they are the auth identity). - Leads contain PII:
list_records/get_recordreturn respondent email, name, custom fields, etc. — handle them responsibly. - FillBlank AI grading (
aiMatch, quiz scene only, Beta) consumes your team’s AI credits.
Security & rate limits
- OAuth or token, the AI acts as you, triggering existing access checks and audit logs (every write is recorded).
- Each connection is rate-limited to 60 requests / minute; exceeding it returns a rate-limit error.
- When no longer needed, revoke (takes effect immediately; for OAuth connections this disconnects the client) or delete (also frees a slot) it in Settings → MCP Integration.
- The OAuth flow enforces PKCE (S256), authorization codes are single-use, and refresh tokens rotate on every renewal — old ones become invalid immediately.