Riddle Quiz Maker
Server Details
Riddle.com is a no-code platform for quizzes, surveys, personality tests, prediction games, interactive graphics, and leaderboards. Use the MCP to create, edit and analyze content.
- Status
- Healthy
- Uptime
- 100.0% over the last 24 hours
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-06-18
- URL
- ChatGPT
- –
- Claude
- Riddle
TDQS
Scored across 48 tools
The set is large but each tool has a sharply delimited scope, and the descriptions go out of their way to contrast near neighbors (riddle_builder_update vs palette_customize, question_bank_publish vs riddle_publish, question_bank_item_delete vs question_bank_delete, riddle_tag_delete vs riddle_tag_remove). A few pairs still require careful reading to separate — riddle_builder_create vs riddle_template_use vs riddle_template_create all produce Riddles, and riddle_get vs riddle_get_embed_code / riddle_preview overlap in 'show me the Riddle' territory — but an agent can resolve them from the text.
Nearly everything is snake_case in a resource_action shape (riddle_list, riddle_publish, question_bank_item_add, palette_get, project_get_settings), so tool families are visually grouped and predictable. Deviations are minor: multi-segment names like riddle_get_embed_code and riddle_template_public_list insert qualifiers mid-name, and utility tools ping/whoami break the pattern, but nothing is chaotic or camelCased.
48 tools is heavy by any measure, and a meaningful share is lifecycle bookkeeping (five question-bank tag/notes/discard tools, four template tools, three project tools) rather than core workflow. The underlying product is genuinely broad — nine Riddle types, banks, templates, media, stats, tags, integrations — so the count is defensible, but it sits well past the comfortable range and raises selection cost for an agent.
Core workflows are fully covered: Riddle create/update/validate/read/list/delete/rename/publish/preview, full question-bank CRUD plus draft/publish/discard semantics, template create/read/list/update/use, tag management, media upload and delete, stats, projects and integrations. Notable gaps remain — no media library listing or media_get, integrations are read-only (list with no connect/disconnect), no project create/update, and no template delete — but each has a documented workaround (e.g. Creator for Sheets setup).
Available Tools
48 toolsintegration_listARead-onlyIdempotentInspect
Lists the Google Sheets and webhook integrations of a project as {items: [{id, type, name, connectedRiddles}]}. "name" is the value a build takes as publish.integrations.googlesheets / .webhook to connect that integration to a Riddle. A Google Sheet can only be connected in the Creator - with none listed, ask the user to add one there. A Riddle with a FileUpload form field cannot be published without a Google Sheets integration. Reads the stored records only - contacts neither Google nor any webhook.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Only this kind. Omit for both. | |
| projectId | No | The project (team) ID, as returned by project_list. Omit for the project the API key is scoped to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations it adds real behavioral context: 'Reads the stored records only - contacts neither Google nor any webhook,' which tells the agent it is a pure local read and cannot diagnose connectivity. It also discloses that a Google Sheet can only be connected in the Creator, a constraint the annotations cannot express.
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?
Front-loads the purpose, then layers the return shape and two practical constraints in four tight sentences. The inline object notation is slightly dense but earns its place because there is no 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?
With no output schema, the description compensates by naming the returned fields, and it covers the publish-integration workflow and the empty-list case. Nothing an agent needs to call this correctly or interpret the result 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% and both parameters (type enum, projectId with default) are already documented in the schema, so the description's mention of googlesheets/webhook filtering is largely redundant. Baseline 3 applies since the schema does the heavy lifting.
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 ('Lists the Google Sheets and webhook integrations of a project') and even sketches the returned item shape and fields. An agent can tell immediately this is the read path for integration records, not a create/connect operation.
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?
Explains the downstream purpose — the returned 'name' is what a build takes as publish.integrations.googlesheets/.webhook — and gives a concrete fallback when the list is empty (ask the user to add the Sheet in the Creator). It also flags the publishing precondition for FileUpload riddles, though it never states an explicit when-not-to-use condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
media_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}. Without full access only files in the "AI Uploads" folder (media_upload_link's destination): riddle://reference/concepts/access.
| 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. | |
| project | No | Project ID; NULL or omitted: your personal project (project API key: its project). A mediaId only resolves in its project - build in the same one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructive/not-idempotent annotations, the description adds substantial context: no undo, ids are not reused, dangling references stop resolving, refusals name the Riddles that block deletion, 'unused' is account-wide rather than per-Riddle, and a permission restriction limiting non-full-access callers to the AI Uploads folder.
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?
Dense but front-loaded: the action and permanence come first, then prerequisites, then the alternative workflow, then the return shape. It is a long single paragraph, but nearly every clause carries decision-relevant information.
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, the description supplies the return shape ({deleted, mediaId, name, type, size}), the failure mode when the file is still in use, and the permission caveat. An agent has everything needed to call it safely or route elsewhere.
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 already documents both mediaId and project, including that a mediaId only resolves in its project. The description adds little parameter-specific detail beyond the account-wide framing, so it sits at the 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?
States a specific verb and resource ('Deletes a file from the media library permanently') and scopes it as cleanup of an unwanted or erroneous upload. It is clearly distinguishable from media_upload_link and from riddle_delete, which act on different resources.
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 explicit when-to-use cases (wrong upload, file no longer wanted), the prerequisite (file must be unused), and the exact alternative workflow when the file is in use: remove it via riddle_builder_update, then riddle_publish, then delete. It also warns to ask the user before calling.
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). Pass the "project" you will build in. Returns {uploadUrl, expiresAt (UTC), singleUse, maxBytes, allowedTypes, project, 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, project}: "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", counts against their storage, and media_delete removes it again.
| Name | Required | Description | Default |
|---|---|---|---|
| project | No | Project ID; NULL or omitted: your personal project (project API key: its project). A mediaId only resolves in its project - build in the same one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say not-read-only, open-world, not-idempotent; the description adds the whole operational contract: 5-minute expiry, death on first use, 20-per-account-per-5-minutes rate limit, network allowlisting, and the file's eventual placement in the "AI Uploads" folder counting against storage. It also explains the download-twice failure mode and how media_delete reverses the effect, all consistent 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?
Front-loaded with the purpose and the key constraint, and nearly every sentence carries operational information (the curl example, the mediaId-only warning). It is a dense single block that would scan faster as short bullets, which is the only thing keeping it off 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?
Even without an output schema, the description enumerates both response shapes ({uploadUrl, expiresAt, singleUse, maxBytes, allowedTypes, project, usage, requiresNetworkAccessTo} and {mediaId, type, width, height, size, folderId, project}) and the downstream usage of mediaId. Nothing an agent needs in order to call this safely 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 "project" parameter already has 100% schema coverage, including the note that a mediaId only resolves in its own project. The description restates this ("Pass the project you will build in", "build in the same one") but adds no syntax, defaults, or edge cases beyond the schema, so baseline 3 is right.
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?
Specific verb and resource: "Creates a single-use link for uploading ONE media file into the media library." It also makes a scope distinction the sibling media_delete does not share, and the ONE/upload semantics are stated up front.
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?
Explicit when-to-use ("Call it when the user has a LOCAL file for a Riddle") and why-not alternatives ("this server cannot receive bytes, so the upload is yours"). It also gives ordering rules: check the file before minting, create one link immediately before each upload, batch one file at a time, and do not retry on network block.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
palette_customizeADestructiveInspect
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. 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. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| 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. | |
| 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?
Annotations already declare destructiveHint=true and idempotentHint=false, but the description adds substantial beyond-schema behavior: values are stored as an override on one Riddle only, built-in 'default:*' palettes are duplicated into a Riddle-owned copy, newPaletteName always operates on a copy, and modifiedAt/modifiedBy are not stamped. The only minor gap is it never explains what makes the call destructive or how overwriting an existing override behaves.
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?
Front-loaded with the core action and scope before the caveats, and no sentence is filler. It is on the long side, with the modifiedAt/drift detection paragraph dense enough that a shorter pointer to the concepts reference might have served.
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, nested-object mutation with no output schema, the description covers access prerequisites, copy/override semantics, the publish step, and change-detection signals — everything an agent needs to call it correctly and verify the result.
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 already 100%, so the baseline is 3, but the description earns extra: it explains that 'values' is a path=>value map with examples and that paths must come from the palette fields reference, and clarifies that newPaletteName applies changes to a copy leaving the original untouched. Minor omissions remain, e.g. how the 'select' flag interacts with an inherited preset.
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 ('Changes the palette ... of ONE Riddle') plus the fields it covers and the path=>value input shape. The scope contrast with siblings is explicit: it modifies a single Riddle while palette_get only reads, so an agent can route without opening the 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?
Gives concrete when-to-use context and prerequisites: paths come from palette_get or riddle://reference/palette/fields, a following riddle_publish is required for the change to reach the live embed, and the call is only valid when origin.writableByThisKey is true. It also tells the agent which detection signal to poll (context.modified.hasChanges) and warns that context.preset.drifted is unreliable alone.
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 establish readOnly/idempotent/non-destructive, so the bar is lower, but the description still adds real context the annotations don't: the response can run to thousands of tokens (~30 values per palette plus unrelated account presets), and omitted keys are echoed under omittedFields so a missing key never means absence. Strong disclosure, though it does not mention pagination or caching.
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?
Front-loaded with the core read, then the size warning and the omit mechanics, then the single-palette shortcut. Efficient and purposeful, though it restates some of the omit semantics already present in the schema and runs long enough to be dense for a 4-parameter tool.
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 4 parameters, the description carries the burden and does so: it describes the shape of the response, the fields worth dropping, the size risk, and the path to a minimal read. Nothing needed to call 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 coverage is 100%, so the baseline is 3, but the description goes further by explaining how the parameters interact as a workflow (omit paletteValues → list by uuid/name → feed paletteUUID), which the schema documents only in isolation. It does not add format or syntax detail beyond the schema for the individual fields.
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 ('Reads the palettes ... of a Riddle') and enumerates exactly what comes back: all usable palettes including inherited account/project presets, the selected one, overridden values, and built-ins. An agent can distinguish it from palette_customize (write) without opening 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?
Gives explicit routing: use omit:["paletteValues"] to find WHICH palette you want, then paletteUUID to read it in full, and selectedPaletteUuid to read just the design in effect. It also names the field reference doc for value semantics. Nothing about when to pick which mode is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingARead-onlyIdempotentInspect
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, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description still adds value beyond them by stating that a call exercises authentication as well as connectivity, which is the non-obvious behavioral property of this endpoint. An output schema exists, so return format needn't be explained.
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 short sentences, front-loaded with the behavior and followed by the use case. The opening "A simple tool that" is minor padding but does not obscure the payload.
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 parameterless health-check tool with full annotations and an output schema, the description covers everything an agent needs: what it returns and what calling it verifies. No gap remains that would cause a misinvocation.
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 takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool applies. Nothing in the description contradicts the empty 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?
States a specific behavior (returns "Pong") and resource (the MCP connection), which is unambiguous and unlike any sibling tool in the list. The only weak point is the filler phrase "A simple tool" at the start, but the operative clause is precise.
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 says when to use it: to test connectivity and authentication to the MCP. Clear usage context with no ambiguity; no exclusion clauses are needed because no sibling competes for this job.
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, idempotentHint, and openWorldHint=false, so the safety profile is covered. The description adds genuinely new scope information: the large nested default-settings tree is deliberately excluded and lives in another tool, which prevents a wrong-tool call. It stops short of describing the permission matrix shape or failure modes for a bad id.
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 short sentences, front-loaded with the payload description, then id sourcing, then the exclusion. No filler, and the negative scoping is stated rather than left to inference.
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 compensates by naming the returned fields. For a one-parameter read tool with full annotation coverage, nothing needed to call 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 coverage is 100% with a single documented projectId, so the baseline is 3. The description adds provenance for that id (project_list or riddle_get's team), which tells the agent how to obtain a valid value rather than just its type.
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?
Specific verb+resource (returns one project by id) with the returned fields enumerated (id, name, image, permission matrix). It explicitly distinguishes itself from the sibling project_get_settings by stating what is 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?
States where the required id comes from ('project_list or the "team" of riddle_get') and routes the agent to project_get_settings when the default Riddle settings tree is actually wanted. Both the when and the when-not are explicit, with named alternatives.
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?
Annotations cover only the safety profile (readOnly, idempotent, non-destructive); the description goes well beyond them by disclosing exclusions (never-published drafts, disabled areas), the internal _ids stripping, and the shape guarantee that both fields are always objects and an empty project yields {} rather than an empty list. This is exactly the non-obvious behavioral context annotations cannot carry.
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?
Front-loaded with the core purpose, and every clause is substantive (scope, exclusions, shape guarantees, sibling pointer). It is dense and long-winded in places, with parenthetical enumerations that could be trimmed, but no sentence is 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?
With no output schema, the description carries the full burden of describing return values, and it does: field names, keying scheme, empty-case behavior, and what is deliberately omitted. An agent has everything needed to call and interpret it.
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 is a single required parameter at 100% schema description coverage, so the schema already fully documents 'projectId'. The description adds no syntax or format detail beyond it, only content of the response, so the baseline of 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?
States a specific verb and resource ('Returns the default Riddle settings every new Riddle of the project starts from') and immediately scopes it to PUBLISHED/ENABLED content. An agent can distinguish it from project_get and riddle_get without opening any 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?
Explicitly tells the agent when to call it ('Read it to know what a project forces onto its Riddles before creating or editing one there') and names the cheaper alternative for a different need ('project_get is the cheap call for name, image and permissions'). It also states what it is not for (inspecting unpublished or disabled defaults).
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 cover the safety profile (readOnly, idempotent, non-destructive), and the description adds substantial context beyond them: the paging envelope shape, 25-per-page/100-max limits, that a project API token only returns its own project, and that invalid page/pageSize is rejected rather than clamped. These are behaviorally meaningful traits the annotations do not 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?
Front-loads the verb and resource, then layers in paging, entry shape, alternatives, and validation in a logical order. It is dense and slightly overloaded with the reference URI and parentheticals, but nearly every clause carries useful information.
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 carries the burden of describing returns and does so fully: envelope fields, per-page counts, and entry fields (id, name, image). It also covers the token-scope edge case and parameter validation, leaving nothing an agent needs in order 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%, so both parameters are already fully documented in the schema, including the rejection-not-clamping rule. The description reinforces the same paging defaults and validation semantics rather than adding new meaning, 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?
States a specific verb (Lists) and resource (projects) with an explicit scope qualifier (\"this token has access to\"). It names and differentiates the two sibling tools that operate on a single project (project_get adds permissions, project_get_settings adds default settings), so an agent can distinguish it without opening any 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?
Gives clear selection context: use project_list to page through many projects, use project_get/project_get_settings when you need one project's permissions or settings. It also notes the project-token scope limitation. No explicit when-not, but the routing to alternatives is unambiguous.
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_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. Needs full access: riddle://reference/concepts/access.
| 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 already declare readOnly=false, destructive=false, idempotent=false, and openWorld=false. The description adds important behavior beyond that: the bank starts empty, its type is fixed for life, it can only be referenced by matching Riddles in the same project, and full access is required.
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 the remaining sentences each add a needed constraint or workflow step. Nothing appears superfluous for a creation tool with cross-entity references.
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 key return value (the new bank's id) and how to use it in later calls. Annotations cover safety hints, and the description covers lifecycle, project scoping, type matching, and access requirements, leaving no material gap 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?
Schema description coverage is 100%, so all three parameters are already documented in the input schema, and the description largely restates the projectId and riddleType semantics rather than adding parameter-level detail. It does reinforce the projectId omission behavior and the cross-type reference restriction, but title semantics are left entirely to 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?
States a specific verb and resource ("Creates a new, empty question bank") and names the required Riddle type, clearly distinguishing it from sibling mutation tools like question_bank_item_add and question_bank_rename. An agent can identify the tool's job without opening the 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?
Gives an explicit workflow: create the bank, add items with question_bank_item_add, then reference the returned id as questionBankId on a riddle_builder_create call. It also spells out selection constraints — matching Riddle type and matching project — so alternatives and prerequisites are clear.
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 and every item it holds (its tags cleaned up exactly as question_bank_tag_remove does) - one item alone is question_bank_item_delete. 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. Permanent: there is no trash and no restore. Rejected for a public template id - a template is copied with question_bank_duplicate, never deleted. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| questionBankId | Yes | The ID of the question bank to delete. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, so the safety bar is partly covered — but the description goes well beyond: tag cleanup semantics matching question_bank_tag_remove, the counterintuitive DRAFT-vs-published-version reference counting (a block removed from a draft still holds the bank until republish), irreversibility ("no trash and no restore"), and the access requirement. These are non-obvious behaviors an agent cannot infer from structured fields.
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?
Front-loaded with the verb and blast radius, then layered with constraints; nearly every clause carries operational weight (error code, permanence, template rule, doc pointer). It is dense in a way that suits a destructive tool, though the DRAFT/republish parenthetical is long enough to slightly slow scanning.
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?
No output schema exists, so the description must carry the full burden — and it does: what is destroyed, what is cleaned up, what blocks it, what is permanent, what requires elevated access, and where to read more. Nothing material for a correct, safe 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?
Only one parameter (questionBankId) with 100% schema description coverage, so the schema fully documents it. The description adds no format, ID-source, or validation detail beyond it. Baseline 3 is appropriate when the schema does the work and nothing extra is offered.
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 ("Deletes a question bank") plus the cascade scope ("every item it holds"), and explicitly contrasts with the nearest sibling: "one item alone is question_bank_item_delete". An agent can distinguish this from question_bank_discard_changes, question_bank_item_delete, and riddle_delete without opening a 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?
Gives concrete when-not conditions with the exact rejection code (QUESTION_BANK_INTERDEPENDENCY) and an alternative path for templates ("a template is copied with question_bank_duplicate, never deleted"). It also points to a specific reference doc section to read before deleting, which is exactly the routing guidance an agent needs for a destructive operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_discard_changesADestructiveInspect
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_publish whenever the draft is what should survive. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| 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?
Goes well beyond destructiveHint=true: it discloses no undo, no copy of the discarded draft, that pending item deletes are resurrected while newly added items are untouched, that only items (not title/notes metadata) are affected, and the access requirement. These are exactly the non-obvious consequences an agent cannot get from 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?
Front-loaded with the destructive action and its irreversibility, then caveats, then scope limits, then alternatives. Dense but every sentence carries distinct semantic content (undo absence, item-delete resurrection, added-item exception, metadata exemption, access rule) with no 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?
For a single-param, idempotent-false destructive mutation with no output schema, the description covers blast radius, irreversibility, edge cases, preconditions, and safer alternatives. Nothing an agent needs to call it safely 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?
There is a single parameter with 100% schema description coverage, so the schema already defines questionBankId. The description adds no format, range, or sourcing guidance for the id beyond what the schema states, 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?
States a specific verb and resource with exact scope: discards every unpublished change to a question bank's items, resetting them to last published content. It explicitly distinguishes itself from question_bank_publish and from a general 'restore the bank' operation, so an agent can tell it apart from siblings 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?
Names concrete alternatives and the conditions that select them: read draft via question_bank_get_items vs published: true to compare sides, and 'prefer question_bank_publish whenever the draft is what should survive.' It also states an exclusion (rejected for public template ids) and an access prerequisite, leaving nothing 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_duplicateAInspect
Copies a question bank and all of its items into a new, independent bank (editing one never affects the other) in projectId or the key's project. The source is left untouched. This is the one write a public template id is accepted for, and the way to change a template: duplicate it and edit the copy. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | The title of the copy. | |
| projectId | No | The project (team) ID the copy should land in, as returned by project_list. Omit for the project the API key is scoped to. | |
| questionBankId | Yes | The ID of the question bank to copy - your own, or a template id from question_bank_list(scope: "templates"). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnly=false, idempotent=false, destructive=false), it discloses that the source is untouched, copies are fully independent, a template id is accepted only here, and full access is required with a reference link. This is meaningful context annotations don't provide.
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?
Front-loads the core copy behavior and independence guarantee before the template/permission notes. Dense but every sentence carries distinct information; slightly crowded by the access reference link.
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 non-destructive write with no output schema, the description covers result semantics (new independent bank, source preserved), the project fallback, and the access requirement—everything needed to invoke 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 baseline is 3; the description adds that projectId falls back to the key's project and that questionBankId may be a template id, reinforcing schema meaning without contradiction. Adds modest value over 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?
States a specific verb (copies) and resource (question bank + items) with the key property that the copy is independent and the source untouched. Clearly distinguishable from siblings like question_bank_rename, publish, or discard_changes.
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 tells the agent this is the accepted route for a public template id and the way to edit a template (duplicate then edit the copy). This reserves the tool for a named scenario and directs away from trying other mutations.
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_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?
Annotations already declare readOnly/idempotent/non-destructive, yet the description adds substantial behavioral context beyond them: a template reads back without owner/tags/notes and belongs to nobody, and the draft-vs-published discrepancy between 'categories' and 'blockTypeCategoryMap' is explained. This is exactly the kind of nuance structured fields cannot carry.
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?
Front-loads the core retrieval statement and what's returned, then tacks on the template and categories caveats. It is somewhat dense with quoted field names, but each sentence conveys distinct, non-redundant information.
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?
No output schema exists, and the description compensates by naming the returned fields, clarifying the exclusion of items, and explaining the two category representations. An agent has everything needed to call it and interpret the result 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 the single parameter's description already explains it comes from question_bank_create/list or a template. The description reinforces the template-id case but adds no syntax or format detail the schema lacks, 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?
States a specific verb and resource ('Retrieves one question bank by id') and enumerates exactly what is returned: title, riddleType, tags, notes, categories/blockTypes, unpublished-changes flag. It explicitly disambiguates from the sibling question_bank_get_items, so an agent can distinguish the two 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?
Gives a concrete usage scenario: call on a built-in template id obtained from question_bank_list(scope: "templates") to inspect contents before duplicating. That covers the primary when-to-use, though it doesn't spell out exclusions or the full set of sibling alternatives (e.g., when to prefer question_bank_list).
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 declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds real value beyond that: it discloses that published items are a different set and the pool a live Riddle actually draws from, gives the response envelope shape, and warns that some response fields are intentionally omitted (pointing to a reference doc). It stops short of full detail on the omission semantics itself.
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?
Purpose and the draft/published distinction are front-loaded, and every clause carries information (filters, template preview, pagination shape, reference pointer). It is dense and em-dash-heavy in one block, which slightly hurts scannability, but there is little waste.
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 an 8-parameter read tool with no output schema, the description supplies the response envelope and routing to a reference resource for item shape and omissions, plus the counting recipe. The main residual gap is that the item shape and 'what the response leaves out' are deferred entirely to an external URI the agent may not resolve.
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 meaning the schema does not: the filters are 'the same filters a QuestionBank block draws with', a template id is a valid questionBankId, and it documents a non-obvious counting pattern (blockType/category/difficultyRange with pageSize: 1, then read 'total'). That is genuine semantics beyond the field docs.
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 ('Lists the items of a question bank') and immediately distinguishes the two content sets it can return (draft vs published). An agent can tell this apart from siblings like question_bank_get and question_bank_item without opening any 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?
Explicitly covers when to use the default (draft content), when to switch (published: true), and names an alternative workflow ('a template id from question_bank_list(scope: "templates") reads too - that is how to preview its questions before duplicating it'). It also explains what the filters mirror, so the agent knows the intended context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_item_addAInspect
Adds ONE new question/item to a question bank; nothing existing is changed (question_bank_item_update replaces an item, question_bank_item_delete removes one). 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). The item lands in the bank's DRAFT - question_bank_publish is what makes it something a QuestionBank block draws. "hasChanges" in the response says whether the bank now has unpublished changes. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| columns | Yes | 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). | |
| category | Yes | The item's category - free text, used to filter what a QuestionBank block draws (see the "questionBankCriteria" of the QuestionBank block type). | |
| blockType | Yes | 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. | |
| difficulty | Yes | The item's difficulty, 1-10 - also used to filter what a QuestionBank block draws. | |
| questionBankId | Yes | The ID of the question bank to add the item to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover safety (readOnly=false, destructive=false, idempotent=false) but not lifecycle; the description supplies that the item lands in DRAFT, that question_bank_publish is required before a QuestionBank block draws it, that 'hasChanges' reports unpublished state, and that full access is required. It even disambiguates that blockTypeColumns is a document, not a tool - a real trap for an agent.
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?
Front-loaded with the action and sibling disambiguation, then prerequisites, then behavior. Dense and mostly waste-free, though the parenthetical about blockTypeColumns being a document and the response-field aside make it slightly longer than strictly needed.
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 mutation tool with no output schema, the description covers lifecycle (draft vs published), the response field an agent should check, permission requirements, rejection cases, and the schema-discovery prerequisite. Nothing essential to calling 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 coverage is 100%, so the baseline is 3 and the nested 'columns' shape is already documented in detail. The description contributes beyond the schema by warning that there is no universal item shape and pointing at the exact reference document that enumerates valid blockType values and their expected column names.
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 ('Adds ONE new question/item to a question bank') and immediately distinguishes itself from the two nearest siblings by naming question_bank_item_update as the replace path and question_bank_item_delete as the remove path. The 'ONE' emphasis clarifies that this is not a bulk operation.
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 explicit when-to-use routing against both alternatives, a concrete prerequisite ('read riddle://reference/question-bank/block-type-columns before the first add into a bank you have not populated'), and a hard exclusion ('Rejected for a public template id'). The access prerequisite is stated rather than implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_item_deleteADestructiveInspect
Deletes ONE question/item of a question bank 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_publish purges it, and question_bank_discard_changes brings it back until then. Permanent once purged: there is no trash and no restore. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| questionBankId | Yes | The ID of the question bank the item belongs to. | |
| questionBankItemId | Yes | The ID of the item to delete, as returned by question_bank_get_items or question_bank_item_add. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds substantial context beyond the destructiveHint annotation: immediate permanent deletion for unpublished items, draft-only removal for published items, live Riddle dependency until purge, restore via discard changes, no trash/restore, and access requirements. It is fully consistent 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 dense but front-loaded and every sentence carries operational meaning. It communicates destructive consequences, related siblings, access needs, and rejection conditions without 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?
For a destructive mutation tool with no output schema and fully covered parameters, the description provides the critical missing behavioral context: permanence, draft semantics, dependency on publish, restore path, and access requirements.
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 both parameters are already well documented in the schema. The description reinforces that only one item is deleted but does not add syntax or format details beyond the structured parameter definitions.
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: deletes exactly one question bank item and touches nothing else. It clearly distinguishes this from sibling operations like question_bank_delete, question_bank_publish, and question_bank_discard_changes.
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 explains the key conditional behavior for never-published versus published items and explicitly names question_bank_publish and question_bank_discard_changes as the operations that affect the item afterward. It also states access requirements and the public-template rejection condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_item_updateADestructiveInspect
Replaces the content of ONE existing question/item of a question bank entirely - not a merge: blockType, category, difficulty and columns must all be sent even when unchanged, and a column or value left out is gone from the draft. blockType is immutable: a different value is rejected rather than retyping the item (delete it with question_bank_item_delete and add a new one instead). Read the item with question_bank_get_items first and send it back with its value ids intact. The change lands in the bank's DRAFT - question_bank_publish makes it live, 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. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| columns | Yes | The question content, as {columnName: [values]}. 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 | Yes | The item's category - free text, used to filter what a QuestionBank block draws. | |
| blockType | Yes | The item's current block type, sent back unchanged (question_bank_get_items returns it). Immutable: a different value is rejected. | |
| difficulty | Yes | 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 | Yes | The ID of the item to update, as returned by question_bank_item_add/question_bank_get_items. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark the tool destructive and non-idempotent, and the description adds substantial context beyond that: omitted columns or values are deleted, blockType is immutable, changes land only in the draft, and hasChanges indicates whether unpublished changes exist. It also discloses access requirements and public-template rejection.
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 the core replace-not-merge behavior, then covers prerequisites, immutability, draft workflow, and access constraints. Every sentence contributes operational detail without redundant repetition.
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 mutation tool with no output schema, the description is complete enough: it explains replacement semantics, required fields, draft visibility, publish/discard lifecycle, immutable blockType, response hasChanges, access needs, and template restrictions.
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 carries most parameter meaning. The description still adds useful semantics by emphasizing that all four content fields must be sent even when unchanged, that omitted values are removed, and that value ids must be preserved to edit existing values rather than replace them.
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: it replaces the content of ONE existing question bank item entirely, and explicitly says this is not a merge. It distinguishes the operation from alternatives such as question_bank_item_delete plus question_bank_item_add when blockType must change.
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 usage instructions: read with question_bank_get_items first, send back every field and value id, use question_bank_publish to make changes live, and use question_bank_discard_changes to throw away unpublished changes. It also names the alternative workflow for immutable blockType changes and notes rejection 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_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_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?
Although annotations already declare a safe read-only and idempotent operation, the description adds important behavior: pagination shape, template-specific itemCount versus draftItemCount semantics, and the rule that every write rejects a template id. Those details materially affect how an agent interprets and uses the results.
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 distinction between own and template scopes, and most sentences carry useful caveats. It is dense and somewhat long for a list tool, with some repetition of schema-level scope and projectId behavior, but not enough to obscure the key 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?
There is no output schema, so the description must explain return shape; it does so by naming pagination fields, template-specific fields, null blockTypes behavior, and category examples. It also covers the critical template caveat and pre-duplication verification flow, making it complete 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?
Schema coverage is 100%, so parameter basics are already documented. The description adds cross-parameter context, especially that templates take only riddleType and are not pageable or searchable, but it largely restates the scope and projectId semantics from 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 question banks") and immediately distinguishes the two listing scopes, own project banks versus built-in templates. It also names the related duplication and read tools, so an agent can understand its role without opening sibling 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?
It gives explicit selection rules: use scope "own" for a project's banks, pass projectId to inspect another project, omit it for the key-scoped project, and use scope "templates" for starter banks. It also routes the agent to question_bank_get, question_bank_get_items, and question_bank_duplicate before copying a template.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_publishADestructiveInspect
Makes every item's draft content its published content - what a QuestionBank block of a live Riddle actually draws at view time - so the change reaches participants immediately: every Riddle using the bank is republished and re-draws its questions, even when nothing changed. The previously published content of each item is overwritten, and a pending item delete (question_bank_item_delete on a published item) is purged for good at this point. A bank with unpublished changes still works in a block, it just draws its last published state; question_bank_discard_changes is the opposite step. Read question_bank_get_items with and without published: true first when unsure what will change. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| questionBankId | Yes | The ID of the question bank to publish. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, but the description adds substantive context beyond them: previously published content is overwritten, a pending item delete is purged permanently, and every Riddle using the bank is republished even when nothing changed. It also discloses auth requirements (full access, with a reference path) and the public-template rejection, which no annotation conveys.
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?
Front-loaded with the core action and what changes at view time, then layers consequences, the alternative, and prerequisites. It is dense and mostly waste-free, though the run-on first sentence and the access-reference tail could be tightened.
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 mutation with no output schema, the description covers consequences (overwrite, purge), scope of side effects (all Riddles using the bank), pre-flight verification, auth requirements, and failure conditions. Nothing an agent needs to invoke it safely 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?
There is a single parameter with 100% schema description coverage, so the schema fully documents questionBankId. The description adds no format or syntax detail about the ID itself; per the high-coverage 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?
States a specific verb+resource ('Makes every item's draft content its published content') and immediately grounds it in the domain ('what a QuestionBank block of a live Riddle actually draws at view time'). It also names the opposite operation, question_bank_discard_changes, so the agent can distinguish it from the sibling without opening 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?
Explicit when-to-use guidance: 'Read question_bank_get_items with and without published: true first when unsure what will change.' It also gives exclusion conditions ('Rejected for a public template id') and points at the inverse sibling, which covers when-not-to-use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_renameADestructiveInspect
Sets the title of a question bank. The title is metadata rather than DRAFT content, so it takes effect immediately AND permanently, is unaffected by publishing or discarding and never counts as an unpublished change. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | The new title. | |
| questionBankId | Yes | The ID of the question bank to rename. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that the change is immediate and permanent, is untouched by publishing or discarding, never counts as an unpublished change, and fails on public template ids. It also names the authorization requirement and points at the access reference. That is exactly the kind of side-effect and permission context an agent cannot infer from destructiveHint/idempotentHint 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?
Front-loaded with the core action in the first sentence, then the side-effect, then the failure/authorization constraints. Efficient overall, though the capitalized "AND permanently" emphasis and the run-on middle sentence are slightly noisier than needed.
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 two-parameter, non-open-world mutation with full schema coverage and annotations declaring the safety profile, this covers side effects, permissions, and the main rejection case. Only the return behavior and behavior on a nonexistent id are left unstated, which is minor since no output schema exists.
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 real meaning to the `title` parameter by classifying it as metadata rather than DRAFT content and spelling out the consequences of that classification. `questionBankId` gains only the implicit constraint that public template ids are rejected.
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 ("Sets the title of a question bank") and immediately differentiates itself from the publishing/draft workflow siblings by explaining that the title is metadata rather than DRAFT content. An agent can distinguish this from question_bank_publish, question_bank_discard_changes, and question_bank_update_notes without opening any 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?
Gives two concrete preconditions that select or block use: it is "Rejected for a public template id" and "Needs full access" with a reference pointer. It does not explicitly contrast with nearby siblings such as question_bank_create or question_bank_duplicate, but the context is clear enough to place the call correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_tag_addAIdempotentInspect
Adds a tag to a question bank, by tagName or tagId from riddle_tag_list - exactly one of the two, as riddle_tag_add 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_list. Reuses the project's tag of that name or creates it, and re-tagging changes nothing. question_bank_tag_remove takes it off again. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| tagId | No | The ID of an existing tag, as returned by riddle_tag_list. Pass either this or tagName. | |
| tagName | No | The name of the tag. The project's tag of that name is reused, or created if there is none yet. Pass either this or tagId. | |
| questionBankId | Yes | The ID of the question bank to tag. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, so the bar is lower, yet the description still adds genuine context: reuse-or-create semantics, 're-tagging changes nothing', rejection on public templates, and the 'Needs full access' auth requirement with a reference link. No contradictions 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?
Front-loaded with the action and the exclusivity constraint, and every sentence carries information. Slightly long in the middle where the one-set-per-project explanation is repeated ('which is why the ids come from riddle_tag_list').
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 3-parameter mutation with no output schema, the description covers the mutation profile, idempotency, error conditions (public template), and auth requirements. What it returns is implicit but low-risk given the idempotent, additive nature.
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 earns above that by restating the oneOf constraint and explaining create-if-absent behavior for tagName. It does not spell out format/ID expectations for questionBankId, keeping it just shy of 5.
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: 'Adds a tag to a question bank', and immediately distinguishes itself from the closely-named siblings riddle_tag_add and question_bank_tag_remove. An agent can select it without opening any 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?
Explicit when-to-use and how: 'exactly one of the two' (tagName or tagId), ids sourced from riddle_tag_list, removal routed to question_bank_tag_remove. It also names an exclusion ('Rejected for a public template id') and the access prerequisite.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_tag_removeADestructiveInspect
Removes a tag from a question bank, by tagName or tagId from riddle_tag_list - exactly one of the two. Never creates anything: a tag the bank does not carry is an error. 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 takes the tag off THIS bank; riddle_tag_delete removes the label from the project itself. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| tagId | No | The ID of an existing tag, as returned by riddle_tag_list. Pass either this or tagName. | |
| tagName | No | The name of the tag. Nothing is ever created; a name the bank does not carry is an error. Pass either this or tagId. | |
| questionBankId | Yes | The ID of the question bank to untag. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already flagging destructiveHint=true, the description adds non-obvious cascade semantics: an orphaned tag is deleted from the project only if neither banks nor Riddles use it, and bank deletion cleans up the same way. It also discloses that a missing tag is an error rather than a create, and the full-access prerequisite.
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 packs a lot of high-value edge-case detail into tight sentences. The cascade explanation is dense but each clause carries distinct behavioral information; slightly heavier than ideal for a three-parameter tool.
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 mutation with cascade effects and no output schema, the description covers error conditions, the exact scope of mutation, the cleanup rule, the access requirement, and the sibling tool to use for project-level deletion. Nothing needed to call it safely 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 that the two identifier parameters are mutually exclusive and that tagName lookups never create. The schema already encodes the oneOf constraint, limiting the added value.
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 ('Removes a tag from a question bank') and immediately clarifies the two lookup modes. It clearly distinguishes itself from riddle_tag_delete and riddle_tag_remove by scoping the effect to THIS bank.
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 the exactly-one-of rule, points to riddle_tag_list as the source of valid values, and contrasts with riddle_tag_delete for project-wide removal. It also notes rejection for a public template id and the required access scope. It stops short of explicitly calling out riddle_tag_remove as the riddle-level alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
question_bank_update_notesADestructiveInspect
Replaces the plain-text maintainer notes of a question bank (never shown to participants) - the previous notes are overwritten entirely, not appended to, so read them with question_bank_get first and send everything that should remain. Notes are metadata rather than DRAFT content: the change takes effect immediately AND permanently, is unaffected by publishing or discarding and never counts as an unpublished change. Rejected for a public template id. Needs full access: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | Yes | Plain-text notes for this bank, e.g. sourcing/curation instructions - replaces any existing notes entirely. | |
| questionBankId | Yes | The ID of the question bank to annotate. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond destructiveHint=true by disclosing that previous notes are overwritten entirely (not appended), that the change is immediate and permanent, and that it is unaffected by publishing or discarding and never counts as an unpublished change. For a non-idempotent destructive mutation, these are exactly the traits an agent needs.
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?
Front-loads the destructive replacement behavior in the first sentence, then adds constraints efficiently. Density is high but essentially every clause carries information, though it is close to over-packed for a two-parameter tool.
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 needed, the description covers the destructive overwrite risk, permanence, interaction with draft/publish lifecycle, auth requirement, and a rejection case. Nothing an agent needs to invoke this safely 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 both parameters (questionBankId, notes) are already fully documented, including the replace-not-append semantics of notes. The description reinforces this but adds little parameter-level detail beyond the schema, 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?
States a specific verb and resource: replaces the plain-text maintainer notes of a question bank, with the scope qualifier that notes are never shown to participants. An agent can immediately distinguish this from question_bank_get, question_bank_rename, or question_bank_item_update.
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 reading notes with question_bank_get first and sending the full desired content, and states a hard exclusion: rejected for a public template id. It also names the access prerequisite with a reference path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reference_getARead-onlyIdempotentInspect
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 19 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 (readOnly, idempotent, non-destructive, closed-world) are fully consistent, and the description adds behavior they don't cover: documents are long and cost real context (~20 KB unscoped block-types vs ~5.5 KB scoped), filters are silently ignored on topics with no per-type split ('whole document returned, stated in the response'), and the availableTopics catalogue is delivered once per session (~2.5 KB) unless overridden. This is exactly the context an agent needs to avoid blowing its window.
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?
Purpose is front-loaded in the first clause, and the sizing advice plus the scoping workflow are genuinely load-bearing. The closing paragraph is dense and slightly tangled (the riddleType/blockTypes/filtering interplay in one block), costing some readability, but no sentence is 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?
For a documentation-fetch tool with an output schema and full annotation coverage, nothing an agent needs is missing: it knows what the tool returns, how large it will be, how to scope it, and when to reach for it versus guessing or retrying a failed call.
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 the topics enum already enumerates every document, so the baseline is 3. The description nevertheless adds cross-parameter semantics the schema does not spell out as clearly — that block-types is never returned unscoped and must be narrowed via blockTypes, that fieldTypes covers both form-field-types and form-field-defaults in one read, and that the per-entity families need no filter because the address itself is the filter.
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 — 'Read this server's own documentation' — and immediately enumerates what the documents contain (block types, form field types, result blocks, palette values, response shapes). It explicitly frames itself as the authoritative parameter reference for the riddle_builder_* and palette_* siblings, so an agent can tell it apart from every other tool in the list without opening a 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?
Gives concrete when-to-use rules: read the relevant topic BEFORE the first call rather than guessing property names, and re-read it on a VALIDATION_ERROR. It also routes by situation — read the index when you don't know which topic you need, getting-started when unsure which tool to use, a prompts/* playbook when the user states a GOAL rather than an operation — and warns to pass only the topics actually needed because most are long.
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; NULL or omitted: your personal project (on a project API key: that key's 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?
Annotations already declare this is a non-read-only, non-idempotent, open-world creation operation, so the safety profile is covered. The description adds useful behavior beyond that: the compact return envelope, the 'queued': true marker when queue is set, and where the view URL appears before and after publishing. It does not cover authorization or rate-limit behavior, but the added return and publishing context is substantial.
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 purpose, then alternatives, then return behavior, which suits a complex nine-type builder. It is dense and long, but most of the length is justified by type-specific creation semantics and cross-references. Some sentences are verbose, so it is not maximally concise.
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 nine Riddle types, nested configuration, and no output schema, the description explains the return envelope and key URL locations. It also points to exhaustive references for per-type shapes, block types, and response format. Combined with a fully described input schema, an agent has enough context to invoke 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%, and the schema itself deeply documents the parameters and nested build fields. The top-level description mainly routes the reader to the schema and external references rather than adding new per-parameter meaning beyond what is already structured. 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 first sentence states a specific verb and resource: it builds a new Riddle from a build configuration. It also distinguishes this creation tool from riddle_builder_update and riddle_builder_validate by naming both siblings and their purposes. An agent can identify the tool without opening its 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 explicitly says to use riddle_builder_update when changing an existing Riddle and riddle_builder_validate when only checking a configuration. It also clarifies the top-level publish boolean versus the stored publish configuration, reducing misuse. These are concrete when-to-use and when-not-to-use instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_builder_updateADestructiveInspect
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. Send only what you mean to change. Returns the compact build-configuration envelope of riddle_get (riddle://reference/response-format). Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| 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?
Annotations already flag destructiveHint=true and non-idempotent, but the description adds real behavioral depth beyond them: omitted fields are left untouched, deleting a block still referenced by CUSTOM logic is rejected unless a replacement tree or $reset is sent, conditions are replaced wholesale and re-sorted so a read-back differs from what was sent, and results replaces all pages. It also states the permission prerequisite and the return envelope.
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?
Front-loaded with the core merge-vs-rebuild distinction, then the block grammar, then preconditions and return shape, so the most decision-relevant information comes first. It is dense but mostly earns its length; the grammar recap overlaps with the per-parameter schema descriptions.
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, deeply nested mutation with no output schema, the description supplies the missing pieces: the return envelope, the read-before-edit workflow, the access precondition, and the classes of rejected edits. Nothing an agent needs to invoke it correctly is absent.
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 baseline is 3, but the description adds the crucial cross-reference that the "build" object is exactly the shape riddle_get returns under "build" and riddle_builder_create accepts, which tells the agent how to construct an undocumented nested payload. The $create/$delete/$blocksOrder grammar is largely restated from the schema, keeping it below a 5.
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 ("Edits an existing Riddle of any type") and immediately distinguishes itself from riddle_builder_create by framing the operation as "a merge, not a rebuild". An agent can tell the difference between this and the create sibling without reading 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?
Explicitly directs to read the Riddle with riddle_get first to obtain the build shape and block IDs, warns "send only what you mean to change," and routes publish-only intent to riddle_publish instead. It also names a precondition (origin.writableByThisKey via riddle_get/riddle_list), so when-not-to-use is covered.
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 context.origin.writableByThisKey on riddle_get is true. | |
| 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, a "mediaId") 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 or omitted: your personal project (on a project API key: that key's project). 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?
Annotations already declare readOnly/idempotent/non-destructive, but the description adds non-obvious behavior beyond them: a deep-copied scratch Riddle is discarded, nothing is persisted or published, no event is dispatched, and one genuine side effect (a live HEAD request per media URL) is disclosed — consistent with openWorldHint. It also bounds the tool honestly by naming what it cannot catch (flush/publish-time DB constraints, queue-worker behaviour).
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 capability and the discard semantics are front-loaded, and every sentence carries real information. However, it is a single dense paragraph with no visual structure, and the "project" caveat is repeated almost verbatim between description and 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 two-parameter, no-output-schema tool this is thorough: it names the return envelope keys ({validate, valid, summary, items}), the ordering guarantee, the 1–20 batching, and points to riddle://reference/riddle-builder/riddle-types for per-type build shapes. An agent has enough to call it and interpret the result.
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 carry detailed descriptions, including the project-scope false-negative warning and the edit-entry origin gate. The description largely restates that same material, adding little syntax or format detail beyond the schema, so the baseline of 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?
States a specific verb and scope: "Dry-runs one or many Riddle Builder creates and/or edits without creating or changing anything". This immediately distinguishes it from riddle_builder_create and riddle_builder_update, whose payloads it mirrors.
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 explicit when-to-use guidance: "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 states a concrete when-not/what-it-misses clause and a prerequisite-type rule (pass "project" for project-scoped references, and the origin-gate requirement for edit entries).
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. 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. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle you want to delete. Pass either this or UUIDs. | |
| UUIDs | No | Several Riddles to delete at once, as Riddle UUID strings, e.g. ["6FA740EW", "OllsevHa"] (max 100). Pass either this or UUID. | |
| 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 destructive annotation, it discloses nuanced behavior: bulk delete is non-atomic, does not stop early, retries dependent Riddles once, and reports per-entry errors. It also explains dryRun validation and the shape of the dry-run response, which is valuable behavioral context for a destructive 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 description is dense and front-loads the key deletion and dry-run guidance. It is longer than typical but justified by the complex bulk and retry semantics, though some reference-link phrasing could be tightened.
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?
It covers most behavior an agent needs for a destructive batch delete, including atomicity, retries, per-item errors, dry-run behavior, and access conditions. It does not describe the normal successful delete response, but the annotations and dry-run detail reduce that 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 coverage is 100%, so the schema already documents UUID, UUIDs, and dryRun. The description adds useful meaning by clarifying the either/or relationship, the 100-item limit, and especially the dryRun result fields and validation semantics.
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: deletes one or many Riddles. It clearly distinguishes UUID single deletion from UUIDs bulk deletion and references sibling tools like riddle_list and riddle_get for context.
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 when-to-use guidance: pass UUID for one, UUIDs for several, and dryRun first whenever the set was not created by you. It also names riddle_list as a source for the UUIDs to bulk-clean and explains the writableByThisKey access condition.
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 this key may change this Riddle: "writableByThisKey", see riddle://reference/concepts/access), 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?
Annotations already declare a safe, idempotent read, and the description adds substantial behavior beyond them: content the config cannot express is surfaced in "warnings" rather than failing the call, bulk reads degrade to compact state with "truncated": true past a size budget, omitted sections are echoed in "omittedFields", and the three states of "published" are enumerated. This is exactly the extra context annotations cannot carry.
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 and response shape are front-loaded, which is good, but the remainder is one dense run-on paragraph that largely restates the omit/omittedDefaults/UUIDs semantics already documented in the schema fields. Information-dense rather than wasteful, yet the duplication with structured fields costs it a point.
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 having no output schema, the description fully describes the returned envelope (uuid, type, modifiedAt, build, nextBlockId, warnings, published, context), explains what build versus published mean, and points to reference resources for field-by-field detail. An agent can consume and act on the result without further clarification.
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 the per-parameter descriptions are already rich, so the baseline is 3. The top-level description still adds meaning the schema does not spell out as directly, notably that partial defaults are intentionally absent and must NOT be resent because presence itself enables features, and the ordering advice ("put the Riddles you need in full first").
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 a specific verb (Reads) and resource (one Riddle - or several, with UUIDs) and immediately specifies the response artifact: the compact build-configuration envelope. It even ties the output back to the consumer tools ("build" is exactly what the riddle_builder_* tools accept back), which lets an agent place this tool in a workflow without opening any 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?
It gives clear operational context: single UUID vs UUIDs, the max-20 bulk cap with the reason it is lower than sibling bulk tools, the incompatibility of UUIDs with includeRiddleData, and when to inflate the response (omit/omittedDefaults/includeRiddleData). What it lacks is explicit routing against the closest siblings (riddle_list for compact state, riddle_preview), so the agent must infer when this is the right read versus those.
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 cover the safety profile (readOnly, idempotent, non-destructive), but the description adds a genuinely useful behavioral fact not in the structured data: the code is returned even for unpublished Riddles, yet the embedded URL will not serve until publish. That caveat directly prevents a 'the embed is broken' misdiagnosis. It stops short of describing the returned markup (script vs iframe) or any rate/auth concerns.
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 tight sentences, zero padding, with the identification and the key publish-state caveat both stated up front. Every clause carries information.
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 single-parameter read with no output schema, the description covers the critical gotcha (unpublished Riddles) and the retrieval key. It leaves the shape of the returned code undocumented, though that is a minor gap for a string-returning lookup.
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 single UUID parameter is fully documented in the schema, so the description adds nothing beyond restating 'by its UUID'. Baseline 3 applies when 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 names a specific verb ('Gets') and a precise resource ('the HTML embed code for a Riddle'), which is materially narrower than riddle_get or riddle_preview. It never explicitly contrasts itself with those siblings, so an agent must infer that 'embed code' differs from previewing the Riddle.
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?
Usage is only implied by the resource name: an agent wanting markup to place on a page will pick this. There is no statement of when to prefer riddle_get or riddle_preview, and no prerequisites or exclusions are given.
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 project the API key is scoped to. 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) or "manual" (made in the Creator). Omit for both. A filter value only - the "origin" returned per Riddle is {builder, aiGenerated, writableByThisKey}; what that means for writes: riddle://reference/concepts/access. | |
| 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, as returned by project_list. Omit to use the project the API key is scoped to (your personal project for a user API key). 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 cover the safe-read profile (readOnly, idempotent, non-destructive, closed-world), so this score reflects added value: the description discloses rejection-rather-than-ignore semantics for inapplicable filters in account scope and summarizes the pagination envelope. It does not describe auth/permission requirements beyond a passing reference in the origin parameter.
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?
Purpose and default scope are front-loaded, and the paragraph is dense with payload rather than filler. It is slightly long for a single block and could be split, but every sentence carries distinct information.
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 an 11-parameter, zero-required list tool with no output schema, the description supplies the response shape ({items, page, pageSize, total, hasMore}) plus the meaning of total/hasMore, and resolves the ambiguous scope/filter interactions. Nothing needed to invoke it correctly 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 description coverage is 100%, so the 3 baseline is already met by the schema. The description adds meaning beyond it by explaining cross-scope filter applicability — notably that projectId and notType are rejected (not ignored) under scope "account", a behavior the schema does not state.
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 ("Returns a paginated list of Riddles") and immediately disambiguates the two listing scopes, so an agent can tell what this returns without opening the schema. It is clearly distinguishable from sibling list tools (riddle_template_list, question_bank_list) by resource.
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 states when to use each scope: "project" (default) for a single project, "account" for the personal project plus every accessible team project. It also names the key condition that changes behavior (projectId omitted = API-key-scoped project) and states that projectId/notType are rejected in account scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_moveADestructiveInspect
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: 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. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| 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?
Beyond the annotations, the description discloses important behavioral traits: check mode changes nothing, move mode is atomic and validates the whole set first, moves drop project-specific ad blocks and update the published version, and the new project's design is not adopted. It also clarifies the access prerequisite via origin.writableByThisKey and references access documentation.
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 long, but the length is justified by the tool's complexity and the importance of atomicity and check-mode semantics. It is generally front-loaded with the core move/check distinction, though the single-paragraph structure makes some details harder to scan than necessary.
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, and the description compensates by naming the check-mode response fields and the move-mode response shape. Given the complex atomic bulk behavior, the description is complete enough for an agent to invoke the tool correctly and interpret the likely 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?
Although the schema coverage is 100%, the description adds substantial meaning beyond the schema: omitting projectId triggers check mode, dryRun is pointless without projectId, projectId may come from project_list or be the literal "personal", and UUIDs for a move must represent the complete set that moves together. These are operational semantics not fully conveyed by the structured fields 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 states a specific verb and resource (move Riddles into another project or personal project) and clearly distinguishes the two operational modes: check mode and move mode. It also differentiates this tool's atomic bulk behavior from other bulk tools, which helps an agent select it correctly among 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?
The description gives explicit when-to-use guidance: run check mode first whenever the Riddles were not all created by you, or to explain why a move is impossible. It also explains how to resolve blocked cases via addUUIDs and when to consult additional references.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_previewARead-onlyIdempotentInspect
Shows the user the current DRAFT of a Riddle as a playable preview - the Riddle as it looks right now, published or not. Call it after riddle_builder_create or riddle_builder_update whenever the user wants to see the result (right after riddle_publish the draft and the live version are identical, so it shows what is live); do not call it on every edit of a multi-step build, once at the end is enough. In a client that renders UI this tool draws the preview widget (playable Riddle, a publish button, a link into the Creator); in any other client use the returned "previewUrl" - it works anonymously and serves the draft for "previewExpiresInSeconds" seconds, after which calling this tool again renews it. Changes nothing about the Riddle; the draft is served from a temporary cache under that anonymous previewUrl. Whether it is live and where: "isPublished", "viewUrl" (null until published - reference_get(topics: ["riddle://reference/concepts/publish"]) explains the draft/live split).
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | Yes | The UUID of the Riddle to preview |
Output Schema
| Name | Required | Description |
|---|---|---|
| UUID | Yes | The UUID of the previewed Riddle. |
| type | Yes | The Riddle type (Quiz, Poll, ...). |
| title | Yes | The draft title of the Riddle. |
| viewUrl | Yes | The public URL of the published Riddle, null while it is not reachable there (not published, or its landing page is disabled). |
| creatorUrl | Yes | The Riddle opened for editing in the Riddle Creator (requires the user to be logged in there). |
| previewUrl | Yes | Anonymous URL that serves the DRAFT as a playable Riddle for previewExpiresInSeconds seconds. Not a link to share - it expires. |
| isPublished | Yes | Whether the Riddle is currently live. |
| hasUnpublishedChanges | Yes | Whether the draft differs from what visitors currently get. Always true for a Riddle that was never published. |
| previewExpiresInSeconds | Yes | How long previewUrl serves the draft from now. Call riddle_preview again to renew. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the safe-read profile; the description adds substantially more: no mutation occurs, the draft is served from a temporary cache, the previewUrl is anonymous, it expires after previewExpiresInSeconds, and re-calling renews it. It also discloses client-dependent behavior (renders a widget in UI clients, returns a URL elsewhere), which no structured field conveys.
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 (what it previews, when to call, when not to) is front-loaded and the sizing is justified by the amount of behavioral detail. A few clauses are redundant, notably restating 'the Riddle as it looks right now' and the trailing reference_get pointer, which mildly dilutes an otherwise dense paragraph.
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?
Return values are covered by an output schema, so the description is free of that burden, and it still explains previewUrl semantics and expiry that the agent needs to act on. Client-rendering divergence, publication state fields, and renewal behavior are all covered, so nothing an agent needs to call this 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?
There is a single required parameter with 100% schema description coverage, so the schema already does the work and the baseline is 3. The description doesn't add format, sourcing, or lookup guidance for the UUID beyond referring to 'a Riddle', leaving nothing extra but nothing missing either.
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 concrete verb+resource ('Shows the user the current DRAFT of a Riddle as a playable preview') and immediately scopes it to the draft-vs-live distinction, which separates it from riddle_get and riddle_publish. An agent can tell exactly what this does without opening the 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?
Gives explicit triggers ('after riddle_builder_create or riddle_builder_update whenever the user wants to see the result') and an explicit anti-pattern ('do not call it on every edit of a multi-step build, once at the end is enough'). It also notes the equivalence right after riddle_publish, so the agent knows when calling is pointless.
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 (there is no unpublish tool). A published Riddle's public URL is the response's "context.viewUrl" - report that, never one spelled from the UUID (hosts differ per environment). 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: a Riddle that cannot be (un)published is that entry's "error", 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 not blocked by the connections 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. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | One Riddle's UUID. Pass this or UUIDs. | |
| omit | No | riddle_get's "omit", for the single-UUID response. Ignored with UUIDs (the bulk entries carry no build configuration). | |
| UUIDs | No | Several Riddle UUIDs, e.g. ["6FA740EW", "OllsevHa"] (max 100). Pass 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?
Annotations already mark destructiveHint=true and idempotentHint=false, but the description goes far beyond: non-atomic bulk semantics (per-entry errors, rest proceed), exact error codes (RIDDLE_PUBLISH_VALIDATE, RIDDLE_UNPUBLISH), validationWarnings appearing even on success, and the unpublish no-op message quirk. This is unusually rich 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?
Front-loads the core verb and the publish:false inversion, then layers PUBLISHING/UNPUBLISHING sections. Dense but nearly every clause is actionable; the only cost is readability from a long single block with heavy parentheticals.
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 carries the return-value burden fully: names context.viewUrl as the public URL to report, context.published state, the compact bulk envelope, validationErrors/Warnings, and the no-op 'message'. Complete for a mutating tool of this complexity.
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 real meaning: publish:false semantics, omit shrinking the single-UUID response, the UUID-vs-UUIDs response shape divergence, and the max-100 bulk cap. It meaningfully enriches parameters beyond the schema's field-level 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?
Opens with a specific verb+resource ('Publishes one or many Riddles') and immediately clarifies the inverse mode via publish:false, noting 'there is no unpublish tool.' It distinguishes itself from siblings by name, contrasting its validation output with riddle_builder_validate and its unpublish path with 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?
Gives explicit routing: use riddle_delete instead when a live Leaderboard blocks unpublish, and clarifies that riddle_builder_validate dry-runs a build config rather than a publish. States the condition (origin.writableByThisKey) under which the tool applies. 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.
riddle_renameADestructiveInspect
Renames a Riddle with the specified UUID. Returns only the confirmation of the change (uuid, title, modified state), not the entire Riddle. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| 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?
Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, so the safety profile is covered. The description adds genuinely non-structured context: the writability precondition and the fact that only a partial confirmation (uuid, title, modified state) comes back rather than the whole Riddle. It does not say what happens on a gate failure or whether the prior title is recoverable, which keeps it below a 5.
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 short sentences: operation, return scope, precondition -- front-loaded and free of filler. The final sentence is telegraphically compressed ("Only if ... : riddle://reference/concepts/access"), which costs a little readability but wastes no words.
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 two-parameter mutation with full annotations and no output schema, the definition covers what it does, what comes back, and the permission gate. Only the failure mode when writableByThisKey is false is left unstated, a minor gap rather than a blocking one.
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 both parameters are fully documented in the structured schema. The description restates UUID and the new title but adds no format, constraint, or uniqueness semantics beyond what the schema already provides, so the 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?
"Renames a Riddle with the specified UUID" states a specific verb and resource, and the second sentence bounds the result to a confirmation payload. An agent can distinguish this from riddle_builder_update, riddle_move, or question_bank_rename without opening another 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 an explicit precondition for invocation -- origin.writableByThisKey must be true -- and names riddle_get / riddle_list as the way to check, plus a reference URI for access concepts. It lacks a stated when-not or alternative path for the case where the gate fails, but the eligibility condition itself is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_tag_addAIdempotentInspect
Puts a tag on Riddles - ONE assignment per Riddle, never the tag itself (riddle_tag_list reads the labels of a project, riddle_tag_remove takes a tag off again, riddle_tag_delete removes a label). 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 no tag needs a publish. 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. Returns 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. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle to tag. Pass either this or UUIDs. | |
| UUIDs | No | Several Riddles to tag 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. | |
| tagName | No | The name of the tag. Each Riddle's project gets the tag of that name, created if it has none yet. Pass either this or tagId. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a non-read-only, idempotent, non-destructive operation, and the description is consistent with that while adding important behavior: tag creation in each Riddle's own project, cross-project bulk calls, no publish requirement, per-item bulk error handling, and the permission gate. This is substantial context beyond what the annotations provide.
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 and key constraints are front-loaded, and the density is justified by the tool's bulk and dual-parameter modes. However, it is a single packed paragraph with repeated schema details, so readability and concision could be improved with sentence breaks or less restatement.
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 return-value burden; it explains that the tag and all tags of the Riddle are returned, and it describes the bulk envelope and per-entry error shape. It also covers permissions, project scoping, and idempotency, leaving little for an agent to infer.
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 useful cross-parameter meaning: tagName may create the tag in each Riddle's own project, and tagId is project-scoped and therefore only valid for that project's Riddles. Some of the parameter detail repeats the schema, so it does not quite reach the top score.
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?
It states a specific verb and resource: putting a tag on Riddles, with the scope constraint of one assignment per Riddle. It explicitly distinguishes itself from riddle_tag_list, riddle_tag_remove, and riddle_tag_delete, so an agent can identify its role without opening sibling 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 names the sibling alternatives and what each does, clarifies when to use UUID versus UUIDs, and explains the tagName-versus-tagId choice. It also states the writableByThisKey prerequisite, which gives the agent a concrete condition for whether the tool can be used.
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_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. Needs full access: riddle://reference/concepts/access.
| 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 already declare destructiveHint=true and idempotentHint=false; the description adds genuinely new behavior: the call detaches nothing, it fails with a message naming how many riddles/question banks still carry the tag, deletion is permanent, and IDs are not reused so a stored riddle_list filter on the old id silently stops matching. It also flags the full-access requirement via riddle://reference/concepts/access.
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?
Front-loaded with the destructive action and the rarity warning, and each sentence carries distinct information (alternative, failure mode, pre-check, permanence, id reuse, access). Slightly dense with ALL-CAPS emphasis and a long run-on pre-check clause, which costs a point.
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 two-parameter tool with annotations covering the safety profile and no output schema, the description covers the precondition, the failure behavior, irreversibility, id-reuse side effects, and the auth requirement. Nothing an agent needs before calling 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 both parameters are already documented, including the 'deleted by id, not by name' point the description repeats. The only added meaning is the gating condition (a tag is free only when count AND bankCount are 0), which is relevant but not a semantic clarification of the parameters themselves. 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?
States a specific verb and resource ('Deletes the TAG ITSELF from a project - the label') and immediately scopes it negatively: no riddle, question bank, or assignment is affected. It explicitly contrasts with the sibling riddle_tag_remove, so an agent can distinguish the two without opening 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?
Gives explicit when-to-use ('for a leftover from before that cleanup existed'), when-not-to-use (untagging the last carrier is handled by riddle_tag_remove), and a mandatory pre-check ('check with riddle_tag_list first ... and untag the carriers before calling this'). The exclusion and the alternative are both named.
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_add/_remove are 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_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 readOnly/idempotent/non-destructive/closed-world, but the description adds substantial non-annotation context: unpaginated result, project-scoped tag identity ('Campaign 2026' differs across projects), and the count vs bankCount split that determines whether a tag is actually unused. This is real behavioral disclosure, not a restatement of the flags.
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?
Return shape is front-loaded, which is correct, and every sentence carries information. It is dense with parenthetical asides and the final sentence is long enough to be a small readability cost, though nothing is truly 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?
No output schema exists, yet the description supplies the exact response shape, the counting semantics, and the cross-tool relationships (riddle_tag_add, riddle_tag_delete, question_bank_tag_*). An agent can call it and interpret results without further inference.
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 baseline is 3; the description earns credit for adding semantics the schema lacks by defining that tags are scoped per project, which is why projectId matters. It doesn't restate the omit/default behavior for projectId, leaving that to 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?
Specific verb + resource ('Lists the tags of a project') plus the exact return shape {items: [{id, name, count, bankCount}]}, and it explicitly distinguishes itself from siblings riddle_list (whose 'tags' filter consumes these ids) and question_bank_tag_add/_remove.
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 explicit when-to-use: 'Read this before riddle_tag_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.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_tag_removeADestructiveInspect
Takes a tag off Riddles - ONE assignment per Riddle (riddle_tag_add puts it on, riddle_tag_delete removes a label nothing carries). Untags one Riddle (UUID) or many (UUIDs, max 100), by tagName or tagId, 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 from the project, unless a question bank still uses it - so a tag rarely has to be deleted by hand, and a tag removed that way is gone for good (re-adding creates a new one with a new id). Returns the tag plus all remaining tags of the Riddle, and with UUIDs the {bulk, operation, summary, results} envelope with one entry per Riddle, a failure reported as that entry's "error" without stopping the others. Only if the Riddle's origin.writableByThisKey is true (riddle_get, riddle_list): riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| UUID | No | The UUID of the single Riddle to untag. Pass either this or UUIDs. | |
| UUIDs | No | Several Riddles to 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. | |
| tagName | No | The name of the tag. Nothing is ever created; a name the Riddle's 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?
Far exceeds the annotations: it discloses the cascading delete of the tag itself when the last carrier is untagged, that this deletion is permanent (re-adding creates a new id), that a nonexistent tag is a per-Riddle error, that nothing is created, and how bulk partial failures are reported. These are exactly the destructive side effects an agent must know about.
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?
Front-loaded and information-dense, but the second sentence is an extremely long, parenthetical-laden run-on that bundles return format, bulk envelope, error semantics, and permissions together. Every fact earns its place, yet the packing hurts 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?
No output schema exists, and the description compensates by spelling out the returns (tag plus remaining tags; {bulk, operation, summary, results} envelope for UUIDs) and the permission gate. Nothing material is missing for a destructive, non-idempotent mutation.
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 each parameter, but the description adds real meaning: tagName never creates (unlike an add tool), a name the project lacks is an error for that Riddle, and the 100-item cap and UUID/UUIDs exclusivity are restated in context. Slightly redundant with the schema but adds error semantics.
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+resource ('Takes a tag off Riddles') and immediately distinguishes itself from both siblings by naming riddle_tag_add and riddle_tag_delete with the exact semantic difference. An agent can route without opening any 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?
Explicitly names the alternatives and their conditions, plus guidance on when NOT to bother ('a tag rarely has to be deleted by hand'), and states the precondition (origin.writableByThisKey must be true, cross-referencing riddle_get/riddle_list).
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. Without full access only for a Riddle whose origin.writableByThisKey is true: riddle://reference/concepts/access.
| 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. | |
| iconMediaId | No | Same, for the "icon". | |
| coverMediaId | No | Media library image to show as the template's "image" from the Riddle's project (see riddle_template_update). Omit for the Riddle's own cover. | |
| 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?
The description adds substantial behavior beyond the annotations: it clarifies snapshot semantics ('The template is a copy taken at this moment... later changes to it do not reach the template'), states copy scope ('copies what the Riddle currently has stored, published or not'), describes permission requirements, and enumerates the return object's fields. These details are not present in the annotations, which only declare readOnlyHint=false, destructiveHint=false, etc.
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 purpose and follows with tightly relevant behavioral, permission, and return-value details. Every sentence adds value, and there is no repetition or filler; even the reference link to access concepts is purposeful.
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?
Although there is no output schema, the description explicitly lists return fields ('{id, title, type, category, isPublic, isQuickCreate, blocksCount, image, icon, createdAt, riddle}'). Combined with rich annotations and a fully described input schema, the definition covers everything an agent needs 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?
With 100% schema description coverage, the schema already documents all five parameters. The description still adds meaningful semantics by clarifying the scope of the copy triggered by the UUID parameter ('copies what the Riddle currently has stored, published or not') and by noting that omitting fields preserves the Riddle's own values, though it does not individually explain each parameter.
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 specific verb and resource: 'Stores an existing Riddle as a template of its project (or of the user, for a personal Riddle)'. It explicitly names the sibling tool riddle_template_use as the consumer of the created template, so an agent can distinguish creation from usage without opening any 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 clear usage context: it explains that the template enables creation via riddle_template_use, and it states permission prerequisites ('Requires the template-create permission') plus an access caveat for non-full-access callers. It does not explicitly list when-not-to-use cases or name an alternative creation pathway, which keeps it at 4 rather than 5.
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?
Annotations already declare readOnly/idempotent/non-destructive, yet the description adds meaningful behavior beyond them: the conditional presence of "preset.paletteValues", the deliberate absence of paletteValues on built-in palettes (with the reference to fall back on), the empty-"build" + warning case, and the size warning that omittedDefaults maps measure 85-90% of the response.
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 key purpose is front-loaded and each sentence carries real information, but the prose is dense with nested parentheticals and repeated cross-references to sibling tools, so it is longer than strictly necessary while remaining on-topic.
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 takes on the burden of return values and does so explicitly, enumerating the returned fields and explaining the build/preset/warnings edge cases. Nothing an agent needs to call 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 coverage is 100%, so the baseline is 3, but the description adds rationale the schema lacks: why id ties back to templateId lineage, and that omittedDefaults is "to read, never to resend" and should be true only to learn what THIS template left at its default. This meaningfully guides correct parameter choice.
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?
"Reads one template, by default INCLUDING its build configuration" names a specific verb, resource, and default scope, and explicitly distinguishes the result from what riddle_get returns and riddle_builder_create accepts. An agent can tell it apart from riddle_template_use (copies whole) and riddle_template_list without opening any 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?
Gives explicit when-to-use and when-not: adapt via riddle_builder_create with this id as "templateId", or if "Not changing anything? riddle_template_use is one call and copies the template whole." It even routes the no-build-config case ("use riddle_template_use for those"). Alternatives and conditions are fully named.
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 cover the safety profile (readOnly, idempotent, non-destructive), so the description's job is to add what they don't: that isQuickCreate templates are merged into the same list, that results are not paginated so total is an exact count, and that build configuration is excluded. Missing only auth/scope caveats beyond the schema's note on API-key scoping.
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?
Dense but front-loaded: scope and the sibling exclusion come first, then quick-create behavior, then the return shape. Every clause carries information, though the formatting as one run-on paragraph with inline literals is slightly harder to scan than it could be.
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 steps in and enumerates the returned fields (id, title, type, blocksCount, image, icon, createdAt, riddle, isPublic, isQuickCreate) plus the total envelope, and explains the non-pagination semantics and where the build configuration lives. Nothing an agent needs to call this correctly is absent.
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 are fully documented there, including the type enum values and the projectId default behavior. The description only restates that type filters by Riddle type and adds no syntax or format detail beyond the schema, so the 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?
States a specific verb (Lists) and resource (templates of a project or your personal ones), and explicitly carves out what it is NOT: Riddle's public ones, which it names as returned by riddle_template_public_list. An agent can distinguish it from riddle_template_create, riddle_template_get, and riddle_template_public_list without opening any 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?
Explicitly names the alternative (riddle_template_public_list) for public templates, and routes onward: read build config with riddle_template_get, or hand the id to riddle_template_use. It also clarifies that there is no separate listing for quick-create templates, closing a likely agent assumption.
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 cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false, openWorldHint=false), so the bar is lower. The description adds non-obvious behavioral context: results are grouped by category rather than returned as a flat 'items' list, and the build configuration is deliberately omitted. It does not discuss pagination or limits, hence not a 5.
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?
Front-loaded with the core purpose in the first clause, and every remaining sentence carries information (grouping behavior, return shape, alternatives). It is a dense, somewhat run-on single paragraph with nested quoting, which costs it a point on readability, but little 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?
With no output schema, the description compensates by spelling out the return shape ({categories: {<category>: [{id, title, type, blocksCount, image, icon, createdAt, riddle, isPublic}]}, total}) and the key structural quirk (grouped, not flat). Combined with sibling routing, an agent has everything needed to call and interpret it.
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 both parameters in detail (the exact Riddle types, the snake_case category slug). The description only notes that 'category' and 'type' narrow the results and that omitting category reveals existing ones, which largely duplicates the schema. Baseline 3 is correct.
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+resource (lists public templates) and immediately differentiates from the sibling riddle_template_list ('as opposed to riddle_template_list's own ones'). It also clarifies what this tool does NOT include (build configuration) versus riddle_template_get. An agent can distinguish it from siblings without opening any 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?
Explicitly states that calling with no arguments is how you discover the available categories, and names the alternatives: riddle_template_get for the build configuration, or handing the id to riddle_template_use. Both when-to-use and routing to alternatives are present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
riddle_template_updateADestructiveIdempotentInspect
Changes a template's title and/or its gallery image and icon. Images: media_upload_link into the template's project, pass the reported "mediaId" (stored by URL - deleting the file breaks the image). Only what you pass changes; the template's content cannot be changed (create a new template from the edited Riddle). Public templates only by Riddle admins. Returns the template like riddle_template_create. Without full access only for a Riddle whose origin.writableByThisKey is true: riddle://reference/concepts/access.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Template ID, from riddle_template_list. | |
| title | No | New title. Omit to keep it. | |
| remove | No | Images to take away again: the cover then falls back to the Riddle's cover, the icon to the type's default. | |
| iconMediaId | No | Same, for the "icon". | |
| coverMediaId | No | Media library image (the "mediaId" media_upload_link reports) to show as the template's "image". Omit to keep the current one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag destructiveHint=true and idempotentHint=true, but the description adds real behavioral context beyond them: partial-update semantics ('only what you pass changes'), the URL-backed media storage caveat (deleting the file breaks the image), fallback behavior suggestion via the remove param, and admin/access gating. It also notes the return shape mirrors riddle_template_create.
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 action and the partial-update rule are front-loaded, and every sentence carries information. The trailing access-condition sentence is dense and cryptic ('without full access only for a Riddle whose origin.writableByThisKey is true'), relying on a reference link rather than plain language.
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?
No output schema exists, and the description substitutes by saying the return matches riddle_template_create. It covers permissions, image lifecycle, and the immutability of content, but leaves open edge behavior such as passing remove and coverMediaId together, or what happens for an unknown id.
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 earns above that by explaining the mediaId workflow (upload first via media_upload_link) and the storage-by-URL consequence for coverMediaId/iconMediaId, which the schema only gestures at. It does not add detail on how remove interacts with coverMediaId/iconMediaId in the same call.
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 (changes a template's title, gallery image, icon) and immediately scopes it against siblings by noting the template's content cannot be changed and that riddle_template_create should be used instead. An agent can distinguish this from riddle_template_create, riddle_template_get, and riddle_builder_update without reading the 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?
Explicitly names the prerequisite workflow for images (media_upload_link into the template's project, then pass the reported mediaId), the alternative for content edits (create a new template from the edited Riddle), and the permission condition (public templates only by Riddle admins; otherwise requires origin.writableByThisKey). When-to-use and when-not-to-use are both present.
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 - except that Riddles the template embeds or that depend on it (a Form, a Leaderboard) are copied and published right away, and so is the new Riddle when one of them depends on it. 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?
Goes well beyond the annotations by disclosing the publish state of the result (DRAFT, with the exception that embedded/dependent Riddles such as a Form or Leaderboard are copied and published immediately), the required permissions ('template-use plus Riddle-create in the target project'), and that riddle_get reports it as context.duplicated. Minor gap: no mention of what happens if the template is deleted or whether a copy can be made repeatedly beyond idempotentHint=false.
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?
Front-loaded with the action and the alternative, then the draft/publish nuance, return shape and permissions. It is a single dense paragraph and the embed/dependency exception is slightly convoluted ('and so is the new Riddle when one of them depends on it'), but no sentence is 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?
With no output schema, the description compensates by describing the return ('the standard build-configuration envelope') and the omit trimming. It also covers the mutation's side effects and auth requirements, so an agent has everything needed to invoke 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 schema already documents id, omit, title and projectId in detail; the baseline of 3 applies. The description only restates the omit parameter ('takes riddle_get's "omit" to leave sections of it out') without adding syntax or defaults beyond the schema, and never mentions title or projectId.
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 Riddle from a template') plus the exact semantics of the operation ('an unchanged copy of it - content, settings and design preset'). It also distinguishes the outcome from the sibling that produces an edited Riddle, so an agent can tell riddle_template_use from riddle_builder_create without opening 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?
Gives an explicit selection rule: '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.' Both the use case and the alternative path with its prerequisite step are named.
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), "breakdown" (the per-block detail, or the per-Riddle summary for namespace "user") or "lookerLink" (no dates, Enterprise): no numbers but {url}, a Looker Studio link opening a ready-made report - per Riddle, per project, or for the whole account (namespace "user", no entityId; with the key\'s own user id: its personal project). On first use the user authorizes the Riddle connector there, then opens the link again. | |
| 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 cover readOnly/idempotent/non-destructive safety, and the description goes well beyond them by disclosing the response document shape, where metrics live, the interval aggregation caveat, the USER-key requirement, and the crucial empty-vs-zero distinction. Slightly short of 5 only because the wall-of-text delivery blurs some of these points.
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 real signal (empty vs zero, interval total not daily, publish check), so it earns its length in content, but it is delivered as one dense run-on paragraph with no headings or front-loading of the most critical pitfalls. Structure could be far better for such a rich 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?
There is no output schema, so the description fully carries the burden of explaining return values, and it does: the core_metrics/stats location, block stats, timeseries interval structure, and breakdown shapes per namespace. An agent has enough to call correctly and interpret 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 coverage is 100%, so the baseline is 3; the description adds meaning by tying entityId sources to project_list/whoami/riddle_list, clarifying that the account-wide summary rejects entityId, and explaining date defaults and per-view behavior. It mostly reinforces the schema rather than introducing new syntax.
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-plus-resource (views/starts/submissions of one entity) and immediately explains how namespace+entityId select the target and how 'view' controls depth. No sibling tool measures statistics, so the purpose stands apart 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?
Gives concrete when-to-use guidance per view: prefer a short range or one Riddle on a big project, narrow with projectIds rather than paging on a big account, and the account-wide summary requires a USER API key and takes no entityId. It also names the prerequisites for breaking down a Riddle and how to interpret empty results.
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, whether this key has full access ("allowsFullAccess", see riddle://reference/concepts/access), 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, idempotentHint, openWorldHint=false and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: that the plan is purely informational and never causes a refusal, plus null semantics for 'userName' and trial 'termEnd'/'daysLeft'. It does not discuss error/auth-failure behavior, so not a 5.
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?
Front-loading is good - the core purpose opens the description - but the remaining text is a dense run-on packed with nested parentheticals that makes field semantics hard to scan. Information density is high and most content is justified given the absent output schema, but the structure could be broken into cleaner clauses.
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 must carry the full burden of return-value explanation, and it does: it names the fields, describes the subscription object's members, explains null cases, and disambiguates key id vs user id vs project id. Nothing an agent needs to interpret the response 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 takes zero parameters, which sets the baseline at 4 by the rubric. The description uses its space instead to document return-value field names and null conditions, which is appropriate given there are no inputs to explain.
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?
Opening clause 'Reports the current API key' gives a specific verb and resource, immediately followed by the concrete payload (authenticated user, project/team, plan). It is unmistakably distinct from siblings like project_get or stats_fetch, which is reinforced by the explicit id-disambiguation against those tools.
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?
There is no explicit when-to-use statement, but the description does route the agent across tools by noting that the response's 'user' field is the entityId the stats tools want, and by clarifying that riddle_get's 'plan' is a different concept. This is useful implied guidance, but the basic 'call this to identify the connected account' framing 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.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
- Changed
riddle_builder_create2 fields changed- changed
Input schema / properties / build / properties / conditions / descriptionPrevious 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\"]."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\", optional \"timezone\") - 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 / logic / descriptionPrevious value: -"Quiz / Poll / Form / Story only. Optional branching logic tree over the blocks. A node is {\"blockId\": int, \"branchingType\": \"linear\"|\"answer\"|\"condition\"|\"score\"}. For \"linear\" add \"next\": {<child node>}; for \"answer\" add \"rules\": [{\"answers\": [\"Answer text\"], \"blockId\": int, \"next\": {...}}]; for \"condition\" add \"condition\": {\"field\": string, \"operator\": string, \"value\"?: mixed} plus \"ifTrue\"/\"ifFalse\": {<child node>} (riddle://reference/concepts/logic lists the \"field\"/\"operator\" values); for \"score\" add \"scoreType\": \"total\"|\"block\" plus \"ranges\": [{\"min\": int, \"max\": int, \"blockId\": int, \"next\": {...}}]. A bare {\"blockId\": X} shows X and ends the flow; to merge paths and keep going you must repeat the shared tail under each branch. Omit for a default linear flow. >> QUIZ: A Quiz containing a Flashcard block is linear-only: one \"answer\"/\"condition\"/\"score\" node anywhere in the tree is then rejected for the whole Riddle. >> STORY: A Story has no answers to branch on, so only \"linear\" nodes are meaningful here."New value: +"Every type except a Leaderboard (a standings page with no flow) and a Placeholder (no blocks of its own to branch between). Optional branching tree over the blocks. A node is {\"blockId\": int, \"branchingType\": \"linear\"|\"answer\"|\"condition\"|\"score\"|\"solved\"|\"won\"}. For \"linear\" add \"next\": {<child node>}; for \"answer\" add \"rules\": [{\"answers\": [\"Answer text\"], \"blockId\": int, \"next\": {...}}]; for \"condition\" add \"condition\": {\"field\": string, \"operator\": string, \"value\"?: mixed} plus \"ifTrue\"/\"ifFalse\": {<child node>} (see riddle://reference/concepts/logic for \"field\"/\"operator\"); for \"score\" add \"ranges\": [{\"min\": int, \"max\": int, \"blockId\": int, \"next\": {...}}] plus \"scoreType\": \"block\" (points of that block) or \"total\" (Quiz only, % of max score); for \"solved\" add \"solved\"/\"notSolved\": {<child node>}; for \"won\" add \"won\"/\"notWon\": {<child node>}. A bare {\"blockId\": X} shows X and ends the flow; to merge paths repeat the shared tail under each branch. Omit for a linear flow. >> QUIZ: A Quiz containing a Flashcard block is linear-only: one \"answer\"/\"condition\"/\"score\" node anywhere in the tree is then rejected for the whole Riddle. >> STORY: A Story has no answers to branch on, so only \"linear\" nodes are meaningful here. >> MINIGAME: Which node fits depends on the game: \"solved\" (= awarded any score) on Sudoku/Crosswords/Minesweeper; \"won\" on a SlotMachine, forking on whether the player finished above its \"startBalance\"; \"score\" with \"scoreType\": \"block\" on Minesweeper (accumulates across games) and a SlotMachine (scores the balance handed on); \"answer\" on a WheelSpinner, whose answers are the spin OUTCOMES \"Win\"/\"Lose\", not the wheel fields - it never scores, so \"score\"/\"solved\" on one are rejected."
- Changed
riddle_builder_update1 field changed- changed
Input schema / properties / build / properties / conditions / descriptionPrevious 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\"]."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\", optional \"timezone\") - 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\"]."
16 tool updates
- Changed
question_bank_delete4 fields changed- changed
Input schema / properties / questionBankId / descriptionPrevious value: -"The ID of the question bank to delete, or of the bank the item belongs to."New value: +"The ID of the question bank to delete." - removed
Input schema / properties / questionBankItemIdRemoved value: -{ - "default": null, - "description": "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\".", - "type": [ - "null", - "integer" - ] -} - removed
Input schema / properties / targetRemoved value: -{ - "description": "What to delete: \"bank\" (the bank itself and every item in it) or \"item\" (one question of it).", - "enum": [ - "bank", - "item" - ], - "type": "string" -} - changed
Input schema / requiredPrevious value: -[ - "questionBankId", - "target" -]New value: +[ + "questionBankId" +]
- Added
question_bank_duplicate - Removed
question_bank_item - Added
question_bank_item_add - Added
question_bank_item_delete - Added
question_bank_item_update - Removed
question_bank_manage - Added
question_bank_publish - Added
question_bank_rename - Removed
question_bank_tag - Added
question_bank_tag_add - Added
question_bank_tag_remove - Added
question_bank_update_notes - Removed
riddle_tag - Added
riddle_tag_add - Added
riddle_tag_remove
6 tool updates
- Changed
media_delete1 field changed- added
Input schema / properties / projectAdded value: +{ + "default": null, + "description": "Project ID; NULL or omitted: your personal project (project API key: its project). A mediaId only resolves in its project - build in the same one.", + "type": [ + "null", + "integer" + ] +}
- Changed
media_upload_link1 field changed- added
Input schema / properties / projectAdded value: +{ + "default": null, + "description": "Project ID; NULL or omitted: your personal project (project API key: its project). A mediaId only resolves in its project - build in the same one.", + "type": [ + "null", + "integer" + ] +}
- Changed
riddle_builder_create2 fields changed- added
Input schema / properties / build / properties / blocks / itemsAdded value: +{ + "required": [ + "type" + ], + "type": "object" +} - changed
Input schema / properties / project / descriptionPrevious value: -"The project ID; pass NULL for personal project; omit to use the currently selected project."New value: +"The project ID; NULL or omitted: your personal project (on a project API key: that key's project)."
- Changed
riddle_builder_update1 field changed- added
Input schema / properties / build / properties / blocks / itemsAdded value: +{ + "type": "object" +}
- Changed
riddle_builder_validate1 field changed- changed
Input schema / properties / project / descriptionPrevious value: -"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."New value: +"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, a \"mediaId\") 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 or omitted: your personal project (on a project API key: that key's project). Ignored by editing entries ({UUID, build}), always evaluated in their own Riddle's project."
- Changed
riddle_template_create1 field changed- changed
Input schema / properties / coverMediaId / descriptionPrevious value: -"Media library image to show as the template's \"image\" (see riddle_template_update). Omit for the Riddle's own cover."New value: +"Media library image to show as the template's \"image\" from the Riddle's project (see riddle_template_update). Omit for the Riddle's own cover."
13 tool updates
- Added
integration_list - Changed
palette_customize1 field changed- changed
Input schema / properties / riddleUUID / descriptionPrevious value: -"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."New value: +"The UUID of the Riddle you want to restyle."
- Changed
reference_get1 field changed- changed
Input schema / properties / topics / descriptionPrevious 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."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 19 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
riddle_builder_create2 fields changed- added
Input schema / properties / build / properties / attributesAdded value: +{ + "description": "Personality only, optional. Scored via answers' \"attributeScores\"; see riddle-types.", + "type": "array" +} - changed
Input schema / properties / build / properties / blocks / descriptionPrevious value: -"The Riddle's blocks - required by every type except Leaderboard and Placeholder, which have none. A block is {\"type\": <one of the block types listed below for the \"type\" you are building>, \"title\": \"...\"} plus that block type's own content, and the content differs sharply per block type - unknown keys are rejected rather than ignored. A CHOICE block's answer options go in \"items\" - not \"answers\" - each one an object: {\"title\": \"Paris\", \"isCorrect\": true} on a Quiz, {\"title\": \"Paris\", \"scores\": [3, 0]} on a Personality Test. The blocks that take typed-in answers instead name their own key - a Quiz TextEntry takes \"answers\", a Quiz GuessIt \"acceptableAnswers\" - and some blocks (a Poll NetPromoterScore or TextEntry) have no options at all; the per-block-type reference below is what says which. A FormBuilder's inputs go in \"fields\" instead. Every remaining property, value range and trap per block type is in riddle://reference/riddle-builder/block-types; read it with reference_get scoped to your \"riddleType\" AND the \"blockTypes\" you intend to build before writing them. The block types each Riddle type allows: >> QUIZ: SingleChoice / MultipleChoice / TextEntry / Order / Flashcard / TypeRush / GuessIt / TapAndFind / SpotTheDifference / QuestionBank - the last two place their answers as hotspots on an image, in percentages of it. >> POLL: SingleChoice / MultipleChoice / Matrix / Order / Upvote / NetPromoterScore / RateIt / Swiper / Reaction / TextEntry / TierList / ThisOrThat / QuestionBank. >> PERSONALITY: SingleChoice / MultipleChoice - every answer item's \"scores\" array must have one integer per personality, in personality order. >> FORM: FormBuilder, whose \"fields\" are the 18 types in riddle://reference/riddle-builder/form-field-types. >> PREDICTOR: PickTheWinner / GuessTheScore. >> MINIGAME: SlotMachine / WheelSpinner / Sudoku / Minesweeper / Crosswords. >> STORY: Content / Ad / Quote / InteractiveGraphic / FormBuilder / FormField / FormSelect - a Story has no answers of any kind, so build a Poll or a Quiz instead if you need them. >> QUIZ / PREDICTOR / MINIGAME / STORY additionally take the lead-collecting blocks FormBuilder, FormField and FormSelect in the same array; on a Quiz, a Predictor or a Minigame a Name and an Email field are what make it Leaderboard-connectable (a Story scores nothing, so it collects leads but never feeds a Leaderboard). A QuestionBank block draws its questions from an existing bank (\"questionBankId\" plus a non-empty \"questionBankBlocks\"; riddle://reference/question-bank/overview)."New value: +"The Riddle's blocks - required by every type except Leaderboard and Placeholder, which have none. A block is {\"type\": <one of the block types listed below for the \"type\" you are building>, \"title\": \"...\"} plus that block type's own content, and the content differs sharply per block type - unknown keys are rejected rather than ignored. A CHOICE block's answer options go in \"items\" - not \"answers\" - each one an object: {\"title\": \"Paris\", \"isCorrect\": true} on a Quiz, {\"title\": \"Paris\", \"scores\": [3, 0]} on a Personality Test. The blocks that take typed-in answers instead name their own key - a Quiz TextEntry takes \"answers\", a Quiz GuessIt \"acceptableAnswers\" - and some blocks (a Poll NetPromoterScore) have no options at all; the per-block-type reference below is what says which. A FormBuilder's inputs go in \"fields\" instead. Every remaining property, value range and trap per block type is in riddle://reference/riddle-builder/block-types; read it with reference_get scoped to your \"riddleType\" AND the \"blockTypes\" you intend to build before writing them. The block types each Riddle type allows: >> QUIZ: SingleChoice / MultipleChoice / TextEntry / Order / Flashcard / TypeRush / GuessIt / TapAndFind / SpotTheDifference / QuestionBank - the last two place their answers as hotspots on an image, in percentages of it. >> POLL: SingleChoice / MultipleChoice / Matrix / Order / Upvote / NetPromoterScore / RateIt / Swiper / Reaction / TierList / ThisOrThat / QuestionBank (free text: FormField, fieldType ShortText/LongText/Number). >> PERSONALITY: SingleChoice / MultipleChoice - every answer item's \"scores\" array must have one integer per personality, in personality order. >> FORM: FormBuilder, whose \"fields\" are the 19 types in riddle://reference/riddle-builder/form-field-types. >> PREDICTOR: PickTheWinner / GuessTheScore. >> MINIGAME: SlotMachine / WheelSpinner / Sudoku / Minesweeper / Crosswords. >> STORY: Content / Ad / Quote / InteractiveGraphic / FormBuilder / FormField / FormSelect - a Story has no answers of any kind, so build a Poll or a Quiz instead if you need them. >> QUIZ / PREDICTOR / MINIGAME / STORY additionally take the lead-collecting blocks FormBuilder, FormField and FormSelect in the same array; on a Quiz, a Predictor or a Minigame a Name and an Email field are what make it Leaderboard-connectable (a Story scores nothing, so it collects leads but never feeds a Leaderboard). A QuestionBank block draws its questions from an existing bank (\"questionBankId\" plus a non-empty \"questionBankBlocks\"; riddle://reference/question-bank/overview)."
- Changed
riddle_builder_update1 field changed- added
Input schema / properties / build / properties / attributesAdded value: +{ + "description": "Personality only, optional. Scored via answers' \"attributeScores\"; see riddle-types.", + "type": "array" +}
- Changed
riddle_builder_validate1 field changed- changed
Input schema / properties / builds / descriptionPrevious 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)."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\ncontext.origin.writableByThisKey on riddle_get is true."
- Changed
riddle_delete2 fields changed- changed
Input schema / properties / UUID / descriptionPrevious value: -"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."New value: +"The UUID of the single Riddle you want to delete. Pass either this or UUIDs." - changed
Input schema / properties / UUIDs / descriptionPrevious value: -"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."New value: +"Several Riddles to delete at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass either this or UUID."
- Changed
riddle_list2 fields changed- changed
Input schema / properties / origin / descriptionPrevious 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}."New value: +"Filter by how the Riddle was created: \"api\" (Riddle Builder API or Riddle AI) or\n\"manual\" (made in the Creator). Omit for both. A filter value only - the \"origin\"\nreturned per Riddle is {builder, aiGenerated, writableByThisKey}; what\nthat means for writes: riddle://reference/concepts/access." - changed
Input schema / properties / projectId / descriptionPrevious value: -"Filter by project ID; omit or null for the authenticated user's personal project. Scope \"project\" only."New value: +"Filter by project ID, as returned by project_list. Omit to use the project the API key is scoped to (your personal project for a user API key). Scope \"project\" only."
- Added
riddle_preview - Changed
riddle_publish3 fields changed- changed
Input schema / properties / UUID / descriptionPrevious value: -"The UUID of the single Riddle you want to publish or unpublish. Pass either this or UUIDs."New value: +"One Riddle's UUID. Pass this or UUIDs." - changed
Input schema / properties / UUIDs / descriptionPrevious value: -"Several Riddles to publish or unpublish at once, as Riddle UUID strings, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass either this or UUID."New value: +"Several Riddle UUIDs, e.g. [\"6FA740EW\", \"OllsevHa\"] (max 100). Pass this or UUID." - changed
Input schema / properties / omit / descriptionPrevious value: -"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."New value: +"riddle_get's \"omit\", for the single-UUID response. Ignored with UUIDs (the bulk entries carry no build configuration)."
- Changed
riddle_tag1 field changed- changed
Input schema / properties / tagName / descriptionPrevious value: -"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."New value: +"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."
- Changed
riddle_template_create2 fields changed- added
Input schema / properties / coverMediaIdAdded value: +{ + "default": null, + "description": "Media library image to show as the template's \"image\" (see riddle_template_update). Omit for the Riddle's own cover.", + "type": [ + "null", + "integer" + ] +} - added
Input schema / properties / iconMediaIdAdded value: +{ + "default": null, + "description": "Same, for the \"icon\".", + "type": [ + "null", + "integer" + ] +}
- Added
riddle_template_update
1 tool update
- Changed
stats_fetch2 fields changed- changed
Input schema / properties / view / descriptionPrevious value: -"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\")."New value: +"How deeply to measure: \"totals\" (one aggregate for the period), \"timeseries\" (that aggregate per consecutive interval, requires dateFrom and dateTo), \"breakdown\" (the per-block detail, or the per-Riddle summary for namespace \"user\") or \"lookerLink\" (no dates, Enterprise): no numbers but {url}, a Looker Studio link opening a ready-made report - per Riddle, per project, or for the whole account (namespace \"user\", no entityId; with the key\\'s own user id: its personal project). On first use the user authorizes the Riddle connector there, then opens the link again." - changed
Input schema / properties / view / enumPrevious value: -[ - "totals", - "timeseries", - "breakdown" -]New value: +[ + "totals", + "timeseries", + "breakdown", + "lookerLink" +]
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
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceRemote MCP server that lets AI assistants read tracked competitive intelligence — competitor news, reviews, website changes, social posts and ads — and act on it by managing projects, competitors, battle cards, reports and canvases. Every answer carries a source and a date, and write actions only publish when explicitly shared.MIT
- AlicenseCqualityCmaintenanceCompetitor Monitor AI - MCP server providing AI-powered tools and automation by MEOK AI Labs112 npm29 PyPIMIT
- AlicenseAqualityDmaintenanceEnables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.1623 npm1MIT

industrylens-mcpofficial
AlicenseNot gradedqualityBmaintenanceBrowse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.