MCP.so
Sign In

Riddle Quiz MakerVerifiedFeatured

@Riddle.com

About Riddle Quiz Maker

Creates and manages quizzes, polls, surveys, personality tests, forms, predictors, minigames and leaderboards on Riddle.com – with branching logic, custom design, live stats and embed code.

Connection details

https://www.riddle.com/creator/api/v3/mcp

Setup

claude mcp add riddle --transport http https://www.riddle.com/creator/api/v3/mcp

Tools

62

Stores an existing Riddle as a template of its project (or of the user, for a personal Riddle), so new Riddles can be created from it with riddleTemplate_use. The template is a copy taken at this moment - the Riddle keeps living its own life and later changes to it do not reach the template. It copies what the Riddle currently has stored, published or not. Returns the created template: {id, title, type, category, isPublic, isQuickCreate, blocksCount, image, icon, createdAt, riddle}. Requires the template-create permission in the Riddle's project.

Lists the templates of a project (or your personal ones) - the ones made from your own Riddles with riddleTemplate_create, NOT Riddle's public ones, which riddleTemplate_publicList returns. Includes quick-create templates (riddleTemplate_create with isQuickCreate: true) alongside regular ones - there is no separate way to list those here. Filter by "type" to get only the templates of one Riddle type. Returns {count, templates: [{id, title, type, blocksCount, image, icon, createdAt, riddle, isPublic, isQuickCreate}]} without the build configuration - call riddleTemplate_get with the id of the one you picked to read that, or hand the id straight to riddleTemplate_use to create a Riddle from it unchanged.

Lists Riddle's public templates - the ready-made ones available to every account, as opposed to riddleTemplate_list, which returns the ones your project made itself. They are grouped by category (the tag the Creator sorts them by), so calling this without arguments is also how you learn which categories exist; pass "category" to get only one of them and "type" to get only one Riddle type. Returns {count, categories: {<category>: [{id, title, type, blocksCount, image, icon, createdAt, riddle, isPublic}]}} without the build configuration - call riddleTemplate_get with the id of the one you picked to read that, or hand the id straight to riddleTemplate_use to create a Riddle from it unchanged.

Reads a single template, by default INCLUDING its build configuration - the same "build" shape riddle_get returns and the riddle_builder_<type> tools accept. This is how a template is adapted rather than copied: edit the returned "build" (change the wording, swap questions, add or remove blocks) and build it with the riddle_builder_<type> tool of the template's "type", passing this template's id as "templateId" so the new Riddle is still recorded as coming from it. The design comes along too: "preset" carries the template's preset settings and its palette; "preset.paletteValues" - what that palette looks like - is included whenever the palette is not an unmodified built-in one, so a custom (or customized built-in) palette rebuilds into the same design directly. A template still on an unmodified built-in palette has no "paletteValues" instead of a partial one - "preset.palette" already names it in full (e.g. "Forest"), and its actual colors/fonts/etc. come from the riddle://reference/palette/built-in-palettes resource (match by "name"), never from a silently missing key. Passing "templateId" additionally starts the new Riddle out on the template's whole preset - layout included - with your build config applied on top of it. If you are not changing anything, use riddleTemplate_use instead - it is one call and copies the template as a whole. Returns {id, title, type, category, isPublic, isQuickCreate, blocksCount, image, icon, createdAt, riddle, build, nextBlockId, warnings}; a template whose content has no build-configuration equivalent comes back with an empty "build" and a warning saying so - use riddleTemplate_use for those.

Creates a new Riddle from a template, as an unchanged copy of it - content, settings and design preset - and records it as a copy of the template's Riddle (riddle_get reports that as context.duplicated). Use this whenever the template is what you want; to adapt it first, read it with riddleTemplate_get and build the edited configuration with a riddle_builder_<type> tool instead. The new Riddle is a draft: call riddle_publish to make it live. Returns the created Riddle in the standard build-configuration envelope. Requires the template-use permission, plus the Riddle-create permission in the target project.

Lists the tags of a project together with how many Riddles use each of them: [{id, name, count}]. Tags are per project - a tag of one project cannot be applied to a Riddle of another - so pass the projectId of the project whose Riddles you are tagging; omitting it returns the tags of the project the API key is scoped to (your personal tags for a user API key). Use this to find the tag "id" values riddle_list/riddle_account_list accept in their "tags" filter, and to check whether a tag already exists before riddle_tag_add creates a new one. "count" counts RIDDLES only, and Riddle tags and question bank tags are ONE set per project (the same tag can be applied to both and has the same id in either): a tag with "count": 0 therefore means "no Riddle uses this tag", not "nothing uses it" - question banks may well be using it, see questionBank_tagList. Such a tag is not removed automatically; a tag is only deleted once neither a Riddle nor a bank uses it.

Adds a tag to one or many Riddles. Identify the tag either by tagName (creating it if the project does not have it yet) or by tagId from riddle_tag_list, and the Riddles either by UUID (a single one) or by UUIDs (array of Riddle UUID strings, max 100) to tag a whole set in one call - e.g. everything riddle_list just returned. Tags belong to the project their Riddle is in, so with tagName a call spanning several projects gives each Riddle the tag of that name in its own project (creating it where it is missing), while tagId only exists in one project and therefore only works for Riddles of that project. Tagging a Riddle that already has the tag is not an error, it changes nothing. Applying a tag does not require publishing. Returns the applied tag plus all tags of the Riddle; with UUIDs, the {bulk, operation, summary, results} envelope with one such entry per Riddle - Riddles that fail (no edit permission, unknown tagId in their project) are reported as that entry's "error" and do not stop the others.

Removes a tag from one or many Riddles. Identify the tag either by tagName or by tagId from riddle_tag_list, and the Riddles either by UUID (a single one) or by UUIDs (array of Riddle UUID strings, max 100). Nothing is ever created here: a tag the Riddle's project does not have, or a tag the Riddle does not actually carry, is an error for that Riddle - with UUIDs it is reported as that entry's "error" in the {bulk, operation, summary, results} envelope while the other Riddles are still untagged. Once nothing uses a tag any more, the tag itself is deleted from the project - "nothing" includes question banks, which share one set of tags with Riddles: a tag a bank still uses survives its last Riddle and stays listed by riddle_tag_list with "count": 0. Returns the removed tag plus the Riddle's remaining tags.

A simple tool that returns "Pong". Can be used to test connectivity and authentication to the MCP.

Returns a paginated list of Riddles from a single project. Use projectId to specify the project, or omit it to list from the personal project. For Riddles across all projects, use riddle_account_list instead.

Returns a paginated list of all Riddles across the entire account — both the personal project and all team projects the user has access to. Use riddle_list to filter by a single project instead.

Gets one Riddle - or several, with UUIDs - as a compact build-configuration envelope: {uuid, type, modifiedAt, build, nextBlockId, warnings, published, context}. "build" is the same build config POST /riddle-builder accepts (see the riddle_builder_* tools) - everything the Riddle contains which cannot be expressed there is left out of "build" and reported in "warnings" instead; this never fails on content it cannot express. A property that is simply still at its block type's default is left out too, but never silently: each block carries an "omittedDefaults" map of those properties with the value each one is at - so "not in the config" does not mean "unknown". Read those values, do not resend them: many build properties enable a feature by being present at all, whatever their value. Pass omit: ["build.omittedDefaults"] to leave those maps out for a much smaller response - riddle://reference/riddle-builder/block-defaults states the same defaults without a Riddle in hand. "id" and "type" are always present on every block and never omitted, and a property the block cannot accept in its current configuration is not listed either. "build" always describes the DRAFT - the version you edit; "published" describes the live version visitors see: null if never published, {"status": "identical"} if the live version is exactly what "build" shows, or {"status": "differs", "build": ..., "warnings": ...} with the live version in full when the draft has unpublished changes; unpublished changes the build config cannot express show up as {"status": "identical", "hasUnpublishedChanges": true, ...}. Either way, call riddle_publish to make "build" live. "context" adds the extra fields an MCP client typically needs next to the build config: title, image (the Riddle's thumbnail), tags, notes, viewUrl (the public URL the Riddle is reachable under - null when it is not published or its landing page is turned off, with "viewUrlUnavailable": {reason, message} saying which of the two), features (incl. hasIntegration, consistent with riddle_list/riddle_account_list), origin (builder/aiGenerated/apiManageable - whether riddle_delete, riddle_builder_update and palette_customize will work on this Riddle, consistent with riddle_list/riddle_account_list), published/unpublished/modified state (both timestamps set = the Riddle was published and then taken offline again), duplicated (the Riddle this one was copied from, if any), project/team identity, and the preset relationship (id/parentId, whether it is merged from a parent preset and whether it has since drifted from it). Pass includeRiddleData=true to additionally receive the full stored Riddle under "riddle" - a large payload, rarely needed. Use "omit" to leave parts of all this out when you do not need them (see that parameter - it is the only way to make this call smaller), and UUIDs to read several Riddles in one call (see that parameter for its own, lower size budget).

Gets the HTML embed code for a Riddle by its UUID. The code is returned regardless of publish state, but the URL it embeds will not serve the Riddle until it is published.

Publishes one or many Riddles; meaning each Riddle will be available via https://www.riddle.com/view/[RIDDLEID]. Pass UUID for a single Riddle - the response is then the same compact build-configuration envelope riddle_get returns, with the new published state under "context.published"; use "omit" to shrink it the same way as riddle_get. Pass UUIDs (array of Riddle UUID strings, max 100) to publish several at once; the response is then the bulk envelope {bulk: true, operation, summary: {total, succeeded, failed}, results: [...]} with one entry per Riddle, each carrying its new state (title, viewUrl, published, modified) instead of a full build configuration - call riddle_get for the ones you want to inspect in detail. A bulk publish is not atomic and never gives up early: a Riddle that cannot be published is reported as that entry's "error" while all other Riddles are still published. A Riddle that fails publish validation says exactly why: the call fails with error "RIDDLE_PUBLISH_VALIDATE" (for a bulk, that entry's "error") carrying "validationErrors" - one {message, code, ...} entry per reason, e.g. code "MIN_ONE_BLOCK", "MIN_ONE_RESULT", "REDIRECT_RESULT_WITHOUT_URL" or "LOGIC_DEAD_ENDS" - so fix those and publish again. Non-blocking findings arrive as "validationWarnings" in the same shape, on a FAILED and on a SUCCESSFUL publish alike (the Riddle is live either way; e.g. "NO_DOMAINS" or "USES_OLD_LAYOUT") - report them to the user instead of retrying. Warnings are only stated when there are any. Publish validation only runs on a publish: riddle_builder_validate dry-runs a build configuration, not a publish, so there is no way to see these lists without calling this tool.

Unpublishes one or many Riddles; meaning each Riddle will no longer be available via https://www.riddle.com/view/[RIDDLEID]. A Leaderboard with active Riddle connections cannot be unpublished - use riddle_delete on it instead, which is always allowed and cleans up the connected Riddles automatically. Pass UUID for a single Riddle - the response is then the same compact build-configuration envelope riddle_get returns, with the cleared published state under "context.published"; use "omit" to shrink it the same way as riddle_get. Pass UUIDs (array of Riddle UUID strings, max 100) to unpublish several at once; the response is then the bulk envelope {bulk: true, operation, summary, results: [...]} with the new state per Riddle. A bulk unpublish is not atomic and never gives up early: a Riddle that cannot be unpublished (e.g. a Leaderboard with active connections) is reported as that entry's "error" while all other Riddles are still unpublished. A refusal says which content stands in the way: it fails with error "RIDDLE_UNPUBLISH" and a "validationErrors" list of {message, code, ...} entries - the same two-list failure shape riddle_publish uses, see riddle://reference/response-format ("errors").

Renames a Riddle with the specified UUID. Returns only the confirmation of the change (uuid, title, modified state), not the entire Riddle.

Generates a QR code for a Riddle by its UUID. The code is generated regardless of publish state, but the URL it links to will not serve the Riddle until it is published. The generated QR code (base64 SVG, with an embedded logo) grows with the length of the destination URL (e.g. UTM params) - typically tens of KB, and usually small enough to inline. If it would overflow the MCP inline response size, this tool reports its size instead of returning the oversized payload. Use riddle_get_embed_code or the Riddle's published view URL if you need a scannable link.

Deletes one or many Riddles. Only Riddles that were created via the Riddle Builder tools (riddle_builder_*) or generated by the Riddle AI can be deleted - use this to clean up Riddles you created for testing. Riddles the user created manually in the Creator cannot be deleted. Check context.origin.apiManageable on riddle_get (or "origin" on riddle_list/riddle_account_list) beforehand to know whether a given Riddle qualifies, instead of finding out from the error. Pass UUID to delete a single Riddle, or UUIDs (array of Riddle UUID strings, max 100) to clean up several at once - e.g. everything riddle_list returned with origin: "api". A bulk delete is not atomic and never gives up early: a Riddle that cannot be deleted is reported as that entry's "error" in the {bulk, operation, summary, results} envelope, and every other Riddle in the list is still deleted. A Riddle another item of the same batch still references (a Leaderboard's connected Quiz/Predictor/Minigame, a FormSelect's Form) is retried once automatically after the rest of the batch has run, so listing the referenced Riddle before its referencer no longer requires a second call - only a failure that survives that retry is reported as an error.

Moves one or many Riddles into another project, or into the personal project when projectId is omitted. Pass UUID for a single Riddle or UUIDs (array of Riddle UUID strings, max 100) for several at once; use project_list to find the target projectId, and riddle_list/riddle_account_list to find the Riddles. Unlike the other bulk tools this validates the whole set BEFORE moving anything and moves nothing at all if any Riddle is rejected, because Riddles that reference each other (a Quiz and the Leaderboard it reports to, a Form embedded in another Riddle) can only move together: not every Riddle can be moved on its own, and the error names both the rejected Riddles and the exact connected Riddles to add to UUIDs, which is all it takes to make the same call work. Call riddle_move_check first (same UUIDs, changes nothing) to see which Riddles are blocked, which connected Riddles are missing from the set, and which projects the whole set can go to at all. Moving also requires the transfer permission in both the source and the target project; it does not adopt the new project's design - the Riddle keeps its current preset/look as-is - but it does drop project-specific ad blocks tied to the old project, and the published version is updated along with the draft. Returns {bulk, operation, summary, results} with the new project per Riddle.

Checks, without changing anything, whether a set of Riddles can be moved and which projects they can be moved to - the same check riddle_move runs before it moves anything. Pass exactly the UUID/UUIDs you intend to hand to riddle_move, because the answer depends on the whole set: a Riddle that is connected to another one (a Form embedded into another Riddle as a form select, a Quiz reporting into a Leaderboard) can only be moved when everything it is connected to moves with it, so the same Riddle can be blocked on its own and movable as part of a larger call. Returns {canMoveAll, movable, blocked, addUUIDs, canMoveToPersonal, projects}: "blocked" names, per Riddle, "missingRiddles" (the exact connected Riddles that are not part of the set, each with uuid, title, type and relation: "dependent" for a Riddle reporting into it, "embedded" for a Riddle it embeds), "missingUUIDs" as the bare UUIDs to add, "connectedRiddles" as the unfiltered picture of everything it is connected to, "inaccessibleConnections" as the number of connected Riddles in projects you cannot access, and "resolvable" telling you whether adding UUIDs can fix it at all; "addUUIDs" is the deduplicated union of every missingUUIDs - add it to UUIDs and check again, repeating until canMoveAll is true, because connections chain (a Quiz you add for one Leaderboard can report into a second one) - and "projects" is the intersection of the projects EVERY Riddle of the set can go to - a project you may lack the transfer permission in, or that does not support something one of the Riddles uses, is not in it. Use this before riddle_move whenever the Riddles were not all created by you, or to explain to the user why a move is not possible.

Returns information about the current API key: the authenticated user (email, name - "userEmail"/"userName", "userName" is null if the user never set one) and the associated project/team if using a project API key. Useful to verify authentication and retrieve your user ID or project ID. Note the response's own "id" is the API KEY's row ID, not the user - the user ID (what stats_fetch/stats_* tools want as "entityId" for namespace "user") is the "user" field; "team" is the project ID if this is a project-scoped key.

Creates a new, empty question bank for the given Riddle type ("Quiz" or "Poll"). Add items with questionBank_addItem, then reference the returned "id" as "questionBankId" on a QuestionBank block of a matching riddle_builder_quiz/riddle_builder_poll call - a bank created for "Quiz" can only be referenced from a Quiz, never a Poll, and vice versa. A bank lives in one project and can only be referenced from Riddles of that same project, so pass the projectId of the project the Riddle belongs to; omitting it creates the bank in the project the API key is scoped to.

Lists the question banks of a project - the same banks the Creator's question bank list shows; pass a projectId to look into another project, omitting it lists the banks of the project the API key is scoped to (the personal ones for a user API key). Always paginated - page defaults to 1 and pageSize to 12 even when both are omitted, unlike questionBank_getItems which returns everything by default; a bank list can be large enough that "everything" is never the right default here. An invalid page/pageSize (zero, negative, non-numeric, fractional, or a pageSize over 50) is rejected outright rather than silently clamped. Use questionBank_templateList instead for the built-in starter banks.

Lists the built-in template question banks - pre-filled starter banks anyone can duplicate with questionBank_duplicate to get a bank with real content immediately, instead of starting empty. An overview only: each template is listed with its id, title, its PUBLISHED item count ("itemCount") and DRAFT item count ("draftItemCount"), which blockTypes those items are (null if that cannot be told yet) and a few example categories out of "categoryCount" - read the chosen id with questionBank_get (every category) and questionBank_getItems (the questions themselves) before duplicating it. A template that was never published shows "itemCount": 0 no matter how many questions it actually holds - "draftItemCount" is the number a questionBank_duplicate of it would give you, and the one to judge a template's real size by. Every other tool here rejects a template id, since a template belongs to nobody and is only ever changed through a copy of it.

Retrieves a single question bank by id: its title, riddleType, tags, notes, its categories/blockTypes and whether it has unpublished changes. Use questionBank_getItems for the items themselves, which are not included here. Works on a built-in template id from questionBank_templateList too, to see what a template holds before duplicating it - a template is read back without its owner and tags/notes, since it belongs to nobody. "categories" and "blockTypeCategoryMap" are NOT the same slice of data and can disagree: "categories" is drawn from every DRAFT item (published or not), while "blockTypeCategoryMap" (categories grouped by blockType) only counts items that are actually PUBLISHED - a category used only by unpublished draft items shows up in "categories" but is missing for that blockType in "blockTypeCategoryMap" until questionBank_publish catches it up.

Renames a question bank, immediately and permanently - the title is metadata, not a bank's DRAFT content, so this is unaffected by questionBank_publish/discardChanges and never shows up as an unpublished change. Rejected for a public template id, see questionBank_templateList.

Sets the plain-text notes of a question bank, replacing whatever was there before, immediately and permanently - like the title, notes are metadata outside the DRAFT/publish split, so this is unaffected by questionBank_publish/discardChanges and never shows up as an unpublished change. Notes are for the bank's maintainers - they are never shown to Riddle participants. Rejected for a public template id, see questionBank_templateList.

Duplicates a question bank and every one of its items into a new, independent bank - the items are copies, editing one bank never affects the other. Works on your own banks and on templates from questionBank_templateList. The copy lands in the project given as projectId, or in the project the API key is scoped to when none is named; a bank can only be referenced from Riddles of its own project.

Publishes a question bank: every item's draft content becomes its published content, which is what a QuestionBank block actually draws from at view time - exactly like publishing a Riddle makes its draft live. A bank with unpublished changes (see questionBank_get) still works in a QuestionBank block, it just draws from the last published state, not the newer draft. This is also when a questionBank_deleteItem of an already-published item finally takes effect: it is purged for good only now, having stayed live under its last published content until this call. Rejected for a public template id, see questionBank_templateList - a template has no draft/publish split to act on.

Discards every unpublished change of a question bank, resetting all of its items back to their last published state. An item that was never published (added after the last questionBank_publish) is unaffected - it has no published state to reset to. A questionBank_deleteItem of an already-published item is undone by this too - the item returns to questionBank_getItems as if it had never been deleted, since its published content never left. Irreversible. Rejected for a public template id, see questionBank_templateList.

Deletes a question bank and every one of its items. Rejected with a QUESTION_BANK_INTERDEPENDENCY error if a Riddle in this bank's own project still references it, and DRAFTS COUNT: the reference tracking is refreshed on every write, whether that is a publish, a duplicate, a template-use, an edit in the Creator, or a draft edit through the Builder API (riddle_builder_update and the riddle_builder_* tools). So adding a QuestionBank block pointing at this id is enough to protect the bank - the Riddle does not have to be (re)published for the guard to see it. A successful delete therefore does mean no Riddle in the project references the bank. Two things the guard still does not cover: a validate-only call (riddle_builder_validate) writes nothing and so registers no reference, and the guard is scoped to this bank's OWN project. If the delete IS rejected, find the referencing Riddles with riddle_list/riddle_get, then either remove the QuestionBank block or repoint it at a different bank via riddle_builder_update - questionBank_riddleBlockItems can preview a specific block you already found. Irreversible once it succeeds. Rejected for a public template id, see questionBank_templateList.

Adds one question/item to a question bank. Call questionBank_blockTypeColumns(riddleType) first to see the valid blockType values for this bank and which "columns" each one expects - there is no single universal shape. The item is added to the bank's draft; call questionBank_publish to make it something a QuestionBank block actually draws. Rejected for a public template id, see questionBank_templateList.

Replaces the content of an existing question bank item entirely - blockType, category, difficulty and columns all have to be sent, even the ones that are not changing. blockType is immutable: it must equal the item's current one, a different value is rejected with an error rather than changing the item's type - an item that should be a different blockType has to be deleted and re-added instead. Changes the item's draft; call questionBank_publish to make the change visible to a QuestionBank block. Rejected for a public template id, see questionBank_templateList.

Deletes one item from a question bank; does not affect the rest of the bank. If the item was never published, it is gone immediately and for good. If it WAS published, it instead only disappears from the draft - questionBank_getItems stops listing it right away, but a QuestionBank block on a live Riddle keeps drawing it from its last published content, exactly as if nothing happened, until the next questionBank_publish actually purges it. questionBank_discardChanges before that publish undoes the delete entirely, restoring the item to questionBank_getItems. "hasChanges" in the response says whether the bank now has unpublished changes to publish - true for a published item's pending delete. Rejected for a public template id, see questionBank_templateList.

Lists the items (draft content) of a question bank, optionally filtered by search term, blockType, category or difficultyRange - the same filters the Creator's question bank grid offers. Also reads a built-in template from questionBank_templateList, which is how to preview a template's actual questions before deciding to duplicate it - pass page/pageSize there, a template can hold tens of thousands of items and is returned in full otherwise. Deliberately unlike questionBank_list: omitting page/pageSize here returns everything rather than defaulting to a page, since a bank you filled yourself is often small enough that "everything" is the right answer - an invalid page/pageSize (zero, negative, non-numeric, fractional, or a pageSize over 100) is rejected outright rather than silently clamped.

Lists every question bank tag of a project together with how many banks use each - the tag "id" values questionBank_list's "tags" filter accepts. Tags are per project, so pass the projectId of the project whose banks you are tagging; omitting it returns the tags of the project the API key is scoped to. Question bank tags and Riddle tags are ONE set per project, not two: the same tag can be applied to banks and to Riddles and has the same id in both. This list is therefore a filtered view - it shows the tags at least one BANK uses, with "count" counting banks - while riddle_tag_list shows every tag of the project with "count" counting Riddles. A tag that only banks use is missing from riddle_tag_list's counts (it appears there with "count": 0), and a tag only Riddles use does not appear here at all.

Adds a tag to a question bank, identified either by tagName (reusing the project's tag of that name, or creating it if there is none yet) or by tagId from questionBank_tagList. Tagging a bank that already has the tag changes nothing. Rejected for a public template id, see questionBank_templateList.

Removes a tag from a question bank by tagId. Once nothing uses a tag any more, the tag itself is deleted from the project - "nothing" includes Riddles, which share one set of tags with question banks: a tag a Riddle still uses survives its last bank and simply stops being listed by questionBank_tagList. Rejected for a public template id, see questionBank_templateList.

Lists every blockType valid for a question bank of the given Riddle type, with the exact "columns" shape questionBank_addItem/updateItem expects for that blockType. There is no universal item shape - a "SingleChoice" item and an "Order" item carry different columns, and the same blockType even differs per Riddle type (a Quiz "SingleChoice" has CORRECT_CHOICE/INCORRECT_CHOICE where a Poll "SingleChoice" has a plain CHOICE) - so call this before the first questionBank_addItem for a bank you have not populated before. The number next to each column name is how many values that column requires at minimum: 1 means it must carry at least one value, 2 at least two, 0 means the column is optional and may be left out entirely. Column names not listed here are rejected by questionBank_addItem/updateItem.

Counts, per criterion of a QuestionBank block, how many published items in the bank currently match it - this is a count preview, NOT a preview of the items a real draw would pick. For each questionBankCriteria entry it returns {blockType, category, count}, where count is every published item matching that criterion's category, difficultyRange and blockType; no items are drawn, selected or returned, and maxNumberOfQuestions is deliberately ignored, so count can be (and often is) higher than what the block will actually show once published - an actual draw caps at maxNumberOfQuestions (a positive integer when the criterion sets it; a criterion that omitted it had a cap written in for it at build time as min(5, max(1, this same matching count)), so it is never uncapped). Use this to answer "does this criterion match anything, and roughly how much inventory is there", not "here is what the Riddle will show" - publish is only hard-blocked (QUESTION_BANK_NO_ITEMS_MATCH) when EVERY criterion of EVERY QuestionBank block in the Riddle matches zero published items; a criterion that matches too few items, or none, while another criterion still matches something, publishes silently with no warning, so this is how to find that out yourself before publishing.

Reads the palettes - colors, fonts, button styles and background settings - of a Riddle. Returns every palette the Riddle can use (including the ones inherited from the account / project default preset) with all of its values, which palette is currently selected, which values this Riddle overrides, and the built-in palettes that can be used as a starting point. See riddle://reference/palette/fields for what each value does.

Changes the palette (colors, fonts, button styles, background) of a single Riddle. Values are given as a path => value map, e.g. {"bgColor": "#ffffff", "font.name": "Roboto"} - call palette_get or read riddle://reference/palette/fields for all available paths. Only ever affects the given Riddle: a palette inherited from the account / project default preset is not changed for other Riddles, the new values are stored as an override on this Riddle. Built-in palettes ("default:*") are not stored anywhere, so they are duplicated into a Riddle-owned copy automatically; pass newPaletteName to always work on a copy. Two things to know: the new design is only visible on the embedded (live) Riddle after publishing it again with riddle_publish, and only Riddles that were created via the Riddle Builder tools (riddle_builder_*) or generated by the Riddle AI can be restyled - Riddles the user created manually in the Creator are rejected. Check context.origin.apiManageable on riddle_get (or "origin" on riddle_list/riddle_account_list) beforehand to know whether a given Riddle qualifies, instead of finding out from the error. A palette write does NOT change the Riddle's modifiedAt/modifiedBy - the Creator itself does not stamp them for a design change either, so a client polling modifiedAt for changes will not notice this. What DOES move is riddle_get's context.preset.drifted (turns true once the Riddle preset diverges from its parent) and context.modified.hasChanges (also true from the preset side) - check those, not modifiedAt, to detect an unpublished design change.

Builds a Quiz from a build configuration. For full block/result options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/quiz. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Poll from a build configuration. For full block options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/poll. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Personality Test from a build configuration. For full options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/personality. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Form from a build configuration. For full field types see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/form Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Predictor from a build configuration. For full options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/predictor Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Leaderboard from a build configuration. Connect quizzes, predictors or minigames (except WheelSpinner exclusive ones) that have Name and Email fields and are already published - connecting a draft Riddle fails with "<Type> <UUID> is not published". For full options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/leaderboard Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Minigame from a build configuration. Supports SlotMachine, WheelSpinner, and Sudoku block types. For full options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/minigame Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Story from a build configuration: the simplest block-based Riddle type - a sequence of content blocks (optionally with form blocks to collect lead data) plus an optional result page, with no questions, scoring or leaderboard. For full block options see: https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Builds a Placeholder from a build configuration: a Riddle with no content of its own, only a routing rule that is resolved when the Placeholder is displayed, to decide which OTHER Riddle (or a Riddle picked by tag) to actually show. Requires the Placeholder feature, which has to be enabled for your account. The rule is never resolved through this API - riddleId and conditions are stored as-is and read back unevaluated, by riddle_get too. See the "conditions" build field for the important note on why what you send is not necessarily what you get back. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set.

Edits an existing Riddle of any type with the same build configuration the riddle_builder_<type> tools take - but as a merge, not a rebuild: only what you send is changed. Blocks are addressed by their ID and can be added with "$create": true, removed with "$delete": true (see the "blocks" field) or reordered with "$blocksOrder" - and so are the entries of a block's "items"/"fields" and, for a Personality Test, its "personalities" (reordered with "$personalitiesOrder"); a Placeholder's "conditions" is replaced as a whole though (see that field). Read the Riddle with riddle_get first to get its block IDs and current build configuration - what it returns under "build" is exactly the shape this takes, so it can be fed straight back in. Only Riddles that were created via the Riddle Builder tools (riddle_builder_*) or generated by the Riddle AI can be edited here - a Riddle the user built manually in the Creator can hold content this build config cannot express (riddle_get reports it as "warnings"), so editing it from here would mean editing around content you never saw, and it is rejected. Check context.origin.apiManageable on riddle_get (or "origin" on riddle_list/riddle_account_list) beforehand instead of finding out from the error; reading such a Riddle keeps working. Returns the edited Riddle in the same compact build-configuration envelope riddle_get returns ({uuid, type, modifiedAt, build, nextBlockId, warnings, published, context}). To replace a Riddle wholesale instead, build a new one with the riddle_builder_<type> tool of its type.

Dry-runs one or many Riddle Builder creates and/or edits without creating or changing anything: per entry of $builds, the same validation the real call would apply, against a scratch/deep-copied Riddle that is discarded before this returns - never persisted, never published, no event dispatched. Any media URL in the build IS still checked for reachability with a live HEAD request (no file content is fetched or stored) exactly as a real call would, so an unreachable URL is rejected here too (INVALID_MEDIA) - this is not deferred to flush/publish time. Each entry is {type, build} for a creation or {UUID, build} for an edit; the answer is {valid, summary, items: [{index, type, UUID?, valid, build|errors, warnings?, internalError?}]} - one entry per item, in the order they were sent, so a single config means one entry and items[0]. "internalError" is only present, and only true, when checking that one item ran into an error on OUR side rather than a rejection: that item's outcome is unknown and has been reported to us, and it does not affect the other items in the same call (a real call with that config would answer a 500). Use this to check a build config, or to see why one would be rejected, before spending a real create/edit on it - and to pre-flight a set of similar Riddles in one call. Needed subscription plan: Business or Enterprise. Does NOT catch anything that only happens once a Riddle is actually flushed or published: a database constraint violation or queue-worker behaviour. See riddle://reference/riddle-builder/riddle-types for per-type build shapes and riddle://reference/response-format for the "build"/"warnings" shape this echoes back.

Read the documentation of this MCP server: the block types, form field types, result blocks, palette values and response shapes the other tools expect. Every "riddle://reference/..." URI mentioned in another tool's description, in a tool response or in an error message is a topic of this tool - pass it here to read that document. These documents are the authoritative parameter reference for the riddle_builder_* and palette_* tools: read the relevant one BEFORE the first call instead of guessing property names, and re-read it when a call fails with a VALIDATION_ERROR. Available topics: - riddle://reference/getting-started: overview of every tool by category, authentication, bulk operation rules, move restrictions and the common workflows. Start here when unsure which tool to use. - riddle://reference/response-format: the {uuid, type, modifiedAt, build, nextBlockId, warnings, published, context} envelope every tool returning a Riddle answers with, plus the bulk envelope. - riddle://reference/riddle-builder/riddle-types: all 9 Riddle types with their required/optional build fields and result structure. - riddle://reference/riddle-builder/block-types: every question and content block type per Riddle type - the reference for the "blocks" of a riddle_builder_* call. - riddle://reference/riddle-builder/block-defaults: the default value of every property a read-back omits for still being at it, per Riddle type and block type - what riddle_get states inline per block, but without needing a Riddle. Filter with "riddleType"/"blockTypes", or drop its shared "commonDefaults" map outright with "omit": ["commonDefaults"] - unfiltered it is this server's largest response. - riddle://reference/riddle-builder/form-field-types: all 18 form field types of the FormBuilder block. - riddle://reference/riddle-builder/result-blocks: all 12 result page block types with their format and styling options. - riddle://reference/palette/fields: every palette value palette_customize accepts, and where it is used in a published Riddle. - riddle://reference/palette/built-in-palettes: the built-in palettes usable as a starting point for a custom one. - riddle://reference/palette/fonts: the font families available as the palette font. - riddle://reference/question-bank/overview: what a question bank is, its draft/publish model, and how its items relate to a QuestionBank block - read before the first questionBank_create. Request only the documents you actually need - most are long. Up to 4 at a time, which is the size of the full Riddle Builder set (riddle-types + block-types + form-field-types + result-blocks). "riddleType" and "blockTypes" narrow riddle-types, block-types and block-defaults down to one Riddle type's (or one block type's) own material - e.g. {"topics": ["riddle://reference/riddle-builder/block-types"], "riddleType": ["Quiz"]} drops every other type's question blocks. "fieldTypes" does the same for form-field-types, e.g. {"topics": ["riddle://reference/riddle-builder/form-field-types"], "fieldTypes": ["Dropdown"]} returns that one field type plus the property sets it refers to. All three are ignored (whole document returned) on a topic without that split, which every response says explicitly rather than silently returning everything. On block-defaults specifically, filtering also narrows "commonDefaults" (the defaults shared by many block types, stated once instead of per block) down to only the names the kept Riddle type(s)/block type(s) still point at via "sharedDefaults" - nothing is lost, a name simply is not returned when nothing you kept refers to it any more; "filtered.omitted" reports it alongside "riddleTypes" the same way. "omit": ["commonDefaults"] drops that whole map instead, regardless of riddleType/blockTypes - the one explicit opt-out this tool has, for the case an unfiltered or broadly-filtered call would otherwise still keep most of it; a kept block's or Riddle type's "sharedDefaults" still names what it would have pointed at …

Returns aggregated statistics (views, starts, submissions) for a single period. Omit dateFrom/dateTo for alltime stats, provide both for a specific date range, or only provide one of them for an open-ended date range (e.g. dateFrom only for stats since a specific date, dateTo only for stats until a specific date).

Returns statistics divided into daily intervals for the given date range. Useful for dashboards, graphs, and trend analysis. Both dateFrom and dateTo are required.

Returns a detailed stats breakdown for a specific Riddle, including titles, choices, views, time spent, and submissions. Every "id" in this breakdown (blocks, choices, results, form fields) is the same stored block id that riddle_get's "build" configuration exposes as its "id", so entries can be cross-referenced directly - e.g. to look up a block's full definition or to write back to it. These ids are stable identifiers, not a display order: they are assigned once per block and are not renumbered when other blocks are added or removed, so it is normal for them to be non-contiguous (e.g. starting above 1, or with gaps) on a Riddle that has been edited over time.

Returns a stats breakdown for the authenticated user across all accessible projects. Requires a user API key — will fail with project API keys. Use stats_project_breakdown for single-project stats instead.

Returns a stats breakdown for a specific project.

Returns a paginated list of projects this token has access to (25 per page by default, 100 max), with a sibling "pagination" object ({page, pageSize, total, hasMore}) to page through accounts with many projects. If it is a project API token, only the project linked to the token will be returned. Each project is a trimmed summary (id, name, image) - use project_get for a single project incl. your permissions on it, and project_get_settings for its default Riddle settings. An invalid page/pageSize (zero, negative, or a pageSize over 100) is rejected outright rather than silently clamped - the same contract as questionBank_list/questionBank_getItems.

Returns a single project by its project ID: id, name, image and the permission matrix of the authenticated user for it. The project ID can either be obtained through the project list tool or by taking the "team" property of the riddle_get tool. The project's default Riddle settings are NOT included - they are a large nested configuration tree that is rarely what a caller wants from this tool; use project_get_settings for them.

Returns the project's default Riddle settings that every new Riddle in it starts from - PUBLISHED and ENABLED only: "publishSettings" (privacy/DOI/OTP, email automation, tracking, data layer, ...) and "embedSettings" (iframe sizing, auto-scroll, ...), each containing only the areas the project owner has switched on ("isDefaultEnabled"/"isEnabled" toggled on) in the last published version. Draft changes that were never published and disabled areas are deliberately left out - this tool is not a way to inspect unpublished or disabled defaults, only what actually applies to Riddles right now. Internal "_ids" bookkeeping (ID counters for repeatable items like data layer entries) is stripped since it means nothing outside the Creator UI. Use this to understand what settings a project forces onto its Riddles before creating or editing one in it; project_get is the cheap way to get a project's name, image and permissions instead.

Overview

Riddle.com is a no-code platform for interactive content: quizzes, polls and surveys, personality tests, lead forms, score predictors, minigames, stories and leaderboards. Publishers, broadcasters and brands such as BBC, Funke, SRF, 20 Minuten and Club Med use it to engage their audience and collect first-party data - typically 30-50% of the people who interact with a Riddle fill out its lead form.

This remote MCP server brings that workflow into your AI app: describe the quiz, poll or form you have in mind and it is created in your own Riddle account - on brand, ready to embed.

What you can do

  • Build - any of the 9 Riddle types from a single build configuration: question and content blocks, 18 form field types, result pages, scoring, and branching logic (linear, answer-based, condition-based or score-based).
  • Refine - read a Riddle back as the same build configuration and adjust it block by block, or preview a change before applying it.
  • Design - palettes per Riddle (colors, fonts, buttons, backgrounds, radii), starting from a built-in palette, one of your presets or a saved template.
  • Reuse - taggable question banks that draw a fresh, randomized set of questions into every new quiz.
  • Share - publish when you are ready, then grab the embed code, the public link or a QR code.
  • Learn - views, starts and submissions, broken down by Riddle, project, user or time range.
  • Organize - projects and teams, tags, notes, templates, and moving Riddles between projects.

Every Riddle keeps a draft alongside its published version, so an agent can iterate as much as it likes and your live content only changes when you say go.

Quickstart

  1. Add https://www.riddle.com/creator/api/v3/mcp as a remote MCP server / connector in your AI app.
  2. Sign in with your Riddle account when prompted - no client setup, no secrets to copy around.
  3. Ask for what you need, e.g. "Turn this article into a five-question quiz with a lead form and publish it."
{
  "mcpServers": {
    "riddle": {
      "type": "http",
      "url": "https://www.riddle.com/creator/api/v3/mcp"
    }
  }
}

Prefer a key? Create an MCP key in the Riddle Creator under API keys and append it to the URL: https://www.riddle.com/creator/api/v3/mcp/[MCP_KEY].

Tools

AreaTools
Buildriddle_builder_quiz, riddle_builder_poll, riddle_builder_form, riddle_builder_personality, riddle_builder_predictor, riddle_builder_minigame, riddle_builder_story, riddle_builder_leaderboard, riddle_builder_update, riddle_builder_validate
Manageriddle_list, riddle_get, riddle_rename, riddle_publish, riddle_unpublish, riddle_move, riddle_delete, riddle_tag_add
Distributeriddle_get_embed_code, riddle_qr_code
Designpalette_get, palette_customize, riddleTemplate_list, riddleTemplate_use
Question banksquestionBank_create, questionBank_addItem, questionBank_publish, questionBank_getItems, questionBank_duplicate
Analyticsstats_fetch, stats_overview_fetch, stats_riddle_breakdown, stats_project_breakdown, stats_user_breakdown
Accountwhoami, ping, project_list, project_get

Example prompts

  • Turn a blog post, PDF or URL into a published, on-brand quiz with a lead form.
  • Build a multi-step survey with conditional branching and a custom result page.
  • Draft a personality quiz that recommends the right product to each visitor.
  • Launch a score predictor plus leaderboard for a match day or tournament.
  • Create a training quiz for onboarding and follow how people do.
  • Check how a live quiz is performing and refresh the questions that need it.
  • Restyle a batch of Riddles to a campaign palette and republish them.
  • Keep a tagged question bank and draw randomized quizzes from it.

FAQ

Which AI apps does it work with? Any MCP client that supports remote servers - Claude and Claude Code, Cursor, VS Code and others. It is the same URL everywhere, and each user signs in with their own Riddle account.

Does anything go live automatically? No. Every Riddle has a draft and a published version, and builds and edits land in the draft - so you can let an agent iterate freely and publish once it looks right.

Can I keep working in the Riddle Creator? Yes. Anything the agent builds shows up in your account like any other Riddle and stays fully editable by hand, and the agent can read and analyze your whole library, including its stats.

What can it build? Quizzes, polls and surveys, personality tests, lead forms, score predictors, minigames, stories and leaderboards - with question and content blocks, 18 form field types, scoring, branching logic, result pages, palettes, templates, question banks, embed codes and QR codes.

Do I need a Riddle account? Yes - the server works with your own Riddle account and its projects, so your content, branding and data stay in one place. Riddle offers a 14-day free trial with full features and no credit card required.

Links

Riddle is GDPR/CCPA compliant, cookie- and tracker-free, and WCAG 2.1 accessible.

Frequently asked questions

What is the Riddle Quiz Maker remote MCP server?

The Riddle Quiz Maker remote MCP server is a hosted Model Context Protocol endpoint at https://www.riddle.com/creator/api/v3/mcp, so AI assistants can connect to it without installing or running anything locally.

How do I connect to the Riddle Quiz Maker MCP server?

Add the endpoint https://www.riddle.com/creator/api/v3/mcp to any MCP-compatible client such as Claude Code, Cursor, or VS Code. The setup snippets on this page configure each client in one step.

Does the Riddle Quiz Maker MCP server require authentication?

Yes. Riddle Quiz Maker uses OAuth: the first time you connect, your MCP client opens a browser window to sign in and authorize access, then reuses the credentials for future sessions.

Which transport does the Riddle Quiz Maker MCP server use?

Riddle Quiz Maker exposes a Streamable HTTP endpoint, the transport used by remote MCP servers and supported by all major MCP clients.

Comments