Upload exercise figure
upload_exercise_figure
Section titled “upload_exercise_figure”Use this to attach one reviewed image, MCP file, HTTPS image, base64 image, or rendered figure to an exercise by providing exerciseId, figureType, source, and width.
Contract metadata
Section titled “Contract metadata”{ "annotations": { "readOnlyHint": false, "destructiveHint": false, "idempotentHint": false, "openWorldHint": true }, "fileParams": [ "file_id_1" ], "requiredPermission": "write", "security": { "type": "oauth2", "scopes": [ "chalksurf:write" ] }}Input schema
Section titled “Input schema”The server advertises this JSON Schema to MCP clients. Runtime authorization and business-rule checks still apply.
{ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": {}, "properties": { "allowNeedsRevision": { "type": "boolean" }, "exerciseId": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", "type": "string" }, "figureType": { "enum": [ "text", "solution" ], "type": "string" }, "file_id_1": { "additionalProperties": false, "description": "A ChatGPT file ID.", "properties": { "download_url": { "format": "uri", "type": "string" }, "file_id": { "minLength": 1, "type": "string" }, "file_name": { "minLength": 1, "type": "string" }, "mime_type": { "minLength": 1, "type": "string" } }, "required": [ "download_url", "file_id" ], "type": "object" }, "organizationId": { "description": "The ChalkSurf organization ID to use for this request.", "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", "type": "string" }, "originalFileName": { "maxLength": 255, "minLength": 1, "type": "string" }, "source": { "additionalProperties": false, "description": "A figure source object. Use file_id_1 for ChatGPT file uploads; for rendered_figure, include input using the figure_render_draft shape.", "properties": { "data": { "maxLength": 14680064, "minLength": 1, "type": "string" }, "input": { "additionalProperties": false, "properties": { "assertions": { "items": { "additionalProperties": false, "properties": { "angleA": { "items": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "maxItems": 3, "minItems": 3, "type": "array" }, "angleB": { "items": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "maxItems": 3, "minItems": 3, "type": "array" }, "bisector": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "circle": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "degrees": { "maximum": 360, "minimum": 0, "type": "number" }, "from": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "id": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "line": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "lineObject": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "objectA": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "objectB": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "objects": { "items": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "maxItems": 8, "minItems": 3, "type": "array" }, "point": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "pointA": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "pointB": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "points": { "items": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "maxItems": 8, "minItems": 3, "type": "array" }, "segmentA": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "segmentB": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "segmentEnd": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "segmentStart": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "to": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "type": { "enum": [ "collinearPoints", "parallel", "perpendicular", "equalLength", "pointOnLine", "pointOnCircle", "angleMeasure", "equalAngle", "angleBisected", "tangent", "pointOnSegment", "concurrent" ], "type": "string" }, "vertex": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" } }, "required": [ "type" ], "type": "object" }, "maxItems": 30, "type": "array" }, "canvas": { "additionalProperties": false, "properties": { "height": { "default": 420, "maximum": 1200, "minimum": 120, "type": "integer" }, "viewBox": { "additionalProperties": false, "properties": { "xMax": { "maximum": 100000, "minimum": -100000, "type": "number" }, "xMin": { "maximum": 100000, "minimum": -100000, "type": "number" }, "yMax": { "maximum": 100000, "minimum": -100000, "type": "number" }, "yMin": { "maximum": 100000, "minimum": -100000, "type": "number" } }, "required": [ "xMin", "xMax", "yMin", "yMax" ], "type": "object" }, "width": { "default": 640, "maximum": 1200, "minimum": 120, "type": "integer" } }, "type": "object" }, "objects": { "items": { "additionalProperties": false, "properties": { "at": { "additionalProperties": false, "properties": { "x": { "maximum": 100000, "minimum": -100000, "type": "number" }, "y": { "maximum": 100000, "minimum": -100000, "type": "number" } }, "required": [ "x", "y" ], "type": "object" }, "definition": { "additionalProperties": false, "properties": { "at": { "additionalProperties": false, "properties": { "x": { "maximum": 100000, "minimum": -100000, "type": "number" }, "y": { "maximum": 100000, "minimum": -100000, "type": "number" } }, "required": [ "x", "y" ], "type": "object" }, "center": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "count": { "maximum": 3, "minimum": 1, "type": "integer" }, "dx": { "maximum": 2, "minimum": -2, "type": "number" }, "dy": { "maximum": 2, "minimum": -2, "type": "number" }, "end": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "endAngleDegrees": { "maximum": 720, "minimum": -360, "type": "number" }, "from": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "grid": { "type": "boolean" }, "kind": { "enum": [ "midpointBetweenPoints", "intersection", "projection", "pointOnSegmentRatio", "triangleCenter", "betweenPoints", "throughPoints", "parallelThrough", "perpendicularThrough", "perpendicularBisector", "triangleMedian", "triangleAltitude", "fromThrough", "angleBisector", "centerRadius", "centerThroughPoint", "throughThreePoints", "diameter", "centerTangentToLine", "triangleIncircle", "centerRadiusAngles", "centerStartEnd", "threePoints", "onSegmentObject", "atPoint", "atCoordinate", "cartesian" ], "type": "string" }, "line": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "mid": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "objectA": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "objectB": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "onto": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "point": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "pointA": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "pointB": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "pointC": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "points": { "items": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "maxItems": 12, "minItems": 3, "type": "array" }, "radius": { "exclusiveMinimum": 0, "maximum": 100000, "type": "number" }, "ratio": { "maximum": 1, "minimum": 0, "type": "number" }, "segment": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "side": { "enum": [ "internal", "external" ], "type": "string" }, "sideA": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "sideB": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "start": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "startAngleDegrees": { "maximum": 360, "minimum": -360, "type": "number" }, "sweepDirection": { "enum": [ "clockwise", "counterclockwise" ], "type": "string" }, "text": { "maxLength": 80, "minLength": 1, "type": "string" }, "through": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "tickStep": { "exclusiveMinimum": 0, "maximum": 1000, "type": "number" }, "to": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "triangle": { "items": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "maxItems": 3, "minItems": 3, "type": "array" }, "vertex": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "which": { "additionalProperties": false, "properties": { "index": { "maximum": 1, "minimum": 0, "type": "integer" }, "kind": { "enum": [ "nearPoint", "upper", "lower", "left", "right", "byIndex" ], "type": "string" }, "point": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" } }, "required": [ "kind" ], "type": "object" }, "xLabel": { "maxLength": 12, "minLength": 1, "type": "string" }, "yLabel": { "maxLength": 12, "minLength": 1, "type": "string" } }, "required": [ "kind" ], "type": "object" }, "id": { "description": "A stable figure object identifier such as A, AB, c1, or angle_mark_1.", "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,31}$", "type": "string" }, "label": { "maxLength": 80, "minLength": 1, "type": "string" }, "radius": { "exclusiveMinimum": 0, "maximum": 1000, "type": "number" }, "size": { "exclusiveMinimum": 0, "maximum": 1000, "type": "number" }, "style": { "additionalProperties": false, "properties": { "dash": { "enum": [ "solid", "dashed", "dotted" ], "type": "string" }, "fill": { "enum": [ "black", "gray", "lightGray", "red", "orange", "green", "blue", "purple", "white", "none" ], "type": "string" }, "opacity": { "maximum": 1, "minimum": 0.05, "type": "number" }, "stroke": { "enum": [ "black", "gray", "lightGray", "red", "orange", "green", "blue", "purple", "white", "none" ], "type": "string" }, "strokeWidth": { "maximum": 8, "minimum": 0.25, "type": "number" }, "textSize": { "maximum": 32, "minimum": 8, "type": "number" } }, "type": "object" }, "type": { "enum": [ "point", "segment", "line", "ray", "circle", "arc", "polygon", "angleMark", "rightAngleMark", "tickMark", "label", "axes" ], "type": "string" } }, "required": [ "id", "type" ], "type": "object" }, "maxItems": 80, "minItems": 1, "type": "array" } }, "required": [ "objects" ], "type": "object" }, "kind": { "enum": [ "https_url", "base64_image", "rendered_figure" ], "type": "string" }, "mimeType": { "enum": [ "image/avif", "image/gif", "image/jpeg", "image/png", "image/svg+xml", "image/tiff", "image/webp" ], "type": "string" }, "url": { "format": "uri", "type": "string" } }, "required": [ "kind" ], "type": "object" }, "widthInCm": { "maximum": 20, "minimum": 1, "type": "number" } }, "required": [ "organizationId", "exerciseId", "figureType" ], "type": "object"}Output schema
Section titled “Output schema”{ "$schema": "https://json-schema.org/draft/2020-12/schema", "additionalProperties": false, "properties": { "figure": { "additionalProperties": false, "properties": { "exerciseFigureId": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", "type": "string" }, "orderIndex": { "maximum": 9007199254740991, "minimum": 0, "type": "integer" }, "provenance": { "additionalProperties": false, "properties": { "byteLength": { "maximum": 104857600, "minimum": 0, "type": "integer" }, "createdBy": { "enum": [ "agent", "user", "import" ], "type": "string" }, "mimeType": { "maxLength": 100, "minLength": 1, "type": "string" }, "originalFileName": { "maxLength": 255, "minLength": 1, "type": "string" }, "pixelHeight": { "maximum": 100000, "minimum": 1, "type": "integer" }, "pixelWidth": { "maximum": 100000, "minimum": 1, "type": "integer" }, "renderQualityStatus": { "enum": [ "passed", "needs_revision", "unchecked" ], "type": "string" }, "renderSpecHash": { "pattern": "^[a-f0-9]{64}$", "type": "string" }, "sourceKind": { "enum": [ "local_file", "mcp_file", "https_url", "base64_image", "rendered_figure", "user_upload", "import", "unknown" ], "type": "string" } }, "required": [ "sourceKind", "createdBy" ], "type": "object" }, "rotationClockwiseDegrees": { "anyOf": [ { "const": 0, "type": "number" }, { "const": 90, "type": "number" }, { "const": 180, "type": "number" }, { "const": 270, "type": "number" } ] }, "type": { "enum": [ "text", "solution" ], "type": "string" }, "url": { "format": "uri", "type": "string" }, "widthInCm": { "maximum": 20, "minimum": 1, "type": "number" } }, "required": [ "type", "url", "widthInCm", "exerciseFigureId", "orderIndex", "rotationClockwiseDegrees" ], "type": "object" }, "receipt": { "additionalProperties": false, "properties": { "changedPaths": { "items": { "type": "string" }, "type": "array" }, "details": {}, "operation": { "enum": [ "copy_exercise", "copy_sheet", "update_exercise", "resolve_quality_issue", "dismiss_quality_issue", "update_sheet", "bulk_update_sheets", "append_exercises_to_sheet", "create_folder", "rename_folder", "delete_exercise", "delete_sheet", "delete_folder", "create_sheet", "create_exercise", "upload_exercise_figure", "set_exercise_visibility", "set_sheet_visibility" ], "type": "string" }, "precondition": { "additionalProperties": false, "properties": { "actualUpdatedAt": { "anyOf": [ { "minLength": 1, "type": "string" }, { "type": "null" } ] }, "expectedUpdatedAt": { "anyOf": [ { "minLength": 1, "type": "string" }, { "type": "null" } ] }, "status": { "enum": [ "matched", "not_required" ], "type": "string" } }, "required": [ "status" ], "type": "object" }, "resource": { "additionalProperties": false, "properties": { "id": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", "type": "string" }, "type": { "enum": [ "exercise", "sheet", "folder" ], "type": "string" } }, "required": [ "type", "id" ], "type": "object" }, "version": { "oneOf": [ { "additionalProperties": false, "properties": { "created": { "const": true, "type": "boolean" }, "resourceType": { "const": "sheet", "type": "string" }, "versionId": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$", "type": "string" }, "versionNumber": { "exclusiveMinimum": 0, "maximum": 9007199254740991, "type": "integer" } }, "required": [ "resourceType", "created", "versionId", "versionNumber" ], "type": "object" }, { "additionalProperties": false, "properties": { "created": { "const": false, "type": "boolean" }, "reason": { "minLength": 1, "type": "string" }, "resourceType": { "const": "sheet", "type": "string" } }, "required": [ "resourceType", "created", "reason" ], "type": "object" } ] }, "warnings": { "items": { "additionalProperties": false, "properties": { "code": { "type": "string" }, "details": {}, "message": { "type": "string" } }, "required": [ "code", "message" ], "type": "object" }, "type": "array" } }, "required": [ "resource", "operation", "changedPaths", "precondition", "warnings", "details" ], "type": "object" }, "review": { "additionalProperties": false, "properties": { "byteLength": { "maximum": 9007199254740991, "minimum": 0, "type": "integer" }, "nextActions": { "items": { "minLength": 1, "type": "string" }, "type": "array" }, "pixelHeight": { "anyOf": [ { "maximum": 9007199254740991, "minimum": 1, "type": "integer" }, { "type": "null" } ] }, "pixelWidth": { "anyOf": [ { "maximum": 9007199254740991, "minimum": 1, "type": "integer" }, { "type": "null" } ] }, "renderQualityStatus": { "anyOf": [ { "enum": [ "passed", "needs_revision", "unchecked" ], "type": "string" }, { "type": "null" } ] }, "sourceKind": { "enum": [ "local_file", "mcp_file", "https_url", "base64_image", "rendered_figure", "user_upload", "import", "unknown" ], "type": "string" }, "warnings": { "items": { "additionalProperties": false, "properties": { "code": { "minLength": 1, "type": "string" }, "details": {}, "message": { "minLength": 1, "type": "string" } }, "required": [ "code", "message" ], "type": "object" }, "type": "array" } }, "required": [ "pixelWidth", "pixelHeight", "byteLength", "sourceKind", "warnings", "renderQualityStatus", "nextActions" ], "type": "object" } }, "required": [ "figure", "review", "receipt" ], "type": "object"}