Canvas
All MCP tools that author and read canvases.
Tools for authoring kid-facing HTML canvases. The canvas runs in a strict iframe sandbox; the sprout.* SDK is the only host bridge. SDK contract: resources/read sprout://canvas/sdk.
canvas.createSafe to retry
Author a new canvas. Two-step commit via dry-run + spec-hash.
Scope: canvas:write
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
name | string | yes | Library label. |
emoji | string | no | For canvas chooser rendering. Nullable. |
html | string | yes | Canvas body. Wrapped with the Sprout design-system stylesheet + SproutBridge shim unless injectBaseStyles:false. |
completionSchema | object | yes | What counts as done. { kind: "score" | "complete" | "timed", ... }. |
dimensions | object | yes | At minimum { age: "5-7" }. Immutable post-create. |
injectBaseStyles | boolean | no | Default true. False persists the bytes verbatim. Not part of version-bump diff. |
dryRun / specHash | various | no | Two-step commit, same shape as skill.write. |
Request example
{
"method": "tools/call",
"params": {
"name": "canvas.create",
"arguments": {
"name": "Sight word race",
"emoji": "🏃",
"html": "",
"completionSchema": { "kind": "score", "maxScore": 100 },
"dimensions": { "age": "5-7" },
"dryRun": true
}
}
}Returns. { canvasId } on commit; { previewHtml, analyzerIssues, specHash } on dryRun.
Response example
{
"result": {
"previewHtml": "",
"analyzerIssues": [],
"specHash": "h_e9f2..."
}
}Errors
BAD_INPUT SAFETY_REJECTED: Content failed the platform safety check.BAD_INPUT INVALID_DIMENSION_VALUE: Empty or whitespace-only dimension axis value.BAD_INPUT UNKNOWN_DIMENSION_AXIS: Axis name not in the V1 set.BAD_INPUT SPEC_HASH_MISMATCH: Input drifted between dry-run and commit.
canvas.update
Edit an existing canvas. Partial. Dimensions are immutable post-create and rejected at schema validation.
Scope: canvas:write
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
canvasId | string | yes | The canvas to update. |
name / emoji / html / completionSchema | various | no | Same shapes as canvas.create. |
injectBaseStyles | boolean | no | Same as canvas.create. Not part of version-bump diff. |
Request example
{
"method": "tools/call",
"params": {
"name": "canvas.update",
"arguments": {
"canvasId": "cv_19...",
"name": "Sight word race (v2)",
"html": ""
}
}
}Returns. { canvasId, version }
Response example
{
"result": { "canvasId": "cv_19...", "version": 2 }
}canvas.list
Keyset-paginated summaries. Omits HTML body and the full completionSchema.
Scope: canvas:read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
cursor / limit | various | no | Standard pagination. |
Request example
{
"method": "tools/call",
"params": {
"name": "canvas.list",
"arguments": { "limit": 50 }
}
}Returns. { items: [{ canvasId, name, dimensions, hasCompletionSchema, createdAt, updatedAt, version }], nextCursor }
Response example
{
"result": {
"items": [
{
"canvasId": "cv_19...",
"name": "Sight word race",
"dimensions": { "age": "5-7" },
"hasCompletionSchema": true,
"version": 2,
"createdAt": "2026-05-21T10:00:00Z",
"updatedAt": "2026-05-23T08:00:00Z"
}
],
"nextCursor": null
}
}canvas.get
Fetch one canvas in full, including HTML and completion schema.
Scope: canvas:read
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
canvasId | string | yes | The canvas. |
Request example
{
"method": "tools/call",
"params": {
"name": "canvas.get",
"arguments": { "canvasId": "cv_19..." }
}
}Returns. { canvasId, name, emoji, html, completionSchema, dimensions, version }
Response example
{
"result": {
"canvasId": "cv_19...",
"name": "Sight word race",
"emoji": "🏃",
"html": "",
"completionSchema": { "kind": "score", "maxScore": 100 },
"dimensions": { "age": "5-7" },
"version": 2
}
}Errors
DOMAIN_NOT_FOUND: Not in this family. For platform-scope skills, canvases linked across families return this in V1; hydration is family-scoped.PERMISSION_DENIED SCOPE_MISSING:canvas:read: Token hasskill:readbut notcanvas:read.
canvas.delete
Permanently delete a canvas. Destructive; refused if any skill still links it.
Scope: canvas:write
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
canvasId | string | yes | The canvas to delete. |
Request example
{
"method": "tools/call",
"params": {
"name": "canvas.delete",
"arguments": { "canvasId": "cv_19..." }
}
}Returns. { deleted: true }
Response example
{
"result": { "deleted": true }
}See also
- Model: Canvas
- Build: Author a canvas
- SDK reference:
resources/read sprout://canvas/sdk