Riddle
Server Details
Build, publish and analyze quizzes, polls, forms and personality tests. Riddle account required.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
Available Tools
38 toolsmedia_deleteADestructiveInspect
Deletes a file from the media library permanently, to clean up after yourself: an upload that turned out wrong, or a file the user no longer wants stored (it frees the storage it counted against). The file must be unused - one any Riddle still shows is refused with a message naming those Riddles, since deleting it would leave a broken image behind in a live Riddle; remove it there first (riddle_builder_update, then riddle_publish so the change is live) and delete afterwards. Unused is a property of the file across the whole ACCOUNT, not of one Riddle: several Riddles can use it and any one of them keeps it alive, and a file the Creator lists as in use cannot be forced out from here either. Not reversible, no undo, and the id is not reused, so anything still pointing at the file stops resolving - ask the user before calling this. Returns {deleted: true, mediaId, name, type, size}.
| Name | Required | Description | Default |
|---|---|---|---|
| mediaId | Yes | The media library id of the file to delete - the "mediaId" the upload response returned, or the id shown for the file in the Creator's media library. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even with destructiveHint=true in annotations, the description goes well beyond by disclosing that deletion is permanent, not reversible, the id is not reused, and anything still pointing at the file stops resolving. It also describes rejection behavior when the file is still in use and the exact return payload.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place, especially for a destructive operation. It front-loads the core action and permanent nature, then layers necessary caveats about usage, account-wide state, and irreversibility in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only one parameter, no output schema, and destructive behavior, the description covers everything an agent needs: what it does, prerequisites, failure behavior, irreversibility, id reuse, and the return shape. No critical context is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter mediaId is fully documented in the schema, giving schema coverage of 100%. The description adds practical guidance on where to find the mediaId (from the upload response or the Creator's media library), which enriches the parameter semantics beyond the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Deletes a file from the media library permanently,' clearly distinguishing this from siblings like riddle_delete and media_upload_link. It also states the purpose is clean-up of unwanted or mistaken uploads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use this tool (cleanup of wrong or unwanted files), when not to use it (if any Riddle still uses the file), and what to do instead: remove the reference first via riddle_builder_update and riddle_publish, then delete. It also advises asking the user before calling because the operation is irreversible.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
media_upload_linkAInspect
Creates a single-use link for uploading ONE media file into the media library. Call it when the user has a LOCAL file for a Riddle: this server cannot receive bytes, so the upload is yours. A link expires after 5 minutes, dies on first use (successful or not), and only 20 are handed out per account per 5 minutes - so create one immediately before each upload, a batch one file at a time rather than the links up front, and never store or share one. Check the file BEFORE minting a link, since a link a rejected file burns is gone: an image, a video or an audio file, at most 10 MB (some environments cap lower - "maxBytes" and "allowedTypes" in the answer are the authoritative pair). Returns {uploadUrl, expiresAt (UTC), singleUse, maxBytes, allowedTypes, usage, requiresNetworkAccessTo}. POST the file to "uploadUrl" as multipart/form-data under the field name "file" - "usage" is that command ready to run, e.g. curl -F 'file=@/path/to/image.png' '' (the link carries its own signature, so no API key or header). That POST leaves your environment and needs outbound HTTPS to the host in "requiresNetworkAccessTo" (allowlist the wildcard it gives; in Claude only an admin can change that organization setting). If it is blocked or does not resolve, tell the user which host to allow - do not retry or look for another way in. The POST answers with {mediaId, type, width, height, size, folderId}: "mediaId" is the ONLY handle - use it as "media": {"type": "Image", "mediaId": } in a block (riddle://reference/riddle-builder/block-types). Never guess a url for it: a CDN url passed as a plain "url" media is re-downloaded as a second, unrelated copy - the account pays twice and this file records no usage, which makes an image in a live Riddle look safe to delete. The file lands in the account's "AI Uploads" folder tagged "AI Upload" (fixed, so the user can review what an agent uploaded in one place), counts against their storage, and media_delete removes it again.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only generic flags, but the description goes far beyond them: link expiry, single-use burn including failed uploads, quota limits, external outbound HTTPS requirements, no-auth-header behavior, mediaId as the only handle, double-billing on CDN URLs, folder/storage side effects, and cleanup via media_delete. This is a thorough behavioral disclosure and does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries operational weight: expiry, quota, validation, network, response, integration, and cleanup. It is front-loaded with the core purpose and then flows logically through the lifecycle. The length is justified by the tool's external side effects and failure modes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and sparse annotations, the description carries the full burden and succeeds: it specifies link response fields, POST response fields, the block-integration pattern, network authorization instructions, quota behavior, and deletion path. Nothing critical is missing for an agent to execute the flow correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero input parameters, so the schema has nothing to document; the baseline of 4 applies. The description adds value by defining the external upload contract: multipart/form-data under the field name 'file', the 'usage' curl command, and the authoritative maxBytes/allowedTypes fields in the response.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Creates a single-use link for uploading ONE media file into the media library.' It also names the precise trigger condition (user has a LOCAL file for a Riddle) and distinguishes itself from the only related sibling, media_delete, making tool selection unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use the tool: when the user has a local file and the server cannot receive bytes. It also gives strong negative guidance: mint immediately before each upload, one at a time, never store/share links, validate the file first, and do not retry if network access is blocked. This is fully actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
palette_customizeAInspect
Changes the palette (colors, fonts, button styles, background) of ONE Riddle, as a path => value map, e.g. {"bgColor": "#ffffff", "font.name": "Roboto"} - the paths are palette_get's or riddle://reference/palette/fields. Never affects another Riddle: a palette inherited from the account/project default preset is not changed for the others, the values are stored as an override on this one. A built-in palette ("default:") is stored nowhere and is therefore duplicated into a Riddle-owned copy automatically; newPaletteName always works on a copy. Two things to know. The new design only reaches the embedded (live) Riddle after another riddle_publish. And only Riddles created by the riddle_builder_ tools or the Riddle AI can be restyled - one the user built by hand in the Creator is rejected, so check context.origin.apiManageable on riddle_get (or "origin" on riddle_list) rather than finding out from the error. A palette write does NOT move modifiedAt/modifiedBy (the Creator does not stamp them for a design change either), so polling those will not notice it: the detector is riddle_get's context.modified.hasChanges, true from the preset side. context.preset.drifted usually moves too but is not reliable alone - it means "diverged from the PARENT preset", so on a Riddle whose context.preset.parentId is null it stays false however much you change; read it only alongside parentId.
| Name | Required | Description | Default |
|---|---|---|---|
| select | No | Select the palette afterwards so the Riddle actually renders with it. Newly created palettes are always selected. | |
| values | Yes | Map of palette path => new value, e.g. {"bgColor": "#ffffff", "buttonColor": "rgba(0,0,0,0.8)", "font.name": "Roboto", "riddleBorderRadius": 12, "isImageInBgDisplayed": true}. Every path must be one of the paths listed in riddle://reference/palette/fields. | |
| riddleUUID | Yes | The UUID of the Riddle you want to restyle. Only Riddles created via the Riddle Builder tools or generated by the Riddle AI can be restyled. | |
| paletteUUID | No | The palette to change. Omit to change the currently selected palette. Pass a built-in id ("default:timeless") to start from that palette. | |
| newPaletteName | No | Create a new palette with this name (copied from paletteUUID / the selected palette) and apply the values to the copy, leaving the original untouched. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only sparse annotations (no readOnly hint, idempotent=false, destructive=false), the description carries the burden and delivers richly: it discloses the isolation guarantee (never affects another Riddle), override storage semantics, automatic duplication of built-in 'default:*' palettes, copy-on-write for newPaletteName, the publish-before-live delay, and the apiManageable eligibility check. This far exceeds annotation coverage and prevents real-world misuse.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but information-dense, with the core purpose and scope isolation front-loaded and a clear 'Two things to know' signpost for the behavioral caveats. Minor redundancy exists (the override/copy concept is restated multiple times), which keeps it from a 5, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 5-parameter tool with nested objects and no output schema, the description covers scope, edge cases, prerequisites, and follow-up actions almost exhaustively. The main gap is that it never describes the return value or success/error shape, which matters more since there is no output schema to fill that void.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 and the schema already documents all five parameters with examples and path validation. The description adds context around copy/override behavior and the path key source, but this complements rather than meaningfully extends the parameter-level documentation already present.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Changes'), a precise resource ('the palette ... of ONE Riddle'), and a concrete mechanism ('path => value map'), with a worked example. It also distinguishes itself from sibling tools by scoping to palette styling only, which differentiates it from riddle_builder_update and palette_get without needing to open their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides strong context: it names the field source (palette_get or riddle://reference/palette/fields), the precondition (Riddles must be builder/AI-created), and the required follow-up (riddle_publish before the design reaches the live embed). It fails to explicitly name alternatives or say 'use X instead when...', so there are no explicit exclusions, but the context is clear enough for routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
palette_getARead-onlyIdempotentInspect
Reads the palettes - colors, fonts, button styles, background settings - of a Riddle: every palette it can use (the ones inherited from the account/project default preset included) with all of their values, which one is selected, which values this Riddle overrides, and the built-in palettes to start from. What each value does is riddle://reference/palette/fields. Mind the size: ~30 values per palette and an account preset can contribute palettes that have nothing to do with this Riddle, so the full response runs into thousands of tokens. Cut it with "omit" - omit: ["paletteValues"] lists the palettes by uuid and name only, which is how you find WHICH one you want (paletteUUID then returns that one in full), and "builtInPalettes"/"customizedValues"/"hints" drop those keys. To read just the design in effect, pass the selectedPaletteUuid from such a listing as paletteUUID.
| Name | Required | Description | Default |
|---|---|---|---|
| omit | No | Leaves parts of the response out - the way to keep this call small. "paletteValues" lists every palette as {uuid, name} instead of with its ~30 values (then read the one you want with paletteUUID); "builtInPalettes", "customizedValues" and "hints" drop those keys entirely. Omit the parameter for the full response. Whatever you leave out is echoed back under "omittedFields", so a missing key never means the Riddle has none of it. | |
| riddleUUID | Yes | The UUID of the Riddle whose palettes you want | |
| paletteUUID | No | Return only this palette instead of all of them. Accepts a palette UUID or a built-in palette id like "default:timeless". | |
| includeBuiltInPalettes | No | Include the full values of all built-in palettes. Defaults to false, in which case only their ids and names are listed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry readOnlyHint=true, idempotentHint=true, and openWorldHint=false; the description adds substantial context beyond them: a concrete size warning (~30 values per palette, responses running into thousands of tokens), the omittedFields echo behavior so a missing key is never interpreted as 'none', and inheritance/override semantics. No contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first sentence, and the size warning is placed before its mitigation. The paragraph is dense but each sentence carries actionable information; the only minor waste is partial redundancy with the schema's omit parameter description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema present, the description fully carries return-value disclosure: it explains which keys exist, what they mean (selected, overridden, built-ins), how to trim them, and the omittedFields echo behavior. Given the tool's complexity (4 parameters, potentially huge response), nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds cross-parameter meaning the schema lacks: how omit interacts with paletteUUID as a two-step listing-then-fetch workflow, and that selectedPaletteUuid values can be fed directly back into paletteUUID. This goes beyond mere restatement of the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Reads the palettes - colors, fonts, button styles, background settings - of a Riddle.' It then enumerates exactly what the response contains (inherited palettes, selected palette, overridden values, built-ins), which clearly distinguishes this read operation from the sibling palette_customize without needing to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a concrete workflow: use the omit parameter to list palettes compactly by uuid/name, then pass a paletteUUID to fetch one in full, and pass the selectedPaletteUuid to read just the design in effect. It provides clear context and sequencing but never explicitly names when-not-to-use or alternatives (e.g., palette_customize for modification), so it falls just short of the top rung.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingARead-onlyInspect
A simple tool that returns "Pong". Can be used to test connectivity and authentication to the MCP.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| message | Yes | The response message. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds the concrete behavior of returning "Pong" plus its intended diagnostic use. This is sufficient for a trivial read-only tool, and there is no contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the core behavior and then states the use case. Every word earns its place with no fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only ping tool with an output schema and clear annotations, the description covers everything an agent needs to decide whether to call it and what to expect. Nothing important is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema coverage is 100%, so there are no parameter semantics to document. The baseline of 4 applies because no parameter guidance is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns "Pong" and can be used to test connectivity and authentication. This is specific enough to convey the tool's function, though it doesn't explicitly differentiate from siblings like whoami, which might also test authentication.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear context for when to use the tool: to test connectivity and authentication to the MCP. It doesn't mention alternatives or exclusions, so it falls short of a full when/when-not comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_getARead-onlyIdempotentInspect
Returns one project by id - id, name, image and the authenticated user's permission matrix for it. The id comes from project_list or from the "team" of riddle_get. The project's default Riddle settings are NOT included; they are a large nested tree with its own tool, project_get_settings.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | The ID of the project to look up |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description adds valuable behavioral context beyond the annotations: the specific return fields, the permission-matrix scope, the source of the id, and the deliberate exclusion of the nested settings tree.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first states the core behavior and return contents, the second provides id provenance, and the third clarifies a likely confusion about settings. No filler or repetition of schema/annotation details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read-only lookup, the description is complete: it lists the return fields, explains where the id comes from, and explicitly warns about the excluded settings tree. The annotations cover idempotency and read-only behavior, so nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents projectId as the project ID. The description adds extra meaning by telling the agent where a valid projectId can be obtained (project_list or riddle_get's team field), which improves correct invocation beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Returns') with a clear resource ('one project by id') and enumerates exactly what is included (id, name, image, permission matrix). It also explicitly differentiates itself from the sibling project_get_settings by stating those settings are NOT included.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool by explaining where the id comes from ('project_list or from the "team" of riddle_get'). It also states when not to use it for settings and routes to the dedicated settings tool, though it does not exhaustively compare against all siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_get_settingsARead-onlyIdempotentInspect
Returns the default Riddle settings every new Riddle of the project starts from - PUBLISHED and ENABLED only: "publishSettings" (privacy/DOI/OTP, email automation, tracking, data layer, ...) and "embedSettings" (iframe sizing, auto-scroll, ...), each holding only the areas whose "isDefaultEnabled"/"isEnabled" was on in the last published version. Never-published drafts and disabled areas are deliberately left out - this is what applies to Riddles right now, not a way to inspect unpublished or disabled defaults. Internal "_ids" bookkeeping (counters for repeatable items) is stripped, meaning nothing outside the Creator. Both fields are always objects keyed by settings area - a project with nothing enabled gets {}, never an empty list. Read it to know what a project forces onto its Riddles before creating or editing one there; project_get is the cheap call for name, image and permissions.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes | The ID of the project whose default Riddle settings to return |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description carries the full behavioral burden since no readOnly/destructive annotations are actually provided. It clearly discloses what is included (PUBLISHED and ENABLED areas only), what is excluded (unpublished drafts, disabled areas, internal _ids), and the response shape (always objects keyed by settings area, {} rather than an empty list). This is strong transparency beyond the name and schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but information-dense and front-loaded with the core purpose. Some redundancy exists ('PUBLISHED and ENABLED only' appears in the first sentence and is restated as never-published drafts and disabled areas being left out), but each clause earns its place by explaining behavior, return shape, or usage guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must explain what the response looks like, and it does: publishSettings and embedSettings are objects keyed by settings area, empty settings yield {} not [], and internal IDs are stripped. It also covers the practical reason to call it and points to project_get for lightweight metadata. The tool is simple enough that nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the parameter description 'The ID of the project whose settings should be returned' fully explains project_id. The tool description adds context about inherited defaults but does not add meaningful new semantics for the parameter itself. Baseline 3 is appropriate because the schema already does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Returns the default Riddle settings every new Riddle of the project starts from.' It names the two returned areas (publishSettings, embedSettings) and explicitly distinguishes itself from project_get, which is the cheap call for name, image and permissions. This makes the tool's role clear and separates it from its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states exactly when to use the tool: 'Read it to know what a project forces onto its Riddles before creating or editing one there.' It also gives an exclusion: this is not a way to inspect unpublished or disabled defaults, and it names project_get as the alternative for name/image/permissions. This is explicit when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
project_listARead-onlyIdempotentInspect
Lists the projects this token has access to as {items, page, pageSize, total, hasMore} - the paging every listing of this server answers with (riddle://reference/concepts/response-envelope), here 25 per page, 100 max, so an account with many projects can be paged through; a project API token only ever returns its own project. Each entry is a trimmed summary (id, name, image): project_get adds your permissions on one, project_get_settings its default Riddle settings. An invalid page/pageSize (zero, negative, or over 100) is rejected rather than silently clamped.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number to fetch (1-indexed). Defaults to 1. Zero, negative or non-numeric is rejected, not clamped. | |
| pageSize | No | How many projects to return per page (max 100). Defaults to 25. Same validation as page; over 100 is rejected, not clamped. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only and idempotent, and the description adds substantial behavioral detail beyond that: paging envelopes, default page size 25, maximum 100, rejection of invalid page/pageSize instead of clamping, and the trimmed summary shape. This gives the agent a reliable model of how the tool behaves at runtime.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: scope, response shape, paging limits, token behavior, sibling differentiation, and validation behavior are all packed into a single coherent paragraph with no filler or repetition of the title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description carries the burden of explaining return values; it defines the envelope fields, item summary fields, paging semantics, limits, and error behavior. For a listing tool, this is complete and leaves no critical gap for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description adds extra meaning by restating the per-page default, the 100 cap, and the reject-not-clamp validation behavior in context with the response envelope. It also mentions that entries are trimmed summaries, which helps an agent understand what the page/pageSize parameters ultimately control.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Lists the projects this token has access to', and immediately specifies the exact response envelope. It also distinguishes itself from project_get and project_get_settings by naming what each sibling does instead, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly contrasts this tool with project_get and project_get_settings, stating which tool adds permissions and which adds settings. It also clarifies token-scope behavior ('a project API token only ever returns its own project'), giving clear context for when listing is appropriate versus drilling into a single project.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_createAInspect
Creates a new, empty question bank for the given Riddle type ("Quiz" or "Poll"). Add items with question_bank_item(action: "add"), then reference the returned "id" as "questionBankId" on a QuestionBank block of a riddle_builder_create call of the matching "type" - 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.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | The bank's title. Defaults to "New question bank" when omitted. | |
| projectId | No | The project (team) ID to create the bank in, as returned by project_list. Omit for the project the API key is scoped to (your personal space on a user API key). | |
| riddleType | Yes | The Riddle type this bank's items are shaped for - "Quiz" or "Poll". Fixed for the lifetime of the bank; every item added later must match it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare non-destructive, non-idempotent hints; the description adds valuable behavioral detail: the bank starts empty, riddleType is fixed for the bank's lifetime, a bank is project-scoped, and omitting projectId falls back to the API key's project. It also clarifies the returned id's downstream role. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences pack the core creation fact and the required follow-up workflow. The second sentence is long but organized around the type and project constraints; no filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema, the description tells the agent what to do with the returned id, how to add items, and which consistency constraints to satisfy. For a creation tool with cross-tool dependencies, nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description meaningfully extends the schema by tying riddleType to downstream Riddle matching and projectId to the Riddle's owning project, explaining the cross-tool constraints behind the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: creates a new, empty question bank for a given Riddle type. It also distinguishes itself from sibling question_bank tools by explaining that this is the creation entry point and that items are added later via question_bank_item.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear workflow: create, then add items with question_bank_item, then reference the id as questionBankId in riddle_builder_create. It does not explicitly name exclusions or alternatives like question_bank_manage, but the context is sufficient for an agent to know when this tool is the intended first step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_deleteADestructiveInspect
Deletes a question bank or ONE of its items - "target" says which, and nothing else deletes either. target "bank" removes the bank and every item it holds (its tags cleaned up exactly as question_bank_tag(action: "remove") does), and is rejected with QUESTION_BANK_INTERDEPENDENCY while a Riddle of the bank's own project still references it - counting the DRAFT and, on a published Riddle, the live version too, so a block removed from a draft does not release the bank until that Riddle is republished; read "deletingABank" in riddle://reference/question-bank/overview before deleting one. target "item" takes questionBankItemId and touches nothing else: on a never-published item the delete is immediate and permanent, on a published one it only leaves the DRAFT - a live Riddle keeps drawing that item until question_bank_manage(action: "publish") purges it, and question_bank_discard_changes brings it back until then. Both are permanent for the caller: there is no trash and no restore. Rejected for a public template id - a template is copied with question_bank_manage(action: "duplicate"), never deleted.
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | What to delete: "bank" (the bank itself and every item in it) or "item" (one question of it). | |
| questionBankId | Yes | The ID of the question bank to delete, or of the bank the item belongs to. | |
| questionBankItemId | No | The ID of the item to delete, as returned by question_bank_get_items or question_bank_item(action: "add"). Required for target "item", rejected for "bank". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say destructiveHint=true, so the description carries the full burden — and it delivers: permanence with 'no trash and no restore', the QUESTION_BANK_INTERDEPENDENCY rejection while a Riddle (draft or live) references the bank, tag cleanup matching question_bank_tag(action: "remove"), and the subtle draft-only deletion for published items until a publish puрges them. No contradiction with annotations; in fact the permanence details amplify the destructiveHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core routing — that target selects bank vs item — is front-loaded, and every sentence carries load-bearing information about errors, permanence, or recovery paths. The cost is a single ~250-word paragraph with heavily nested clauses that is genuinely hard to parse; breaking it into per-target sections would earn a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity destructive operation with no output schema, the description covers nearly all decision-relevant edges: interdependency, draft/live semantics, template rejection, tag cleanup, and a reference pointer. Minor gaps: the success response is never characterized, ownership/permission requirements are only implied by 'for the caller', and the error code 'QUESTION_BANK_INTERDEPENDENCY' appears possibly misspelled.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, setting a baseline of 3. The description adds meaning beyond the schema by explaining the behavioral consequences of each target value, the 'touches nothing else' guarantee for questionBankItemId, its state-dependent behavior (never-published vs published), and the dual role of questionBankId as either the bank to delete or the parent of the item.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Deletes a question bank or ONE of its items - target says which', and immediately asserts 'nothing else deletes either', which distinguishes this tool from every sibling that manipulates banks/items without deleting them. The two explicit modes (bank vs item) leave no ambiguity about the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use and when-not-to-use guidance: the interdependency rejection condition, the draft-vs-live distinction for published items, and the hard exclusion 'Rejected for a public template id - a template is copied with question_bank_manage(action: "duplicate"), never delected'. Names the alternatives that complement it (question_bank_manage publish to purge, question_bank_discard_changes to recover) and points to a reference document. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_discard_changesADestructiveIdempotentInspect
Throws away every unpublished change to a question bank's items at once, resetting each of them to its last published content. Irreversible - there is no undo and no copy of the discarded draft. A pending item delete comes back; an item ADDED since the last publish has no published state and is left alone, so this is not "restore the bank as it was published". Only items are affected: the title and the notes are metadata outside the draft/publish split and never change here. Read the two sides before calling - question_bank_get_items reads the draft, the same call with published: true reads exactly the state this resets to - and prefer question_bank_manage(action: "publish") whenever the draft is what should survive. Rejected for a public template id.
| Name | Required | Description | Default |
|---|---|---|---|
| questionBankId | Yes | The ID of the question bank to discard the unpublished changes of. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint and idempotentHint annotations, the description adds critical behavioral detail: the operation is irreversible with no undo, pending deletes are restored, items added since last publish are left alone, and only items are affected while title/notes metadata are untouched. This significantly enriches the agent's understanding of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is long, every sentence earns its place by covering a distinct aspect: core action, irreversibility, edge cases around pending deletes and additions, metadata exclusion, pre-call guidance, and rejection condition. The most important information is front-loaded,
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter destructive tool with no output schema and no nested objects, the description is highly complete. It explains what happens, what does not happen, irreversibility, alternatives, and the public template rejection. An agent has everything it needs to decide whether and how to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the sole parameter questionBankId is clearly documented in the schema as 'The ID of the question bank to discard the unpublished changes of.' The description itself does not add additional parameter-level semantics beyond what the schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Throws away every unpublished change to a question bank's items at once, resetting each of them to its last published content.' It also distinguishes itself from related operations by noting it is not 'restore the bank as it was published' and by naming question_bank_get_items and question_bank_manage as different operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance on when to call this tool versus alternatives: it tells the agent to read both draft and published states first, explains how to read those states with question_bank_get_items, and says to prefer question_bank_manage(action: 'publish') when the draft should survive. It also states a rejection condition for public template ids.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_getARead-onlyIdempotentInspect
Retrieves one question bank by id: title, riddleType, tags, notes, its categories/blockTypes and whether it has unpublished changes. The items themselves are question_bank_get_items, not included here. Works on a built-in template id from question_bank_list(scope: "templates") to see what it holds before duplicating - a template reads back without owner and tags/notes, belonging to nobody. "categories" and "blockTypeCategoryMap" are different slices and can disagree: "categories" comes from every DRAFT item, while "blockTypeCategoryMap" (categories per blockType) counts only PUBLISHED ones - a category used only by unpublished items is in "categories" but missing for its blockType there until question_bank_manage(action: "publish").
| Name | Required | Description | Default |
|---|---|---|---|
| questionBankId | Yes | The ID of the question bank to retrieve, as returned by question_bank_create/question_bank_list - or of a built-in template from question_bank_list(scope: "templates"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses meaningful behavioral nuance: templates read back without owner/tags/notes and 'belonging to nobody'; 'categories' and 'blockTypeCategoryMap' can disagree because one counts drafts and other only published items; and certain categories can be missing per blockType until publish. These are real behaviors an agent could not infer from annotations alone, and no contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose and field list, then moves to exclusions, then template behavior, then the nuanced categories-vs-blockTypeCategoryMap discrepancy. Every sentence carries information needed for correct use, and the most important scoping statements appear first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-param, no-output-schema tool, the description is exceptionally complete: it lists the return fields, states what isn't included and where to find it, covers template-id special cases, and explains the subtle draft-vs-published category discrepancy. An agent has everything needed to invoke the tool correctly and interpret its response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, so the baseline is 3. The description adds no extra parameter-level semantics beyond referring to the id and acceptable sources for it, but the single integer parameter is simple enough that this is not a meaningful gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Retrieves one question bank by id' and enumerates the returned fields (title, riddleType, tags, notes, categories/blockTypes, unpublished-changes status). It also explicitly distinguishes itself from the sibling question_bank_get_items by stating the items are not included here, so a selecting agent can tell the two apart immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides concrete usage context: it should be called on a built-in template id from question_bank_list(scope: "templates") to inspect before duplicating, and it routes item retrieval away by naming question_bank_get_items as the tool that contains the items. This is clear when-and-when-not guidance, not vague.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_get_itemsARead-onlyIdempotentInspect
Lists the items of a question bank - its DRAFT content by default, or its published items with published: true. Filter by search term, blockType, category or difficultyRange - the same filters a QuestionBank block draws with. A template id from question_bank_list(scope: "templates") reads too - that is how to preview its questions before duplicating it. Paginated {items, page, pageSize, total, hasMore}. The item shape, the "columns" format, the pagination it runs with and what the response leaves out: riddle://reference/concepts/question-bank-items.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, starting at 1 (default: 1). | |
| search | No | Filter items by their column values (e.g. a question title or a choice). | |
| category | No | Filter to one category. | |
| pageSize | No | Items per page (default: 250, max: 500). | |
| blockType | No | Filter to one block type (e.g. "SingleChoice"). | |
| published | No | Read the bank's PUBLISHED items instead of its draft (default false) - a different set of items, and the pool a live Riddle's QuestionBank block actually draws from. Counting what one block criterion can draw is then a single call: its blockType/category/difficultyRange plus pageSize: 1, then read "total" - what that number does and does not include is in riddle://reference/concepts/question-bank-items. | |
| questionBankId | Yes | The bank to list items of - your own, or a template id from question_bank_list(scope: "templates"). | |
| difficultyRange | No | Filter to a difficulty range, as [min, max] (e.g. [1, 5]). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint and idempotentHint, and the description adds valuable behavioral detail beyond those: the draft/published distinction, the fact that published items are what a live Riddle block draws from, the paginated response shape, the total-count technique for block criteria, and a reference for what the response omits. This is rich, non-obvious behavior disclosed clearly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but well-structured: core purpose first, then filtering modes, template usage, pagination shape, and reference pointer. Every sentence adds useful guidance, and nothing is padded with redundant restatement of the tool name or schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by giving the exact pagination fields ({items, page, pageSize, total, hasMore}) and linking to a reference for item shape, column format, pagination behavior, and omitted fields. It also covers template previews, filtering parity with QuestionBank blocks, and the total-count trick. This is complete enough for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all parameters; the baseline is 3. The description adds meaningful semantic value beyond the schema for questionBankId (template ids from question_bank_list) and published (explains draft vs published pools and how to count block draws), which justifies a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'Lists the items of a question bank', and clarifies two distinct modes (draft by default vs published with published: true). It also differentiates itself from siblings like question_bank_get and question_bank_list by scope and purpose, so an agent can select it correctly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: listing a bank's draft or published items, filtering the same way a QuestionBank block draws, and previewing template questions via a template id from question_bank_list. It doesn't explicitly name exclusions or alternative tools for other scenarios, but the usage context is strong and unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_itemAInspect
Adds or replaces ONE question/item of a question bank, by "action" - deleting one is question_bank_delete. There is no universal item shape: read riddle://reference/question-bank/block-type-columns before the first "add" into a bank you have not populated - it lists the valid blockType values per Riddle type and the "columns" each expects (the blockTypeColumns listing is that document, not a tool). "update" replaces the item's content entirely, so blockType, category, difficulty and columns must all be sent even when unchanged, and blockType is immutable: a different value is rejected rather than retyping the item (delete it and add a new one instead). Both change the bank's DRAFT - question_bank_manage(action: "publish") is what makes a change something a QuestionBank block draws, and question_bank_discard_changes throws every unpublished change away again. "hasChanges" in the response says whether the bank now has unpublished changes. Rejected for a public template id.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do: "add" a new item (takes blockType, category, difficulty, columns) or "update" an existing one (the same, plus questionBankItemId). | |
| columns | No | The question content, as {columnName: [values]} - never a list, and a column holding a single value still takes a list. Which names are valid depends on the bank's riddleType AND the blockType, so take them from riddle://reference/question-bank/block-type-columns instead of guessing (an unknown one is rejected, naming it and the valid ones). On "update" this replaces the content entirely rather than merging: send every column, and hand question_bank_get_items output straight back with its {"id", "value"} objects intact - keeping those ids is what edits the stored values instead of replacing them with a fresh set. | |
| category | No | The item's category - free text, used to filter what a QuestionBank block draws (see the "questionBankCriteria" of the QuestionBank block type). | |
| blockType | No | The block type this question is shaped for, e.g. "SingleChoice". riddle://reference/question-bank/block-type-columns lists the ones valid for this bank's riddleType. Immutable: on "update" send the item's current one back unchanged (question_bank_get_items returns it), a different value is rejected. | |
| difficulty | No | The item's difficulty, 1-10 - also used to filter what a QuestionBank block draws. | |
| questionBankId | Yes | The ID of the question bank the item belongs to. | |
| questionBankItemId | No | The ID of the item to update, as returned by question_bank_item(action: "add")/question_bank_get_items. Required for "update", rejected for "add". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals that update replaces content entirely, blockType is immutable, public template ids are rejected, and both actions modify the DRAFT until published. It even discloses the hasChanges response signal. The annotations are thin, so this behavioral disclosure is essential and well supplied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with purpose and sibling distinction, and every sentence carries operational information. It is a bit long and contains a parenthetical clarification about the reference document, but the complexity justifies most of the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity tool with no output schema, the description covers alternatives, prerequisites, mutation semantics, draft/publish flow, and a response signal. The schema handles parameter detail, while the description supplies the behavioral context needed to invoke the tool safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents every parameter with 100% coverage, so the baseline is 3. The description adds cross-parameter meaning: update requires all fields even when unchanged, blockType must be echoed back, and valid blockType/columns come from the referenced document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Adds or replaces ONE question/item of a question bank, by action' and immediately distinguishes the delete case via question_bank_delete. This makes the core operation and its scope unambiguous, and the sibling distinction is explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit routing: deletion goes to question_bank_delete, publishing to question_bank_manage(action: 'publish'), and discarding to question_bank_discard_changes. It also instructs reading the reference document before first add and explains that blockType retyping is rejected, so the correct alternative is delete and re-add.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_listARead-onlyIdempotentInspect
Lists question banks. Scope "own" (the default) lists the banks of a project - the same ones the Creator shows; pass a projectId to look into another project, omit it for the project the API key is scoped to (your personal ones on a user API key). Paginated {items, page, pageSize, total, hasMore}. Scope "templates" lists the built-in starter banks instead - pre-filled banks anyone can copy with question_bank_manage(action: "duplicate") to get real content immediately instead of starting empty. It takes riddleType and nothing else (a handful of them, nothing to page or search) and answers with id, title, PUBLISHED "itemCount", DRAFT "draftItemCount", which blockTypes those items are (null when that cannot be told yet) and a few example categories out of "categoryCount". A template that was never published reports "itemCount": 0 however many questions it holds - judge its real size by "draftItemCount", the number a duplicate would give you, and read the chosen id with question_bank_get and question_bank_get_items before duplicating. Every write here rejects a template id: a template is only ever changed through a copy of it.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (default: 1). Scope "own" only. | |
| tags | No | Filter by tag IDs (array of integers), as returned by riddle_tag_list. Omit to ignore tags. Scope "own" only. | |
| scope | No | What to list: "own" (default) for the question banks of a project, "templates" for the built-in starter banks anyone can duplicate. | |
| search | No | Search term to filter banks by title. Scope "own" only. | |
| sortBy | No | Sort field: "createdAt" or "modifiedAt". Defaults to "createdAt". Scope "own" only. | |
| pageSize | No | Items per page (default: 12, max: 50). Scope "own" only. | |
| projectId | No | The project (team) ID whose banks you want, as returned by project_list. Omit for the banks of the project the API key is scoped to (your personal ones on a user API key). Scope "own" only. | |
| sortOrder | No | Sort direction: "ASC" or "DESC". Defaults to "DESC". Scope "own" only. | |
| riddleType | No | Filter by Riddle type ("Quiz" or "Poll"). Omit to list banks of every type. Applies to both scopes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, it reveals pagination shape, scope-specific response fields, the template itemCount vs draftItemCount pitfall, and the rule that writes reject template ids. This is rich behavioral context that an agent could not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries a distinct behavioral fact, and it is front-loaded with the core purpose before the scope-specific details. The structure moves from general behavior to own-scope to templates to warnings, which makes the density navigable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the necessary return contract: pagination envelope, template item fields, and the itemCount caveat. It also names the related tools for follow-up, making the definition complete for an agent to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already documents all 9 parameters, the description adds the crucial cross-parameter constraints: scope 'templates' accepts only riddleType, projectId determines whose banks appear, and several parameters apply to the 'own' scope only. This goes well beyond the baseline schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names the verb and resource ('Lists question banks') and the scope distinction ('own' vs 'templates') differentiates this from the several other question_bank siblings immediately. It also clarifies what 'own' means relative to a project and the API key, so there is no ambiguity about what the tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the own scope versus templates, and gives an actionable path for templates: read with question_bank_get and question_bank_get_items before duplicating via question_bank_manage. It even warns that template ids are rejected by write operations, preventing a likely misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_manageAInspect
Everything that acts on a question bank as a whole, by "action" - the items themselves are question_bank_item, and the two calls that only destroy are question_bank_delete and question_bank_discard_changes. A public template id is accepted for "duplicate" only and rejected by every other action. "rename" sets the title and "updateNotes" replaces the plain-text maintainer notes (never shown to participants): both are metadata rather than DRAFT content, so they take effect immediately AND permanently, are unaffected by publishing or discarding and never count as an unpublished change. "publish" makes every item's draft content its published content - what a QuestionBank block actually draws at view time - and is when a pending item delete is finally purged; a bank with unpublished changes still works in a block, it just draws its last published state. "duplicate" copies the bank and all of its items into a new independent bank (editing one never affects the other) in projectId or the key's project, and is the way to change a public template.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Plain-text notes for this bank, e.g. sourcing/curation instructions - replaces any existing notes. Required for "updateNotes", rejected for every other action. | |
| title | No | The new title for "rename", or the title of the copy for "duplicate". Required for both, rejected for every other action. | |
| action | Yes | What to do with the bank: "rename" (takes title), "updateNotes" (takes notes), "duplicate" (takes title and optionally projectId) or "publish" (no further parameters). | |
| projectId | No | The project (team) ID the copy should land in, as returned by project_list. Only for "duplicate", where omitting it uses the project the API key is scoped to. | |
| questionBankId | Yes | The ID of the question bank to act on. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
It adds rich behavioral detail far beyond the annotations: metadata changes are immediate and permanent, publish swaps draft to published content and purges pending deletes, duplicate creates an independent copy, and a bank with unpublished changes still draws its last published state. This is exactly the side-effect disclosure an agent needs for a mutation-style dispatcher.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and front-loaded with the scope, and every sentence carries meaningful information. However, it is one long paragraph with many semicolons and clauses; bullet separation per action would make it easier to parse quickly without losing content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a multi-action tool with no output schema, the description covers invocation semantics, side effects, permanence, template restrictions, and sibling boundaries comprehensively. It does not describe return shape or error behavior, which is a minor gap for an action dispatcher given that the call itself is fully specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds critical cross-parameter meaning: title is required for rename and duplicate and rejected otherwise, notes are required for updateNotes and rejected otherwise, projectId is duplicate-only with a fallback to the key's project, and public template ids are accepted only for duplicate. This goes well beyond the schema's per-parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as a whole-bank action dispatcher with the four concrete actions (rename, updateNotes, duplicate, publish), and explicitly separates it from question_bank_item and the delete/discard siblings. An agent can tell what this tool operates on and what it does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names the item-level sibling and the two destroy-only siblings, giving clear routing context for when not to use this call. It does not explicitly mention creation/read-only siblings, but the 'acts on a question bank as a whole' framing plus action enum is enough for most routing decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_tagAInspect
Adds a tag to a question bank or removes one from it, by tagName or tagId from riddle_tag_list - exactly one of the two, as riddle_tag does. Question bank tags and Riddle tags are ONE set per project, not two: the same tag applies to banks and Riddles and has the same id in both, which is why the ids come from riddle_tag. "add" reuses the project's tag of that name or creates it, and re-tagging changes nothing. "remove" never creates anything - a tag the bank does not carry is an error - and a tag nothing uses any more is deleted from the project, where "nothing" includes Riddles: a tag a Riddle still uses survives its last bank. Deleting a tagged bank cleans up the same way. This only ever adds or removes the tag on THIS bank; riddle_tag_delete removes the label from the project itself. Rejected for a public template id.
| Name | Required | Description | Default |
|---|---|---|---|
| tagId | No | The ID of an existing tag, as returned by riddle_tag_list. Pass either this or tagName. | |
| action | Yes | "add" the tag to the bank, or "remove" it from the bank. | |
| tagName | No | The name of the tag. On "add" the project's tag of that name is reused, or created if there is none yet; on "remove" nothing is ever created and a name the bank does not carry is an error. Pass either this or tagId. | |
| questionBankId | Yes | The ID of the question bank to tag or untag. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only openWorldHint, idempotentHint, and destructiveHint, all false, which are generic. The description goes well beyond them by detailing idempotency ('re-tagging changes nothing'), error behavior ('a tag the bank does not carry is an error'), side effects (deleting an unused tag from the project), survival rules when a Riddle still uses the tag, and cleanup after bank deletion. This is comprehensive behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but each sentence earns its place by conveying a distinct behavioral or relational fact. It is longer than average, but the complexity of shared tag sets, idempotency, error cases, and cascading deletions justifies the length. The core purpose is front-loaded, and the rest flows logically.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of an output schema, and the rich annotations, this description covers everything an agent needs: primary action, parameter constraints, side effects, error conditions, relationships to sibling tools, and a usage restriction. Nothing critical is missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all four parameters with descriptions (100% coverage), so the baseline is 3. The description adds meaningful cross-tool semantics—tag ids are shared with riddle_tag, 'add' vs 'remove' creation behavior, and the 'exactly one' rule—which enriches an agent's understanding beyond the schema fields. It doesn't fully compensate for all schema details, but it provides valuable additional context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource—'Adds a tag to a question bank or removes one from it'—and immediately clarifies the parameter source and the one-of requirement. It also distinguishes itself from riddle_tag_delete ('removes the label from the project itself') and references riddle_tag, so an agent can tell it apart from siblings without guessing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit scoping: 'This only ever adds or removes the tag on THIS bank,' and explicitly points to riddle_tag_delete for project-level label removal. It also states the rejection condition for public template ids and clarifies that tag ids come from riddle_tag_list, making both when-to-use and when-not-to-use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reference_getARead-onlyInspect
Read this server's own documentation: the block types, form field types, result blocks, palette values and response shapes the other tools expect. Every "riddle://reference/..." URI named in a tool description, a response or an error message is a topic of this tool - pass it here to read that document. These 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. Up to 3 topics per call, and only the ones you need - most are long. Which topics exist, and what each one holds, is the "topics" parameter's own enum and description - not repeated here.
"riddleType", "blockTypes" and "fieldTypes" narrow a document to your own material, and are ignored - whole document returned, stated in the response - on one that has no such split. block-types is never returned unscoped: {"riddleType": ["Quiz"]} is still all thirteen of a Quiz's block types (~20 KB), so name the ones you are about to build in "blockTypes" (a Quiz filtered to ["SingleChoice"]: ~5.5 KB, and it says everything about that block the wide read does). Decide the blocks first, then read only those. "fieldTypes" does the same for form-field-types and form-field-defaults, so reading both of them with {"fieldTypes": ["Dropdown"]} is the complete reference for one field type and nothing else. The per-entity families need no filter at all - riddle://reference/block-defaults/SingleChoice IS the filtered read.
| Name | Required | Description | Default |
|---|---|---|---|
| topics | Yes | The documents to read, as their "riddle://reference/..." URIs (a document's short resource name, e.g. "block-types", works too). What each one holds: - riddle://reference/index: every document this server has, with its exact size. Read this first when you do not know which of the others you need - it is by far the smallest, and the one place the member names of the {...} families below are listed. - riddle://reference/getting-started: what this server is for, the authentication model, the guided prompts, and the addresses of the documents that hold the rules. Start here when unsure which tool to use. - riddle://reference/prompts/{prompt} (one per guided prompt, e.g. riddle://reference/prompts/build_LeadGenQuiz): the playbook for a whole goal - what to ask the user first, the tool calls in order, what to verify, the traps. Read one when the user states a GOAL rather than an operation. - riddle://reference/response-format: the envelope every Riddle-returning tool answers with, plus the list, bulk and error shapes. - 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 - the reference for the "blocks" of a riddle_builder_* call. Returned scoped only, and worth scoping twice (see "blockTypes"). - riddle://reference/riddle-builder/form-field-types and .../result-blocks: the 18 form field types of the FormBuilder block, and the 12 result page block types with their format and styling options. - riddle://reference/concepts/{concept} (one per subject, e.g. riddle://reference/concepts/merge-semantics): how an edit merges, the "preset" and "publish" objects, branching logic, defaults, bulk calls, move restrictions, limits, troubleshooting. - riddle://reference/block-defaults/{blockType}, riddle://reference/riddle-defaults/{riddleType}, riddle://reference/form-field-defaults, riddle://reference/publish-defaults: what a read-back leaves out for still being at its default, and what that default is. Read riddle://reference/concepts/defaults once for how to use them. - riddle://reference/palette/fields, .../built-in-palettes, .../fonts: every palette value palette_customize accepts and where it shows up, the built-in palettes to start from, the available font families. - 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 question_bank_create. | |
| blockTypes | No | The block type name(s) you are actually going to build (e.g. "SingleChoice", "WheelSpinner"), narrowing block-types on top of whatever "riddleType" kept - the normal way to read that document, not an optimization for later: pass the two or three the Riddle needs, and come back for another. The names are deliberately not enumerated here (dozens of them, on a schema every agent reads every turn); an unknown one, or a real one outside the Riddle type(s) you filtered to, is rejected with the names that are valid for your situation. Omit for every block type. | |
| fieldTypes | No | Narrow form-field-types and form-field-defaults to these form field type name(s) (e.g. "Dropdown", "Privacy"); the property sets a kept type refers to (propertySets/commonProperties) and the "fields" usage notes always come with it. Not enumerated here for the same reason "blockTypes" is not - an unknown one is rejected with the full list. Ignored on every other topic. Omit for every field type. | |
| riddleType | No | Narrow riddle-types/block-types to these Riddle type(s) - on block-types that drops every other type's question blocks while keeping the shared conventions (commonBlockProperties, the general Content/Ad/Quote blocks). REQUIRED on block-types unless "blockTypes" is given instead, and only the WIDE scope of it. Ignored on a topic with no per-type split, and not applicable to the block-defaults/riddle-defaults families - read the entity's own address there. Omit for every type. | |
| includeAvailableTopics | No | Whether to carry the full "availableTopics" catalogue. Omit it - the first reference_get of a session gets it, later ones get a pointer instead of repeating ~2.5 KB you already have. true gets it again (a fresh conversation on an existing session), false never pays for it. |
Output Schema
| Name | Required | Description |
|---|---|---|
| references | Yes | One entry per requested topic, in the order requested. |
| availableTopics | Yes | Every topic this tool can return, uri => {sizeBytes, summary} - sent in full on the FIRST reference_get of a session, then replaced by a short {omitted, namesAndSizesIn, resend} pointer ("includeAvailableTopics" overrides both directions). The generated families are compacted under "families" - the address template, how many addresses and what they cost in total, the individual names being in riddle://reference/index. Build one by replacing a "uriTemplate" variable with your entity, e.g. riddle://reference/block-defaults/Flashcard. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true and openWorldHint=false. The description adds substantial behavioral context beyond that: filter parameters are 'ignored' on topics with no split, block-types is 'never returned unscoped' even when riddleType is given, and the availableTopics catalogue is carried on the first call then replaced by a pointer on later calls to avoid repeating ~2.5 KB. These are non-obvious behaviors the annotation alone would never convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but densely informative; each sentence carries operational guidance such as sizing, filtering behavior, and when to re-read. It delegates the topic enumeration to the schema ('not repeated here') rather than duplicating it, which keeps it as tight as the tool complexity allows. It is well front-loaded with the core purpose before filtering details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and a dedicated topic (riddle://reference/response-format) explaining return shapes, the description need not cover return values. It covers what an agent must know to call correctly: which topics exist, which filters apply per topic, how big responses are, when to read before other tools, and how the availableTopics catalogue behaves across calls. Nothing an agent needs to invoke this tool successfully is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the parameter descriptions are exceptionally rich, enumerating every topic URI with its purpose, giving examples like 'SingleChoice' and 'Dropdown', and documenting rejection behavior for unknown names. The main description adds complementary semantics: the interplay between blockTypes and riddleType for scoping, size implications (~20 KB vs ~5.5 KB), and the explicit statement that the topic enum is not repeated in the description. This far exceeds the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Read this server's own documentation: the block types, form field types, result blocks, palette values and response shapes the other tools expect.' This enumerates exactly what the tool retrieves and clearly differentiates it from sibling tools that operate on riddles, media, palettes, and question banks. The title 'Get builder reference document' reinforces the same purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use instructions: '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.' It also imposes practical constraints ('Up to 3 topics per call, and only the ones you need') and explains the filtering strategy ('Decide the blocks first, then read only those'). The schema parameter descriptions add topic-level routing guidance, such as 'Read this first when you do not know which of the others you need.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_builder_createAInspect
Builds a new Riddle of any of the nine types from a build configuration: "type" says which kind (see that argument for what each one is and what it needs at a minimum), "build" carries the content. Everything a type accepts is described on the "build" fields themselves, marked with the types it belongs to; the exhaustive per-type shapes are in riddle://reference/riddle-builder/riddle-types, the block types in riddle://reference/riddle-builder/block-types, and the human help pages at https://www.riddle.com/help/api/build-riddles/riddle-types-and-other-blocks/. To change an existing Riddle instead, use riddle_builder_update (a merge, not a rebuild); to check a configuration without creating anything, riddle_builder_validate. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format), with 'queued': true added when queue is set. The new Riddle's view URL comes back in it - "context.viewUrl" once published, "context.viewUrlUnavailable.url" (already final, not live yet) before that.
| Name | Required | Description | Default |
|---|---|---|---|
| omit | No | Sections of the returned envelope to leave out; omit the parameter for the whole envelope. "uuid"/"type"/"modifiedAt" are always returned, and whatever you leave out is echoed back under "omittedFields", so a missing key never means the Riddle has none of it. Details: riddle://reference/concepts/warnings. | |
| type | Yes | Which kind of Riddle to build - this decides which "build" fields and which block types exist. Quiz: questions with right and wrong answers, scored, one result page per score range (title + blocks). Poll: opinion questions, nothing right or wrong, one shared result page (title + blocks). Personality: answers score towards personalities, the winner is the result (title + blocks + personalities). Form: lead-collecting fields only, no questions (title + blocks). Predictor: predictions of real-world outcomes, scored once the actual result is entered (title + blocks). Minigame: SlotMachine, WheelSpinner, Sudoku, Minesweeper or Crosswords (title + blocks). Story: linear content pages, no answers of any kind (title + blocks). Leaderboard: a standalone ranking other published Riddles connect to, no blocks (title). Placeholder: no content of its own, routes to another Riddle by prioritized, time-windowed rules (title). Per-type shapes: riddle://reference/riddle-builder/riddle-types. | |
| build | Yes | The build configuration of the Riddle type named in "type".This is the raw build configuration in the engine's own key names - the exact same shape riddle_get returns under "build", riddle_builder_update takes, and riddle_builder_validate dry-runs, so a read-back can be fed straight back in - riddle_get's "build" KEY, never the outer envelope around it, whose "uuid" and siblings are rejected as unsupported properties. Unknown keys are rejected rather than ignored. WHICH fields exist is decided by "type": each one below opens with the types it belongs to, and a field the chosen type does not have is rejected. Only "title" exists on all nine. | |
| queue | No | Whether to queue the creation asynchronously. | |
| project | No | The project ID; pass NULL for personal project; omit to use the currently selected project. | |
| publish | No | Whether to publish the Riddle right after creation; default false (draft). Distinct from the "publish" field INSIDE the build config, which is the stored publish configuration. | |
| templateId | No | Only when this build config came from a template you adapted (riddle_template_get): that template's id. Always pass it when you have one - the new Riddle then starts out on the template's whole DESIGN, including what no build config can express, with your build config applied on top. The content is yours either way. Details: riddle://reference/concepts/unknown-properties. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations are sparse (no readOnly/destructive hints, idempotent false, openWorld false), and the description adds meaningful creation behavior: it returns the compact riddle_get envelope, adds 'queued': true when queueing is set, and explains how the view URL appears before and after publication. It doesn't fully describe async queue behavior or failure modes, but it goes beyond annotations and schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and information-rich but not actually concise: the first paragraph is a long semicolon-heavy run-on sentence mixing type semantics, references, sibling alternatives, and return behavior. It front-loads the core action and alternatives, but it is harder to scan than it could be given how much detail the input schema already carries.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex creation tool with nested objects, seven parameters, and no output schema, the description is remarkably complete: it explains the return envelope, the queued flag, the view URL semantics, the build-configuration model, and points to authoritative references for per-type shapes, block types, preset, publish, and response format. An agent has enough to select and call the tool correctly and to know what it will get back.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 per the rubric. The tool description mostly defers to schema fields ("see that argument", "described on the build fields themselves") rather than adding new parameter semantics; the real value is the conditional per-type docs and references, not new elucidation of the parameters themselves.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource, "Builds a new Riddle," and explains the build/type configuration model. It also names the sibling distinctions (riddle_builder_update for edits, riddle_builder_validate for dry-run checks), so an agent can immediately tell this tool apart from adjacent operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when not to use this tool: "To change an existing Riddle instead, use riddle_builder_update... to check a configuration without creating anything, riddle_builder_validate." This is concrete routing guidance, not just an implication.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_builder_updateAInspect
Edits an existing Riddle of any type with the same build configuration riddle_builder_create takes - but as a merge, not a rebuild: only the fields you send are touched, an omitted one is left exactly as it is. Blocks are addressed by their "id", added with "$create": true, removed with "$delete": true and reordered with "$blocksOrder"; the same grammar edits a block's "items"/"fields" and a Personality Test's "personalities", while a Placeholder's "conditions" is replaced as a whole (see each field). Read the Riddle with riddle_get first: what it returns under "build" is exactly the shape this takes, block IDs included. Only Riddles created by the riddle_builder_* tools or by the Riddle AI can be edited here - one built manually in the Creator can hold content this build config cannot express, and is rejected; check context.origin.apiManageable on riddle_get ("origin" on riddle_list) beforehand. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format).
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | Yes | The UUID of the Riddle to edit, as returned by riddle_list or riddle_get (e.g. "6FA740EW") - the Riddle itself, never a block id or a project id. | |
| omit | No | Sections of the returned envelope to leave out; omit the parameter for the whole envelope. "uuid"/"type"/"modifiedAt" are always returned, and whatever you leave out is echoed back under "omittedFields", so a missing key never means the Riddle has none of it. Details: riddle://reference/concepts/warnings. | |
| build | Yes | The changes to apply, as a partial build configuration in the engine's own key names - the same shape riddle_get returns under "build" and riddle_builder_create takes. Only the fields you send are touched; send at least one. A field only exists for the Riddle types that have it, and unknown keys are rejected rather than ignored. | |
| publish | No | Whether to publish the Riddle after the edit; default false, which leaves the changes in the draft. It rides along with an edit, it is not one: publish: true with an empty "build" is rejected. To publish what is already in the draft, call riddle_publish. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the sparse annotations (openWorldHint/idempotentHint/destructiveHint), the description discloses deep behavioral traits: omitted fields remain untouched, blocks merge by id while Placeholder conditions replace wholesale, deletes are rejected if still referenced, and a read-back can differ due to normalization. These details materially shape how an agent should form a request and interpret results. No contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: core merge semantics are front-loaded, the block-edit grammar is condensed, prerequisites and exclusions follow, and the return format is stated last. Despite the density, the prose is structured and free of padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with nested objects, type-specific behaviors, and no output schema, the description covers prerequisites, input-shape provenance, restrictions, reference URLs, and return semantics. An agent has enough context to invoke it correctly and to know where to look for deeper details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each property is richly described, so the baseline is 3, but the top-level description adds cross-cutting meaning beyond the schema: the $create/$delete/$blocksOrder grammar common to blocks, items, fields, and personalities, and the merge-vs-wholesale-replacement distinction. It ties the schema fields together into one coherent model.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a precise action: 'Edits an existing Riddle of any type' using the same build configuration as riddle_builder_create, and immediately distinguishes it as a merge rather than a rebuild. This clearly identifies the tool as the update counterpart to the create sibling and removes ambiguity about its role.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit workflow instructions: read the Riddle with riddle_get first because its 'build' output is exactly the expected shape, and check context.origin.apiManageable beforehand. It also states a hard exclusion—only Riddles created by riddle_builder_* tools or the Riddle AI can be edited—while manual Creator Riddles are rejected, so the agent knows when not to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_builder_validateARead-onlyIdempotentInspect
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, run against a scratch/deep-copied Riddle that is discarded before this returns - never persisted, never published, no event dispatched. A media URL in the build IS still checked for reachability with a live HEAD request (no content fetched or stored), so an unreachable one is rejected here too (INVALID_MEDIA) instead of at flush/publish time. An entry is {type, build} for a would-be creation or {UUID, build} for an edit; the answer is the {validate, valid, summary, items} envelope of riddle://reference/concepts/bulk, one item per entry in the order sent - a single config is items[0]. Use it to see why a config would be rejected before spending a real create/edit on it, and to pre-flight a set of similar Riddles in one call. PASS "project" whenever a build references anything project-scoped (a Form behind FormSelect, a tag, a project ad slot), set to the project you will actually create in: creating entries are dry-run inside it, and without it they run in the personal project, where such a reference is invisible and comes back as "You are not authorized to access ..." for a build a real create would accept. Catches nothing that only happens once a Riddle is really flushed or published - a database constraint violation, queue-worker behaviour. Per-type build shapes: riddle://reference/riddle-builder/riddle-types.
| Name | Required | Description | Default |
|---|---|---|---|
| builds | No | The build configs to dry-run, 1 to 20 entries, creates and edits mixable: {type, build} for a would-be creation or {UUID, build} for an edit, exactly one of "type"/"UUID" per entry. "type" is one of Quiz / Poll / Personality / Form / Predictor / Leaderboard / Minigame / Story / Placeholder, and "build" is exactly what riddle_builder_create or riddle_builder_update takes, so a config moves between them unchanged. An edit entry hits the same origin gate as riddle_builder_update - rejected unless the Riddle is apiManageable (context.origin.apiManageable on riddle_get). | |
| project | No | The project to dry-run the CREATING entries in - riddle_builder_create's own parameter, and it must be the project you intend to create in: the scratch Riddle is built inside it, and anything project-scoped the build REFERENCES (a Form behind FormSelect, a tag, a project ad slot) is only resolvable from there. Without it such a build is evaluated in the personal project and rejected with "You are not authorized to access Form <UUID>" - a scope problem wearing a permissions error, and a false negative for a build a real create would accept. NULL means the personal project, omitted the currently selected one. Ignored by editing entries ({UUID, build}), always evaluated in their own Riddle's project. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description is exceptionally transparent: it states the Riddle is scratch/deep-copied and discarded, never persisted, never published, no event dispatched, that media URLs are still checked via a live HEAD request with no content fetched or stored, and that the personal-project fallback can produce a false negative. This goes well beyond the readOnlyHint and idempotentHint annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description front-loads its core purpose and safety guarantees well, but it becomes verbose in the project section, repeating nearly verbatim what the input schema already says about project-scoped references and the personal-project fallback. Fine structure, but not every sentence earns its place given the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description still explains the {validate, valid, summary, items} envelope, per-entry ordering, items[0] for a single config, the INVALID_MEDIA reachability check, and the project-scope edge case. Combined with the exhaustive schema and annotations, an agent has everything needed to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already thoroughly documents both builds and project. The description adds the output envelope shape and batch ordering, but that is return-value semantics rather than parameter meaning. The project-related explanation is largely duplicated from the schema's own parameter description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Dry-runs one or many Riddle Builder creates and/or edits without creating or changing anything.' It clearly distinguishes this validation-only tool from the actual riddle_builder_create/ruddle_builder_update siblings, and states the practical purpose: see why a config would be rejected before spending a real create/edit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit context for when to use: 'Use it to see why a config would be rejected before spending a real create/edit on it, and to pre-flight a set of similar Riddles in one call.' It also explains how the project parameter affects dry-run resolution. It does not explicitly name the create/update alternatives or list a when-not case, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_deleteADestructiveInspect
Deletes one or many Riddles. Only Riddles created through the riddle_builder_* tools or generated by the Riddle AI can be deleted - the ones a user built by hand in the Creator cannot, so check "origin.apiManageable" (riddle_get's context.origin, or riddle_list's "origin") beforehand rather than learning it from the error. Pass UUID for one, or UUIDs (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 that entry's "error" and every other Riddle is still deleted (riddle://reference/concepts/bulk). A Riddle another item of the same batch still references (a Leaderboard's connected Quiz/Predictor/Minigame, a FormSelect's Form) is retried once after the rest of the batch, so the order of the list does not matter; only a failure that survives the retry is reported. DRY RUN: pass dryRun: true and NOTHING is deleted - the call runs the same validation a real delete runs and answers {dryRun, deletable, summary, items, addUUIDs} per Riddle. Do this first whenever the set was not created by you; then act on "addUUIDs" to delete the referencing Riddles along with their targets. Every field, the batch effect and which blockers no addition to the call can lift: riddle://reference/concepts/bulk.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle you want to delete. Pass either this or UUIDs. Only Riddles created via the Riddle Builder tools or generated by the Riddle AI can be deleted. | |
| UUIDs | No | Several Riddles to delete at once, as Riddle UUID strings, e.g. ["6FA740EW", "OllsevHa"] (max 100). Pass either this or UUID. Same restriction as UUID: each one must have been created via the Riddle Builder or generated by the Riddle AI. | |
| dryRun | No | true reports whether each Riddle could be deleted and deletes nothing. Works for one UUID and for UUIDs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint annotation, the description discloses that bulk deletion is non-atomic, never gives up early, reports per-entry errors, and retries referenced Riddles once. This is exactly the kind of behavioral context that helps an agent predict side effects and partial-failure outcomes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and then layers in necessary eligibility and bulk-behavior details. It is fairly long, and some per-entry error behavior is repeated across sentences, but the length is largely justified for a destructive tool with non-atomic semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers eligibility, single versus bulk usage, non-atomic partial failure, and retry behavior, which is strong for a destructive operation. However, with no output schema present, it does not fully spell out the response shape beyond mentioning per-entry 'error' entries, and dryRun behavior is left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all three parameters with descriptions (100% coverage), so the baseline is 3. The description adds practical guidance by showing how to batch-delete results from riddle_list and by emphasizing the origin-apiManageable precondition, which is not in the schema. It does not re-explain dryRun, but the schema covers that clearly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Deletes one or many Riddles,' a specific verb and resource that clearly distinguishes this tool from siblings like riddle_rename or riddle_publish. It also immediately scopes what kinds of Riddles are eligible, so there is no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when deletion is allowed (builder-created or AI-generated Riddles), how to verify eligibility via origin.apiManageable before calling, and how to pass UUID versus UUIDs with a max of 100. It also explains bulk behavior and retry semantics, leaving little room for guessing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_getARead-onlyIdempotentInspect
Reads one Riddle - or several, with UUIDs - as the compact build-configuration envelope {uuid, type, modifiedAt, build, nextBlockId, warnings, published, context}. "build" is the DRAFT and is exactly what the riddle_builder_* tools accept back; "published" is the live version visitors see (null = never published, {"status": "identical"} = the live version matches the draft, {"status": "differs", "build": ...} = unpublished edits, and "isLive" on either says whether it is on the web right now). Content the build config cannot express never fails the call - it is reported in "warnings" instead. A property still at its block type's default is left out rather than returned: riddle://reference/block-defaults/ and riddle://reference/riddle-defaults/ state what it is, and it must NOT be resent as a property, since many build properties enable a feature by being present at all. "context" holds what sits around the config: title, image, tags, notes, viewUrl, features, origin (whether riddle_delete/riddle_builder_update/palette_customize work on this Riddle), publish/unpublish/modify state, project and preset identity. Make the response smaller with "omit"; bigger with omittedDefaults or includeRiddleData, both off by default and both large. Field by field: riddle://reference/concepts/response-envelope, plus /warnings, /publish and /bulk.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle you want to read. Pass either this or UUIDs. | |
| omit | No | Leaves whole sections out: "build", "warnings", "nextBlockId", "published", "context" (identity fields always stay). The one omission that materially shrinks a response is "published" on a Riddle with unpublished changes - a second full build configuration. Whatever you leave out is echoed in "omittedFields", so a missing key never reads as "this Riddle has none of that". Details: riddle://reference/concepts/warnings. | |
| UUIDs | No | Several Riddles to read at once, as Riddle UUID strings, e.g. ["6FA740EW", "OllsevHa"] (max 20 - lower than the other bulk tools, since every entry is a full envelope rather than compact state). Either this or UUID; rejected together with includeRiddleData. Entries are read in the order given and, once the response would exceed the inline size budget, the remaining ones come back as compact state with "truncated": true instead - so put the Riddles you need in full first. See riddle://reference/concepts/bulk. | |
| omittedDefaults | No | Whether every block should additionally carry its "omittedDefaults" map: the properties it left at that block type's default, with the value each is at. Off by default - measured, those maps are 85-90% of a read-back, and riddle://reference/block-defaults/<block type> states the same defaults without a Riddle in hand. Ask for them only to learn what THIS Riddle left at its default, and read them, never resend them. | |
| includeRiddleData | No | Additionally returns the full stored Riddle payload (content, settings, preset merge/diff, ...) under "riddle" - tens of KB, only for inspecting raw stored data. Not allowed together with UUIDs. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses rich behavior: draft vs. published variants, null/identical/differs semantics, warnings for content the build config cannot express, omission of default-valued properties, and the instruction not to resend omitted defaults. This is exactly the contextual behavior annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded: the first sentence states the core action, and each subsequent sentence adds non-obvious field, published-state, default, or context semantics without redundancy. Its length is justified by the tool's complexity and the absence of an output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex read tool with no output schema, the description covers the response envelope, published-state model, warning behavior, default-property omission, context contents, and response-size controls. It also references field-by-field documentation, leaving no significant gap for an agent to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the detailed parameter descriptions already carry most of the weight. The description adds cross-cutting meaning beyond the schema by tying UUIDs, omit, omittedDefaults, and includeRiddleData to envelope size and read-only inspection purpose, and by warning that omittedDefaults must be read but never resent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: it reads one or several Riddles by UUID and returns a compact build-configuration envelope, naming the main fields ({uuid, type, modifiedAt, build, ...}). This clearly distinguishes riddle_get from the many list/search siblings and states exactly what it produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes a clear use case: retrieve known Riddles by UUID as the envelope that riddle_builder_* tools accept, and explains when to use omit, omittedDefaults, and includeRiddleData. It does not explicitly name when-not-to-use siblings such as riddle_list, so it falls just short of a full exclusions/alternatives statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_get_embed_codeARead-onlyIdempotentInspect
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.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | Yes | The UUID of the Riddle you want to retrieve the HTML embed code for |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint and idempotentHint, so the safety profile is covered. The description adds meaningful behavioral nuance: the embed code is returned regardless of publish state, but the URL will not serve the Riddle until published. This is valuable context beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The core action is front-loaded, and the second sentence adds a critical behavioral caveat about publish state. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one fully documented parameter, the description plus annotations are complete. The publish-state caveat covers the main edge case an agent would need to know. No output schema is present, but the description adequately conveys what is returned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage of the single parameter, including a clear description of UUID. The tool description adds nothing beyond restating 'by its UUID', so the schema carries the semantic weight. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Gets') and a specific resource ('HTML embed code for a Riddle'), clearly distinguishing it from siblings like riddle_get or riddle_publish. It also identifies the key identifier (UUID), making the tool's purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly establishes the tool's use case: retrieve HTML embed code for a Riddle by UUID. It adds practical context about publish state affecting whether the embedded URL serves content. It does not explicitly name alternative tools, but the purpose is specific enough that an agent can infer when to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_listARead-onlyIdempotentInspect
Returns a paginated list of Riddles. With the default scope "project" they come from a single project - use projectId to name it, or omit it for the personal project. With scope "account" they come from the entire account instead: the personal project and every team project the user has access to, in one list - the account-wide listing is this scope, not a tool of its own; projectId and notType do not apply there and are rejected rather than ignored. Every other filter works the same in both scopes. Answers with {items, page, pageSize, total, hasMore}, where "total" is how many Riddles match the filters in total and "hasMore" whether another page follows.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number, 1-indexed, 12 Riddles per page (default: 1). Zero or negative is rejected with a VALIDATION_ERROR rather than clamped. | |
| tags | No | Filter by tag IDs (array of integers). Omit to ignore tags. | |
| type | No | Filter by Riddle type (array of strings). Valid values: "Quiz", "Poll", "Form", "Personality", "Predictor", "Minigame", "Leaderboard", "Placeholder", "Story". Omit to include all types. | |
| scope | No | What to list: "project" (default) for the Riddles of a single project, "account" for every Riddle of the account at once. | |
| origin | No | Filter by how the Riddle was created: "api" (Riddle Builder API or Riddle AI, so riddle_delete/riddle_builder_update/palette_customize work on it) or "manual" (built by hand in the Creator, where those three are rejected). Omit for both. A filter value only - the "origin" returned per Riddle is {builder, aiGenerated, apiManageable}. | |
| search | No | Search term to filter Riddles by title | |
| sortBy | No | Sort field: "created", "published", or "modified" | |
| status | No | Filter by status: "published", "modified", or "draft". Omit to include all statuses. | |
| notType | No | Exclude specific Riddle types (array of strings, same valid values as type). Omit to exclude nothing. Scope "project" only - the account list has no exclusion filter. | |
| projectId | No | Filter by project ID; omit or null for the authenticated user's personal project. Scope "project" only. | |
| sortOrder | No | Sort direction: "ASC" or "DESC" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the operation as readOnly and idempotent, and the description adds valuable behavioral detail beyond that: the paginated response shape, "rejected rather than ignored" behavior for inapplicable filters, and the nuanced origin filter semantics. Nothing in the description contradicts the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but not bloated; every sentence contributes scope, filtering, or response information. It is front-loaded with the core purpose. A slight structural improvement would be breaking the long paragraph into scoped bullets, but it remains efficiently written.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 parameters, no output schema, and no required fields, the tool carries significant complexity. The description compensates by defining pagination fields, scope-specific behavior, rejection semantics, and filter applicability. The parameter schemas cover the remaining details, so an agent has enough context to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, and the description adds meaning by clarifying scope-dependent rejection of projectId and notType, and by explaining that origin is a filter value while the per-Riddle origin is an object. This goes beyond the schema's individual parameter descriptions, though not dramatically.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Returns a paginated list of Riddles." It then clearly differentiates the two scopes, including the explicit statement that the account-wide listing is this same tool, not a separate one, which distinguishes it from any potential sibling ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use project scope versus account scope and explains how projectId behaves when omitted. It also states that projectId and notType are rejected in account scope, which is useful exclusionary guidance. However, it does not explicitly name alternatives like riddle_get for single-resource retrieval, so the guidance stops short of a full when/when-not comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_moveAInspect
Moves one or many Riddles into another project or into the personal project - and, given no destination, reports whether it could instead of moving anything. Pass UUID for one Riddle or UUIDs (max 100) for several. CHECK MODE (the move check - a mode of this tool, not a tool of its own): leave projectId out (or pass dryRun: true alongside one) and NOTHING is changed - the call runs the very same validation a real move runs and answers {canMoveAll, movable, blocked, addUUIDs, canMoveToPersonal, projects}. Do this first whenever the Riddles were not all created by you, or to explain to a user why a move is impossible. MOVE MODE: pass projectId (a project/team ID from project_list, or the string "personal") and the Riddles move, answering {bulk, operation, summary, results} with the new project per Riddle. Unlike the other bulk tools this one is atomic - it validates the whole set first and moves nothing 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. So pass exactly the set you intend to move: the same Riddle can be blocked on its own and movable inside a larger call. When something is blocked, act on the top-level "addUUIDs" (or a blocked entry's "resolveByAddingUUIDs"), add those to UUIDs and check again until canMoveAll is true - connections chain, and blocking travels along them, so never read an empty "missingUUIDs" as "this one is fine" or a blocked Riddle as having a problem of its own. A move drops project-specific ad blocks tied to the old project and updates the published version along with the draft, but it does not adopt the new project's design. Every field of the check answer, why "projects" can be shorter than project_list and when a blocker cannot be resolved at all: riddle://reference/concepts/move-restrictions.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle you want to move or check. Pass either this or UUIDs. | |
| UUIDs | No | Several Riddles to move or check at once, as Riddle UUID strings, e.g. ["6FA740EW", "OllsevHa"] (max 100). Pass either this or UUID. For a move, this must be the complete set of Riddles that have to move together. | |
| dryRun | No | true runs the movability check against the given projectId and changes nothing. Pointless without projectId, which already only checks. | |
| projectId | No | Where to move the Riddles: the project (team) ID to move them into, as returned by project_list, or the string "personal" for your personal project. There is no default destination - omit this and nothing is moved, the call reports the read-only movability check instead. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the sparse annotations by disclosing that check mode changes nothing, move mode drops project-specific ad blocks and updates the published version alongside the draft, and the operation is atomic. It also reveals the chained-blocking behavior and warns that an empty missingUUIDs must not be interpreted as 'this one is fine.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but it is well organized into CHECK MODE and MOVE MODE sections and front-loaded with the core action. Every sentence carries distinct, practical information, though a slightly tighter structure would improve scannability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a dual-mode, atomic bulk tool with no output schema, the description covers the check response shape, move response shape, the addUUIDs resolution loop, unresolvable blockers, why 'projects' may be shorter than project_list, and links to deeper reference docs. Nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds substantial meaning: omitting projectId triggers the read-only check, dryRun is pointless without projectId, UUIDs must be the complete set that has to move together, and 'personal' targets the personal project. It also explains how to use the returned addUUIDs fields for iterative resolution.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action—moving one or many Riddles into another project or the personal project—and immediately distinguishes its two modes: move vs. check. This clearly separates it from sibling tools like riddle_delete or riddle_get.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to use check mode first (when Riddles were not all created by you, or to explain why a move is impossible) and warns that the tool is atomic, so callers must pass exactly the intended set. It also explains when a move should not proceed and how to iterate using the returned addUUIDs until canMoveAll is true.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_publishADestructiveInspect
Publishes one or many Riddles, or takes them off the web again with publish: false - unpublishing is this tool, there is no separate unpublish tool. A published Riddle is live at https://www.riddle.com/view/[RIDDLEID]. With UUID the response is the riddle_get envelope with the new state under "context.published" ("omit" shrinks it the same way); with UUIDs (max 100) it is the bulk envelope, one compact entry per Riddle instead of a build configuration - not atomic and never giving up early, so a Riddle that cannot be (un)published is reported as that entry's "error" while the rest still go through (riddle://reference/concepts/bulk). PUBLISHING: a refusal is error "RIDDLE_PUBLISH_VALIDATE" carrying "validationErrors", one {message, code} per reason ("MIN_ONE_BLOCK", "MIN_ONE_RESULT", "REDIRECT_RESULT_WITHOUT_URL", "LOGIC_DEAD_ENDS", ...) - fix them all and publish again. Non-blocking findings arrive as "validationWarnings" on a FAILED and on a SUCCESSFUL publish alike (the Riddle is live either way): report them, do not retry. Only a publish produces either list - riddle_builder_validate dry-runs a build configuration, not a publish. UNPUBLISHING: a LIVE Leaderboard with active Riddle connections is refused ("RIDDLE_UNPUBLISH", same list naming what is in the way) - riddle_delete it instead, which is always allowed and cleans up the connected Riddles. Unpublishing a Riddle that is not live is a no-op that says so in a "message" - read it before reporting a Riddle as taken offline, because "context.published.at" is null whether it was never published or already offline. Codes and the draft-vs-live model: riddle://reference/concepts/publish.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle you want to publish or unpublish. Pass either this or UUIDs. | |
| omit | No | Same "omit" parameter as riddle_get's, applied to the single-UUID response envelope (see riddle_get for the full description). Has no effect on the bulk (UUIDs) response, which never carries a build configuration to begin with. | |
| UUIDs | No | Several Riddles to publish or unpublish at once, as Riddle UUID strings, e.g. ["6FA740EW", "OllsevHa"] (max 100). Pass either this or UUID. | |
| publish | No | true (the default) publishes the Riddles, false takes them off the web again. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the sparse annotations (openWorldHint=false, idempotentHint=false, destructiveHint=true) by disclosing non-atomic bulk behavior ('not atomic and never giving up early... while the rest still go through'), the validation-error envelope, the no-op semantics of unpublishing a non-live Riddle, and the trap that 'context.published.at' is null whether it was never published or already offline. This is exactly the state-change nuance an agent needs before invoking a destructiveHint tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded and every sentence carries real content, but the body is one dense run-on paragraph with semicolons, dashes, parenthetical asides, and a garbled validation-code list ('REDIRECT_RESULT_WITHOUT_URL' apparent duplication). The material would be far more scannable as short bullets or separate sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly carries the burden of explaining response shapes for both modes, partial failure, refusal codes, and the no-op edge case, and points to riddle://reference/concepts/publish and /bulk for the rest. Minor gaps remain: the bulk 'compact entry' fields are unspecified and auth expectations are never mentioned, but the reference links largely close the gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for all four parameters, so the baseline is 3; the schema already explains UUID/UUIDs exclusivity, maxItems 100, the publish boolean, and omit. The description adds modest value by mapping each parameter to its response envelope (single vs bulk) and noting omit has no effect on the bulk response, but it does not need to compensate for any schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'Publishes one or many Riddles, or takes them off the web again with publish: false', and immediately draws the boundary that 'unpublishing is this tool, there is no separate unpublish tool.' This states both the action and its scope while distinguishing it from any sibling that might handle removal, so an agent cannot confuse it with riddle_delete or riddle_get.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for the two invocation modes (single UUID vs bulk UUIDs max 100), the publish:false unpublish route, and when the tool will refuse (RIDDLE_PUBLISH_VALIDATE) or no-op (unpublishing a non-live Riddle). It does not, however, name sibling alternatives such as riddle_delete for permanent removal or riddle_builder_update for editing before publishing, so the when-not-to-use guidance is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_renameAInspect
Renames a Riddle with the specified UUID. Returns only the confirmation of the change (uuid, title, modified state), not the entire Riddle.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | Yes | The UUID of the Riddle you want to rename | |
| title | Yes | The new title for the Riddle |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses a meaningful behavioral trait: only a confirmation with uuid, title, and modified state is returned, not the full Riddle. It does not contradict the annotations and adds useful response-shape context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence front-loads the operation and includes only essential return-payload information. No wasted or duplicated content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter rename operation, the description plus schema and annotations cover the required input, the action, and the return shape even without an output schema. Nothing critical is missing for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters already have clear descriptions in the schema. The description adds no new parameter-level detail beyond restating the target UUID and new title, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Renames') on a specific resource ('a Riddle') and uniquely identifies the target by UUID. It also clarifies the return payload, distinguishing the operation from broad read/update tools like riddle_get or riddle_delete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The use case is implicitly clear from the verb and resource, but the description does not explicitly mention when to choose this over sibling tools or when not to use it. No alternatives or exclusions are named, so the guidance remains implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_tagAInspect
Puts a tag on Riddles or takes it off again, by "action" - ONE assignment per Riddle, never the tag itself (riddle_tag_list reads the labels of a project, riddle_tag_delete removes one). "add" gives one Riddle (UUID) or many (UUIDs, max 100) the tag named by tagName - created in each Riddle's OWN project if it has none of that name, so one call can span projects - or by tagId, which exists in one project and therefore works only for that project's Riddles; re-tagging changes nothing and needs no publish. "remove" takes the tag off again and creates nothing: a tag the Riddle or its project does not have is an error for that Riddle. Untagging the last carrier deletes the tag itself, unless a question bank still uses it - so a tag rarely has to be deleted by hand. There is no projectId here: a tag lives in the project of the Riddle it is put on, which is where the scope comes from. Both actions return the tag plus all tags of the Riddle, and with UUIDs the {bulk, operation, summary, results} envelope with one entry per Riddle, a failure (no edit permission, a tagId from another project) reported as that entry's "error" without stopping the others.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle to tag or untag. Pass either this or UUIDs. | |
| UUIDs | No | Several Riddles to tag or untag at once, as Riddle UUID strings, e.g. ["6FA740EW", "OllsevHa"] (max 100). Pass either this or UUID. | |
| tagId | No | The ID of an existing tag, as returned by riddle_tag_list. Pass either this or tagName. | |
| action | Yes | What to do with the tag on those Riddles: "add" it or "remove" it. Each takes UUID or UUIDs and tagName or tagId. | |
| tagName | No | The name of the tag. On "add" the Riddle\'s project gets the tag of that name, created if it has none yet; on "remove" nothing is ever created and a name the project does not have is an error. Pass either this or tagId. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide only hints (openWorldHint, idempotentHint, destructiveHint), so the description carries the burden of behavioral disclosure and largely exceeds it: it describes idempotent re-tagging, publish-free behavior, creation of tags in each Riddle's own project, automatic deletion of the tag when the last carrier is untagged unless a question bank uses it, per-Riddle error handling, and the shape of bulk responses. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph with many parentheticals, which makes it harder to scan, but every sentence carries substantive information and the main verb is front-loaded. A bullet or sentence split would improve structure, but the content is not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (5 params, no output schema, minimal annotations), the description covers all behavioral and error aspects an agent needs: return values including the bulk envelope, per-entry errors, project scoping, creation/deletion side effects, and sibling disambiguation. Nothing critical appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so this starts at baseline 3, but the description adds meaning far beyond the schema: tagName is created per-project when missing, tagId is project-scoped, UUIDs are limited to 100, and each parameter's role in add vs remove is explained. It also clarifies the interaction between UUID/UUIDs and tagName/tagId selectors.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Puts a tag on Riddles or takes it off again, by action.' It also explicitly differentiates itself from sibling tools by stating what riddle_tag_list and riddle_tag_delete do, so an agent can distinguish it without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear conditions for using tagName vs tagId, explains the absence of projectId and why, and names the siblings riddle_tag_list and riddle_tag_delete with their distinct purposes. It also states behavior on add vs remove, including error cases, so the agent knows when this tool is or is not appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_tag_deleteADestructiveInspect
Deletes the TAG ITSELF from a project - the label, for good - and no Riddle, no question bank and no assignment. Rarely needed: untagging the last carrier already removes a tag (riddle_tag action "remove"), so this is for a leftover from before that cleanup existed. It detaches nothing on the way, so a tag any Riddle or question bank still carries is rejected with a message naming how many of each - check with riddle_tag_list first, where a tag is free only when count AND bankCount are 0, and untag the carriers before calling this. Permanent, and ids are not reused, so a stored riddle_list filter on the old id stops matching a tag of the same name created later.
| Name | Required | Description | Default |
|---|---|---|---|
| tagId | Yes | The ID of the tag to delete, as returned by riddle_tag_list. The only way to name it: a tag is deleted by id, not by name. | |
| projectId | No | The project (team) ID the tag belongs to, as returned by project_list. Omit for the project the API key is scoped to, or your personal tags on a user API key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare destructiveHint and idempotentHint; the description adds the important behavioral details: the operation is permanent, ids are not reused, it detaches nothing, and it rejects deletion if a Riddle or question bank still carries the tag, with a message naming counts. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although dense, every sentence earns its place: scope, rarity/alternative, rejection behavior, prerequisite check, and permanence/id-reuse implications. The primary action and scope are front-loaded before caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive tool with no output schema and complex side effects, the description covers what is deleted, what is not deleted, prerequisites, failure behavior, and post-deletion consequences. An agent has enough information to decide when and how to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, providing the baseline of 3, and the description adds extra meaning by defining when a tagId is valid: a tag is deletable only when count AND bankCount are 0, and carriers must be untagged first. This goes beyond the schema's tagId description, which only says to use the id from riddle_tag_list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a precise verb and resource: 'Deletes the TAG ITSELF from a project - the label, for good - and no Riddle, no question bank and no assignment.' It explicitly distinguishes this tool from the sibling riddle_tag action 'remove', so an agent can tell exactly what entity is affected.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when the tool is needed: 'Rarely needed: untagging the last carrier already removes a tag' and names the alternative 'riddle_tag action "remove"'. It also instructs the agent to check riddle_tag_list first and untag carriers before calling, giving concrete usage criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_tag_listARead-onlyIdempotentInspect
Lists the tags of a project as {items: [{id, name, count, bankCount}]}, unpaginated - the labels the Creator shows and riddle_list's "tags" filter selects by, and where the ids that filter takes come from. Riddle tags and question bank tags are ONE set per project (question_bank_tag is the bank side of the same tags, with the same ids), and a tag belongs to a project: "Campaign 2026" in one project is a different tag from the one of that name in another. "count" counts RIDDLES and "bankCount" question banks, so "count": 0 alone never means unused - a tag is free of carriers only when both are 0, which is what riddle_tag_delete requires. Read this before riddle_tag(action: "add"), which creates a tag it does not find, to tag with the name a project already has rather than a second one beside it.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | No | The project (team) ID, as returned by project_list. Omit for the project the API key is scoped to, or your personal tags on a user API key. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, and the description adds substantial behavioral context: the response is unpaginated, count vs bankCount have distinct meanings, tags are project-scoped, and riddle and bank tags share the same ids. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries essential information: output shape, identity semantics, count semantics, and pre-usage guidance. It is dense but not padded, and the most immediately useful fact, what the tool lists, comes first.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shape, field meanings, scoping rule, and integration points with riddle_list and riddle_tag. Nothing an agent needs to call the tool correctly or interpret its results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully documents projectId, including how to omit it and when it refers to personal tags, so the baseline is 3. The description adds value by explaining why projectId matters semantically: a tag with the same name in different projects is a different tag.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Lists'), a specific resource ('tags of a project'), and the exact output shape. It also distinguishes itself from riddle_tag and riddle_tag_delete by referencing their roles, and clarifies its relationship to question_bank_tag.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly directs the agent to read this before riddle_tag(action: 'add') to avoid creating duplicate tag names, and explains that the returned ids are exactly what riddle_list's tags filter selects by. This gives concrete when-to-use context and connects to related sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_template_createAInspect
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 riddle_template_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.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | Yes | The UUID of the Riddle to store as a template, e.g. "6FA740EW". | |
| title | No | Title for the template. Omit to keep the Riddle's own title. | |
| isQuickCreate | No | Whether the template also shows up in the Creator's "quick create" list, i.e. among the starting points offered when creating a new Riddle. Defaults to false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide shallow hints (idempotent false, destructive false), so the description carries the behavioral burden. It discloses that a template is a point-in-time copy, that later changes to the source Riddle do not propagate, that unpublished content is included, and that the template-create permission is required. This goes well beyond the annotations and gives the agent accurate expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-organized: first the primary action, then the important snapshot semantics, then the return shape and permission requirement. Every sentence adds useful information and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the explicit return object listing is valuable. The description also covers permission requirements, the non-propagation behavior, and what content is copied. For a tool of this complexity, an agent has enough context to invoke it correctly and understand its effects.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already explains UUID, title, and isQuickCreate in detail. The description adds general copy semantics and return-field context but does not need to re-document parameters. Baseline 3 is appropriate because the description does not materially expand on the schema's parameter explanations.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb-resource pair ('Stores an existing Riddle as a template') and clearly distinguishes this from the sibling riddle_template_use by explaining that new Riddles can later be created from the template. It also clarifies scope (project or user) and copy semantics, so an agent can immediately tell what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description names riddle_template_use as the follow-up tool and gives a clear reason for using this tool: to create a reusable template from an existing Riddle. It does not explicitly say when not to use alternatives like riddle_template_list or riddle_template_get, but the context is clear enough that an agent should not confuse creation with retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_template_getARead-onlyIdempotentInspect
Reads one template, by default INCLUDING its build configuration - the same "build" shape riddle_get returns and riddle_builder_create accepts. This is how a template is ADAPTED rather than copied: edit the returned "build" (wording, questions, blocks) and build it with riddle_builder_create under the template's "type", passing this id as "templateId" so the new Riddle is still recorded as coming from it - and so it starts out on the template's whole preset, layout included, with your build config on top. The design comes along in "preset", which carries the preset settings and the palette; "preset.paletteValues" is included whenever that palette is not an unmodified built-in one, so a custom (or customized) palette rebuilds directly. On an unmodified built-in palette there is no "paletteValues" at all rather than a partial one: "preset.palette" names it in full (e.g. "Forest") and its colors/fonts come from riddle://reference/palette/built-in-palettes, matched by "name". Not changing anything? riddle_template_use is one call and copies the template 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 riddle_template_use for those.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The ID of the template, as returned by riddle_template_list or riddle_template_public_list. | |
| omittedDefaults | No | Whether every block additionally carries its "omittedDefaults" map - the properties it left out for still being at that block type's default, with the value each is at. Off by default: those maps measure 85-90% of the response, and riddle://reference/riddle-defaults/<riddle type> plus riddle://reference/block-defaults/<block type> state the same defaults without a template in hand. Pass true only to learn what THIS template left at its default - to read, never to resend. | |
| includeBuildConfig | No | Whether to read the template as a build configuration. Defaults to true, which is the point of this tool; false returns only the template's metadata, a far smaller response. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint and idempotentHint already in annotations, the description carries the lower safety burden but adds substantial behavioral context: the default includeBuildConfig=true behavior, the conditional presence of preset.paletteValues (included only for non-unmodified built-in palettes, absent entirely otherwise, never partial), and the empty-build-plus-warning edge case. It tells an agent exactly what the response will contain and what an absent paletteValues field means, which annotations and schema cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long and dense - a single multi-clause paragraph that is harder to parse than it needs to be - but every sentence carries load-bearing information: core read behavior, adaptation workflow, palette semantics, sibling routing, and return shape. There is minor redundancy (the riddle_template_use recommendation appears twice) and bullet formatting would improve scannability, but the most important facts are front-loaded in the first sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly takes on the return-value burden, specifying the full field list and the empty-build warning edge case. The tricky palette semantics - built-in versus custom palettes, how colors and fonts resolve via riddle://reference/palette/built-in-palettes matched by name - are fully specified. Given the tool's complexity and its chaining role in an adaptation workflow, nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline 3 applies: id, omittedDefaults, and includeBuildConfig all already carry detailed descriptions with types, defaults, and purpose. The description adds minimal parameter-level value - it reinforces that includeBuildConfig true is 'the point of this tool' and provides workflow context about passing this id as templateId, but it largely restates what the schema's own parameter descriptions already say.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names the exact operation - reading one template - and the distinguishing default of including its build configuration, linking it to the build shapes of riddle_get and riddle_builder_create. It also separates itself from siblings by framing the tool as adaptation ('ADAPTED rather than copied') and contrasting it with riddle_template_use, which copies the template whole. The generic title 'Get riddle template' is fully compensated by the specific first sentence.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: use this tool to adapt a template by editing the returned build and rebuilding with riddle_builder_create, and 'Not changing anything? riddle_template_use is one call and copies the template whole' states the exact alternative condition. It even routes the edge case - templates with no build-configuration equivalent - back to riddle_template_use, and explains when includeBuildConfig=false is appropriate. There is no ambiguity about when to pick this tool over its siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_template_listARead-onlyIdempotentInspect
Lists the templates of a project (or your personal ones) - the ones made from your own Riddles with riddle_template_create, NOT Riddle's public ones, which riddle_template_public_list returns. Quick-create templates (isQuickCreate: true) are included alongside the regular ones; there is no separate listing for them. "type" filters by Riddle type. Returns {items: [{id, title, type, blocksCount, image, icon, createdAt, riddle, isPublic, isQuickCreate}], total} - not paginated, so "total" is simply how many there are - without the build configuration - read that with riddle_template_get, or hand the id straight to riddle_template_use.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only return templates of this Riddle type: "Quiz", "Poll", "Form", "Personality", "Predictor", "Minigame", "Leaderboard", "Story" or "Placeholder". Omit to get all of them. | |
| projectId | No | The project (team) ID whose templates you want, as returned by project_list. Omit to use the project the API key is scoped to (your personal templates for a user API key). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, and closed-world behavior, so the bar is lower, but the description still adds valuable behavioral context: results are not paginated, total means total count, quick-create templates are mixed in, and build configurations are omitted from the response. It also gives the exact response shape, which is especially useful because no output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every clause earns its place: primary purpose, sibling distinction, quick-create behavior, filter guidance, response shape, pagination clarification, and follow-up tool routing. The most important scoping information is front-loaded before any secondary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With only two optional params, no output schema, and rich annotations, the description is complete. It explains what is returned, what is not returned, why total behaves as it does, and how to proceed for configuration details or actual usage of a template.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not significantly extend parameter meaning beyond what the schema already states for 'type' and 'projectId'; it mainly confirms the filtering behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool as listing project or personal riddle templates created via riddle_template_create, not Riddle's public ones. It names the sibling tool riddle_template_public_list as the alternative, so the agent can distinguish them immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly contrasts this tool with riddle_template_public_list and routes the agent to riddle_template_get for build configuration and riddle_template_use for using a template. It also clarifies that quick-create templates are included here with no separate listing, removing ambiguity about when to call this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_template_public_listARead-onlyIdempotentInspect
Lists Riddle's public templates - the ready-made ones every account has, as opposed to riddle_template_list's own ones. 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; "category" and "type" narrow it. Returns {categories: {: [{id, title, type, blocksCount, image, icon, createdAt, riddle, isPublic}]}, total} - the one listing here that is grouped rather than a flat "items" - and without the build configuration, which is riddle_template_get (or hand the id straight to riddle_template_use).
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only return templates of this Riddle type: "Quiz", "Poll", "Form", "Personality", "Predictor", "Minigame", "Leaderboard", "Story" or "Placeholder". Omit to get all of them. | |
| category | No | Only return templates of this category (the tag public templates are grouped under), a snake_case slug such as "audience_research" or "feedback_surveys" - not a display name. Omit to get every category, which is also how you find out which ones exist. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so the safety profile is covered. The description goes beyond by disclosing the grouped return shape ({categories: {...}, total}), the absence of build configuration, and that it is the grouped listing rather than a flat 'items' list. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences carry the full purpose, the distinction from siblings, parameter behavior, return shape, and routing to related tools. Each clause earns its place, and the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list tool with no output schema, the description is complete: it provides the return structure, explains grouping, covers both optional parameters, and distinguishes sibling tools. An agent has enough context to invoke it correctly and interpret the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description adds meaningful context by explaining that category is a snake_case tag, both parameters narrow the grouped result, and omitting them is how you learn which categories exist. This goes beyond merely restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Lists Riddle's public templates', and immediately distinguishes itself from riddle_template_list's own templates. An agent can tell exactly what this tool does and why it exists as a separate sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative riddle_template_list and the distinction between public templates and account-owned ones. It also explains how calling without arguments discovers categories, how category/type narrow results, and points to riddle_template_get/riddle_template_use for follow-up actions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_template_useAInspect
Creates a new Riddle from a template as an unchanged copy of it - content, settings and design preset - recorded as a copy of the template's Riddle (riddle_get reports it as context.duplicated). Use this whenever the template is what you want; to adapt it first, read it with riddle_template_get and build the edited configuration with riddle_builder_create instead. The new Riddle is a DRAFT - riddle_publish makes it live. Returns it in the standard build-configuration envelope, and takes riddle_get's "omit" to leave sections of it out. Requires the template-use permission plus Riddle-create in the target project.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The ID of the template to create a Riddle from, as returned by riddle_template_list or riddle_template_public_list. | |
| omit | No | Same "omit" parameter as riddle_get's, applied to the returned envelope (see riddle_get for the full description): sections of it to leave out, "published" being the one that still moves a copy of a template materially. The per-block default maps are not in this response at all - they are opt-in through riddle_get/riddle_template_get and this tool has no such parameter. | |
| title | No | Title for the new Riddle. Omit to keep the template's own title. | |
| projectId | No | The project (team) ID to create the Riddle in, as returned by project_list. Omit to use the project the API key is scoped to (your personal project for a user API key). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the minimal annotations, the description discloses crucial behaviors: the copy is unchanged and recorded as duplicated (context.duplicated), the result is a draft, the return envelope supports an 'omit' parameter, and specific permissions are required. This adds substantial context that annotations do not provide, with no contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: it front-loads the core purpose, then gives usage guidance, draft status, return envelope details, and permissions. No filler or redundancy; the structure guides the agent from what to why and how.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a creation tool with no output schema, the description covers all essential operational context: what the copy contains, how it is marked, the draft state, the publish path, the return envelope, the omit behavior, and required permissions. An agent has enough to invoke the tool correctly and anticipate results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already richly documents each parameter, including the omit enum details and default behavior for title and projectId. The main description adds no meaningful parameter semantics beyond what the schema provides, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Creates a new Riddle from a template as an unchanged copy of it - content, settings and design preset'. It clearly differentiates this from sibling tools by contrasting with riddle_template_get and riddle_builder_create, so an agent can identify the exact operation without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use this tool: 'Use this whenever the template is what you want; to adapt it first, read it with riddle_template_get and build the edited configuration with riddle_builder_create instead.' It also gives workflow context by noting the new Riddle is a DRAFT and riddle_publish makes it live, so an agent knows the follow-up step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stats_fetchARead-onlyIdempotentInspect
Views/starts/submissions of one entity - "namespace" plus "entityId" says which (a project, a user, or a Riddle by UUID), "view" how deeply. "totals": one aggregate for the period. The response IS the entity's stats document: metrics sit in "core_metrics" under "global_stats" (a Riddle) or under "stats" (a user/project aggregate, or an old Riddle) - read only "stats" and a Riddle with real traffic looks unmeasured. A Riddle also carries one "block__stats" per block, keyed by riddle_get's ids. "timeseries": those numbers per consecutive interval - {intervalDays, intervalCount, intervals}, each {from, to, days, stats} inclusive of both ends. Up to 31 days give one interval per day; a longer range is grouped into at most 31 equal intervals whose "stats" is the interval TOTAL, not a daily number - divide by "days", and never read the shorter final interval as a drop. "breakdown" is per namespace: "riddle" gives one Riddle down to its blocks, choices and fields, every "id" being the stored block id riddle_get's "build" exposes, so a weak question can be fixed directly; "project" gives that tree for every Riddle in it - prefer a short range, or one Riddle, on a big project; "user" gives NOT a deep breakdown but the account-wide summary: one row per Riddle plus the totals over every Riddle in scope, ranked by sortBy, 25 per page ("hasMore" says whether another follows), narrowed with projectIds rather than paged on a big account, requires a USER API key, takes no entityId. Two kinds of "no data": an empty response ({}, always an object, never a list) means nothing was recorded - report "no stats recorded", never 0 - while a missing key inside a POPULATED "core_metrics" is a genuine zero (no "finish" beside a "view" means no submissions). A "breakdown" signals nothing by shape: a Riddle nobody opened still answers with its full tree at 0, so confirm it was published then (riddle_get's "published": null means it never was) before reading zeros as a finding.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number of the account-wide summary, 1-indexed (default: 1). Zero or negative is rejected with a VALIDATION_ERROR, not clamped to page 1 - the same contract as riddle_list/project_list. That view only. | |
| view | Yes | How deeply to measure: "totals" (one aggregate for the period), "timeseries" (that aggregate per consecutive interval, requires dateFrom and dateTo) or "breakdown" (the per-block detail, or the per-Riddle summary for namespace "user"). | |
| dateTo | No | End date (inclusive), format: YYYY-MM-DD, e.g. "2026-01-31". Same rules as dateFrom; where a default applies it is today. | |
| sortBy | No | Metric the account-wide summary's Riddles are ranked by before the page is cut: "views" (default), "starts", "submissions" or "timeActive". Sorting always spans the whole account (or the projects given), so page 1 is genuinely the top of the account. That view only. | |
| dateFrom | No | Start date (inclusive), format: YYYY-MM-DD, e.g. "2026-01-01". Required for "timeseries". On "totals" and a Riddle/project "breakdown", omit both dates for alltime and pass only one for an open-ended range; the account-wide summary and the project breakdown instead default to one CALENDAR month before today - the same default the Creator's dashboards use, so 29 to 32 days depending on the month, not exactly 30. Send it explicitly when the exact span matters. | |
| entityId | No | ID of the entity: a project ID (integer as string) for "project", a user ID (integer as string) for "user", a Riddle UUID for "riddle". Get them from project_list, whoami ("user", not the string "user") and riddle_list respectively. Required for every view except the account-wide summary (view "breakdown" with namespace "user"), which measures the API key's own account and rejects it. | |
| namespace | Yes | Entity type to fetch stats for. | |
| projectIds | No | Narrow the account-wide summary to these project IDs (array of integers, from project_list). Omit to cover the whole account, including the personal project. Passing a project the user cannot view stats of is an error, not a silently skipped project. That view only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, yet the description goes far beyond them: the response IS the entity's stats document with metrics under either 'global_stats' or 'stats' depending on Riddle age, the 31-interval grouping where 'stats' is a TOTAL to divide by 'days', the empty-object vs missing-key zero semantics ('report no stats recorded, never 0'), pagination at 25 per page with hasMore, and the published-null verification caveat. Exceptionally candid about traps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence carries substantive edge-case information with zero fluff, and the purpose is front-loaded in the first clause. However, the entire disclosure is one dense ~450-word paragraph with heavy nesting and dashes, making it difficult for an agent to scan the three views, their response shapes, and the no-data rules. Paragraph breaks per view or a list structure would improve parseability substantially without cutting content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and high complexity (3 namespaces × 3 views, shape varying by Riddle age), the description covers response structure for every combination, interval math and its caveat, empty vs zero semantics, pagination, API key requirements, date defaults, and how to distinguish 'no data' from 'genuine zero'. Nothing an agent needs to call and interpret this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with unusually rich per-parameter descriptions, so the baseline is 3. The tool description adds value above that by explaining cross-parameter semantics: valid view×namespace combinations, the user breakdown taking no entityId, the interaction between date range and interval count, and performance implications of namespace choice. It does not need to restate parameter syntax, which the schema already owns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening clause 'Views/starts/submissions of one entity' states a specific verb, resource, and metric set, immediately establishing what the tool returns. The namespace/entityId/view trio precisely defines the selection mechanism, and the tool is clearly distinct from every sibling (no other stats tool exists among them).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Rich when-to-use context: which view suits which need, 'prefer a short range, or one Riddle, on a big project', the USER API key requirement for account-wide breakdown, and when to send dateFrom explicitly. It does not explicitly name alternative tools to route around, but references riddle_get as a complementary verification step, which is clear enough guidance for invocation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
whoamiARead-onlyIdempotentInspect
Reports the current API key: the authenticated user ("userEmail"/"userName", the latter null if never set), the project/team on a project-scoped key, and the account's plan in "subscription" ({plan, period, active, created, termEnd, isFreeTrial, daysLeft} - on a free trial "termEnd" is when the trial ends and "daysLeft" what is left of it, null on a paid plan). The plan is informational: every tool here works on every plan, free trial included, and no call is refused for it. Mind which id is which: the response's own "id" is the API KEY row, the user id (what the stats tools want as "entityId" for namespace "user") is "user", and "team" is the project id on a project key. A Riddle's own "plan" in riddle_get is a different thing - the plan level the features used in THAT Riddle need, not the account's.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, and the description aligns with these while adding substantial behavioral detail: userName may be null, termEnd semantics differ by trial status, the plan does not affect tool availability, and the response id/user/team fields map to different concepts. This is exactly the kind of context that prevents misinterpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: first sentence defines the resource, second sentence defines the subscription object with edge cases, third sentence clarifies id mappings for downstream tools, and fourth sentence disambiguates the plan concept from riddle_get. The most important info is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no parameters, the description carries the full burden of explaining the return payload and behavioral nuances. It covers identities, null cases, plan semantics, id disambiguation, differences from a similar field in riddle_get, and the fact that all plans work with all tools. Nothing material is missing for an agent to call this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and an empty input schema, so there is nothing for the description to clarify. Per baseline for 0-parameter tools, a 4 is appropriate; the description instead focuses on return-value semantics, which is the meaningful dimension here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb ('Reports') tied to a clear resource ('the current API key') and enumerates exactly what is reported: user, project/team scope, and subscription. This unambiguously distinguishes whoami from sibling tools like ping, project_get, and stats_fetch.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool—to inspect the authenticated identity, key scope, and account plan. It also provides important 'do not' guidance: the plan is informational and should not be used to gate behavior, and the Riddle plan field in riddle_get is explicitly distinguished. It stops short of naming alternative tools or stating an explicit when-not-to-use condition, so it does not earn a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
71 tool updates
- Added
media_delete - Added
media_upload_link - Added
question_bank_create - Added
question_bank_delete - Added
question_bank_discard_changes - Added
question_bank_get - Added
question_bank_get_items - Added
question_bank_item - Added
question_bank_list - Added
question_bank_manage - Added
question_bank_tag - Removed
questionBank_addItem - Removed
questionBank_addTag - Removed
questionBank_blockTypeColumns - Removed
questionBank_create - Removed
questionBank_delete - Removed
questionBank_deleteItem - Removed
questionBank_discardChanges - Removed
questionBank_duplicate - Removed
questionBank_get - Removed
questionBank_getItems - Removed
questionBank_list - Removed
questionBank_publish - Removed
questionBank_removeTag - Removed
questionBank_rename - Removed
questionBank_riddleBlockItems - Removed
questionBank_tagList - Removed
questionBank_templateList - Removed
questionBank_updateItem - Removed
questionBank_updateNotes - Changed
reference_get8 fields changed- changed
Input schema / properties / blockTypes / descriptionPrevious value: -"Narrow block-types further, to these block type name(s) (e.g. \"SingleChoice\", \"WheelSpinner\"), on top of whatever \"riddleType\" already kept. Names are NOT enumerated here - there are dozens across 9 Riddle types, and this schema is read by every agent on every turn regardless of whether it filters. An unknown name, or one that exists but is not part of the Riddle type(s) you filtered to, is rejected and the error names the valid names for your situation. Omit for every block type."New value: +"The block type name(s) you are actually going to build (e.g. \"SingleChoice\", \"WheelSpinner\"), narrowing block-types on top of whatever \"riddleType\" kept - the normal way to read that document, not an optimization for later: pass the two or three the Riddle needs, and come back for another. The names are deliberately not enumerated here (dozens of them, on a schema every agent reads every turn); an unknown one, or a real one outside the Riddle type(s) you filtered to, is rejected with the names that are valid for your situation. Omit for every block type." - changed
Input schema / properties / fieldTypes / descriptionPrevious value: -"Narrow form-field-types down to these form field type name(s) (e.g. \"Dropdown\", \"Privacy\"). The property sets a kept field type refers to (propertySets/commonProperties) and the \"fields\" usage notes are always returned with it. Names are NOT enumerated here for the same reason \"blockTypes\" does not enumerate its own - an unknown one is rejected with the full list of the 18 valid names. Ignored on every other topic. Omit for every field type."New value: +"Narrow form-field-types and form-field-defaults to these form field type name(s) (e.g. \"Dropdown\", \"Privacy\"); the property sets a kept type refers to (propertySets/commonProperties) and the \"fields\" usage notes always come with it. Not enumerated here for the same reason \"blockTypes\" is not - an unknown one is rejected with the full list. Ignored on every other topic. Omit for every field type." - changed
Input schema / properties / includeAvailableTopics / descriptionPrevious value: -"Whether the response should carry the full \"availableTopics\" catalogue. Omit it: the first reference_get of a session gets the catalogue, every call after it gets a one-line pointer back to it instead of repeating ~2.5 KB you already have - which on a small document is several times the document itself. Pass true to get it again (a fresh conversation on an existing session, or after losing it), false to never pay for it."New value: +"Whether to carry the full \"availableTopics\" catalogue. Omit it - the first reference_get of a session gets it, later ones get a pointer instead of repeating ~2.5 KB you already have. true gets it again (a fresh conversation on an existing session), false never pays for it." - changed
Input schema / properties / riddleType / descriptionPrevious value: -"Narrow riddle-types/block-types down to these Riddle type(s) - e.g. [\"Quiz\"] on block-types drops every other type's question blocks while keeping the shared conventions (commonBlockProperties, the general Content/Ad/Quote blocks, ...). Ignored, with the whole document returned, on a topic that has no per-type split (form-field-types, result-blocks, concepts/defaults, the palette/question-bank documents). Not applicable to the block-defaults/riddle-defaults families - read the entity's own address instead. Omit for every type."New value: +"Narrow riddle-types/block-types to these Riddle type(s) - on block-types that drops every other type's question blocks while keeping the shared conventions (commonBlockProperties, the general Content/Ad/Quote blocks). REQUIRED on block-types unless \"blockTypes\" is given instead, and only the WIDE scope of it. Ignored on a topic with no per-type split, and not applicable to the block-defaults/riddle-defaults families - read the entity's own address there. Omit for every type." - changed
Input schema / properties / topics / descriptionPrevious value: -"The reference documents to read, as their \"riddle://reference/...\" URIs."New value: +"The documents to read, as their \"riddle://reference/...\" URIs (a document's short resource name, e.g. \"block-types\", works too). What each one holds:\n- riddle://reference/index: every document this server has, with its exact size. Read this first when you do not know which of the others you need - it is by far the smallest, and the one place the member names of the {...} families below are listed.\n- riddle://reference/getting-started: what this server is for, the authentication model, the guided prompts, and the addresses of the documents that hold the rules. Start here when unsure which tool to use.\n- riddle://reference/prompts/{prompt} (one per guided prompt, e.g. riddle://reference/prompts/build_LeadGenQuiz): the playbook for a whole goal - what to ask the user first, the tool calls in order, what to verify, the traps. Read one when the user states a GOAL rather than an operation.\n- riddle://reference/response-format: the envelope every Riddle-returning tool answers with, plus the list, bulk and error shapes.\n- riddle://reference/riddle-builder/riddle-types: all 9 Riddle types with their required/optional build fields and result structure.\n- riddle://reference/riddle-builder/block-types: every question and content block type - the reference for the \"blocks\" of a riddle_builder_* call. Returned scoped only, and worth scoping twice (see \"blockTypes\").\n- riddle://reference/riddle-builder/form-field-types and .../result-blocks: the 18 form field types of the FormBuilder block, and the 12 result page block types with their format and styling options.\n- riddle://reference/concepts/{concept} (one per subject, e.g. riddle://reference/concepts/merge-semantics): how an edit merges, the \"preset\" and \"publish\" objects, branching logic, defaults, bulk calls, move restrictions, limits, troubleshooting.\n- riddle://reference/block-defaults/{blockType}, riddle://reference/riddle-defaults/{riddleType}, riddle://reference/form-field-defaults, riddle://reference/publish-defaults: what a read-back leaves out for still being at its default, and what that default is. Read riddle://reference/concepts/defaults once for how to use them.\n- riddle://reference/palette/fields, .../built-in-palettes, .../fonts: every palette value palette_customize accepts and where it shows up, the built-in palettes to start from, the available font families.\n- 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 question_bank_create." - changed
Input schema / properties / topics / items / anyOfPrevious value: -[ - { - "enum": [ - "riddle://reference/index", - "riddle://reference/getting-started", - "riddle://reference/response-format", - "riddle://reference/riddle-builder/riddle-types", - "riddle://reference/riddle-builder/block-types", - "riddle://reference/riddle-builder/form-field-types", - "riddle://reference/riddle-builder/result-blocks", - "riddle://reference/palette/fields", - "riddle://reference/palette/built-in-palettes", - "riddle://reference/palette/fonts", - "riddle://reference/publish-defaults", - "riddle://reference/form-field-defaults", - "riddle://reference/question-bank/overview" - ], - "type": "string" - }, - { - "pattern": "^riddle://reference/(block-defaults|riddle-defaults|concepts)/[^/]+$", - "type": "string" - } -]New value: +[ + { + "enum": [ + "riddle://reference/index", + "riddle://reference/getting-started", + "riddle://reference/response-format", + "riddle://reference/riddle-builder/riddle-types", + "riddle://reference/riddle-builder/block-types", + "riddle://reference/riddle-builder/form-field-types", + "riddle://reference/riddle-builder/result-blocks", + "riddle://reference/palette/fields", + "riddle://reference/palette/built-in-palettes", + "riddle://reference/palette/fonts", + "riddle://reference/publish-defaults", + "riddle://reference/form-field-defaults", + "riddle://reference/question-bank/overview", + "riddle://reference/question-bank/block-type-columns" + ], + "type": "string" + }, + { + "pattern": "^riddle://reference/(block-defaults|riddle-defaults|concepts|prompts)/[^/]+$", + "type": "string" + }, + { + "pattern": "^[a-zA-Z0-9][a-zA-Z0-9-]*$", + "type": "string" + } +] - changed
Input schema / properties / topics / maxItemsPrevious value: -8New value: +3 - changed
Output schema / properties / availableTopics / descriptionPrevious value: -"Every topic this tool can return - sent in full on the FIRST reference_get of a session only, so a client that reached this tool without reading its schema still learns what else is documented and what reading it would cost. Later calls carry a short {omitted, namesAndSizesIn, resend} pointer instead of repeating ~2.5 KB the caller already has; \"includeAvailableTopics\" overrides both directions. In the full form the static documents are listed as uri => {sizeBytes, summary}, same as riddle://reference/index and what resources/list advertises as \"size\". The two generated families (block-defaults, riddle-defaults - one address per entity) are compacted under \"families\": the address template, how many addresses it has and what they cost in total, without the individual names - those, with their exact sizes, are in riddle://reference/index. An address is built by replacing the {variable} of a \"uriTemplate\" with the entity you are working on, e.g. riddle://reference/block-defaults/Flashcard."New value: +"Every topic this tool can return, uri => {sizeBytes, summary} - sent in full on the FIRST reference_get of a session, then replaced by a short {omitted, namesAndSizesIn, resend} pointer (\"includeAvailableTopics\" overrides both directions). The generated families are compacted under \"families\" - the address template, how many addresses and what they cost in total, the individual names being in riddle://reference/index. Build one by replacing a \"uriTemplate\" variable with your entity, e.g. riddle://reference/block-defaults/Flashcard."
- Removed
riddle_account_list - Added
riddle_builder_create - Removed
riddle_builder_form - Removed
riddle_builder_leaderboard - Removed
riddle_builder_minigame - Removed
riddle_builder_personality - Removed
riddle_builder_placeholder - Removed
riddle_builder_poll - Removed
riddle_builder_predictor - Removed
riddle_builder_quiz - Removed
riddle_builder_story - Changed
riddle_builder_update18 fields changed- changed
Input schema / properties / UUID / descriptionPrevious value: -"The UUID of the Riddle to edit (as returned by riddle_list / riddle_get)"New value: +"The UUID of the Riddle to edit, as returned by riddle_list or riddle_get (e.g. \"6FA740EW\") - the Riddle itself, never a block id or a project id." - changed
Input schema / properties / build / descriptionPrevious value: -"The changes to apply, as a partial build configuration in the engine's own key names - the same shape riddle_get returns under \"build\" and the riddle_builder_<type> tools take. Only the fields you send are touched; send at least one. A field only exists for the Riddle types that have it, and unknown keys are rejected rather than ignored."New value: +"The changes to apply, as a partial build configuration in the engine's own key names - the same shape riddle_get returns under \"build\" and riddle_builder_create takes. Only the fields you send are touched; send at least one. A field only exists for the Riddle types that have it, and unknown keys are rejected rather than ignored." - changed
Input schema / properties / build / properties / $blocksOrder / descriptionPrevious value: -"The new order of the Riddle's blocks, as the complete list of their IDs - [3, 1, 2] puts block 3 first. Complete means every ID the Riddle has after this edit, exactly once: a partial list is rejected, because where the blocks you left out belong is exactly what it does not say. It is applied after everything else in the same call, so a block you delete here must NOT be listed and a block you add here MUST be - give a \"$create\" entry an explicit \"id\" to name it, taken from \"nextBlockId\" in the riddle_get response (count up from it for several new blocks) and never derived from the ids in \"build\", which are shared with the Riddle's results and personalities; claiming a taken id is rejected with an error naming the free one. The same marker works inside a block, next to the collection it orders: {\"id\": 3, \"$itemsOrder\": [2, 1]} reorders that block's items, \"$fieldsOrder\" a Form's fields, and it reaches one level deeper through a merged \"fields\" edit - {\"id\": 3, \"fields\": [{\"id\": 5, \"$itemsOrder\": [2, 1]}]} reorders the items of that one Dropdown field. Only a collection whose entries have ids of their own can be ordered at all, and a few that do still reject the marker because an entry's position carries meaning of its own - riddle://reference/concepts/merge-semantics says which collection is which, and the error says so too if you try."New value: +"The new order of the Riddle's blocks, as the complete list of their IDs - [3, 1, 2] puts block 3 first. Complete means every ID the Riddle has AFTER this edit, exactly once; a partial list is rejected. It runs last, so a deleted block must NOT be listed and an added one MUST be - give the \"$create\" entry an explicit \"id\" from riddle_get's \"nextBlockId\". The same marker orders a collection inside a block (\"$itemsOrder\", \"$fieldsOrder\"). Rules: riddle://reference/concepts/merge-semantics." - changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"The blocks to change, add or remove - only the ones you touch, everything else stays as it is. To EDIT, pass the block's \"id\" (riddle_get reports it) plus only the properties that change - {\"id\": 3, \"title\": \"New question title\"}. To ADD, pass \"$create\": true instead of an \"id\" plus everything a new block needs, the same shape the riddle_builder_<type> tool of this Riddle's type takes - {\"$create\": true, \"type\": \"SingleChoice\", \"title\": \"New question\", \"items\": [...]}. To REMOVE, pass \"id\" plus \"$delete\": true. A block cannot change its \"type\" in an edit (delete it and add a new one instead), and an unknown \"id\" is rejected with the list of IDs that do exist. The collections INSIDE a block work the same way wherever their entries have ids - {\"id\": 3, \"items\": [{\"id\": 2, \"title\": \"Bonn\"}]} renames one answer and leaves the others alone - and are replaced wholesale where they do not. Which collection is which, what an entry id is scoped to, why an entry without an \"id\" or \"$create\" is rejected, which deletes are refused for still being referenced (custom logic, a hotspot's \"goToImage:\"), and which rules are checked against the merge result rather than against what you sent: riddle://reference/concepts/merge-semantics, with the marker rules themselves in riddle://reference/concepts/editing."New value: +"The blocks to change, add or remove - only the ones you touch, everything else stays as it is. EDIT: the block's \"id\" (riddle_get reports it) plus only the properties that change - {\"id\": 3, \"title\": \"New question title\"}. ADD: \"$create\": true instead of an \"id\", plus everything a new block needs in the shape riddle_builder_create takes - {\"$create\": true, \"type\": \"SingleChoice\", \"title\": \"New question\", \"items\": [...]}. REMOVE: \"id\" plus \"$delete\": true. A block cannot change its \"type\"; an unknown \"id\" is rejected naming the ids that exist. A collection inside a block merges by \"id\" the same way - {\"id\": 3, \"items\": [{\"id\": 2, \"title\": \"Bonn\"}]} renames one answer and leaves the others alone. Which collections merge, which are replaced wholesale, and which deletes are refused for still being referenced: riddle://reference/concepts/merge-semantics (markers: riddle://reference/concepts/editing)." - changed
Input schema / properties / build / properties / conditions / descriptionPrevious value: -"Prioritized (first match wins), time-windowed list of routing rules evaluated before the fallback \"riddleId\" (max 100 conditions). Each condition targets either another Riddle or a tag - exactly one of \"riddleId\" (UUID of an existing, non-Placeholder, published Riddle) or \"tag\" (name or numeric id of an EXISTING tag in this Riddle's own scope - a typo'd name is rejected, never auto-created; sending a numeric id reads back as the tag NAME, which is ambiguous if two tags in this scope share a name) is required, never both. No other key is accepted on a condition: unknown keys and \"$create\"/\"$delete\" markers are rejected - \"conditions\" always replaces the whole list, there is no per-entry merge (see \"resend\" below). A \"tag\" condition additionally requires \"tagMode\": \"lastPublished\" (the most recently published Riddle carrying that tag) or \"random\" (a random one, optionally re-picked every \"randomRefreshIntervalSeconds\", a positive integer of seconds, only accepted together with tagMode \"random\"; defaults to 86400 when omitted and that default is written into the read-back, so echo it back on a resend for a byte-identical round-trip). Each condition may also carry a time window, either a date range (\"from\", required; \"to\", optional - open-ended) or a daily time-of-day range (\"dailyFrom\" and \"dailyTo\", both required together) - never both kinds on the same condition, and a condition with neither always matches whenever it is reached. Dates accept \"YYYY-MM-DD\" (midnight UTC) or full ISO 8601 (a trailing \"Z\" allowed) and are canonicalized to \"YYYY-MM-DDTHH:MM:SS+00:00\"; daily times accept \"HH:MM\" or \"HH:MM:SS\" and always come back as \"HH:MM:SS\"; a non-string date/time value (a unix int, a bool) is rejected. A date \"to\" before \"from\" is rejected; an out-of-range daily component (\"25:00:00\", \"12:60\") is rejected too, NOT wrapped - \"dailyTo\" before \"dailyFrom\" is the one legitimate exception, meaning an overnight window (e.g. 22:00-02:00). Normalization: the list is NOT stored or returned in the order you send it. It is sorted into three tiers - date-windowed conditions first, then daily-windowed, then windowless (so a daily window can never outrank a date window) - ascending within a tier by \"from\"/\"dailyFrom\" (windowless entries keep your send order); date and daily windows are never compared against each other, and duplicates are kept, not deduplicated. When two windows of the SAME kind overlap, the earlier condition's \"to\"/\"dailyTo\" is silently rewritten to the later condition's start (the later condition wins the contested interval - this is lossy and unannounced); a \"to\"-less condition that is not last in its tier gets a \"to\" synthesized as the next condition's start, so only the last condition of a tier may stay open-ended. Applying this to an already-normalized list changes nothing (idempotent). Resend safety: because \"conditions\" replaces the whole list, a condition (or the fallback) whose target Riddle was deleted/unpublished, or whose tag was removed, is DROPPED from riddle_get with a warning (reason \"PROPERTY_NOT_SERIALIZABLE\" for a condition, path \"conditions[<target>] (<why>)\"; reason \"RIDDLE_DATA_NOT_EXPRESSIBLE\" for the fallback, path \"riddleId\") while still being RETAINED in storage - it reappears once the target becomes valid again. Sending that damaged read-back straight back to riddle_builder_update therefore PERMANENTLY deletes the hidden dangling condition(s); the fallback is not affected the same way, because an omitted \"riddleId\" means \"don't touch it\" rather than \"clear it\" (see that field)."New value: +"Placeholder only. Prioritized (first match wins), time-windowed routing rules evaluated before the fallback \"riddleId\"; at most 100. Each targets exactly one of \"riddleId\" (UUID of an existing, non-Placeholder, published Riddle) or \"tag\" (name or numeric id of an EXISTING tag in this Riddle's scope - a typo'd name is rejected, never auto-created), never both; a \"tag\" also requires \"tagMode\": \"lastPublished\" or \"random\" (with optional \"randomRefreshIntervalSeconds\", \"random\" only). ONE kind of time window per condition - a date range (\"from\" required, \"to\" optional) or a daily one (\"dailyFrom\" plus \"dailyTo\") - with neither it always matches. No other key is accepted. This REPLACES the whole list, and the stored list is re-sorted into tiers with overlapping windows trimmed, so a read-back is not what you sent. Normalization, and why resending a read-back can delete a condition: riddle://reference/riddle-builder/riddle-types with riddleType [\"Placeholder\"]." - changed
Input schema / properties / build / properties / leaderboard / descriptionPrevious value: -"Quiz/Predictor/Minigame only. New leaderboard connection, same shape as in the riddle_builder_<type> tools. Omit to leave the Riddle's leaderboard connections exactly as they are - unlike \"riddleConnections\", this is not resolved into a scalar leaf that could be silently reset: the underlying block only runs, and only ever appends a connection, when you actually send this field, so there is nothing to merge per key."New value: +"Quiz/Predictor/Minigame only. New leaderboard connection: \"connections\" (leaderboard UUIDs), \"identifier\", \"nickname\", as in riddle_builder_create. Omit to leave the Riddle's connections exactly as they are - sending this only ever appends a connection, so there is nothing to merge per key." - changed
Input schema / properties / build / properties / logic / descriptionPrevious value: -"New branching logic tree, same shape as in the riddle_builder_<type> tools. Replaces the current logic; omit to keep it. Deleting a block (see \"blocks\") that is still referenced by the Riddle's existing CUSTOM logic is rejected unless the same request resolves it: either send a full replacement tree here that no longer references the deleted block(s), or send \"logic\": {\"$reset\": true} to discard the custom logic and fall back to the default linear flow - mutually exclusive, \"$reset\": true alongside any other key in \"logic\" is rejected. The error names exactly which deleted block(s) are still referenced and by which logic node(s). This guard never fires when the logic is already the default linear one: deleting a block always works there, the linear order is simply regenerated."New value: +"New branching logic tree, same shape as in riddle_builder_create. Replaces the current logic; omit to keep it. Deleting a block the stored CUSTOM logic still references is rejected unless the same call sends a replacement tree without it, or \"logic\": {\"$reset\": true} to fall back to the default linear flow (\"$reset\" with any other key is rejected). Node shapes: riddle://reference/concepts/logic." - changed
Input schema / properties / build / properties / personalities / descriptionPrevious value: -"Personality Test only. The personalities to change, add or remove - only the ones you touch, everything else stays as it is, merged entry-by-entry by \"id\" exactly like the Riddle's own \"blocks\" (see EDIT_BLOCKS). To EDIT, pass the personality's \"id\" (riddle_get reports it) plus only the properties that change. To ADD, pass \"$create\": true instead of an \"id\" plus everything a new personality needs (the same shape riddle_builder_personality takes). To REMOVE, pass \"id\" plus \"$delete\": true. An entry with no \"id\" and no \"$create\" is rejected the same way a block is - it has no \"id\"; add \"$create\": true to add it as a new one instead. The order of the personalities is NOT editable: there is no \"$personalitiesOrder\" (sending one is rejected) and, because this collection is merged by id, the order the entries are sent in has no meaning either - a \"$create\" is appended at the end and everything else keeps the place it has. Reorder them in the Creator if the order matters. The minimum of 2 personalities is checked against the result AFTER the merge, so a \"$delete\" that would leave fewer than 2 is rejected. The scores already stored on every answer item follow their personality BY IDENTITY, not by position: a personality that stays keeps its score, a deleted personality takes its scores with it, and a newly created personality starts at 0 on every existing answer item until you say otherwise - resend the affected blocks' \"items\" with their full \"scores\" arrays in the same call to set them yourself (that is applied after this and simply wins)."New value: +"Personality Test only. The personalities to change, add or remove, merged by \"id\" exactly like \"blocks\" - \"id\" plus the changed properties, \"$create\": true plus a full new personality, or \"id\" plus \"$delete\": true. There is no \"$personalitiesOrder\": the order is not editable, and the order you send carries no meaning. The minimum of 2 is checked against the merge result. Answer \"scores\" follow a personality by identity, not position - a new one starts at 0 on every existing answer item, so resend the affected blocks' \"items\" with their full \"scores\" arrays in the same call." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Design and riddle-level behaviour settings to change, same shape as in the riddle_builder_<type> tools. Only the keys you send are applied. A Leaderboard's own display settings are part of this too, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them."New value: +"Design and riddle-level behaviour settings to change, same shape as in riddle_builder_create; only the keys you send are applied. A Leaderboard's podium colours (\"color1st\"/\"color2nd\"/\"color3rd\") and \"isEmailVerificationEnabled\" live here too." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish-configuration settings to change, same shape as in the riddle_builder_<type> tools. Only the keys you send are applied. Distinct from this tool's top-level \"publish\" boolean, which publishes the Riddle right away."New value: +"Publish-configuration settings to change, same shape as in riddle_builder_create; only the keys you send are applied. Distinct from this tool's top-level \"publish\" boolean, which publishes right away." - changed
Input schema / properties / build / properties / result / descriptionPrevious value: -"New single result page (Poll / Form / Predictor / Personality / Minigame / Story), same shape as in the riddle_builder_<type> tools. Replaces the current result page as a whole - a result page cannot be edited property-by-property or merged by id the way \"blocks\" can; send it complete, exactly as you would when creating the Riddle. Omit to keep the current one untouched."New value: +"New single result page (Poll / Form / Predictor / Personality / Minigame / Story), same shape as in riddle_builder_create. Replaces the current one as a whole - a result page is neither editable property-by-property nor mergeable by \"id\", so send it complete. Omit to keep it untouched." - changed
Input schema / properties / build / properties / results / descriptionPrevious value: -"New result pages (Quiz), same shape as in riddle_builder_quiz. Replaces ALL current result pages with what you send, in the order you send it: result pages are deliberately neither editable per entry nor reorderable, so read them with riddle_get first and resend every page you want to keep, including its \"id\", which is honored to keep the page stable across the resend. Omit the field to keep all result pages untouched. Why, and which markers are rejected on a page: riddle://reference/concepts/result-pages."New value: +"New result pages (Quiz), same shape as in riddle_builder_create. Replaces ALL current pages with what you send, in the order you send it - pages are neither editable per entry nor reorderable, so read them with riddle_get first and resend every page you want to keep, including its \"id\", which is honored to keep the page stable. Omit to keep them all untouched. riddle://reference/concepts/result-pages." - changed
Input schema / properties / build / properties / riddleConnections / descriptionPrevious value: -"Leaderboard only. The complete list of connected Riddle UUIDs - it REPLACES the stored set wholesale rather than appending (the property has no \"append\" flag and buildRiddleConnections() rebuilds the array from scratch), so to add or drop a single connection, call riddle_get first and resend every UUID you want to keep. Max 10; each target Riddle must already be published and must have Name and Email form fields."New value: +"Leaderboard only. The complete list of connected Riddle UUIDs - it REPLACES the stored set rather than appending, so read the Riddle with riddle_get first and resend every UUID you want to keep. Max 10; each target must already be published and have Name and Email form fields." - changed
Input schema / properties / build / properties / riddleId / descriptionPrevious value: -"The fallback target: the UUID of the Riddle to show when no condition matches (or there are none). Must be an existing, non-Placeholder, published Riddle, and cannot be this Placeholder itself. Having no fallback at all is meaningful on its own - a Placeholder with no fallback and no matching condition resolves to nothing, which is a decision the Embed side makes, not this repo. On an EDIT, omitting this field means \"don't touch it\"; send \"riddleId\": null to actually clear the fallback back to none - which is rejected when it would leave the Placeholder with no fallback AND no conditions at all (it could then never display any Riddle), so clear it only while at least one condition remains, or send a replacement \"conditions\" list in the same call. The same rule rejects \"conditions\": [] on a Placeholder that has no fallback. If the target is later deleted/unpublished, the fallback is dropped from riddle_get with a warning (reason \"RIDDLE_DATA_NOT_EXPRESSIBLE\", path \"riddleId\") but stays in storage and reappears once the target is valid again."New value: +"Placeholder only. The fallback target: the UUID of the Riddle to show when no condition matches. Must be an existing, non-Placeholder, published Riddle, and not this Placeholder itself. Having none is meaningful - the Placeholder then resolves to nothing. On an EDIT, omitting it leaves it as it is; \"riddleId\": null clears it, and is rejected if that would leave the Placeholder with no fallback and no conditions at all - as is \"conditions\": [] while this is empty. riddle://reference/riddle-builder/riddle-types with riddleType [\"Placeholder\"]." - changed
Input schema / properties / build / properties / scoring / descriptionPrevious value: -"Predictor only. New scoring rules, same shape as in riddle_builder_predictor - only the keys you send are changed, the rest of the stored rules are kept. Applied the same way \"preset\"/\"publish\" are: a merge into the existing nested config, not a wholesale replacement, so e.g. sending only {\"correct\": 50} leaves tendency/difference/wrong exactly as they were."New value: +"Predictor only. New scoring rules, same shape as in riddle_builder_create - only the keys you send are changed, so {\"correct\": 50} leaves \"tendency\"/\"difference\"/\"wrong\" as they were. Omit to keep them." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Sections of the returned envelope to leave out; omit the parameter for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned, and whatever you leave out is echoed back under \"omittedFields\", so a missing key never means the Riddle has none of it. Details: riddle://reference/concepts/warnings." - changed
Input schema / properties / omit / items / enumPrevious value: -[ - "build", - "warnings", - "nextBlockId", - "published", - "context", - "build.omittedDefaults" -]New value: +[ + "build", + "warnings", + "nextBlockId", + "published", + "context" +] - changed
Input schema / properties / publish / descriptionPrevious value: -"Whether to publish the Riddle after the edit; default is false, which leaves the changes in the draft. It rides along with an edit, it is not one: this tool with publish: true and an empty \"build\" is rejected with \"Nothing to edit: send at least one of ...\". To publish what is already in the draft, call riddle_publish."New value: +"Whether to publish the Riddle after the edit; default false, which leaves the changes in the draft. It rides along with an edit, it is not one: publish: true with an empty \"build\" is rejected. To publish what is already in the draft, call riddle_publish."
- Changed
riddle_builder_validate3 fields changed- changed
Input schema / properties / builds / descriptionPrevious value: -"The build configs to dry-run, one entry each: {type, build} for a would-be creation or\n{UUID, build} for a would-be edit - exactly one of \"type\"/\"UUID\" per entry, creates and\nedits mixable in one call, 1 to 20 entries. \"type\" is one of Quiz / Poll / Personality /\nForm / Predictor / Leaderboard / Minigame / Story / Placeholder. \"build\" is exactly the\nbuild configuration the matching riddle_builder_<type> tool (creation) or\nriddle_builder_update (edit) takes, so a config can be moved between them unchanged. An\nedit entry is subject to the same origin gate as riddle_builder_update: rejected if the\nRiddle is not apiManageable (check context.origin.apiManageable on riddle_get first)."New value: +"The build configs to dry-run, 1 to 20 entries, creates and edits mixable: {type, build}\nfor a would-be creation or {UUID, build} for an edit, exactly one of \"type\"/\"UUID\" per\nentry. \"type\" is one of Quiz / Poll / Personality / Form / Predictor / Leaderboard /\nMinigame / Story / Placeholder, and \"build\" is exactly what riddle_builder_create or\nriddle_builder_update takes, so a config moves between them unchanged. An edit entry hits\nthe same origin gate as riddle_builder_update - rejected unless the Riddle is\napiManageable (context.origin.apiManageable on riddle_get)." - removed
Input schema / properties / omitRemoved value: -{ - "default": null, - "description": "Leaves the per-block \"omittedDefaults\" maps out of every echoed-back build config, for a much smaller answer: omit: [\"build.omittedDefaults\"]. The same defaults are stated in riddle://reference/riddle-defaults/<riddle type> and riddle://reference/block-defaults/<block type>, so nothing is lost - what you must not do either way is resend those values. Omit the parameter to keep them. The other values of riddle_get's \"omit\" do not apply here: this envelope has no sections to drop.", - "items": { - "enum": [ - "build.omittedDefaults" - ], - "type": "string" - }, - "type": "array", - "uniqueItems": true -} - added
Input schema / properties / projectAdded value: +{ + "default": null, + "description": "The project to dry-run the CREATING entries in - riddle_builder_create's own parameter, and it must be the project you intend to create in: the scratch Riddle is built inside it, and anything project-scoped the build REFERENCES (a Form behind FormSelect, a tag, a project ad slot) is only resolvable from there. Without it such a build is evaluated in the personal project and rejected with \"You are not authorized to access Form <UUID>\" - a scope problem wearing a permissions error, and a false negative for a build a real create would accept. NULL means the personal project, omitted the currently selected one. Ignored by editing entries ({UUID, build}), always evaluated in their own Riddle's project.", + "type": [ + "null", + "integer" + ] +}
- Changed
riddle_delete6 fields changed- added
Input schema / oneOfAdded value: +[ + { + "properties": { + "UUID": { + "not": { + "type": "null" + } + }, + "UUIDs": { + "const": null + } + }, + "required": [ + "UUID" + ] + }, + { + "properties": { + "UUID": { + "const": null + }, + "UUIDs": { + "not": { + "type": "null" + } + } + }, + "required": [ + "UUIDs" + ] + } +] - removed
Input schema / properties / UUIDs / definitionRemoved value: -{ - "items": { - "pattern": "^[A-Za-z0-9]{4,32}$", - "type": "string" - }, - "maxItems": 100, - "minItems": 1, - "type": "array", - "uniqueItems": true -} - added
Input schema / properties / UUIDs / itemsAdded value: +{ + "pattern": "^\\s*[A-Za-z0-9]{4,32}\\s*$", + "type": "string" +} - added
Input schema / properties / UUIDs / maxItemsAdded value: +100 - added
Input schema / properties / UUIDs / minItemsAdded value: +1 - added
Input schema / properties / dryRunAdded value: +{ + "default": false, + "description": "true reports whether each Riddle could be deleted and deletes nothing. Works for one UUID and for UUIDs.", + "type": "boolean" +}
- Changed
riddle_get10 fields changed- added
Input schema / oneOfAdded value: +[ + { + "properties": { + "UUID": { + "not": { + "type": "null" + } + }, + "UUIDs": { + "const": null + } + }, + "required": [ + "UUID" + ] + }, + { + "properties": { + "UUID": { + "const": null + }, + "UUIDs": { + "not": { + "type": "null" + } + } + }, + "required": [ + "UUIDs" + ] + } +] - removed
Input schema / properties / UUIDs / definitionRemoved value: -{ - "items": { - "pattern": "^[A-Za-z0-9]{4,32}$", - "type": "string" - }, - "maxItems": 20, - "minItems": 1, - "type": "array", - "uniqueItems": true -} - changed
Input schema / properties / UUIDs / descriptionPrevious value: -"Several Riddles to read at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"]\n(max 20 - lower than the other bulk tools, since every entry here is a full\nbuild-configuration envelope, not compact state). Pass either this or UUID; rejected\ntogether with includeRiddleData: true, which would overflow the inline response size.\nThe response is the {bulk, operation: \"read\", summary, results} envelope the other bulk\ntools answer with, but with the full riddle_get envelope per entry. Size is therefore\nthe thing to manage: entries are read in the order you listed them, and once the\nresponse would exceed the inline size budget, the remaining ones are reported as\n{uuid, success: true, truncated: true, ...compact state} instead of their full envelope\n- never silently dropped - with a top-level \"truncated\" block naming those UUIDs. Put\nthe Riddles you most need in full first, and use \"omit\" to fit more of them in: an\nunfiltered bulk read of several non-trivial Riddles will truncate.\nomit: [\"build.omittedDefaults\"] is by far the most effective (~85-90% off every entry);\nleaving out whole sections saves much less, a build configuration being almost the\nentire envelope."New value: +"Several Riddles to read at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"]\n(max 20 - lower than the other bulk tools, since every entry is a full envelope rather\nthan compact state). Either this or UUID; rejected together with includeRiddleData.\nEntries are read in the order given and, once the response would exceed the inline size\nbudget, the remaining ones come back as compact state with \"truncated\": true instead -\nso put the Riddles you need in full first. See riddle://reference/concepts/bulk." - added
Input schema / properties / UUIDs / itemsAdded value: +{ + "pattern": "^\\s*[A-Za-z0-9]{4,32}\\s*$", + "type": "string" +} - added
Input schema / properties / UUIDs / maxItemsAdded value: +20 - added
Input schema / properties / UUIDs / minItemsAdded value: +1 - changed
Input schema / properties / includeRiddleData / descriptionPrevious value: -"Additionally returns the full stored Riddle payload (content, settings, preset\nmerge/diff, ...) under \"riddle\". A large payload (tens of KB) - only for\ninspecting raw stored data, leave it false for normal use. Not allowed\ntogether with UUIDs."New value: +"Additionally returns the full stored Riddle payload (content, settings, preset\nmerge/diff, ...) under \"riddle\" - tens of KB, only for inspecting raw stored\ndata. Not allowed together with UUIDs." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the response out - the one way to make this call smaller. Valid values:\n\"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole envelope sections) and\n\"build.omittedDefaults\" (the per-block \"omittedDefaults\" maps inside every build\nconfiguration in the response, including \"published.build\" - not a section, but by far\nthe largest part of one). Omit the parameter, or pass [], for everything;\n\"uuid\"/\"type\"/\"modifiedAt\" are always present and cannot be left out.\nWhich value to reach for: \"build.omittedDefaults\" shrinks a read-back by ~85-90% and\nloses no information, since riddle://reference/block-defaults/<block type> and\nriddle://reference/riddle-defaults/<riddle type> state the very same defaults - the right\ndefault for any call that does not specifically need to know which properties sit at\ntheir default. Whole sections\nare worth naming when you truly do not need them: \"published\" is a second full build\nconfiguration whenever the draft has unpublished changes (about half the response),\nwhile \"warnings\"/\"nextBlockId\"/\"context\" together are only a few percent of it - though\nleaving out \"published\" also skips re-serializing the live version entirely, and\n\"context\" skips that section's extra lookups (features/origin, cover image, preset\ndiff), so the saving is in work as well as bytes.\nWhatever you leave out is echoed back in \"omittedFields\", so a key missing from the\nresponse never has to be read as \"this Riddle has none of that\", only as \"I asked for it\nto be left out\"; a call that omitted nothing carries no such key. With UUIDs, the same\nomissions apply to every entry."New value: +"Leaves whole sections out: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\"\n(identity fields always stay). The one omission that materially shrinks a response is\n\"published\" on a Riddle with unpublished changes - a second full build configuration.\nWhatever you leave out is echoed in \"omittedFields\", so a missing key never reads as\n\"this Riddle has none of that\". Details: riddle://reference/concepts/warnings." - changed
Input schema / properties / omit / items / enumPrevious value: -[ - "build", - "warnings", - "nextBlockId", - "published", - "context", - "build.omittedDefaults" -]New value: +[ + "build", + "warnings", + "nextBlockId", + "published", + "context" +] - added
Input schema / properties / omittedDefaultsAdded value: +{ + "default": null, + "description": "Whether every block should additionally carry its \"omittedDefaults\" map: the properties it left at that block type's default, with the value each is at. Off by default - measured, those maps are 85-90% of a read-back, and riddle://reference/block-defaults/<block type> states the same defaults without a Riddle in hand. Ask for them only to learn what THIS Riddle left at its default, and read them, never resend them.", + "type": "boolean" +}
- Changed
riddle_list5 fields changed- changed
Input schema / properties / notType / descriptionPrevious value: -"Exclude specific Riddle types (array of strings, same valid values as type). Omit to exclude nothing."New value: +"Exclude specific Riddle types (array of strings, same valid values as type). Omit to exclude nothing. Scope \"project\" only - the account list has no exclusion filter." - changed
Input schema / properties / origin / descriptionPrevious value: -"Filter by how the Riddle was created: \"api\" (built via the Riddle Builder API or\ngenerated by the Riddle AI, so riddle_delete/riddle_builder_update/palette_customize\nwork on it) or \"manual\" (created by hand in the Creator, where those three are\nrejected). Omit to include both. Filter value only: the \"origin\" field returned per\nRiddle is an object {builder, aiGenerated, apiManageable}, not one of these strings."New value: +"Filter by how the Riddle was created: \"api\" (Riddle Builder API or Riddle AI, so\nriddle_delete/riddle_builder_update/palette_customize work on it) or \"manual\" (built by\nhand in the Creator, where those three are rejected). Omit for both. A filter value\nonly - the \"origin\" returned per Riddle is {builder, aiGenerated, apiManageable}." - changed
Input schema / properties / page / descriptionPrevious value: -"Page number, 1-indexed, 12 Riddles per page (default: 1). Zero or negative is rejected with a VALIDATION_ERROR, not clamped to page 1 - the same contract as project_list/questionBank_list."New value: +"Page number, 1-indexed, 12 Riddles per page (default: 1). Zero or negative is rejected with a VALIDATION_ERROR rather than clamped." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Filter by project ID; omit or null for the authenticated user's personal project"New value: +"Filter by project ID; omit or null for the authenticated user's personal project. Scope \"project\" only." - added
Input schema / properties / scopeAdded value: +{ + "default": null, + "description": "What to list: \"project\" (default) for the Riddles of a single project, \"account\" for every Riddle of the account at once.", + "enum": [ + "project", + "account" + ], + "type": "string" +}
- Changed
riddle_move11 fields changed- added
Input schema / oneOfAdded value: +[ + { + "properties": { + "UUID": { + "not": { + "type": "null" + } + }, + "UUIDs": { + "const": null + } + }, + "required": [ + "UUID" + ] + }, + { + "properties": { + "UUID": { + "const": null + }, + "UUIDs": { + "not": { + "type": "null" + } + } + }, + "required": [ + "UUIDs" + ] + } +] - changed
Input schema / properties / UUID / descriptionPrevious value: -"The UUID of the single Riddle you want to move. Pass either this or UUIDs."New value: +"The UUID of the single Riddle you want to move or check. Pass either this or UUIDs." - removed
Input schema / properties / UUIDs / definitionRemoved value: -{ - "items": { - "pattern": "^[A-Za-z0-9]{4,32}$", - "type": "string" - }, - "maxItems": 100, - "minItems": 1, - "type": "array", - "uniqueItems": true -} - changed
Input schema / properties / UUIDs / descriptionPrevious value: -"Several Riddles to move at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass either this or UUID."New value: +"Several Riddles to move or check at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass either this or UUID. For a move, this must be the complete set of Riddles that have to move together." - added
Input schema / properties / UUIDs / itemsAdded value: +{ + "pattern": "^\\s*[A-Za-z0-9]{4,32}\\s*$", + "type": "string" +} - added
Input schema / properties / UUIDs / maxItemsAdded value: +100 - added
Input schema / properties / UUIDs / minItemsAdded value: +1 - added
Input schema / properties / dryRunAdded value: +{ + "default": false, + "description": "true runs the movability check against the given projectId and changes nothing. Pointless without projectId, which already only checks.", + "type": "boolean" +} - added
Input schema / properties / projectId / anyOfAdded value: +[ + { + "description": "A project (team) ID from project_list.", + "minimum": 1, + "type": "integer" + }, + { + "const": "personal", + "description": "Move the Riddles into the personal project.", + "type": "string" + } +] - changed
Input schema / properties / projectId / descriptionPrevious value: -"The project (team) ID to move the Riddles into, as returned by project_list. Omit or pass null to move them to your personal project instead."New value: +"Where to move the Riddles: the project (team) ID to move them into, as returned by project_list, or the string \"personal\" for your personal project. There is no default destination - omit this and nothing is moved, the call reports the read-only movability check instead." - changed
Input schema / properties / projectId / typePrevious value: -[ - "null", - "integer" -]New value: +[ + "null", + "integer", + "string" +]
- Removed
riddle_move_check - Changed
riddle_publish9 fields changed- added
Input schema / oneOfAdded value: +[ + { + "properties": { + "UUID": { + "not": { + "type": "null" + } + }, + "UUIDs": { + "const": null + } + }, + "required": [ + "UUID" + ] + }, + { + "properties": { + "UUID": { + "const": null + }, + "UUIDs": { + "not": { + "type": "null" + } + } + }, + "required": [ + "UUIDs" + ] + } +] - changed
Input schema / properties / UUID / descriptionPrevious value: -"The UUID of the single Riddle you want to publish. Pass either this or UUIDs."New value: +"The UUID of the single Riddle you want to publish or unpublish. Pass either this or UUIDs." - removed
Input schema / properties / UUIDs / definitionRemoved value: -{ - "items": { - "pattern": "^[A-Za-z0-9]{4,32}$", - "type": "string" - }, - "maxItems": 100, - "minItems": 1, - "type": "array", - "uniqueItems": true -} - changed
Input schema / properties / UUIDs / descriptionPrevious value: -"Several Riddles to publish at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass either this or UUID."New value: +"Several Riddles to publish or unpublish at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass either this or UUID." - added
Input schema / properties / UUIDs / itemsAdded value: +{ + "pattern": "^\\s*[A-Za-z0-9]{4,32}\\s*$", + "type": "string" +} - added
Input schema / properties / UUIDs / maxItemsAdded value: +100 - added
Input schema / properties / UUIDs / minItemsAdded value: +1 - changed
Input schema / properties / omit / items / enumPrevious value: -[ - "build", - "warnings", - "nextBlockId", - "published", - "context", - "build.omittedDefaults" -]New value: +[ + "build", + "warnings", + "nextBlockId", + "published", + "context" +] - added
Input schema / properties / publishAdded value: +{ + "default": true, + "description": "true (the default) publishes the Riddles, false takes them off the web again.", + "type": "boolean" +}
- Added
riddle_tag - Removed
riddle_tag_add - Changed
riddle_tag_delete2 fields changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"The project (team) ID the tag belongs to, as returned by project_list. Omit for the project the API key is scoped to, or your personal tags on a user API key - the same scoping riddle_tag_list uses."New value: +"The project (team) ID the tag belongs to, as returned by project_list. Omit for the project the API key is scoped to, or your personal tags on a user API key." - changed
Input schema / properties / tagId / descriptionPrevious value: -"The ID of the tag to delete, as returned by riddle_tag_list."New value: +"The ID of the tag to delete, as returned by riddle_tag_list. The only way to name it: a tag is deleted by id, not by name."
- Changed
riddle_tag_list1 field changed- changed
Input schema / properties / projectId / descriptionPrevious value: -"The project (team) ID whose tags you want, as returned by project_list. Omit for the tags of the project the API key is scoped to, or your personal tags on a user API key."New value: +"The project (team) ID, as returned by project_list. Omit for the project the API key is scoped to, or your personal tags on a user API key."
- Removed
riddle_tag_remove - Added
riddle_template_create - Added
riddle_template_get - Added
riddle_template_list - Added
riddle_template_public_list - Added
riddle_template_use - Removed
riddle_unpublish - Removed
riddleTemplate_create - Removed
riddleTemplate_get - Removed
riddleTemplate_list - Removed
riddleTemplate_publicList - Removed
riddleTemplate_use - Changed
stats_fetch11 fields changed- changed
Input schema / properties / dateFrom / descriptionPrevious value: -"Start date (inclusive), format: YYYY-MM-DD. Omit both dateFrom and dateTo to get alltime stats."New value: +"Start date (inclusive), format: YYYY-MM-DD, e.g. \"2026-01-01\". Required for \"timeseries\". On \"totals\" and a Riddle/project \"breakdown\", omit both dates for alltime and pass only one for an open-ended range; the account-wide summary and the project breakdown instead default to one CALENDAR month before today - the same default the Creator's dashboards use, so 29 to 32 days depending on the month, not exactly 30. Send it explicitly when the exact span matters." - changed
Input schema / properties / dateTo / descriptionPrevious value: -"End date (inclusive), format: YYYY-MM-DD. Omit both dateFrom and dateTo to get alltime stats."New value: +"End date (inclusive), format: YYYY-MM-DD, e.g. \"2026-01-31\". Same rules as dateFrom; where a default applies it is today." - added
Input schema / properties / entityId / defaultAdded value: +null - changed
Input schema / properties / entityId / descriptionPrevious value: -"ID of the entity: a project ID (integer as string) for \"project\", a user ID (integer as string) for \"user\", a Riddle UUID for \"riddle\". Get them from project_list, whoami and riddle_list respectively."New value: +"ID of the entity: a project ID (integer as string) for \"project\", a user ID (integer as string) for \"user\", a Riddle UUID for \"riddle\". Get them from project_list, whoami (\"user\", not the string \"user\") and riddle_list respectively. Required for every view except the account-wide summary (view \"breakdown\" with namespace \"user\"), which measures the API key's own account and rejects it." - changed
Input schema / properties / entityId / typePrevious value: -"string"New value: +[ + "null", + "string" +] - changed
Input schema / properties / namespace / descriptionPrevious value: -"Entity type to fetch stats for: \"project\", \"user\" or \"riddle\"."New value: +"Entity type to fetch stats for." - added
Input schema / properties / pageAdded value: +{ + "default": null, + "description": "Page number of the account-wide summary, 1-indexed (default: 1). Zero or negative is rejected with a VALIDATION_ERROR, not clamped to page 1 - the same contract as riddle_list/project_list. That view only.", + "type": [ + "null", + "integer" + ] +} - added
Input schema / properties / projectIdsAdded value: +{ + "default": null, + "description": "Narrow the account-wide summary to these project IDs (array of integers, from project_list). Omit to cover the whole account, including the personal project. Passing a project the user cannot view stats of is an error, not a silently skipped project. That view only.", + "type": [ + "array", + "null" + ] +} - added
Input schema / properties / sortByAdded value: +{ + "default": null, + "description": "Metric the account-wide summary's Riddles are ranked by before the page is cut: \"views\" (default), \"starts\", \"submissions\" or \"timeActive\". Sorting always spans the whole account (or the projects given), so page 1 is genuinely the top of the account. That view only.", + "enum": [ + "views", + "starts", + "submissions", + "timeActive" + ], + "type": "string" +} - added
Input schema / properties / viewAdded value: +{ + "description": "How deeply to measure: \"totals\" (one aggregate for the period), \"timeseries\" (that aggregate per consecutive interval, requires dateFrom and dateTo) or \"breakdown\" (the per-block detail, or the per-Riddle summary for namespace \"user\").", + "enum": [ + "totals", + "timeseries", + "breakdown" + ], + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "namespace", - "entityId" -]New value: +[ + "view", + "namespace" +]
- Removed
stats_overview_fetch - Removed
stats_project_breakdown - Removed
stats_riddle_breakdown - Removed
stats_user_breakdown
10 tool updates
- Changed
palette_get1 field changed- added
Input schema / properties / omitAdded value: +{ + "default": null, + "description": "Leaves parts of the response out - the way to keep this call small. \"paletteValues\" lists every palette as {uuid, name} instead of with its ~30 values (then read the one you want with paletteUUID); \"builtInPalettes\", \"customizedValues\" and \"hints\" drop those keys entirely. Omit the parameter for the full response. Whatever you leave out is echoed back under \"omittedFields\", so a missing key never means the Riddle has none of it.", + "items": { + "enum": [ + "paletteValues", + "builtInPalettes", + "customizedValues", + "hints" + ], + "type": "string" + }, + "type": "array", + "uniqueItems": true +}
- Changed
reference_get2 fields changed- added
Input schema / properties / includeAvailableTopicsAdded value: +{ + "default": null, + "description": "Whether the response should carry the full \"availableTopics\" catalogue. Omit it: the first reference_get of a session gets the catalogue, every call after it gets a one-line pointer back to it instead of repeating ~2.5 KB you already have - which on a small document is several times the document itself. Pass true to get it again (a fresh conversation on an existing session, or after losing it), false to never pay for it.", + "type": "boolean" +} - changed
Output schema / properties / availableTopics / descriptionPrevious value: -"Every topic this tool can return. The static documents are listed as uri => {sizeBytes, summary}, same as riddle://reference/index and what resources/list advertises as \"size\". The two generated families (block-defaults, riddle-defaults - one address per entity) are compacted under \"families\": the address template, how many addresses it has and what they cost in total, without the individual names - those, with their exact sizes, are in riddle://reference/index. An address is built by replacing the {variable} of a \"uriTemplate\" with the entity you are working on, e.g. riddle://reference/block-defaults/Flashcard. Repeated in the response so a client that reached this tool without reading its schema still learns what else is documented - and what reading it would cost, so the next call can be planned instead of guessed."New value: +"Every topic this tool can return - sent in full on the FIRST reference_get of a session only, so a client that reached this tool without reading its schema still learns what else is documented and what reading it would cost. Later calls carry a short {omitted, namesAndSizesIn, resend} pointer instead of repeating ~2.5 KB the caller already has; \"includeAvailableTopics\" overrides both directions. In the full form the static documents are listed as uri => {sizeBytes, summary}, same as riddle://reference/index and what resources/list advertises as \"size\". The two generated families (block-defaults, riddle-defaults - one address per entity) are compacted under \"families\": the address template, how many addresses it has and what they cost in total, without the individual names - those, with their exact sizes, are in riddle://reference/index. An address is built by replacing the {variable} of a \"uriTemplate\" with the entity you are working on, e.g. riddle://reference/block-defaults/Flashcard."
- Changed
riddle_account_list1 field changed- changed
Input schema / properties / page / descriptionPrevious value: -"Page number, 12 Riddles per page (default: 1)"New value: +"Page number, 1-indexed, 12 Riddles per page (default: 1). Zero or negative is rejected with a VALIDATION_ERROR, not clamped to page 1 - the same contract as project_list/questionBank_list."
- Changed
riddle_builder_minigame1 field changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of minigame blocks. Supported types: SlotMachine (title, plus optional startBalance, winningProbability, custom reel symbols and win message), WheelSpinner (title and an \"items\" array of at least 2 objects with title, type (Win/Loss/FreeSpin), percent (all of them must sum to 100) and award (required on a Win item)), Sudoku (difficulty, score, plus an optional success message). Only Sudoku has a score - neither SlotMachine nor WheelSpinner (nor its items) supports scoring, so a Minigame consisting of nothing but a WheelSpinner cannot be connected to a Leaderboard. The remaining per-type properties are in riddle://reference/riddle-builder/block-types. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable."New value: +"Array of minigame blocks. Supported types: SlotMachine (title, plus optional startBalance, winningProbability (\"Low\" / \"Medium\" / \"High\" - an enum, NOT a percentage), custom reel symbols and win message), WheelSpinner (title and an \"items\" array of at least 2 objects with title, type (Win/Loss/FreeSpin), percent (all of them must sum to 100) and award (required on a Win item)), Sudoku (difficulty as an integer 0-100, the percentage of cells blanked out rather than \"easy\"/\"medium\"/\"hard\", plus score and an optional success message). Only Sudoku has a score - neither SlotMachine nor WheelSpinner (nor its items) supports scoring, so a Minigame consisting of nothing but a WheelSpinner cannot be connected to a Leaderboard. The remaining per-type properties are in riddle://reference/riddle-builder/block-types. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable."
- Changed
riddle_builder_poll1 field changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice / Matrix / Order / Upvote / NetPromoterScore / RateIt / Swiper / Reaction / TextEntry / TierList / ThisOrThat / QuestionBank) and items (array of answer objects, each {\"title\": \"Answer text\"} plus that type's optional per-item properties). Optional: media (URL or object), isRequired, otherOption (SingleChoice/MultipleChoice only - adds an \"Other\" answer with a free-text entry). Three types differ structurally: TextEntry is a free-text answer with no items and no scoring at all, TierList needs \"tiers\" and treats its \"items\" as the optional pool the respondent drags into them, and QuestionBank draws its questions from an existing question bank instead of items authored here (\"questionBankId\" plus a non-empty \"questionBankBlocks\" - see riddle://reference/question-bank/overview first). Every type has further structural and display properties on top of that (ThisOrThat pairs its contenders positionally out of ONE flat \"items\" list, never a list of pairs; the RateIt scale, selection limits, wrapping, sorting after vote, mobile view, ...) - look them up per type in riddle://reference/riddle-builder/block-types instead of guessing names or value ranges."New value: +"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice / Matrix / Order / Upvote / NetPromoterScore / RateIt / Swiper / Reaction / TextEntry / TierList / ThisOrThat / QuestionBank) and items (array of answer objects, each {\"title\": \"Answer text\"} plus that type's optional per-item properties). Optional: media (URL or object), isRequired, otherOption (SingleChoice/MultipleChoice only - adds an \"Other\" answer with a free-text entry). Four types differ structurally: NetPromoterScore is a fixed 0-10 scale with no items at all and REQUIRES positiveTitle plus negativeTitle (the labels of its high (10) and low (0) end); TextEntry is a free-text answer with no items and no scoring at all, TierList needs \"tiers\" and treats its \"items\" as the optional pool the respondent drags into them, and QuestionBank draws its questions from an existing question bank instead of items authored here (\"questionBankId\" plus a non-empty \"questionBankBlocks\" - see riddle://reference/question-bank/overview first). Every type has further structural and display properties on top of that (ThisOrThat pairs its contenders positionally out of ONE flat \"items\" list, never a list of pairs; the RateIt scale, selection limits, wrapping, sorting after vote, mobile view, ...) - look them up per type in riddle://reference/riddle-builder/block-types instead of guessing names or value ranges."
- Changed
riddle_list1 field changed- changed
Input schema / properties / page / descriptionPrevious value: -"Page number, 12 Riddles per page (default: 1)"New value: +"Page number, 1-indexed, 12 Riddles per page (default: 1). Zero or negative is rejected with a VALIDATION_ERROR, not clamped to page 1 - the same contract as project_list/questionBank_list."
- Removed
riddle_qr_code - Added
riddle_tag_delete - Changed
riddleTemplate_use1 field changed- added
Input schema / properties / omitAdded value: +{ + "default": null, + "description": "Same \"omit\" parameter as riddle_get's, applied to the returned envelope (see riddle_get for the full description). Reach for omit: [\"build.omittedDefaults\"] here as well - the created Riddle is a copy of the template, so its per-block default maps are the biggest part of this response and state nothing riddle://reference/block-defaults/<block type> does not.", + "items": { + "enum": [ + "build", + "warnings", + "nextBlockId", + "published", + "context", + "build.omittedDefaults" + ], + "type": "string" + }, + "type": "array", + "uniqueItems": true +}
- Changed
stats_user_breakdown5 fields changed- changed
Input schema / properties / dateFrom / descriptionPrevious value: -"Start date (inclusive), format: YYYY-MM-DD, e.g. \"2026-01-01\". Optional."New value: +"Start date (inclusive), format: YYYY-MM-DD, e.g. \"2026-01-01\". Optional, defaults to 30 days ago." - changed
Input schema / properties / dateTo / descriptionPrevious value: -"End date (inclusive), format: YYYY-MM-DD, e.g. \"2026-01-31\". Optional."New value: +"End date (inclusive), format: YYYY-MM-DD, e.g. \"2026-01-31\". Optional, defaults to today." - added
Input schema / properties / pageAdded value: +{ + "default": null, + "description": "Page number, 1-indexed (default: 1). Zero or negative is rejected with a VALIDATION_ERROR, not clamped to page 1 - the same contract as riddle_list/project_list.", + "type": [ + "null", + "integer" + ] +} - added
Input schema / properties / projectIdsAdded value: +{ + "default": null, + "description": "Narrow the summary to these project IDs (array of integers, from project_list). Omit to cover the whole account, including the personal project. Passing a project the user cannot view stats of is an error, not a silently skipped project.", + "type": [ + "array", + "null" + ] +} - added
Input schema / properties / sortByAdded value: +{ + "default": null, + "description": "Metric the Riddles are ranked by before the page is cut: \"views\" (default), \"starts\", \"submissions\" or \"timeActive\". Sorting always spans the whole account (or the projects given), so page 1 is genuinely the top of the account.", + "enum": [ + "views", + "starts", + "submissions", + "timeActive" + ], + "type": "string" +}
16 tool updates
- Changed
questionBank_addItem1 field changed- changed
Input schema / properties / columns / descriptionPrevious value: -"The question content, as {columnName: [values]}. Which column names are expected depends on the bank's riddleType AND the blockType, so read them off questionBank_blockTypeColumns rather than guessing: an unknown column name is rejected. E.g. a \"Quiz\" bank's \"SingleChoice\" takes {\"QUESTION\": [\"Capital of France?\"], \"CORRECT_CHOICE\": [\"Paris\"], \"INCORRECT_CHOICE\": [\"London\", \"Berlin\"]}, a \"Poll\" bank's \"SingleChoice\" {\"QUESTION\": [...], \"CHOICE\": [...]} instead, a Poll answer never being right or wrong."New value: +"The question content, as {columnName: [values]}. Which column names are expected depends on the bank's riddleType AND the blockType, so read them off questionBank_blockTypeColumns rather than guessing: an unknown column name is rejected, naming the column it did not recognise and listing the valid ones. E.g. a \"Quiz\" bank's \"SingleChoice\" takes {\"QUESTION\": [\"Capital of France?\"], \"CORRECT_CHOICE\": [\"Paris\"], \"INCORRECT_CHOICE\": [\"London\", \"Berlin\"]}, a \"Poll\" bank's \"SingleChoice\" {\"QUESTION\": [...], \"CHOICE\": [...]} instead, a Poll answer never being right or wrong."
- Changed
questionBank_updateItem1 field changed- changed
Input schema / properties / columns / descriptionPrevious value: -"The question content, as {columnName: [values]} - the same shape questionBank_addItem takes, with the columns questionBank_blockTypeColumns lists for this riddleType and blockType (an unknown column name is rejected). Replaces the item's content entirely, it is not a partial merge. The values questionBank_getItems returns can go straight back in, {\"id\": .., \"value\": ..} objects included: keeping their ids is what makes this an edit of the existing values rather than a fresh set."New value: +"The question content, as {columnName: [values]} - the same shape questionBank_addItem takes, with the columns questionBank_blockTypeColumns lists for this riddleType and blockType (an unknown column name is rejected, naming the column it did not recognise and listing the valid ones). Replaces the item's content entirely, it is not a partial merge. The values questionBank_getItems returns can go straight back in, {\"id\": .., \"value\": ..} objects included: keeping their ids is what makes this an edit of the existing values rather than a fresh set."
- Changed
reference_get9 fields changed- changed
Input schema / properties / blockTypes / descriptionPrevious value: -"Narrow block-types/block-defaults further, to these block type name(s) (e.g. \"SingleChoice\", \"WheelSpinner\"), on top of whatever \"riddleType\" already kept. Names are NOT enumerated here - there are dozens across 9 Riddle types, and this schema is read by every agent on every turn regardless of whether it filters. An unknown name, or one that exists but is not part of the Riddle type(s) you filtered to, is rejected and the error names the valid names for your situation. Omit for every block type."New value: +"Narrow block-types further, to these block type name(s) (e.g. \"SingleChoice\", \"WheelSpinner\"), on top of whatever \"riddleType\" already kept. Names are NOT enumerated here - there are dozens across 9 Riddle types, and this schema is read by every agent on every turn regardless of whether it filters. An unknown name, or one that exists but is not part of the Riddle type(s) you filtered to, is rejected and the error names the valid names for your situation. Omit for every block type." - removed
Input schema / properties / omitRemoved value: -{ - "default": null, - "description": "Leaves parts of a document out instead of narrowing it. The only value with anything to leave out here is \"commonDefaults\", on block-defaults: its shared-defaults map is not itself scoped to a Riddle type or block type, so \"riddleType\"/\"blockTypes\" alone cannot always shrink it (an unfiltered call, or one whose kept blocks still reference most of it, keeps the whole map either way) - \"omit\": [\"commonDefaults\"] drops it outright. Nothing about a kept Riddle type or block type is lost by dropping it: their \"sharedDefaults\" lists still name what they need, \"filtered.omitted\" reports the drop the same way every other omission is reported, and the document itself says to call reference_get again (without this omit, or with a narrower riddleType/blockTypes) to get those names' actual values back. Ignored on every other topic. Omit for the complete document.", - "items": { - "enum": [ - "commonDefaults" - ], - "type": "string" - }, - "type": "array", - "uniqueItems": true -} - changed
Input schema / properties / riddleType / descriptionPrevious value: -"Narrow riddle-types/block-types/block-defaults down to these Riddle type(s) - e.g. [\"Quiz\"] on block-types drops every other type's question blocks while keeping the shared conventions (commonBlockProperties, the general Content/Ad/Quote blocks, ...). Ignored, with the whole document returned, on a topic that has no per-type split (form-field-types, result-blocks, the palette/question-bank documents). Omit for every type."New value: +"Narrow riddle-types/block-types down to these Riddle type(s) - e.g. [\"Quiz\"] on block-types drops every other type's question blocks while keeping the shared conventions (commonBlockProperties, the general Content/Ad/Quote blocks, ...). Ignored, with the whole document returned, on a topic that has no per-type split (form-field-types, result-blocks, concepts/defaults, the palette/question-bank documents). Not applicable to the block-defaults/riddle-defaults families - read the entity's own address instead. Omit for every type." - added
Input schema / properties / topics / items / anyOfAdded value: +[ + { + "enum": [ + "riddle://reference/index", + "riddle://reference/getting-started", + "riddle://reference/response-format", + "riddle://reference/riddle-builder/riddle-types", + "riddle://reference/riddle-builder/block-types", + "riddle://reference/riddle-builder/form-field-types", + "riddle://reference/riddle-builder/result-blocks", + "riddle://reference/palette/fields", + "riddle://reference/palette/built-in-palettes", + "riddle://reference/palette/fonts", + "riddle://reference/publish-defaults", + "riddle://reference/form-field-defaults", + "riddle://reference/question-bank/overview" + ], + "type": "string" + }, + { + "pattern": "^riddle://reference/(block-defaults|riddle-defaults|concepts)/[^/]+$", + "type": "string" + } +] - removed
Input schema / properties / topics / items / enumRemoved value: -[ - "riddle://reference/getting-started", - "riddle://reference/response-format", - "riddle://reference/riddle-builder/riddle-types", - "riddle://reference/riddle-builder/block-types", - "riddle://reference/riddle-builder/block-defaults", - "riddle://reference/riddle-builder/form-field-types", - "riddle://reference/riddle-builder/result-blocks", - "riddle://reference/palette/fields", - "riddle://reference/palette/built-in-palettes", - "riddle://reference/palette/fonts", - "riddle://reference/question-bank/overview" -] - removed
Input schema / properties / topics / items / typeRemoved value: -"string" - changed
Input schema / properties / topics / maxItemsPrevious value: -4New value: +8 - changed
Output schema / properties / availableTopics / descriptionPrevious value: -"Every topic this tool can return, as uri => summary. Repeated in the response so a client that reached this tool without reading its schema still learns what else is documented."New value: +"Every topic this tool can return. The static documents are listed as uri => {sizeBytes, summary}, same as riddle://reference/index and what resources/list advertises as \"size\". The two generated families (block-defaults, riddle-defaults - one address per entity) are compacted under \"families\": the address template, how many addresses it has and what they cost in total, without the individual names - those, with their exact sizes, are in riddle://reference/index. An address is built by replacing the {variable} of a \"uriTemplate\" with the entity you are working on, e.g. riddle://reference/block-defaults/Flashcard. Repeated in the response so a client that reached this tool without reading its schema still learns what else is documented - and what reading it would cost, so the next call can be planned instead of guessed." - changed
Output schema / properties / references / items / properties / filtered / descriptionPrevious value: -"Always present, even when no scoping was requested. {riddleType, blockTypes, fieldTypes, omit: the values you sent (or [] if you sent none); applied: whether this document was actually narrowed down or had something omitted; omitted: {\"<bucket>\": <count dropped>, ...}; note: a plain-language explanation, including why nothing was narrowed on a document with no per-type split, and - on block-defaults with \"omit\": [\"commonDefaults\"] - that the drop was requested rather than narrowed away."New value: +"Always present, even when no scoping was requested. {riddleType, blockTypes, fieldTypes: the values you sent (or [] if you sent none); applied: whether this document was actually narrowed down; omitted: {\"<bucket>\": <count dropped>, ...}; note: a plain-language explanation, including why nothing was narrowed on a document with no per-type split."
- Changed
riddle_builder_form4 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of form blocks. Each block must have: title (string), type (FormBuilder), fields (array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}). 18 field types exist, including \"Privacy\" (GDPR consent text + the two consent checkboxes) and \"Captcha\" (spam protection; a \"google\"/\"cloudflare\" captchaType requires both key and secret, omitting either fails the build) - see riddle://reference/riddle-builder/form-field-types."New value: +"Array of form blocks. Each block must have: title (string), type (FormBuilder), fields (array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}). 18 field types exist, from plain inputs to the GDPR \"Privacy\" consent and \"Captcha\" spam protection - they and their properties are in riddle://reference/riddle-builder/form-field-types." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_leaderboard2 fields changed- changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_minigame4 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of minigame blocks. Supported types: SlotMachine (title, plus optional startBalance, winningProbability: Low/Medium/High, customSymbols replacing reel symbols with images, and the win message), WheelSpinner (title and an items array of at least 2 objects with title (string), type (Win/Loss/FreeSpin), percent (int, all of them must sum to 100) and award (string, required on Win items, optional on Loss/FreeSpin)), Sudoku (difficulty, score, plus an optional success message - supplying successMessage already switches the message on, isSuccessMessageEnabled: false switches it back off while keeping the text). The remaining per-type properties (custom symbol keys, win message fields, emojis, copy-to-clipboard, success message media) are in riddle://reference/riddle-builder/block-types. Only Sudoku has a score - neither SlotMachine nor WheelSpinner (nor its items) supports scoring, as both only produce a win/loss outcome; a Minigame consisting of nothing but a WheelSpinner therefore cannot be connected to a Leaderboard. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable."New value: +"Array of minigame blocks. Supported types: SlotMachine (title, plus optional startBalance, winningProbability, custom reel symbols and win message), WheelSpinner (title and an \"items\" array of at least 2 objects with title, type (Win/Loss/FreeSpin), percent (all of them must sum to 100) and award (required on a Win item)), Sudoku (difficulty, score, plus an optional success message). Only Sudoku has a score - neither SlotMachine nor WheelSpinner (nor its items) supports scoring, so a Minigame consisting of nothing but a WheelSpinner cannot be connected to a Leaderboard. The remaining per-type properties are in riddle://reference/riddle-builder/block-types. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_personality5 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice), items (array of answer objects, each {\"title\": \"Answer text\", \"scores\": [2, 0]}) - every entry with a \"scores\" key holding an integer array, whose length must match the number of personalities and whose position corresponds to the personality index. Optional: media (URL or object) plus the usual choice-block display properties (wrapping, flexible height, item descriptions, and on MultipleChoice the selection limits) - see riddle://reference/riddle-builder/block-types."New value: +"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice), items (array of answer objects, each {\"title\": \"Answer text\", \"scores\": [2, 0]}) - every entry carries a \"scores\" integer array whose length must match the number of personalities and whose position corresponds to the personality index. Optional: media (URL or object) plus the usual choice-block display properties - see riddle://reference/riddle-builder/block-types." - changed
Input schema / properties / build / properties / personalities / descriptionPrevious value: -"Array of personality objects (min 2). Each must have title (string). Optional: description (string), media (URL string or object), minScore / maxScore (0-100, the score window in which this personality wins), ctaButtonText, ctaButtonURL (supplying either shows the CTA button, clearing both hides it), isIncludeCTAButtonEnabled (explicit override for that: send false alongside a ctaButtonText to keep the button configured but hidden), areOtherResultsEnabled (the same override for the runner-up results), areOtherResultsMediaEnabled, otherResults (supplying them shows the runner-up results; each takes title, description, media, minScore, maxScore, ctaButtonText, ctaButtonURL)."New value: +"Array of personality objects (min 2). Each must have title (string). Optional: description, media (URL string or object), minScore / maxScore (0-100, the score window in which this personality wins), the CTA button (ctaButtonText / ctaButtonURL - supplying either shows it - plus the isIncludeCTAButtonEnabled override that keeps it configured but hidden) and the runner-up results (\"otherResults\" plus the areOtherResultsEnabled / areOtherResultsMediaEnabled overrides). The exact shape of each of those is in riddle://reference/riddle-builder/riddle-types under types.Personality." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_placeholder3 fields changed- changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_poll4 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice / Matrix / Order / Upvote / NetPromoterScore / RateIt / Swiper / Reaction / TextEntry / TierList / ThisOrThat / QuestionBank) and items (array of answer objects, each {\"title\": \"Answer text\"} plus that type's optional per-item properties; TextEntry has none, TierList needs \"tiers\" instead, QuestionBank \"questionBankId\" (int)). Optional: media (URL or object), otherOption ({isEnabled: bool, label: string}, SingleChoice/MultipleChoice only - adds an \"Other\" answer option with a free-text entry the respondent fills in; both keys are independent and optional, label defaults to \"Other\" and must not be empty), isRequired (all types). Three types differ structurally: TextEntry is a free-text answer with no items and no scoring at all; TierList needs \"tiers\" (at least 2 objects with title plus optional colorBg/colorText), its \"items\" being the optional pool the respondent drags into them; ThisOrThat takes at least 2 contenders as ONE flat \"items\" list, never a list of pairs - the pairs are formed positionally, so the item order decides who competes against whom, and each contender needs a title, an image or both. QuestionBank draws its questions from an existing question bank instead of items authored here: it needs questionBankId plus a non-empty \"questionBankBlocks\" (one entry per block type to draw into), and a block with none draws nothing and is rejected - see riddle://reference/question-bank/overview and the questionBank_* tools first. Every type has further display/behaviour properties on top of that (wrapping, flexible height, item descriptions, selection limits, remaining votes, sorting after vote, the RateIt scale (stars vs numbers and its bounds), rank format, mobile view, swiper text position and button type, text-entry validation, tier item media, this-or-that progress bar and separator, ...) - look them up per type in riddle://reference/riddle-builder/block-types instead of guessing names or value ranges."New value: +"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice / Matrix / Order / Upvote / NetPromoterScore / RateIt / Swiper / Reaction / TextEntry / TierList / ThisOrThat / QuestionBank) and items (array of answer objects, each {\"title\": \"Answer text\"} plus that type's optional per-item properties). Optional: media (URL or object), isRequired, otherOption (SingleChoice/MultipleChoice only - adds an \"Other\" answer with a free-text entry). Three types differ structurally: TextEntry is a free-text answer with no items and no scoring at all, TierList needs \"tiers\" and treats its \"items\" as the optional pool the respondent drags into them, and QuestionBank draws its questions from an existing question bank instead of items authored here (\"questionBankId\" plus a non-empty \"questionBankBlocks\" - see riddle://reference/question-bank/overview first). Every type has further structural and display properties on top of that (ThisOrThat pairs its contenders positionally out of ONE flat \"items\" list, never a list of pairs; the RateIt scale, selection limits, wrapping, sorting after vote, mobile view, ...) - look them up per type in riddle://reference/riddle-builder/block-types instead of guessing names or value ranges." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_predictor4 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of predictor blocks. Each block must have: title (string), type (PickTheWinner / GuessTheScore), items (array of objects with title and optional backgroundImage, logo, backgroundColor, textColor). Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable."New value: +"Array of predictor blocks. Each block must have: title (string), type (PickTheWinner / GuessTheScore), items (array of objects with title and optional backgroundImage, logo, backgroundColor, textColor). When EDITING an existing Predictor (riddle_builder_update) a block also takes correctResult: the real-world outcome as the two scores in the order of its items - [3, 1] for a GuessTheScore block, or which side won for a PickTheWinner one ([1, 0] / [0, 1] / [1, 1] for a draw); [0, 0] clears it. It is rejected when the block is being created (including a \"$create\" marked block), since an outcome only exists once the Riddle does. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_quiz4 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of question blocks. Each block must have: title (string), type (SingleChoice / MultipleChoice / TextEntry / Order / Flashcard / TypeRush / GuessIt / QuestionBank), and that type's content: items (array of answer objects, each {\"title\": \"Answer text\", \"isCorrect\": true|false} plus any of description/media/score/explanation for that one answer - the last two on SingleChoice/MultipleChoice only) on the choice types, answers (array of {\"title\": \"...\"} objects) on TextEntry, acceptableAnswers (array of {\"title\": \"...\"} objects) on GuessIt, questionBankId (int) on QuestionBank. Optional on every type: media (URL or object), explanation (object with title - supplying it is what switches the explanation on; send isExplanationEnabled: false to switch it back off while keeping the content). Every type has further display/behaviour properties on top of that (shuffling, layout, item descriptions, selection limits, hints, lives, guesses, rank format, case/space handling, column titles, blur mode, ...) - look them up per type in riddle://reference/riddle-builder/block-types instead of guessing names or value ranges. Two GuessIt-specific traps: it is the one Quiz type without a \"score\" - it is always scored by how many guesses were needed, so sending \"score\" on it is a validation error, not silently ignored - and its \"media\" is the picture to be guessed rather than a decorative image (also not a validation error, just a different meaning than on every other type); on TypeRush set either a total block \"score\" or a per-item score, never both. QuestionBank draws its questions from an existing question bank instead of items authored here: it needs questionBankId plus a non-empty \"questionBankBlocks\" (one entry per block type to draw into) - a block with no questionBankBlocks draws nothing and is rejected. See riddle://reference/question-bank/overview and the questionBank_* tools before using it. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable."New value: +"Array of question blocks. Each block must have: title (string; a QuestionBank block does not need one), type (SingleChoice / MultipleChoice / TextEntry / Order / Flashcard / TypeRush / GuessIt / QuestionBank), and that type's content: items (array of answer objects, each {\"title\": \"Answer text\", \"isCorrect\": true|false} plus any of description/media/score/explanation for that one answer - the last two on SingleChoice/MultipleChoice only) on the choice types, answers (array of {\"title\": \"...\"} objects) on TextEntry, acceptableAnswers (array of {\"title\": \"...\"} objects) on GuessIt, questionBankId (int) plus a non-empty \"questionBankBlocks\" on QuestionBank. Optional on the authored types: media (URL or object) and explanation (an object with a title is what switches it on; isExplanationEnabled: false switches it back off while keeping the content) - TypeRush has no explanation, and a QuestionBank block, which authors nothing itself, takes neither. Every type has further display/behaviour properties and its own traps on top of that (GuessIt accepts no \"score\" at all, TypeRush either a block score or per-item scores but never both, ...) - look them up per type in riddle://reference/riddle-builder/block-types instead of guessing names or value ranges, and read riddle://reference/question-bank/overview before your first QuestionBank block. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_story4 fields changed- changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"Array of content blocks. Each block must have: type (Content / Ad / Quote / InteractiveGraphic / FormBuilder / FormField / FormSelect). Content takes title plus optional description and media; Quote takes title, quoteText and quoteAuthor plus optional description, media, quoteMedia, quoteBackgroundColor, quoteTextColor; Ad takes either projectSlot ({slotId, variables}) or iframe ({url, height}) plus optional media, isNextButtonVisible, showNextButtonDelay, isShowNextButtonAfterDelayEnabled; InteractiveGraphic takes an \"images\" array (min 1) of {media, label, hotspots} - \"media\" and at least one \"hotspots\" entry are required on every image you create (an image without media is an empty canvas its hotspots float on, one without hotspots is a picture nobody can interact with), \"label\" only names the image inside the editor; each hotspot placed at x/y percentages with an \"action\" that decides its remaining properties (\"showInfo\" pop-up, \"openUrl\", \"goToNextBlock\", \"noAction\", \"goToImage:<image id or label>\" to another image of the same block, which you can point at by its \"label\" so a connection needs no prior riddle_get). Hotspot coordinates cannot be judged from JSON: build it, publish it, look at the rendered Riddle in a browser and correct the hotspots that are off - see the \"authoringNote\" in riddle://reference/riddle-builder/block-types. A Story has no question blocks of any kind - use riddle_builder_poll or riddle_builder_quiz if you need answers. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable."New value: +"Array of content blocks. Each block must have: type (Content / Ad / Quote / InteractiveGraphic / FormBuilder / FormField / FormSelect) plus that type's own content - Content a title, Quote a title with quoteText and quoteAuthor, Ad either a projectSlot ({slotId, variables}) or an iframe ({url, height}), InteractiveGraphic an \"images\" array (min 1) whose every image needs \"media\" and at least one \"hotspots\" entry. A hotspot is placed at x/y percentages, and those cannot be judged from JSON: build it, publish it, look at the rendered Riddle in a browser and correct the hotspots that are off. A Story has no question blocks of any kind - use riddle_builder_poll or riddle_builder_quiz if you need answers. The properties of each type, the hotspot actions (including \"goToImage:<image id or label>\") and the authoring note are in riddle://reference/riddle-builder/block-types. Lead-collecting blocks go in the same array: FormBuilder (\"fields\": array of field objects, each {\"title\": \"Your email\", \"type\": \"Email\"}, the 18 types are in riddle://reference/riddle-builder/form-field-types), FormField (one standalone field) or FormSelect (\"form\": UUID of an existing Form Riddle). Name and Email fields are what make this Riddle Leaderboard-connectable." - changed
Input schema / properties / build / properties / preset / descriptionPrevious value: -"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact names: presetStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Riddle-level design and behaviour settings (design, open/close scheduling, timers, progress, live score, result visibility, vote integrity, page chrome, ~20 UX flags); only the keys you send are applied and a key only exists for the types that have it. On a Leaderboard this is also where its own display settings live, the podium colours (color1st/color2nd/color3rd) and isEmailVerificationEnabled among them. Exact name: riddle://reference/concepts/preset." - changed
Input schema / properties / build / properties / publish / descriptionPrevious value: -"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: publishStructure in riddle://reference/riddle-builder/riddle-types."New value: +"Publish CONFIGURATION stored on the Riddle - an object, and not to be confused with this tool's separate top-level \"publish\" boolean, which publishes the Riddle right away. Covers showcase/QR code, lead verification (double opt-in, email OTP, SMS OTP - mutually exclusive), email automation, dataLayer, tracking, integrations, embedSettings. Keys: riddle://reference/concepts/publish." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_update5 fields changed- changed
Input schema / properties / build / properties / $blocksOrder / descriptionPrevious value: -"The new order of the Riddle's blocks, as the complete list of their IDs - [3, 1, 2] puts block 3 first. Complete means every ID the Riddle has after this edit, exactly once: a partial list is rejected, because where the blocks you left out belong is exactly what it does not say. It is applied after everything else in the same call, so a block you delete here must NOT be listed and a block you add here MUST be - give a \"$create\" entry an explicit \"id\" to name it, taken from \"nextBlockId\" in the riddle_get response (count up from it for several new blocks). Do not derive that id from the ids in \"build\": they are shared with the Riddle's results and personalities and are never reused, so the next one is usually already taken; claiming a taken id is rejected with an error naming the free one. The same marker works inside a block, next to the collection it orders: {\"id\": 3, \"$itemsOrder\": [2, 1]} reorders that block's items, \"$fieldsOrder\" a Form's fields, and so on. It reaches one level deeper through a merged \"fields\" edit: {\"id\": 3, \"fields\": [{\"id\": 5, \"$itemsOrder\": [2, 1]}]} reorders the items of that one Dropdown field. The one limit is that the collection's entries need ids of their own. Collections without ids - reply-to/CC/BCC addresses, selected Riddles/types/tags, a TypeRush item's answers, a reaction scale, a Matrix question's scale, custom symbols, riddle connections, tracking networks, share networks, ad variables, per-block timer times, a personality answer's scores, a Predictor block's items (their id IS their position, 0/1 - resend \"items\" in the order you want instead), a Swiper block's items (their position IS the swipe answer, first card \"dislike\", second \"like\" - swap the two by resending both cards by id) - are simply sent in the order you want them in, and the error says so if you try."New value: +"The new order of the Riddle's blocks, as the complete list of their IDs - [3, 1, 2] puts block 3 first. Complete means every ID the Riddle has after this edit, exactly once: a partial list is rejected, because where the blocks you left out belong is exactly what it does not say. It is applied after everything else in the same call, so a block you delete here must NOT be listed and a block you add here MUST be - give a \"$create\" entry an explicit \"id\" to name it, taken from \"nextBlockId\" in the riddle_get response (count up from it for several new blocks) and never derived from the ids in \"build\", which are shared with the Riddle's results and personalities; claiming a taken id is rejected with an error naming the free one. The same marker works inside a block, next to the collection it orders: {\"id\": 3, \"$itemsOrder\": [2, 1]} reorders that block's items, \"$fieldsOrder\" a Form's fields, and it reaches one level deeper through a merged \"fields\" edit - {\"id\": 3, \"fields\": [{\"id\": 5, \"$itemsOrder\": [2, 1]}]} reorders the items of that one Dropdown field. Only a collection whose entries have ids of their own can be ordered at all, and a few that do still reject the marker because an entry's position carries meaning of its own - riddle://reference/concepts/merge-semantics says which collection is which, and the error says so too if you try." - changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"The blocks to change, add or remove - only the ones you touch, everything else stays as it is. To EDIT, pass the block's \"id\" (riddle_get reports it) plus only the properties that change - {\"id\": 3, \"title\": \"New question title\"}; the block's other properties, and every block you do not list, are untouched. To ADD, pass \"$create\": true instead of an \"id\" plus everything a new block needs (the same shape the riddle_builder_<type> tool of this Riddle's type takes) - {\"$create\": true, \"type\": \"SingleChoice\", \"title\": \"New question\", \"items\": [...]}. To REMOVE, pass \"id\" plus \"$delete\": true - {\"id\": 3, \"$delete\": true}. Removing a block still referenced by custom logic is rejected unless \"logic\" (see that field) resolves it in the same request. A block cannot change its \"type\" in an edit (delete it and add a new one instead), and an unknown \"id\" is rejected with the list of IDs that do exist. The collections INSIDE a block whose entries have a stable id merge the very same way - a question's \"items\" (of every type: Quiz/Personality answers, Poll answers, Matrix rows, Swiper cards, TierList tiers and items, ThisOrThat contenders, WheelSpinner items), an InteractiveGraphic's \"images\" and the \"hotspots\" inside each of them (deleting an image a hotspot still points at with \"goToImage:\" is rejected the same way a logic-referenced block is - repoint or delete those hotspots in the same request), a FormBuilder's \"fields\" and a Dropdown field's \"items\": {\"id\": 3, \"items\": [{\"id\": 2, \"title\": \"Bonn\"}]} renames one answer and leaves the others alone, {\"$create\": true, ...} adds an entry, {\"id\": 2, \"$delete\": true} removes one - those entry ids are scoped to their own collection and never come from \"nextBlockId\", so they repeat across blocks and only mean anything together with the id of the block holding them. An entry with no \"id\" is rejected rather than added under a new one, so a resend that dropped its ids cannot silently re-create the collection and break references into it (blockId_fieldId identifiers, logic, personality scores) - add \"$create\": true when you do mean a new entry. Every entry of every collection is an object, which is what lets it carry its \"id\" or its marker and so address a stored entry. Minimum/maximum entry counts are checked against the result of the merge, not against what you sent, and so is any rule spanning the whole collection (a question needs a correct answer; a WheelSpinner's item percents must sum to 100, so send the percent of every item you shift weight between). Collections that have NOT opted into this (a question bank's target blocks, a Matrix question's \"scale\") are still replaced wholesale - send every entry you want to keep. A Matrix \"scale\" is keyed by the value each rating stands for and has no ids at all, so a merge-style entry ({\"id\": 2, ...}, \"$create\", \"$delete\") is rejected instead of taken as the new scale: resend the complete scale, e.g. {\"id\": 3, \"scale\": {\"0\": {\"title\": \"Bad\"}, \"1\": {\"title\": \"Okay\"}, \"2\": {\"title\": \"Good\"}}}."New value: +"The blocks to change, add or remove - only the ones you touch, everything else stays as it is. To EDIT, pass the block's \"id\" (riddle_get reports it) plus only the properties that change - {\"id\": 3, \"title\": \"New question title\"}. To ADD, pass \"$create\": true instead of an \"id\" plus everything a new block needs, the same shape the riddle_builder_<type> tool of this Riddle's type takes - {\"$create\": true, \"type\": \"SingleChoice\", \"title\": \"New question\", \"items\": [...]}. To REMOVE, pass \"id\" plus \"$delete\": true. A block cannot change its \"type\" in an edit (delete it and add a new one instead), and an unknown \"id\" is rejected with the list of IDs that do exist. The collections INSIDE a block work the same way wherever their entries have ids - {\"id\": 3, \"items\": [{\"id\": 2, \"title\": \"Bonn\"}]} renames one answer and leaves the others alone - and are replaced wholesale where they do not. Which collection is which, what an entry id is scoped to, why an entry without an \"id\" or \"$create\" is rejected, which deletes are refused for still being referenced (custom logic, a hotspot's \"goToImage:\"), and which rules are checked against the merge result rather than against what you sent: riddle://reference/concepts/merge-semantics, with the marker rules themselves in riddle://reference/concepts/editing." - changed
Input schema / properties / build / properties / personalities / descriptionPrevious value: -"Personality Test only. The personalities to change, add or remove - only the ones you touch, everything else stays as it is, merged entry-by-entry by \"id\" exactly like the Riddle's own \"blocks\" (see EDIT_BLOCKS). To EDIT, pass the personality's \"id\" (riddle_get reports it) plus only the properties that change. To ADD, pass \"$create\": true instead of an \"id\" plus everything a new personality needs (the same shape riddle_builder_personality takes). To REMOVE, pass \"id\" plus \"$delete\": true. An entry with no \"id\" and no \"$create\" is rejected the same way a block is - it has no \"id\"; add \"$create\": true to add it as a new one instead. Reorder with \"$personalitiesOrder\": the complete list of personality ids in the new order, the same way \"$blocksOrder\"/\"$itemsOrder\" work (see EDIT_BLOCKS_ORDER). The minimum of 2 personalities is checked against the result AFTER the merge, so a \"$delete\" that would leave fewer than 2 is rejected. The scores already stored on every answer item follow their personality BY IDENTITY, not by position: a personality that stays keeps its score wherever it ends up in the order, a deleted personality takes its scores with it, and a newly created personality starts at 0 on every existing answer item until you say otherwise - resend the affected blocks' \"items\" with their full \"scores\" arrays in the same call to set them yourself (that is applied after this and simply wins)."New value: +"Personality Test only. The personalities to change, add or remove - only the ones you touch, everything else stays as it is, merged entry-by-entry by \"id\" exactly like the Riddle's own \"blocks\" (see EDIT_BLOCKS). To EDIT, pass the personality's \"id\" (riddle_get reports it) plus only the properties that change. To ADD, pass \"$create\": true instead of an \"id\" plus everything a new personality needs (the same shape riddle_builder_personality takes). To REMOVE, pass \"id\" plus \"$delete\": true. An entry with no \"id\" and no \"$create\" is rejected the same way a block is - it has no \"id\"; add \"$create\": true to add it as a new one instead. The order of the personalities is NOT editable: there is no \"$personalitiesOrder\" (sending one is rejected) and, because this collection is merged by id, the order the entries are sent in has no meaning either - a \"$create\" is appended at the end and everything else keeps the place it has. Reorder them in the Creator if the order matters. The minimum of 2 personalities is checked against the result AFTER the merge, so a \"$delete\" that would leave fewer than 2 is rejected. The scores already stored on every answer item follow their personality BY IDENTITY, not by position: a personality that stays keeps its score, a deleted personality takes its scores with it, and a newly created personality starts at 0 on every existing answer item until you say otherwise - resend the affected blocks' \"items\" with their full \"scores\" arrays in the same call to set them yourself (that is applied after this and simply wins)." - changed
Input schema / properties / build / properties / results / descriptionPrevious value: -"New result pages (Quiz), same shape as in riddle_builder_quiz. Replaces ALL current result pages with what you send, in the order you send it. Result pages are deliberately not editable and not reorderable: there is no \"$resultsOrder\" marker, no \"$create\"/\"$delete\" on an entry, and a page's \"id\" does not address it for a partial update - a score window, its blocks and the answers it reveals only make sense as one consistent set. Read them with riddle_get first and resend every page you want to keep, including its \"id\", which is honored to keep the page stable across the resend. Omit the field to keep all result pages untouched."New value: +"New result pages (Quiz), same shape as in riddle_builder_quiz. Replaces ALL current result pages with what you send, in the order you send it: result pages are deliberately neither editable per entry nor reorderable, so read them with riddle_get first and resend every page you want to keep, including its \"id\", which is honored to keep the page stable across the resend. Omit the field to keep all result pages untouched. Why, and which markers are rejected on a page: riddle://reference/concepts/result-pages." - changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/riddle-builder/block-defaults states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."New value: +"Leaves parts of the returned envelope out. Values: \"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole sections) and \"build.omittedDefaults\" (the per-block maps of properties left at their default, inside every build config in the response). Omit for the whole envelope. \"uuid\"/\"type\"/\"modifiedAt\" are always returned. Reach for omit: [\"build.omittedDefaults\"] on almost every build - it drops ~85-90% of the read-back and loses nothing, since riddle://reference/block-defaults/<block type> states the same defaults; what you must not do either way is resend those values. When you leave anything out the response names it under \"omittedFields\", so a missing key never means the Riddle has none of it. Same parameter as riddle_get's."
- Changed
riddle_builder_validate1 field changed- changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves the per-block \"omittedDefaults\" maps out of every echoed-back build config, for a much smaller answer: omit: [\"build.omittedDefaults\"]. The same defaults are stated per Riddle type and block type in riddle://reference/riddle-builder/block-defaults, so nothing is lost - what you must not do either way is resend those values. Omit the parameter to keep them. The other values of riddle_get's \"omit\" do not apply here: this envelope has no sections to drop."New value: +"Leaves the per-block \"omittedDefaults\" maps out of every echoed-back build config, for a much smaller answer: omit: [\"build.omittedDefaults\"]. The same defaults are stated in riddle://reference/riddle-defaults/<riddle type> and riddle://reference/block-defaults/<block type>, so nothing is lost - what you must not do either way is resend those values. Omit the parameter to keep them. The other values of riddle_get's \"omit\" do not apply here: this envelope has no sections to drop."
- Changed
riddle_get1 field changed- changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the response out - the one way to make this call smaller. Valid values:\n\"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole envelope sections) and\n\"build.omittedDefaults\" (the per-block \"omittedDefaults\" maps inside every build\nconfiguration in the response, including \"published.build\" - not a section, but by far\nthe largest part of one). Omit the parameter, or pass [], for everything;\n\"uuid\"/\"type\"/\"modifiedAt\" are always present and cannot be left out.\nWhich value to reach for: \"build.omittedDefaults\" shrinks a read-back by ~85-90% and\nloses no information, since riddle://reference/riddle-builder/block-defaults states the\nvery same defaults per Riddle type and block type - the right default for any call that\ndoes not specifically need to know which properties sit at their default. Whole sections\nare worth naming when you truly do not need them: \"published\" is a second full build\nconfiguration whenever the draft has unpublished changes (about half the response),\nwhile \"warnings\"/\"nextBlockId\"/\"context\" together are only a few percent of it - though\nleaving out \"published\" also skips re-serializing the live version entirely, and\n\"context\" skips that section's extra lookups (features/origin, cover image, preset\ndiff), so the saving is in work as well as bytes.\nWhatever you leave out is echoed back in \"omittedFields\", so a key missing from the\nresponse never has to be read as \"this Riddle has none of that\", only as \"I asked for it\nto be left out\"; a call that omitted nothing carries no such key. With UUIDs, the same\nomissions apply to every entry."New value: +"Leaves parts of the response out - the one way to make this call smaller. Valid values:\n\"build\", \"warnings\", \"nextBlockId\", \"published\", \"context\" (whole envelope sections) and\n\"build.omittedDefaults\" (the per-block \"omittedDefaults\" maps inside every build\nconfiguration in the response, including \"published.build\" - not a section, but by far\nthe largest part of one). Omit the parameter, or pass [], for everything;\n\"uuid\"/\"type\"/\"modifiedAt\" are always present and cannot be left out.\nWhich value to reach for: \"build.omittedDefaults\" shrinks a read-back by ~85-90% and\nloses no information, since riddle://reference/block-defaults/<block type> and\nriddle://reference/riddle-defaults/<riddle type> state the very same defaults - the right\ndefault for any call that does not specifically need to know which properties sit at\ntheir default. Whole sections\nare worth naming when you truly do not need them: \"published\" is a second full build\nconfiguration whenever the draft has unpublished changes (about half the response),\nwhile \"warnings\"/\"nextBlockId\"/\"context\" together are only a few percent of it - though\nleaving out \"published\" also skips re-serializing the live version entirely, and\n\"context\" skips that section's extra lookups (features/origin, cover image, preset\ndiff), so the saving is in work as well as bytes.\nWhatever you leave out is echoed back in \"omittedFields\", so a key missing from the\nresponse never has to be read as \"this Riddle has none of that\", only as \"I asked for it\nto be left out\"; a call that omitted nothing carries no such key. With UUIDs, the same\nomissions apply to every entry."
- Changed
riddleTemplate_get1 field changed- changed
Input schema / properties / omit / descriptionPrevious value: -"Leaves parts of the response out. The only value with anything to leave out here is \"build.omittedDefaults\": every block then loses its \"omittedDefaults\" map (the properties left out for still being at their default, with the value each one is at), for a much smaller response. Nothing is lost by it: the same defaults are stated per Riddle type and block type in riddle://reference/riddle-builder/block-defaults - and a value read there must not be resent as the property either way. Same parameter as riddle_get's; its section values do not apply here, this envelope has no such sections."New value: +"Leaves parts of the response out. The only value with anything to leave out here is \"build.omittedDefaults\": every block then loses its \"omittedDefaults\" map (the properties left out for still being at their default, with the value each one is at), for a much smaller response. Nothing is lost by it: the same defaults are stated in riddle://reference/riddle-defaults/<riddle type> and riddle://reference/block-defaults/<block type> - and a value read there must not be resent as the property either way. Same parameter as riddle_get's; its section values do not apply here, this envelope has no such sections."
62 tool updates
- First observed
palette_customize - First observed
palette_get - First observed
ping - First observed
project_get - First observed
project_get_settings - First observed
project_list - First observed
questionBank_addItem - First observed
questionBank_addTag - First observed
questionBank_blockTypeColumns - First observed
questionBank_create - First observed
questionBank_delete - First observed
questionBank_deleteItem - First observed
questionBank_discardChanges - First observed
questionBank_duplicate - First observed
questionBank_get - First observed
questionBank_getItems - First observed
questionBank_list - First observed
questionBank_publish - First observed
questionBank_removeTag - First observed
questionBank_rename - First observed
questionBank_riddleBlockItems - First observed
questionBank_tagList - First observed
questionBank_templateList - First observed
questionBank_updateItem - First observed
questionBank_updateNotes - First observed
reference_get - First observed
riddle_account_list - First observed
riddle_builder_form - First observed
riddle_builder_leaderboard - First observed
riddle_builder_minigame - First observed
riddle_builder_personality - First observed
riddle_builder_placeholder - First observed
riddle_builder_poll - First observed
riddle_builder_predictor - First observed
riddle_builder_quiz - First observed
riddle_builder_story - First observed
riddle_builder_update - First observed
riddle_builder_validate - First observed
riddle_delete - First observed
riddle_get - First observed
riddle_get_embed_code - First observed
riddle_list - First observed
riddle_move - First observed
riddle_move_check - First observed
riddle_publish - First observed
riddle_qr_code - First observed
riddle_rename - First observed
riddle_tag_add - First observed
riddle_tag_list - First observed
riddle_tag_remove - First observed
riddle_unpublish - First observed
riddleTemplate_create - First observed
riddleTemplate_get - First observed
riddleTemplate_list - First observed
riddleTemplate_publicList - First observed
riddleTemplate_use - First observed
stats_fetch - First observed
stats_overview_fetch - First observed
stats_project_breakdown - First observed
stats_riddle_breakdown - First observed
stats_user_breakdown - First observed
whoami
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user, then choose Claim with GitHub. An organization namespace such asio.github.acme/serveralso needs that organization to have installed the Glama AI GitHub App and approved its permissions, because GitHub discloses organization membership only to apps it has installed. Use HTTP or DNS when it has not.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Connectors
Create forms, surveys, quizzes & polls — publish shareable links and analyze responses.
Build, publish and read scored forms and quizzes where the score picks the next screen.
Create and manage Google Forms to run surveys and collect data. Add text and multiple-choice quest…
Real-time polls, surveys, quizzes, trivia, Q&A, and word clouds for teams, educators, and creators.
Related MCP Servers
- AlicenseAqualityBmaintenanceCreate and manage quizzes, question banks, and translations; capture and manage leads, respondents, and bookings; and pull stats and funnel analytics on RooQuiz — a lightweight assessment platform for lead capture and viral sharing.521MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI assistants to create, manage, and analyze Google Forms with all question types, sections, quiz mode, and Google Drive/Sheets integration.11MIT
- AlicenseNot gradedqualityDmaintenanceEnables creation and management of Google Forms with support for all 12 question types, response collection, CSV export, and form publishing through OAuth-authenticated API access.2MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to build and operate production-ready forms, quizzes, surveys, and workflows, including creation, publishing, submission management, and integration with webhooks and analytics.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Each tool is scoped to a distinct resource/action area: media, palettes, projects, question banks, Riddles, templates, tags, stats, and support. Potentially close pairs like riddle_tag/riddle_tag_delete and question_bank_delete/question_bank_manage are cleanly separated by their descriptions, so an agent can reliably select the right one.
The naming is mostly consistent snake_case with strong resource prefixes like riddle_, question_bank_, and template_, followed by clear verbs. Minor deviations such as question_bank_item, riddle_tag, and stats_fetch break the strict verb-noun pattern but remain predictable once the convention is understood.
At 38 tools this is a heavy surface, though the breadth is justified by the many subdomains the server covers: media, palettes, projects, question banks, Riddles, templates, tags, and stats. Most tools earn their place, but the count sits above the range where an agent can quickly survey all options.
The set covers the full lifecycle for Riddles, question banks, templates, and tags, including publish/unpublish, move, stats, and media upload/delete. Minor gaps like no media library listing and read-only project settings are workable because media IDs come from upload responses and project permissions are exposed.