scene_write
Write FX scene source
Creates or replaces a complete programmable effect, not a fixed-template parameter preset. It takes an ES module exporting scene with id, mount(ctx), reset(ctx), frame(ctx), and optional dispose(ctx). mount appends under ctx.layer and returns refs including root. HTML/CSS, SVG, Canvas and WebGL are supported; ctx.elapsedMs is the authored clock. No ambient application, network or provider authority is available. New scenes use expected_revision:0. Replacing an existing scene requires both its revision and sha256 from scene_read; a stale edit refuses without overwriting. Saved source versions are retained. scene_preview renders actual pixels; saving source does not apply an opener/outro or change any Episode. Without project_id it writes to the caller's account library; an accessible Project selects its account scope.
Surface: Default model and app
Product release eb8538f4a297f331d0399351c1e175bffcd212d2
Public contract commit 20688e11af473a363145ed880d5019c90a7ec1e2
Public contract SHA-256 87a94b85a84dc19245fc03f9b544c70d64bd9f5e08585dcccb38157cace5700d
Captured 2026-10-04T11:55:45.577Z. Review or improve this contract on GitHub.
These blocks show the complete MCP descriptors captured from serving Rails. Security schemes and resource URIs can differ by connected host.
Default model descriptor
{
"name": "scene_write",
"title": "Write FX scene source",
"description": "Creates or replaces a complete programmable effect, not a fixed-template parameter preset. It takes an ES module exporting scene with id, mount(ctx), reset(ctx), frame(ctx), and optional dispose(ctx). mount appends under ctx.layer and returns refs including root. HTML/CSS, SVG, Canvas and WebGL are supported; ctx.elapsedMs is the authored clock. No ambient application, network or provider authority is available. New scenes use expected_revision:0. Replacing an existing scene requires both its revision and sha256 from scene_read; a stale edit refuses without overwriting. Saved source versions are retained. scene_preview renders actual pixels; saving source does not apply an opener/outro or change any Episode. Without project_id it writes to the caller's account library; an accessible Project selects its account scope.",
"inputSchema": {
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Optional Project scope; omitted means the caller's own account."
},
"scene_id": {
"type": "string",
"description": "Stable account scene identifier, lowercase letters/numbers/hyphens."
},
"name": {
"type": "string",
"maxLength": 120
},
"source": {
"type": "string",
"maxLength": 131072,
"description": "Complete ES module source, up to 128 KiB."
},
"expected_revision": {
"type": "integer",
"minimum": 0,
"description": "0 for creation; current scene revision for an existing scene."
},
"expected_sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "Required for changes to existing scenes; sha256 from scene_read."
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"duration_ms": {
"type": "integer",
"minimum": 100,
"maximum": 60000
},
"fps": {
"type": "integer",
"enum": [
24,
30,
60
]
},
"aspect": {
"type": "string",
"enum": [
"1:1",
"16:9",
"9:16",
"4:5"
]
},
"asset_ids": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"items": {
"type": "string"
},
"description": "Explicit account image/texture asset IDs from identity_asset_ingest; the runtime receives only these admitted bytes."
}
}
}
},
"required": [
"scene_id",
"source",
"expected_revision"
],
"additionalProperties": false
},
"annotations": {
"title": "Write FX scene source",
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": false
},
"securitySchemes": [
{
"type": "noauth"
}
],
"_meta": {
"securitySchemes": [
{
"type": "noauth"
}
],
"ui": {
"visibility": [
"model",
"app"
]
},
"openai/widgetAccessible": true
}
}App descriptor
{
"name": "scene_write",
"title": "Write FX scene source",
"description": "Creates or replaces a complete programmable effect, not a fixed-template parameter preset. It takes an ES module exporting scene with id, mount(ctx), reset(ctx), frame(ctx), and optional dispose(ctx). mount appends under ctx.layer and returns refs including root. HTML/CSS, SVG, Canvas and WebGL are supported; ctx.elapsedMs is the authored clock. No ambient application, network or provider authority is available. New scenes use expected_revision:0. Replacing an existing scene requires both its revision and sha256 from scene_read; a stale edit refuses without overwriting. Saved source versions are retained. scene_preview renders actual pixels; saving source does not apply an opener/outro or change any Episode. Without project_id it writes to the caller's account library; an accessible Project selects its account scope.",
"inputSchema": {
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Optional Project scope; omitted means the caller's own account."
},
"scene_id": {
"type": "string",
"description": "Stable account scene identifier, lowercase letters/numbers/hyphens."
},
"name": {
"type": "string",
"maxLength": 120
},
"source": {
"type": "string",
"maxLength": 131072,
"description": "Complete ES module source, up to 128 KiB."
},
"expected_revision": {
"type": "integer",
"minimum": 0,
"description": "0 for creation; current scene revision for an existing scene."
},
"expected_sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "Required for changes to existing scenes; sha256 from scene_read."
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"duration_ms": {
"type": "integer",
"minimum": 100,
"maximum": 60000
},
"fps": {
"type": "integer",
"enum": [
24,
30,
60
]
},
"aspect": {
"type": "string",
"enum": [
"1:1",
"16:9",
"9:16",
"4:5"
]
},
"asset_ids": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"items": {
"type": "string"
},
"description": "Explicit account image/texture asset IDs from identity_asset_ingest; the runtime receives only these admitted bytes."
}
}
}
},
"required": [
"scene_id",
"source",
"expected_revision"
],
"additionalProperties": false
},
"annotations": {
"title": "Write FX scene source",
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": false
},
"securitySchemes": [
{
"type": "noauth"
}
],
"_meta": {
"securitySchemes": [
{
"type": "noauth"
}
],
"ui": {
"visibility": [
"model",
"app"
]
},
"openai/widgetAccessible": true
},
"outputSchema": {
"type": "object",
"properties": {
"scene": {
"type": "object"
},
"warnings": {
"type": "array",
"items": {
"type": "object"
}
},
"schema": {
"type": "string",
"description": "Receipt schema identifier, bitterclip.scene_write_receipt.v1."
},
"changed": {
"type": "boolean",
"description": "False when the submitted source, name and settings matched the saved scene, so no revision was written."
},
"validation": {
"type": "object",
"description": "Validation state of the scene code: syntax is checked when the scene is written; runtime is not checked.",
"properties": {
"syntax": {
"type": "string"
},
"runtime": {
"type": "string"
}
}
},
"project_id": {
"type": "string",
"description": "Project public ID the scene was written through; absent for an account-level write."
},
"blockers": {
"type": "array",
"items": {
"type": "object"
},
"description": "Typed blockers; empty when the call succeeded."
}
},
"required": [],
"additionalProperties": false
}
}Live Workspace descriptor
{
"name": "scene_write",
"title": "Write FX scene source",
"description": "Creates or replaces a complete programmable effect, not a fixed-template parameter preset. It takes an ES module exporting scene with id, mount(ctx), reset(ctx), frame(ctx), and optional dispose(ctx). mount appends under ctx.layer and returns refs including root. HTML/CSS, SVG, Canvas and WebGL are supported; ctx.elapsedMs is the authored clock. No ambient application, network or provider authority is available. New scenes use expected_revision:0. Replacing an existing scene requires both its revision and sha256 from scene_read; a stale edit refuses without overwriting. Saved source versions are retained. scene_preview renders actual pixels; saving source does not apply an opener/outro or change any Episode. Without project_id it writes to the caller's account library; an accessible Project selects its account scope.",
"inputSchema": {
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Optional Project scope; omitted means the caller's own account."
},
"scene_id": {
"type": "string",
"description": "Stable account scene identifier, lowercase letters/numbers/hyphens."
},
"name": {
"type": "string",
"maxLength": 120
},
"source": {
"type": "string",
"maxLength": 131072,
"description": "Complete ES module source, up to 128 KiB."
},
"expected_revision": {
"type": "integer",
"minimum": 0,
"description": "0 for creation; current scene revision for an existing scene."
},
"expected_sha256": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "Required for changes to existing scenes; sha256 from scene_read."
},
"settings": {
"type": "object",
"additionalProperties": false,
"properties": {
"duration_ms": {
"type": "integer",
"minimum": 100,
"maximum": 60000
},
"fps": {
"type": "integer",
"enum": [
24,
30,
60
]
},
"aspect": {
"type": "string",
"enum": [
"1:1",
"16:9",
"9:16",
"4:5"
]
},
"asset_ids": {
"type": "array",
"maxItems": 16,
"uniqueItems": true,
"items": {
"type": "string"
},
"description": "Explicit account image/texture asset IDs from identity_asset_ingest; the runtime receives only these admitted bytes."
}
}
}
},
"required": [
"scene_id",
"source",
"expected_revision"
],
"additionalProperties": false
},
"annotations": {
"title": "Write FX scene source",
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": false
},
"securitySchemes": [
{
"type": "noauth"
}
],
"_meta": {
"securitySchemes": [
{
"type": "noauth"
}
],
"ui": {
"visibility": [
"model",
"app"
]
},
"openai/widgetAccessible": true
},
"outputSchema": {
"type": "object",
"properties": {
"scene": {
"type": "object"
},
"warnings": {
"type": "array",
"items": {
"type": "object"
}
},
"schema": {
"type": "string",
"description": "Receipt schema identifier, bitterclip.scene_write_receipt.v1."
},
"changed": {
"type": "boolean",
"description": "False when the submitted source, name and settings matched the saved scene, so no revision was written."
},
"validation": {
"type": "object",
"description": "Validation state of the scene code: syntax is checked when the scene is written; runtime is not checked.",
"properties": {
"syntax": {
"type": "string"
},
"runtime": {
"type": "string"
}
}
},
"project_id": {
"type": "string",
"description": "Project public ID the scene was written through; absent for an account-level write."
},
"blockers": {
"type": "array",
"items": {
"type": "object"
},
"description": "Typed blockers; empty when the call succeeded."
}
},
"required": [],
"additionalProperties": false
}
}Errors
[
"project_not_found",
"invalid_input",
"revision_conflict"
]Examples
[
{
"label": "Create a minimal scene",
"input": {
"scene_id": "light-study",
"expected_revision": 0,
"source": "export const scene = { id: 'light-study', mount(ctx) { const root = document.createElement('div'); root.textContent = 'Light'; ctx.layer.append(root); return { root }; }, reset() {}, frame(ctx) { ctx.refs.root.style.opacity = String(Math.min(1, ctx.elapsedMs / 1000)); } };"
}
}
]