angle_mutate
Change a camera angle
One camera-angle change per call: hide, show, trim, nudge, or remove. A camera is positioned by its footage session's clock, so there is no action that moves one by hand; nudge is how a slightly-off placement is corrected. hide/show exclude or return an angle from automatic picture selection without touching saved explicit picture choices. trim persists source-clip trim handles; nudge persists a small user timing offset without rewriting measured sync times; remove deletes the clip while leaving media archived. Pass the Episode's current revision and a caller-stable idempotency key with every action.
Surface: App-only
Product release 1dce717408a55fac1047e7d779177fa3ef8ede51
Public contract commit 1ce47f7857ae3d9b6933fe83d5c33de3ae5efc64
Public contract SHA-256 241d47d25e4b4c1dae9d2263793874d06fc4ba7bc3c78d4cf2bc63fbb32ed7dc
Captured 2026-09-24T16:39:30.100Z. 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.
App descriptor
{
"name": "angle_mutate",
"title": "Change a camera angle",
"description": "One camera-angle change per call: hide, show, trim, nudge, or remove. A camera is positioned by its footage session's clock, so there is no action that moves one by hand; nudge is how a slightly-off placement is corrected. hide/show exclude or return an angle from automatic picture selection without touching saved explicit picture choices. trim persists source-clip trim handles; nudge persists a small user timing offset without rewriting measured sync times; remove deletes the clip while leaving media archived. Pass the Episode's current revision and a caller-stable idempotency key with every action.",
"inputSchema": {
"type": "object",
"properties": {
"episode_id": {
"type": "string",
"description": "Editable Episode public ID that scopes this change."
},
"expected_revision": {
"type": "integer",
"description": "Current Episode structural revision from the editor document."
},
"idempotency_key": {
"type": "string",
"description": "Caller-stable retry key for this exact change."
},
"action": {
"type": "object",
"description": "One camera-angle action. Use the canonical field names in the matching action shape.",
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"hide"
]
},
"angle_id": {
"type": "string",
"description": "Camera-angle anchor public ID from the Episode camera roster."
}
},
"required": [
"type",
"angle_id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"show"
]
},
"angle_id": {
"type": "string",
"description": "Camera-angle anchor public ID from the Episode camera roster."
}
},
"required": [
"type",
"angle_id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"trim"
]
},
"angle_id": {
"type": "string",
"description": "Camera-angle anchor public ID from the Episode camera roster."
},
"trim_start_seconds": {
"type": "number",
"description": "Seconds trimmed from the source clip start."
},
"trim_end_seconds": {
"type": "number",
"description": "Seconds trimmed from the source clip end."
}
},
"required": [
"type",
"angle_id"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"nudge"
]
},
"angle_id": {
"type": "string",
"description": "Camera-angle anchor public ID from the Episode camera roster."
},
"delta_seconds": {
"type": "number",
"description": "Small user timing offset to add."
}
},
"required": [
"type",
"angle_id",
"delta_seconds"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"remove"
]
},
"angle_id": {
"type": "string",
"description": "Camera-angle anchor public ID from the Episode camera roster."
}
},
"required": [
"type",
"angle_id"
],
"additionalProperties": false
}
]
}
},
"required": [
"episode_id",
"expected_revision",
"idempotency_key",
"action"
],
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": true,
"openWorldHint": false
},
"securitySchemes": [
{
"type": "noauth"
}
],
"_meta": {
"securitySchemes": [
{
"type": "noauth"
}
],
"ui": {
"visibility": [
"app"
]
},
"openai/widgetAccessible": true,
"openai/visibility": "private"
},
"outputSchema": {
"type": "object",
"properties": {
"composition_id": {
"type": "string"
},
"revision": {
"type": "integer"
},
"render_stale": {
"type": "boolean"
},
"angle": {
"type": "object"
},
"already_applied": {
"type": "boolean"
},
"audit_receipt_id": {
"type": "string"
}
},
"required": [],
"additionalProperties": false
}
}Errors
[
"composition_not_found",
"recording_not_found",
"angle_not_found",
"camera_program_conflict",
"stale_composition_revision",
"idempotency_conflict",
"invalid_time_range",
"invalid_input"
]Examples
[]