Skip to Content
Integrations & APIMCP Integration

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.

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”.

Open claude.ai’s Settings → Connectors → Add custom connector:

  1. Name it anything (e.g. RooQuiz).
  2. Use your endpoint (looks like https://your-domain/api/mcp) as the remote MCP server URL.
  3. 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”:

  1. Give it a name (for recognition, e.g. Cursor - my Mac).
  2. 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_tenant tool.
  3. 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.

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)

ToolWhat it does
list_my_tenantsList all teams you belong to, marking the currently active one.
get_active_tenantReturn the team the token is currently active in; all writes default to it.
switch_active_tenantSwitch the active team (persists across sessions; target must be a team you’ve joined).

Form

ToolWhat it does
create_formCreate 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_formsList the current team’s quizzes, with optional scene or title filtering.
get_formView 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_formUpdate 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_formMove 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_formRestore 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_formDuplicate 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

ToolWhat it does
add_questionAppend 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_questionInsert an item at a specific position, using after / before to reference an existing code.
move_questionMove an existing question or page break to a new position by code.
update_questionUpdate stem, note, explanation, required flag, score, correct answer, or FillBlank AI grading by code. Cannot change question type or choice content.
delete_questionDelete a question or page break by code.

Report dimensions

ToolWhat it does
set_dimension_analysisSet 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).

ToolWhat it does
create_form_translationAdd 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_translationsList a quiz’s existing language versions (language, active flag, public link, etc.).
get_form_translationRead one language version’s full content (including fields[] and report) to translate in place — every code must stay identical to the source.
update_form_translationSave 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_translationDelete 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.

ToolWhat it does
list_examineesList the current team’s examinees, with optional fuzzy search by email / name and status (active / disabled) filtering.
get_examineeView an examinee’s detail (including custom customData) by its business ID examineeId (e.g. AB1234567890, shown in the list).
update_examineeEdit 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).

ToolWhat it does
get_form_statsRead 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_funnelRead 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_recordsList the current team’s submission records (leads): examinee, answers, a compact report result and UTM; filter by quiz, report status and submitted time.
get_recordView one record’s detail by its id (returned by list_records): full answers, report result and submission metadata.

Image upload

ToolWhat it does
prepare_image_uploadStep 1: issue a direct-upload URL for a cover/image (PUT the file to it).
finalize_image_uploadStep 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_form to create the quiz and get each question’s code → use update_form or set_dimension_analysis to configure report formulas / dimensions by code.
  • Outcome quiz: create_form in one call with report.outcomes (give each type a unique code of 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 via update_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_question then add_question to 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_question rejects score / 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_form moves 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_form clones 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_examinee can’t change email, team, or examineeId (they are the auth identity).
  • Leads contain PII: list_records / get_record return 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.
Last updated on