Ceci est le manuel de Studio 1.0.2, une version antérieure. Le manuel de la dernière version
Documentation 1.0.2 Référence
Cette référence est générée à partir du programme et n’existe qu’en anglais.
MCP tool reference
Twinwright Studio offers its twin to AI clients (Claude, ChatGPT, Cursor and others) over the Model Context Protocol. A client starts the program in the background as TwinwrightStudio.exe --mcp (the command is shown under AI > Connect AI clients…, The command and configuration) and calls these 31 tools. Each acts on one machine: the one the user sees in the window ("machine": "window", while the window's AI switch is on) or an invisible practice machine ("sandbox"). Parameters marked * are required.
Contents
- Machines:
machine_status,machine_control,machine_mdi - Set-ups:
setup_workpiece,setup_tool,setup_work_zero,inspect_part,inspect_report,setup_sheet,probe_cycle,setup_part,setup_copy,setup_example - Programs:
program_check,program_simulate,program_run,program_load,program_debug,program_restart,program_optimize,geometry_import,geometry_nest,program_generate,program_edit,program_versions - Runs and results:
run_status,run_profile,result_compare,result_image,log_query - The licence:
licence_status
Machines
machine_status - Machine status
read-only · the same call twice does no more than once
The state of a machine: controller state and alarm (with its meaning), homed or not, machine and work positions, G54, the tool in the spindle, the spindle, the workpiece on the table and the program's progress - and the other machines, a line each. detail "full" adds the controller's modes, offsets and planner queue; detail "program" gives the loaded program's text in pages. Changes nothing. Tell the user which machine you looked at: only the window's is the one they see.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" | |
detail | string | "brief" | (one of brief, full, program) |
offset | integer | 0 | detail program: the first line (0-based) |
limit | integer | 400 |
Returns (structured content): machine, notice, status, machines, program.
machine_control - Operate a machine
changes the machine (destructive)
An operator's action on a machine, then its state. home: homes (resets and unlocks first if it is in an alarm; does nothing when already homed - force: true homes again). unlock: $X, when the position is still known. reset: Ctrl-X. hold / resume: feed hold / cycle start. stop: stops the running program. move: to x, y and/or z (mm) in the work (G54) or machine frame, rapid or at feed; moving X/Y it first goes up to the top of Z, where homing left it (safe_z). power_on / power_off: the main switch (and START). estop / estop_release. restart: a practice machine starts afresh (never the window's). On the user's machine the user allows each change in the window; when the window's twin follows a real machine (shadow mode) it takes none of these, stops included - the real machine is stopped at its own controls or in its sender.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
action * | string | (one of home, unlock, reset, hold, resume, stop, move, power_on, power_off, estop, estop_release, restart) | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" | |
x | number | ||
y | number | ||
z | number | ||
frame | string | "work" | (one of work, machine) |
feed | number | mm/min (G1); omitted: rapid (G0) | |
safe_z | boolean | true | |
force | boolean | false | |
drive | string | restart: the drive model (L0 ideal motion, fastest; L1 closed-loop drives, the default; L2 flexible transmission with backlash; L3 electrical) (one of L0, L1, L2, L3) |
Returns (structured content): machine, notice, status, action, did, next.
machine_mdi - Send MDI lines
changes the machine (destructive)
Send G-code or $ lines to a machine as an operator types them: one at a time, each with the controller's answer - ok, or the error and what it means. After a refused line the rest are not sent (the controller would refuse them too) and the result says so. Waits until the machine is idle again and gives its state. For homing, unlocking, stopping or moving, machine_control is simpler.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
lines * | array of string | ||
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" | |
timeout_s | number | 120 | simulated seconds a line may take |
Returns (structured content): machine, notice, status, lines.
Set-ups
setup_workpiece - Place a blank
changes the machine (destructive)
Put a blank on a machine's table (replacing the one there), take it off (op "remove") or turn it over where it stands (op "flip": the other side up, what was machined stays - for a part's second side; refused while a program runs). Table coordinates in mm: X 0..200 left to right, Y 0..150 front to back, centre [100, 75]. Homes first if needed. The twin refuses setups that do not fit and says why. A thin sheet cut through: fixture tape on a sacrificial plate (sacrificial) - the blank that much higher, the cuts through it go into the plate, not the table.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
op | string | "place" | (one of place, remove, flip) |
turn | string | "u" | op flip: u about the blank's u axis (its length as placed, X at angle 0): front and back change places; v about its v axis: left and right change places (the blank also turns 180 degrees about Z) (one of u, v) |
shape | string | "block" | (one of block, cylinder, tube, hex, rod, stl) |
size | array of number | block: [x, y, z] mm; cylinder/rod: [diameter, length]; tube: [outer, inner, length]; hex: [across flats, length] | |
material | string | "6061-T6" | (one of 6061-T6, 7075-T6, ADC12, HPb59-1, H59, T2, Q235, 45, 304, HT200, POM, PMMA, PA6, HDPE, MDF, hardwood, wax) |
fixture | string | "vise" | (one of vise, clamps, tape, fixed, vblock, none) |
at | array of number | [100, 75] | blank centre on the table [x, y] mm |
angle | number | 0 | rotation about Z, degrees |
res | number | simulation cell size in mm (0.01..0.2; smaller is finer and slower) | |
file | string | shape stl: the blank's STL on this computer | |
keep_zero | string | set G54 on the new blank at once, at this corner (as setup_work_zero does); left out, G54 stays where it was (one of front-left-top, center-top) | |
sacrificial | object | fixture tape only: the blank taped on a sacrificial plate, so that what is cut through goes into the plate, not the table. The blank sits higher by the plate and the tape; the tool may cut into the plate (the summary's setup.sacrificial_cut_mm says how deep), the collet and the spindle may not; the tape holds as on the table | |
sacrificial.material | string | "MDF" | a material of the list above (for the drawing and the set-up sheet) |
sacrificial.thickness | number | 10 | mm, 3 to 25 |
sacrificial.size | array of number | [length, width] mm along the blank's own axes; left out: the blank's footprint and 10 mm each side | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, placed, flipped, refused, reason, setup.
setup_tool - Tool and tool table
changes the machine · the same call twice does no more than once
The tool in a machine's spindle (spec) and/or its tool table for programs that change tools with M6 (tools: {"1": spec, ...}; the change and the length measurement then happen by themselves). Tool spec: kind and diameter in mm, then options. Kinds: 'flat D', 'ball D', 'bull D RC' (corner radius), 'v D ANGLE' (V-bit), 'drill D ANGLE', 'tslot D THICKNESS dNECK', 'dovetail D ANGLE dNECK', 'thread D PITCH', 'probe D' (a touch probe with a ball of D; ' typical' a kinematic one: it triggers its pretravel past the touch, scattered with a seed; ' ideal' at the touch, the default). Options: 'nN' flutes (default 2), 'LMM' stick-out from the collet (the length reference tool sticks out 15.5 mm), ' sD lR' a shank of diameter D and the reach R below it, ' tirU' the cutter's runout in the collet, TIR in um (a precision collet's class, or as measured; default: the machine's). Examples: 'flat 6 n3 L20', 'ball 3 n2 L16', 'v 6 60 L18', 'flat 1.5 n2 s4 l5 L14', 'flat 0.2 n2 s4 l1 L15 tir3', 'probe 2 L30 typical'.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
spec | string | e.g. 'flat 6 n3 L20' | |
tools | object of string | the tool table for M6: {"1": "flat 6 n3 L20", ...} | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, tool, tool_table.
setup_work_zero - Set G54 on the blank
changes the machine · the same call twice does no more than once
Set a machine's G54 work zero on its blank - the front-left top corner (default: the corner at the machine's front left, X and Y least, when the blank lies square - turned over "v" too) or the top centre, with the tool now in the spindle as the length reference; an optional offset [x, y, z] mm. Homes first if needed.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
corner | string | "front-left-top" | (one of front-left-top, center-top) |
offset | array of number | [0, 0, 0] | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, g54_mpos.
inspect_part - Inspect the part with the probe
changes the machine
Check the finished part on the machine with the touch probe in the spindle against its design: from the features of a program program_generate made (program; or features as it takes them) the checks - a pocket's sizes, centre and depth, a hole's diameter and position, a slot's width and depth, a faced step, a rectangle's or a circle's contour - each measured by a probe cycle (as probe_cycle runs them: results from the trigger points) and judged against the design (the tolerance given, else ISO 2768-1 - class f unless tol.class says) and against the twin's prediction (the same touches on the workpiece the twin cut: the twin's estimate, not a measuring uncertainty). Depths from a touch on the top where no feature reaches. A chamfer: two touches down onto its face - its angle, its width from the outline and its depth there (its V-bit: the feature's tool, else the job's; the material's side from the job's pocket or contour with that outline). V-carving, engraving, threads and 3D surfaces are said not measured. ISO 2768-2's class after part 1's as a drawing writes it (tol.class "mK") adds form checks and touches: a floor's flatness (a grid of 9 instead of 1), the walls' perpendicularity to Z (4 more at a second depth), a long wall's straightness (5 along it, 20 mm and longer), a circle's circularity (8 round instead of 4) and its axis' perpendicularity (4 more) - the answer's form_cost and the window's question say how many and how long before; only: [..] does part of them; one letter adds none. Least-squares estimates from a few touches, not ISO 1101's minimum zone nor a CMM's form measurement (summary.form_method). The work offset must be the one the part was cut with. Each inspection is kept as a record (written once, its SHA-256 in the audit log): inspect_report makes its CSV and PDF. plan: true only says what it would do. Professional edition.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
program | string | a program program_generate made: the features of the job kept with it | |
version | integer | that job's version (0: the last) | |
features | array of object | instead of program: the features as program_generate takes them | |
tool | string | with features: the tool they were cut with (a drilling's holes are its size) | |
only | array of integer | only these features (1, 2 ... in the job) | |
tol | object | +/- mm (an angle: degrees) instead of ISO 2768-1 | |
tol.size | number | ||
tol.depth | number | ||
tol.position | number | ||
tol.angle | number | a chamfer's, degrees | |
tol.class | string | "f" | ISO 2768-1's class where no tolerance is given (a drawing's ISO 2768-mK: m) - with ISO 2768-2's after it (mK: H, K or L) its form checks too, more touches (one of f, m, c, v, fH, fK, fL, mH, mK, mL, cH, cK, cL, vH, vK, vL) |
probe | object | the probe's compensation instead of this machine's calibration: r_eff, lobing, phase_deg, pretravel_z | |
plan | boolean | false | only plan it, nothing moves and nothing is recorded: each feature, what it measures there or why not, the touches and about how long, the form checks' share, the classes, the program zero it would measure in (zero_mpos), each touch's point and way (points) - with the spindle's probe, else the tool table's first, else probe 2 L30 (planned_with) |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, plan, features, summary, reference, cycles, twin_cell_mm, inspection, record, sha256, record_error, error, form_cost.
inspect_report - Inspection report
changes the machine · the same call twice does no more than once
The report of an inspection inspect_part recorded, written by the program itself: a CSV (UTF-8, for a spreadsheet) and a PDF - the job, setup, tools, the probe and its ring-gauge calibration, each feature's nominal, tolerance and its basis (ISO 2768-1's class and table, or given), the twin's estimate, the measured value, the deviation and the verdict, why a feature was not measured, and the twin's workpiece from above. Into the reports folder (Documents/Twinwright Studio/Reports); their SHA-256 into the audit log. The same record gives the same bytes again. The twin's estimate is the twin's own calculation for the same touches on its simulated workpiece, not the machine's measuring uncertainty; the report says nothing about how precisely the machine measures or positions. The PDF is in English where the language in use needs letters its fonts lack (the CSV is in it). verify: a file checked instead - its SHA-256 searched for in the audit log and the log's chain checked. It moves nothing. Professional edition.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
inspection | string | "last" | the record's name as inspect_part gave it (last: the one recorded last) |
format | string | "both" | (one of csv, pdf, both) |
unit | string | lengths (default: the units in use) (one of mm, in) | |
paper | string | the PDF's (default: the region's) (one of a4, letter) | |
verify | string | a file's path: check it against the audit log instead of writing a report |
Returns (structured content): machine, notice, inspection, record, record_sha256, csv, pdf, found, chain_whole, sha256.
setup_sheet - Setup sheet
changes the machine · the same call twice does no more than once
The setup sheet of a job program_generate made, for the operator at the machine: one HTML page to print (A4 or Letter: the region's) in the language in use - each program's name, lines and SHA-256 (to match it with the one loaded), the blank and its fixture as the twin sets it up (the vise's parallels, the grip), the tools, each setup's way there (turned over, held another way), its work zero and the probe panel's cycles that find it, the program's travel, its Z clearance (the probe and each tool over the set-up and to the program's highest and lowest points - the twin's Z budget: enough, or how much short), the operations (strategy, tool, speed, feed, depth, the twin's estimate of each one's time), a top view, the notes, a box to sign. The blank as the machine has it set up (the call's machine), else the job's. Into the reports folder (Documents/Twinwright Studio/Reports) as <job>-setup-sheet.html; its SHA-256 into the audit log. The times are the twin's estimates from the program, not measured. It moves nothing. Professional edition.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
program * | string | the name program_generate was given (its job is kept with it; a job in setups: each setup's program) | |
version | integer | the job's version (left out: the last) | |
paper | string | left out: the region's (one of a4, letter) | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, file, sha256, bytes, paper, programs, z_clearance.
probe_cycle - Touch-probe cycle
changes the machine
Measure with the touch probe in the spindle (setup_tool "probe 2 L30") and, if asked, set the work zero from what it finds: cycle edge (a face of the blank: side x-, x+, y-, y+), corner (front-left, front-right, back-left, back-right; inside: a pocket's corner), bore (its centre and diameter, 4 or 8 points), boss (the same from outside), surface (its Z) or calibrate (a ring gauge of known d: the probe's effective ball radius, its lobes and pretravel - this machine's later cycles here use them). Each touch: a protected move to its start (G38.3), a fast touch, the release (G38.4), a slow touch (F25 at most); the results come from the slow touches' trigger points ([PRB:]), not from where the axes stopped. Left out, at comes from the blank the twin knows. Refused: no probe in the spindle, its input already triggered, the spindle turning, a move outside the soft limits. set {x, y, z}: the active work offset moved so the feature gets these work coordinates (G10 L2); the result's set_parts give each axis found as its G10 L2 word (the feature at work 0, or at set's value). Uncalibrated, the results are off by the probe's pretravel. dry: the plan only - checks (probe, machine, soft limits, safe height, depth: ok, warn or bad), each touch's path (machine coordinates), the program and its time; nothing moves. calibrate keep false: its numbers and a cal_id, kept later with save (this session's measurement only).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
cycle * | string | (one of edge, corner, bore, boss, surface, calibrate) | |
side | string | edge: the face (x- the blank's least X, touched from outside moving +X; y- its front) (one of x-, x+, y-, y+) | |
corner | string | "front-left" | (one of front-left, front-right, back-left, back-right) |
inside | boolean | false | corner: a pocket's corner, its walls touched from inside (at needed) |
at | array of number | [x, y] in the active work coordinates: a point on the face (edge), the corner, the centre (bore, boss, calibrate), where to touch (surface) - left out: from the blank | |
d | number | bore, boss: the nominal diameter; calibrate: the ring gauge's known diameter, mm (left out: a tube's or cylinder blank's) | |
depth | number | 3 | how far below the top the ball's centre touches, mm |
top | number | the work Z the depth is from (left out: the blank's top) | |
points | integer | edge 1, or 2 (span apart: the face's turn too), 3, 4 or 8 over span (its straightness too: about their least-squares line); corner 2, or 3 (two on its X face: the blank's turn and where its faces meet); bore, boss 4 (default) or 8 (its roundness too) (one of 1, 2, 3, 4, 8) | |
span | number | mm between the first and the last touch on one face (left out: 0.6 of the face) | |
grid | array of integer | surface: [nx, ny] touches over size (25 at most): the plane through them - its tilt and flatness | |
size | array of number | surface grid: [w, h] mm about at (left out: 0.6 of the blank) | |
inset | number | 5 | corner: mm from the corner along each face |
clear | number | 3 | mm between the probe and where the face should be when a touch starts |
search | number | 5 | mm past where it should be a touch looks |
fast | number | 300 | |
slow | number | 20 | (at most 25) |
set | object | move the active work offset so the feature found gets these work coordinates (the axes the cycle finds) | |
set.x | number | ||
set.y | number | ||
set.z | number | ||
probe | object | the probe's compensation instead of this machine's last calibration here: r_eff, lobing, phase_deg, pretravel_z (mm, degrees) | |
dry | boolean | false | the plan only: the checks, the path, the program and its time - nothing moves, nobody is asked |
keep | boolean | true | calibrate: keep the calibration on the machine (false: its numbers and a cal_id only) |
save | string | calibrate: keep the calibration this session measured with keep false (its cal_id) - nothing measured | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, cycle, touches, result, work, set, comp, archive, notes, program, sent, error, dry, checks, plan, seconds, set_parts, cal_id.
setup_part - Set the design part
changes the machine · the same call twice does no more than once
The design part (an STL of the finished part, mm) to compare a machine's workpiece with. origin: machine mm of the part's origin; omitted: the program zero (as CAM writes it). An empty stl takes it away.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
stl * | string | ||
origin | array of number | ||
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, part.
setup_copy - Copy a setup
changes the machine (destructive) · the same call twice does no more than once
Copy one machine's setup - blank and fixture, the tool in the spindle, the tool table, G54, the design part - onto an invisible practice machine, to try programs there at full speed (default: from the user's window to "sandbox"). The workpiece comes as it is there, cuts and all (stock: "fresh" for a new blank).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
stock | string | "current" | current: the machine's workpiece as it is, cuts and all (carry on with a part already cut); fresh: a new blank (a whole program from the start) (one of current, fresh) |
from | string | the machine to copy (default: the user's window) | |
to | string | "sandbox" | a practice machine: sandbox or sandbox-<name> |
Returns (structured content): machine, notice, copied_from, workpiece, tool.
setup_example - Example parts
changes the machine (destructive)
Without id: the example parts that come with the twin (id, title, material, blank, summary). With id: a machine set up as the example's operator would - blank, tool table, homing, G54 on the blank, the design part - with the example's program loaded, not started. To verify an example without setting anything up: program_simulate {example: id}.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
id | string | ||
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, examples, example, ready.
Programs
program_check - Check a program
read-only · the same call twice does no more than once
Check a program without running it: the controller's own check mode ($C) - every line it refuses, with the error explained - the preview of its path against a machine's setup (estimated time, collisions, rapids into the stock, travel) and the static rules S01-S20 (start block, end, F and S missing or out of range, dense short lines, plunges, rapids below Z0, the water-cooled spindle without M8, arcs in inverse time, G33 without a spindle encoder, characters the controller takes for real-time commands, drilling cycles' holes a single-precision controller plunges once more, Z down after a tool change before X and Y, ...) with a suggested line for each. Runs on a hidden copy of the machine's setup, its workpiece as it is (stock): the machine does not change.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
gcode | string | the program's text - or leave it out and give name (and version) of a program in the working folder (program_versions) | |
name | string | "program.nc" | |
version | integer | with name, no gcode: that saved version's text (0: the last) | |
stock | string | "current" | current: the machine's workpiece as it is, cuts and all (carry on with a part already cut); fresh: a new blank (a whole program from the start) (one of current, fresh) |
example | string | an example's setup (and program, when gcode is omitted) instead of the machine's: see setup_example | |
setup | object | an explicit setup instead of the machine's: {spec: the workpiece's setup as machine_status shows it (status.workpiece), tool, tools: {T: spec}, g54: [x,y,z] MPos, part: STL path} | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, ok, refused, preview, static_rules.
program_simulate - Simulate a program
read-only · the same call twice does no more than once
Run a program to its end on a hidden copy of a machine's setup - the machine itself does not change; the copy starts from the machine's workpiece as it is, cuts and all (stock: "fresh" for a new blank) - as fast as the computer goes: moves hundreds of times faster than real time, cutting a few times faster (a heavy cut can be slower than real time). The report: completed or not, machine time, alarms, collisions, near misses, rapids into material, cuts with the spindle stopped, workpiece slip, chatter margin, force and power peaks, removed volume, deviation from the design part, the slowest lines - and a run id for run_profile, result_compare and result_image. Programs with M6 need tools. Longer than budget_s: the answer is the run id (run_status waits).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
gcode | string | the program's text - or leave it out and give name (and version) of a program in the working folder (program_versions) | |
name | string | "program.nc" | |
version | integer | with name, no gcode: that saved version's text (0: the last) | |
tools | object of string | the tool table for M6: {"1": "flat 6 n3 L20", ...} | |
stock | string | "current" | current: the machine's workpiece as it is, cuts and all (carry on with a part already cut); fresh: a new blank (a whole program from the start) (one of current, fresh) |
example | string | an example's setup (and program, when gcode is omitted) instead of the machine's: see setup_example | |
setup | object | an explicit setup instead of the machine's: {spec: the workpiece's setup as machine_status shows it (status.workpiece), tool, tools: {T: spec}, g54: [x,y,z] MPos, part: STL path} | |
check_first | boolean | true | |
timeout_s | number | 3600 | simulated seconds allowed |
budget_s | number | 40 | wall-clock seconds this call waits before it answers with a run id (at most 45: clients give up after 60 s; run_status waits for the rest) |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, run, completed, simulated_time_s, issues, status.
program_run - Run a program on the machine
changes the machine (destructive)
Run a program on the machine itself - the one loaded, or gcode (it replaces the loaded one): on the user's machine in real time, after the user allows it in the window; on a practice machine (sandbox) at full speed, cutting its workpiece. Checked first, the loaded program too (check_first): not run when the controller refuses a line or the check ends in an alarm - and on the user's machine not when the check's preview finds a collision, a rapid move into material, a cut with the spindle stopped or a move out of travel. Same report as program_simulate. To find out first what a program would do, use program_simulate.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
gcode | string | the program's text - or leave it out and give name (and version) of a program in the working folder (program_versions) | |
name | string | "program.nc" | |
version | integer | with name, no gcode: that saved version's text (0: the last) | |
tools | object of string | the tool table for M6: {"1": "flat 6 n3 L20", ...} | |
check_first | boolean | true | |
fits_only | boolean | false | nothing run, nothing moved: only the twin's grid made finer where the touch probe will measure the fits of the saved program name (its CAM job), as a run does before it starts - for a program started some other way (the window's own start); the answer's fit_regions says how many regions, where (program mm) and their cells, or why none (no job, no fits, several setups). Before the cut, never after: what is cut already stays as coarse as it was |
timeout_s | number | 3600 | simulated seconds allowed |
budget_s | number | 40 | wall-clock seconds this call waits before it answers with a run id (at most 45: clients give up after 60 s; run_status waits for the rest) |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, run, completed, simulated_time_s, issues, status.
program_load - Load a program
changes the machine · the same call twice does no more than once
Load a program into a machine without starting it. On the user's machine the window shows how it differs from the program loaded there and the user allows it; they may then start it themselves.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
gcode | string | the program's text - or leave it out and give name (and version) of a program in the working folder (program_versions) | |
name | string | "program.nc" | |
version | integer | with name, no gcode: that saved version's text (0: the last) | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, lines.
program_debug - Debug a program
read-only
Debug a program on a hidden copy of a machine's setup. run_to: runs gcode from its start until a file line (line) or a condition (when: force_n, load_pct, ferr_mm, margin, near_mm as limits; cut, rapid_cut, collision, alarm, state true; modal ["units","wcs","tool","spindle",...]) and stops virtual time there - mid-motion, exactly as the program has it, at the same instant every time. Then inspect (the line, modes, positions, speed, the cut, the planner's queue), step (until: time with ms, block, or pause), continue (to the next pause or the end), end.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
action * | string | (one of run_to, inspect, step, continue, end) | |
gcode | string | the program's text | |
name | string | "program.nc" | |
line | integer | file line (1-based) | |
when | object | conditions, e.g. {"force_n": 60, "cut": true} | |
tools | object of string | the tool table for M6: {"1": "flat 6 n3 L20", ...} | |
until | string | "time" | (one of time, block, pause) |
ms | number | 10 | |
stock | string | "current" | current: the machine's workpiece as it is, cuts and all (carry on with a part already cut); fresh: a new blank (a whole program from the start) (one of current, fresh) |
example | string | an example's setup (and program, when gcode is omitted) instead of the machine's: see setup_example | |
setup | object | an explicit setup instead of the machine's: {spec: the workpiece's setup as machine_status shows it (status.workpiece), tool, tools: {T: spec}, g54: [x,y,z] MPos, part: STL path} | |
timeout_s | number | 3600 | simulated seconds allowed |
budget_s | number | 40 | wall-clock seconds this call waits before it answers with a run id (at most 45: clients give up after 60 s; run_status waits for the rest) |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, reached, pause, where.
program_restart - Restart from a line
changes the machine (destructive)
The program loaded on a machine from a file line on, as an operator restarts after a broken tool: a start block from the program's own state before that line (units, plane, work offset, tool, spindle speed and direction with its spin-up, coolant, over the start point at the safe height, down to it, feed, distance mode), then the rest. start: true loads and runs it (on the user's machine after the user allows it).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
line * | integer | ||
start | boolean | false | |
safe_z | number | machine Z to go up to first (default 2 mm below home) | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, line, started, program.
program_optimize - Optimize a program
changes the machine · the same call twice does no more than once
Make a program faster without asking more of any tool than the program already does: it runs on a hidden copy of the setup; lighter cuts get feeds up to the heaviest cut the same tool already makes (or the limits in goals), moves in air go at the axes' top speed, finishing passes and plunges keep theirs, a chattering tool gets the steadiest speed near its own (0.7 to 1.8 times it, the depth within 10 % of it the deepest) where that takes the cut half as deep again, collinear lines are merged, rapid retracts come down to just over the blank and the fixture, arcs are fitted where the sender could not keep up. The result runs again on a second copy (lines over a limit are lowered and it runs once more). Answers with the program, its changes and the comparison; saved as a version (author optimizer) when it is better in every respect. Takes two or three runs of the program: a run id comes back after budget_s.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
gcode | string | the program's text | |
name | string | "program.nc" | |
stock | string | "current" | current: the machine's workpiece as it is, cuts and all (carry on with a part already cut); fresh: a new blank (a whole program from the start) (one of current, fresh) |
example | string | an example's setup (and program, when gcode is omitted) instead of the machine's: see setup_example | |
setup | object | an explicit setup instead of the machine's: {spec: the workpiece's setup as machine_status shows it (status.workpiece), tool, tools: {T: spec}, g54: [x,y,z] MPos, part: STL path} | |
goals | object | ||
goals.feeds | boolean | true | |
goals.speeds | boolean | true | |
goals.merge | boolean | true | |
goals.retracts | boolean | true | |
goals.arcs | boolean | default: when the sender could not keep up | |
goals.chip_mm | number | ||
goals.force_n | number | ||
goals.load_pct | number | ||
goals.load_cap | number | 80 | |
goals.feed_max | number | ||
goals.arc_acc | number | mm/s2 towards an arc's centre: its feed no more than 60 sqrt(arc_acc r) - the controller's (the MC-1's kernel: sqrt(3)/2 of the axes' 300 = 260); default 0, no bound | |
goals.air_feed | number | ||
goals.finish_ae | number | 0.15 | |
timeout_s | number | 3600 | simulated seconds allowed |
budget_s | number | 40 | wall-clock seconds this call waits before it answers with a run id (at most 45: clients give up after 60 s; run_status waits for the rest) |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, optimized, verdict, gcode, status, run.
geometry_import - Import a shape
changes the machine · the same call twice does no more than once
Make a shape the programs can cut, from what you write - SVG path data (svg_path, its numbers in mm: e.g. a heart "M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z"), an SVG or DXF drawing (svg, dxf: the text) or file (an .svg or .dxf path; a DXF's layers: [names] reads only those), formulas in t (curve: {x: "16*sin(t)^3", y: "13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)", t: [0, "2*pi"]}), basic shapes added or cut in order (shapes: rect, circle, ellipse, slot, polygon, star, path), single-stroke text (text, font, text_height, align) or points - instead of working out its points yourself. Then where it goes: width_mm or height_mm (scaled to fit), scale, rotate, mirror, and center [x, y] (its box's middle) or at [x, y] (its lower left corner) in the program's mm (Z0 on the blank's top). SVG's y points down: it is turned the right way up. Saved under name as a version (the same shape again: not saved again); the answer says its size and box, outlines and islands, area, the sharp inner corners a pocket's tool cannot get into, the largest tool that fits and the narrowest place, its symmetry - with a picture: look at it before cutting. Then program_generate {features: [{op: "pocket", geometry: name, depth}]} (or contour, engrave). A mesh (file: .stl, .obj, .3mf, .glb, .gltf; units, up, width_mm or scale, depth_mm, rotate, mirror, center or at, top) is saved the same way for 3D: rough3d and finish3d take it. With only name: a saved shape again (version: an older one); with nothing: the shapes there are. Units are mm; a shape is data - it does not touch a machine.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
name | string | the shape's name: saved under it, used by it (geometry: name) | |
version | integer | with only name: that saved version (default the last) | |
svg_path | string | SVG path data: M L H V C S Q T A Z, lower case relative | |
svg | string | an SVG document's text | |
dxf | string | a DXF drawing's text (ASCII): lines, arcs, circles, polylines, splines, ellipses, blocks | |
file | string | an .svg or .dxf file's path - or a mesh for 3D: .stl, .obj, .3mf, .glb, .gltf | |
layers | array or string | DXF: only these layers (default: all that are on) | |
join | number | 0.01 | DXF: mm within which ends are joined into closed outlines |
curve | object | formulas in t (radians; sin cos tan sqrt abs exp ln pow pi ...) | |
curve.x * | string | ||
curve.y * | string | ||
curve.t | array of ['number', 'string'] | ||
curve.closed | boolean | true | |
shapes | array of object | rect {x,y,w,h[,r]}, circle {cx,cy,d}, ellipse {cx,cy,rx,ry}, slot {x0,y0,x1,y1,w}, polygon {points} or {cx,cy,n,d}, star {cx,cy,n,d,d_inner}, path {svg}; op: add, cut, intersect | |
text | string | text: single strokes to engrave (font simplex, duplex, script: Latin letters, digits, signs) or the letters' outlines to pocket or V-carve (an outline font) | |
font | string | simplex (default), duplex, script: single strokes; sans (Noto Sans, comes with Studio) or a font of the computer's by its name - "微软雅黑", "宋体", "Arial" ... (Chinese: a computer's font): outlines | |
text_height | number | the capitals' height, mm (10) | |
align | string | (one of left, center, right) | |
points | array of array | a polygon: [[x, y], ...] | |
units | string | "mm" | svg_path's numbers; a DXF's that does not say its own; an STL's or OBJ's (mm, cm, m, in) (one of mm, cm, m, in, pt, px) |
up | string | "z" | a mesh: which of its file's axes points up (most OBJ: y) (one of z, -z, y, -y, x, -x) |
depth_mm | number | a mesh: its Z size (Z alone: a relief made shallower) | |
top | number | 0 | a mesh: the Z its highest point goes to |
bottom | number | a mesh: the Z its lowest point goes to (instead of top) | |
px_per_in | number | 96 | |
flip_y | boolean | ||
scale | number | ||
width_mm | number | ||
height_mm | number | ||
mirror | string | (one of x, y) | |
rotate | number | degrees, counter-clockwise | |
center | array of number | ||
at | array of number | ||
tolerance | number | 0.005 | mm: curves that are not circles become lines this close |
fill_rule | string | "evenodd" | (one of evenodd, nonzero) |
Returns (structured content): machine, notice, name, version, size_mm, bbox, shapes.
geometry_nest - Lay parts out on the blank
read-only · the same call twice does no more than once
Lay several parts out on the machine's blank (or a plate given) and cut them out - nesting. Each part a shape: geometry (a name from geometry_import) or one given as geometry_import takes it (svg_path, dxf with layers, shapes ...); count copies of it, each turned by quarter turns where that fits them better (turns: 0, 90, 180, 270; default all), its own features (holes, pockets ...) written in its shape's coordinates. They go in the largest first, each where it fits lowest, then leftmost - the shapes, not their boxes: a small part in a larger one's notch or its hole (in_holes) - gap apart (default the tool's diameter + 1 mm) and margin (1) inside the plate (default the blank's top). Nothing is machined: the answer says where each copy went, how much of the plate the parts use, the copies that did not fit (placed less than asked), with a picture; and features - each copy's own where it went, then every copy cut out, those in holes first (a contour outside its shape, depth deep - default through the blank and 0.2 - with tabs, 3 unless given) - for program_generate as they are, with nest (kept with the job).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
parts * | array of object | the parts, 1 to 16, e.g. [{geometry: "bracket", count: 4}, {shapes: [{type: "circle", cx: 0, cy: 0, d: 20}], count: 3}] | |
plate | array of number | [x0, y0, x1, y1] where the parts go, the program's mm (default the blank's top) | |
depth | number | how deep each part is cut out (mm; default the blank's thickness + 0.2) | |
gap | number | mm between two parts (default the tool's diameter + 1) | |
margin | number | 1 | mm from the plate's edge to the parts' outlines |
tabs | integer or object | the cut-outs' tabs: a count or {count, width, height, holes: false - none round the parts' holes} (default 3) | |
tool | string | the tool the gap is for (default the one in the spindle) | |
setup | object | the setup to measure the blank and the tool on instead of the machine's, as program_generate takes it (spec, tool, tools, g54): a hidden copy set up so | |
in_holes | boolean | true | a small part may go into a larger one's hole (cut out before it); false: the holes taken as filled |
outlines | boolean | false | each placed copy's outline where it went and each part's own: {outer: [[x, y], ...], holes: [...]}; each copy's tabs where the program will leave them: [[x, y, nx, ny], ...] on its outline, the normal away from its material - for drawing the layout |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, placed, parts, used_pct, features, nest.
program_generate - Generate a program from features
changes the machine · the same call twice does no more than once
Write a program from machining features instead of line by line: face, pocket, slot, contour (outside, inside or on an outline; tabs hold a part cut through), drill, bore (helix), ream (a reamer widening holes drilled before to its size and class: drill, then ream), engrave (single-stroke text, or a shape's lines), chamfer (a V-bit along edges), thread (a thread mill in a bored hole), vcarve (a V-bit's tip along an outline's middle lines, each point as deep as the V reaches: lettering in an outline font, any closed shape). A pocket or a contour takes any outline, islands and all: a shape made with geometry_import (geometry: its name), SVG path data right in the feature (svg_path with geometry_import's width_mm, center ...), a rectangle with corner radius, a circle, polygon points, or the closed outline another program cuts (from_program). E.g. {op: "pocket", geometry: "heart", depth: 4}; {op: "pocket", svg_path: "M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z", width_mm: 40, center: [30, 30], depth: 4}; {op: "pocket", from_program: "heart.nc", offset: 3, depth: 13} (a hollow where heart.nc cut the heart's outline; offset: grown by the tool's radius). A pocket is cleared in rings from its deepest spot out - or, strategy "adaptive", by a walk that cuts a set width (ae, 10 % of the tool) all the way: deeper layers, a faster feed for the thinner chips, no slotting but the entry; or "zigzag", straight passes to and fro - its walls, round the outside and every island, finished to size (a slot: strategy "trochoidal", loops along it); the answer says where the tool cannot reach (corners narrower than its radius stay round). Speeds, feeds and depths come from the blank's material and the tool, within the spindle's range: with verify, the twin's stability model picks the speed and keeps each depth (roughing steps, the walls' finishing passes) to 80 % of the stable one before the program is written. Ramps and helices into material, climb milling. The clearance height stays within what the setup leaves above the blank. With verify (default) it runs on a hidden copy of the setup, its workpiece as it is (stock), and where the tool would still chatter it is written again shallower there - a program too long to try within the call likewise behind it (verification.check_run: run_status gives the last version's report, closed_loop what it changed). Saved as a version (author generator; each one the loop tried too). operations says each feature's lines, layers and values - the first 64; past them (a nest's) feature_spans gives every feature's [first line, last line, layers, tool]. A hole's or a shaft's diameter (a circle's pocket or contour, a bore, a reaming) may carry its fit (ISO 286): d "Ø8 H7", or d 8 with fit "H7", a pair "H7/g6" (the hole takes H7, the shaft g6) or a common fit (sliding, locating, transition, press), or tol "+0.015/0" - cut to the middle of its zone, a spring pass where the twin's estimate of the tool's give asks for one (operations[].fit says what and why: the twin's estimate). So may a slot's width (width "6 N9", or width 6 with fit "N9": a keyway's N9, P9, JS9 - cut with a cutter narrower than it, its walls to size) and a rectangle's pocket or contour, both its sizes (fit "H7"; outside: a shaft's class, a key's h9). The program's zero: the machine's G54 (setup_work_zero). A part machined from two sides or more: setups instead of features - a program each, setup 1 on the machine as it is, each later one turned over (turn) or held another way (fixture) from the one before, G54 set again on the blank (zero); the job and every program saved together.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
stock | string | "current" | current: the machine's workpiece as it is, cuts and all (carry on with a part already cut); fresh: a new blank (a whole program from the start) (one of current, fresh) |
features | array of object | each {op, ...}: face {x0,y0,x1,y1,depth}; pocket {geometry name \| svg_path (+ width_mm, center) \| shape rect x0,y0,x1,y1[,r] \| shape circle cx,cy,d \| shape polygon points [[x,y],..] \| from_program name[,version]; [offset]; [strategy adaptive[, ae] \| zigzag[, angle]]; [rest true]; depth}; slot {x0,y0,x1,y1[,width],depth[,strategy trochoidal[,step]]}; contour {the same outlines, side outside\|inside\|on, depth}; drill {points [[x,y]..],depth[,peck]}; bore {points,d,depth}; engrave {text,x,y,height,depth[,font] \| geometry name, depth}; chamfer {an outline, width} (a V-bit); thread {points,d,pitch,depth[,hand]} (a thread mill); vcarve {an outline, or text with font sans or a computer's font, text_height, center[, max_depth]} (a V-bit); rough3d {geometry: a mesh's name[, allowance, stepdown, ae, area]} (a flat end mill); finish3d {geometry[, strategy, scallop or stepover, angle, steep_angle, area, rest_from]} (a ball end mill; strategy pencil: along the creases); contour tabs: n or {count,width,height,holes} | |
setups | array of object | instead of features: a part machined from two sides or more, a program each, in order. Setup 1 is the machine's setup as it is; each later one turned over (turn) or held another way (fixture) from the one before, G54 set again on the blank (zero). Within the call each later program is written for the blank as it was (what the setups before cut is not known yet). name, tool, material, cutting and safe_z here are every setup's defaults. E.g. setups: [{features: [{op: "pocket", shape: "rect", x0: 8, y0: 8, x1: 24, y1: 22, depth: 3}]}, {turn: "u", features: [{op: "face", x0: 0, y0: 0, x1: 40, y1: 30, depth: 1}]}] | |
nest | object | geometry_nest's nest (its parts laid out on a plate): kept with the job beside the features it made; given without features, the parts are laid out here (plate, depth and the parts needed) - not with setups | |
tool | string | default: the machine's tool in the spindle | |
material | string | default: the machine's blank's; a code of the machine's table (6061-T6, 45, 304 ...) or another standard's name for one (EN AW-6061, C45, SUS304 ...: read as that code, the nearest grade - for its cutting data) | |
cutting | object | rpm, feed, ap (depth of cut), ae (stepover), finish_ap to use instead | |
setup | object | the setup to generate for and verify on instead of the machine's (as program_optimize takes it) | |
safe_z | number | 5 | the clearance height over Z0; kept within what the setup leaves above the blank |
name | string | "generated.nc" | |
title | string | the job's name to show (one line, 80 characters at most; kept with the job, not in the program) | |
description | string | a line about the job (200 characters at most; kept with the job) | |
verify | boolean | true | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, gcode, verification, operations, setups, total.
program_edit - Change a program by intent
changes the machine · the same call twice does no more than once
Change a program without sending it again line by line: edits applied in order - set_s value (every S), set_f value or scale (every F), shift_z by and scale_z factor (the cuts: Z at or below the program's zero; all: every Z), split into (from..to: one pass cut in that many layers, a ramp kept a ramp - back up and over to its start in between), safe_z z (the clearance height: every Z above zero); from/to: file lines (default all). G53, G28, G30, G10 and G92 lines are left alone; programs in absolute mm (G90 G21). The program: gcode, or name (and version: default the last) from the working folder. The result is saved as a new version (save false: not) with the difference; check it with program_check {name, version}.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
gcode | string | the program's text (or name and version) | |
name | string | ||
version | integer | with name, no gcode: that saved version (0: the last) | |
edits * | array of object | each {op, ...}: set_s {value}; set_f {value \| scale}; shift_z {by[, all]}; scale_z {factor[, all]}; split {from, to, into}; safe_z {z}; any of them with from, to (file lines) | |
save | boolean | true |
Returns (structured content): machine, notice, gcode, version, changed_lines, diff.
program_versions - Program versions
changes the machine · the same call twice does no more than once
Program versions in the working folder (Documents/Twinwright Studio/programs/<name>/vNNNN.nc with who, when and why). action list: the versions (without name: every program, the last changed first); get: a version's text (default the last); save: gcode as a new version (reason: what changed and why; the same text is not saved twice); diff: how b differs from a - texts, or name with a_version and b_version - with their simulation results side by side when both ran on this host. The user's own files are never written.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
action | string | "list" | (one of list, get, save, diff) |
name | string | ||
version | integer | ||
gcode | string | ||
reason | string | ||
a | string | ||
b | string | ||
a_version | integer | ||
b_version | integer |
Returns (structured content): machine, notice, name, version, versions, gcode, programs.
Runs and results
run_status - Runs
changes the machine
Without run: the runs kept on this host (the last 16) - program, machine, who started it, running or done, a summary. With run: waits up to wait_s for it (at most 45 s: clients give up after 60 s) and gives its full report - how it ended first (done, stopped by whom, an alarm, out of time) and at which line; stop: true ends it early. A call that is cancelled or times out never stops a run.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
run | string | a run id (program_simulate's, program_run's), or "latest": your newest run | |
wait_s | number | 40 | at most 45 |
stop | boolean | false |
Returns (structured content): machine, notice, run, completed, simulated_time_s, issues, status, runs.
run_profile - Where a run's time went
read-only · the same call twice does no more than once
A run line by line (a run id from program_simulate or program_run; default the latest): the time each line took (they add up to the run), the feed asked for and reached and why it fell short (the axes' top speed, corners, arcs, the planner's look-ahead, a sender that could not keep up, the override, a hold), the cutting force, chip, chatter margin, spindle load, material removed, cutting air, events. sort: time (slowest first), risk (events first) or line; from/to: a range of file lines; paged (offset, limit).
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
run | string | a run id (program_simulate's, program_run's), or "latest": your newest run | |
sort | string | "time" | (one of time, risk, line) |
limit | integer | 20 | |
offset | integer | 0 | |
from | integer | ||
to | integer | ||
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, run, total_s, lines.
result_compare - Compare with the design part
read-only · the same call twice does no more than once
How a machined workpiece deviates from its design part: cells within tolerance, material left above the part, cut into it. run: the workpiece a run left; else the machine's workpiece now.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
run | string | a run id (program_simulate's, program_run's), or "latest": your newest run | |
tol | number | 0.02 | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, comparison, in_tolerance_pct.
result_image - Picture of a result
read-only · the same call twice does no more than once
A picture (PNG) and its key numbers in words - kind: workpiece = the workpiece in 3D (view iso, top, front, right; color material, height, line = the program line that cut there last, deviation; path: a run's toolpath over it); toolpath = the path coloured by feed, force, chip, margin, line, z or limit (why the programmed feed was not reached), rapids dashed, the highest value marked with its line (view top or iso); deviation = the design part's deviation map from above, the worst places marked with their program lines (needs a part); profile = the slowest lines, coloured by what limited them; timeline = cutting force, spindle load, feed, chatter margin and the program line over time; comparison = two runs side by side (runs). run: a run of program_simulate - its end state; without it, workpiece and deviation show the machine now and the others its latest simulation (a simulation runs on a copy: to see its result, name its run). A picture larger than about 100 KB is drawn smaller (clients limit a result's size). The key numbers come in the text too.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
kind | string | "workpiece" | (one of workpiece, toolpath, deviation, profile, timeline, comparison) |
run | string | a run id (program_simulate's, program_run's), or "latest": your newest run | |
runs | array of string | comparison: two run ids, A then B | |
view | string | (one of iso, top, front, right) | |
color | string | workpiece: material, height, line, deviation; toolpath: feed, force, chip, margin, line, z, limit | |
path | boolean | false | |
top | integer | 15 | profile: lines shown, at most 40 |
tol | number | 0.02 | deviation: the tolerance band, mm |
width | integer | 960 | |
height | integer | 640 | |
machine | string | which machine. Leave it out for the machine the user sees and means - the one in their Twinwright Studio window ("window"; needs the window open with its AI switch on). "sandbox" (or "sandbox-<name>") is an invisible practice machine of yours, faster than real time (far faster moving, a few times while cutting), shared by the user's AI clients: the user does not see it - use it only to try something out, and say so when you report. No other names. Left out while the window's AI switch is off: "sandbox" |
Returns (structured content): machine, notice, image, kind, of.
log_query - Audit log
read-only · the same call twice does no more than once
The audit log: who did what, when, to which machine - the user in the window, the AI clients, the machines themselves (alarms, homing, programs started and ended, collisions), the twin host. Newest first; filters: since / until (a time's start, e.g. "2026-09-29T17:5"), category (machine, operator, program, setup, ai, system), action (a prefix: "machine.alarm", "ai.tool"), who (user, ai, system, or a name), machine, text, severity (warn, error); paged. Useful to see what the user did in the window, or what became of a machine.
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
since | string | ||
until | string | ||
category | string | (one of machine, operator, program, setup, ai, system) | |
action | string | ||
who | string | ||
machine | string | ||
text | string | ||
severity | string | (one of warn, error) | |
limit | integer | 30 | |
offset | integer | 0 |
Returns (structured content): machine, notice, records, matching.
The licence
licence_status - Licence and edition
read-only · the same call twice does no more than once
This copy's edition and licence: the edition in force (in_force: learning, maker, pro, shop; classroom, trial), the licence files in the computer's licence folder - each one's kind, holder, seats, dates (valid_until, renew_after, updates_until), days left (a subscription past its period: its days of grace) and whether it holds, and why not - the local trials used, whether a bought licence's updates cover this release, every paid feature with the edition it needs, why it is closed and whether this release has it at all (shipped false: not built yet - never offer it), and the site's pages for the next step (pricing: buy or upgrade; licence: a year more of updates, managing a subscription, offline activation). Changes nothing; gives no activation code and no computer fingerprint. Use it to explain a refusal ("edition: ... comes with the pro edition") and what the user can do.
No parameters.
Returns (structured content): edition, in_force, files, trials_used, features, links.