Skip to content

Render draft figure

Use this to render a bounded semantic 2D figure draft to SVG/PNG and receive deterministic diagnostics, assertion results, and review hints before any save/upload step.

{
"annotations": {
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": false,
"openWorldHint": false
},
"fileParams": [],
"requiredPermission": "read",
"security": {
"type": "oauth2",
"scopes": [
"chalksurf:read"
]
}
}

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": 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"
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"assertions": {
"items": {
"additionalProperties": false,
"properties": {
"delta": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
]
},
"expected": {
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"propertyNames": {
"type": "string"
},
"type": "object"
},
"id": {
"type": "string"
},
"measured": {
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"propertyNames": {
"type": "string"
},
"type": "object"
},
"revisionHint": {
"type": "string"
},
"status": {
"enum": [
"passed",
"failed"
],
"type": "string"
},
"tolerance": {
"type": "number"
},
"type": {
"type": "string"
}
},
"required": [
"id",
"type",
"status",
"measured",
"expected",
"delta",
"tolerance"
],
"type": "object"
},
"type": "array"
},
"diagnostics": {
"items": {
"additionalProperties": false,
"properties": {
"assertionId": {
"type": "string"
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"objectId": {
"type": "string"
},
"severity": {
"enum": [
"error",
"warning"
],
"type": "string"
}
},
"required": [
"code",
"severity",
"message"
],
"type": "object"
},
"type": "array"
},
"png": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"byteLength": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"height": {
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"nonBlankPixelRatio": {
"maximum": 1,
"minimum": 0,
"type": "number"
},
"width": {
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
}
},
"required": [
"width",
"height",
"byteLength",
"nonBlankPixelRatio"
],
"type": "object"
},
{
"type": "null"
}
]
},
"quality": {
"additionalProperties": false,
"properties": {
"revisionHints": {
"items": {
"type": "string"
},
"type": "array"
},
"status": {
"enum": [
"passed",
"needs_revision",
"unchecked"
],
"type": "string"
},
"summary": {
"type": "string"
}
},
"required": [
"status",
"summary",
"revisionHints"
],
"type": "object"
},
"reviewRubric": {
"items": {
"type": "string"
},
"type": "array"
},
"schemaVersion": {
"const": 1,
"type": "number"
},
"svg": {
"anyOf": [
{
"additionalProperties": false,
"properties": {
"byteLength": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"height": {
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
},
"width": {
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"type": "integer"
}
},
"required": [
"width",
"height",
"byteLength"
],
"type": "object"
},
{
"type": "null"
}
]
},
"visualCueSuggestions": {
"items": {
"additionalProperties": false,
"properties": {
"assertionId": {
"type": "string"
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"objectIds": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"code",
"message"
],
"type": "object"
},
"type": "array"
}
},
"required": [
"schemaVersion",
"quality",
"diagnostics",
"assertions",
"visualCueSuggestions",
"svg",
"png",
"reviewRubric"
],
"type": "object"
}