NestingCalc Calculators
37 cutting and woodworking calculators: cut lists, sheet nesting, timber volume, kiln drying
Should I use this
Quality & Safety
Findings (3)
- LOWin miter_angle_calculator
- LOWin lumber_weight_calculator
- LOWin kiln_capacity
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"calculators": {
"url": "https://mcp.nestingcalc.com/mcp"
}
}
}Remote endpoints
https://mcp.nestingcalc.com/mcpstreamable-httpWhat it can do
Tool inventory
Tools (37)
⚪linear_cutting_optimizer(unit, stock_length, stock_count, kerf, trim, ...)
Optimize 1D cutting plans for bars, pipes and profiles (linear cutting stock problem, best-fit decreasing heuristic). Returns bars used, per-bar cut lists with positions, total waste and unplaced parts. A web_url with the plan prefilled is included for a visual SVG diagram.
Input Schema
{
"type": "object",
"properties": {
"unit": {
"type": "string",
"enum": [
"mm",
"cm",
"m",
"in",
"ft"
],
"description": "Unit for all lengths"
},
"stock_length": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Length of one stock bar"
},
"stock_count": {
"default": 1,
"description": "How many stock bars are available",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"kerf": {
"default": 0,
"description": "Saw blade width consumed by each cut",
"type": "number",
"minimum": 0
},
"trim": {
"default": 0,
"description": "Unusable trim at bar ends",
"type": "number",
"minimum": 0
},
"parts": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"length": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Cut length"
},
"qty": {
"default": 1,
"description": "How many of this part",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"label": {
"description": "Optional part name",
"type": "string"
}
},
"required": [
"length"
]
},
"description": "Parts to cut"
}
},
"required": [
"unit",
"stock_length",
"parts"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪sheet_cutting_optimizer(unit, stock_width, stock_height, stock_count, stocks, ...)
Optimize 2D guillotine cutting plans for plywood, MDF, glass, sheet metal (2D nesting with kerf, per-part rotation lock for grain direction, optional sheet trim and multiple stock sizes). Returns sheets used, piece positions, utilization, estimated cut length/count and unplaced pieces. Includes a web_url with the plan prefilled for a visual layout diagram.
Input Schema
{
"type": "object",
"properties": {
"unit": {
"type": "string",
"enum": [
"mm",
"cm",
"m",
"in",
"ft"
],
"description": "Unit for all dimensions"
},
"stock_width": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sheet width"
},
"stock_height": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sheet height"
},
"stock_count": {
"default": 1,
"description": "How many sheets are available",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"stocks": {
"description": "Optional mixed stock sizes; replaces stock_width/stock_height/stock_count when given",
"maxItems": 6,
"type": "array",
"items": {
"type": "object",
"properties": {
"width": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sheet width"
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sheet height"
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "Sheets available of this size"
}
},
"required": [
"width",
"height",
"count"
]
}
},
"kerf": {
"default": 0,
"description": "Blade/saw width consumed by each cut",
"type": "number",
"minimum": 0
},
"trim_x": {
"default": 0,
"description": "Symmetric trim removed from left/right sheet edges (damaged edges)",
"type": "number",
"minimum": 0
},
"trim_y": {
"default": 0,
"description": "Symmetric trim removed from top/bottom sheet edges",
"type": "number",
"minimum": 0
},
"pieces": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"width": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Piece width"
},
"height": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Piece height"
},
"qty": {
"default": 1,
"description": "How many of this piece",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"rotatable": {
"default": true,
"description": "Allow 90-degree rotation (false = grain lock)",
"type": "boolean"
},
"label": {
"description": "Optional piece name",
"type": "string"
}
},
"required": [
"width",
"height"
]
},
"description": "Pieces to cut"
}
},
"required": [
"unit",
"stock_width",
"stock_height",
"pieces"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢board_feet_calculator(unit, boards, price, price_unit)
Calculate board feet and lumber cost (thickness x width x length / 144 in inches). Accepts multiple boards and an optional price quoted per board foot or per MBF (thousand board feet).
Input Schema
{
"type": "object",
"properties": {
"unit": {
"default": "in",
"description": "Unit for board dimensions",
"type": "string",
"enum": [
"in",
"ft",
"mm",
"cm",
"m"
]
},
"boards": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"thickness": {
"type": "number",
"exclusiveMinimum": 0
},
"width": {
"type": "number",
"exclusiveMinimum": 0
},
"length": {
"type": "number",
"exclusiveMinimum": 0
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"label": {
"type": "string"
}
},
"required": [
"thickness",
"width",
"length"
]
},
"description": "Boards (dimensions in the chosen unit)"
},
"price": {
"description": "Optional price per price_unit",
"type": "number",
"minimum": 0
},
"price_unit": {
"default": "bf",
"description": "Unit the price is quoted in: single board foot or MBF (1,000 bf)",
"type": "string",
"enum": [
"bf",
"mbf"
]
}
},
"required": [
"boards"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪miter_angle_calculator(mode, corner_angle_deg, sides, spring_angle_deg)
Miter angles three ways: corner mode (any corner angle between two pieces), sides mode (regular polygon with N sides), crown mode (miter + bevel for crown molding at a spring angle).
Input Schema
{
"type": "object",
"properties": {
"mode": {
"type": "string",
"enum": [
"corner",
"sides",
"crown"
],
"description": "Calculation mode"
},
"corner_angle_deg": {
"description": "corner mode: interior corner angle, e.g. 90 or 135",
"type": "number",
"exclusiveMinimum": 0,
"exclusiveMaximum": 180
},
"sides": {
"description": "sides mode: number of sides of the frame/polygon",
"type": "integer",
"minimum": 3,
"maximum": 120
},
"spring_angle_deg": {
"description": "crown mode: spring angle, typically 38 or 45",
"type": "number",
"exclusiveMinimum": 0,
"exclusiveMaximum": 90
}
},
"required": [
"mode"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪lumber_weight_calculator(species, thickness_mm, width_mm, length_m, qty, ...)
Weight of lumber by species, dimensions, quantity and moisture (dry/fresh), using species density tables. Optional custom density in kg/m3.
Input Schema
{
"type": "object",
"properties": {
"species": {
"type": "string",
"enum": [
"pine",
"spruce",
"fir",
"cedar",
"poplar",
"oak-red",
"oak-white",
"maple-hard",
"birch",
"ash",
"beech",
"walnut",
"cherry",
"mahogany",
"teak",
"mdf",
"plywood",
"oak-engineered"
],
"description": "Wood species key"
},
"thickness_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"width_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"length_m": {
"type": "number",
"exclusiveMinimum": 0
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"moisture": {
"default": "dry",
"description": "fresh (green) wood uses 1.5x density (+50% weight)",
"type": "string",
"enum": [
"dry",
"fresh"
]
},
"custom_density_kg_m3": {
"description": "Overrides species density",
"type": "number",
"minimum": 0
}
},
"required": [
"species",
"thickness_mm",
"width_mm",
"length_m"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢rebar_takeoff(lines)
Rebar weight takeoff (d2/162 rule): total length, weight in kg and bars per tonne for a list of rebar lines. Supports metric mm bars and US # sizes as diameters.
Input Schema
{
"type": "object",
"properties": {
"lines": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"diameter_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Bar diameter, e.g. 12 or 15.875 (#5)"
},
"length_m": {
"type": "number",
"exclusiveMinimum": 0
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"diameter_mm",
"length_m"
]
},
"description": "Rebar lines"
}
},
"required": [
"lines"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪metal_weight_calculator(profile, material, length_m, qty, od_mm, ...)
Weight of metal stock per profile: pipe/tube (OD + wall), round bar, square/rectangular tube, flat bar, angle, beam/I-beam. Materials: steel, stainless, aluminum, copper, brass.
Input Schema
{
"type": "object",
"properties": {
"profile": {
"type": "string",
"enum": [
"pipe",
"round-bar",
"square-tube",
"rect-tube",
"flat-bar",
"angle",
"beam"
]
},
"material": {
"type": "string",
"enum": [
"steel",
"stainless",
"aluminum",
"copper",
"brass"
]
},
"length_m": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Length in meters"
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"od_mm": {
"description": "pipe/round-bar: outer diameter",
"type": "number",
"minimum": 0
},
"wall_mm": {
"description": "pipe/tubes: wall thickness",
"type": "number",
"minimum": 0
},
"width_mm": {
"description": "rect-tube/flat-bar/angle/beam: width",
"type": "number",
"minimum": 0
},
"height_mm": {
"description": "rect-tube/beam: height",
"type": "number",
"minimum": 0
},
"web_mm": {
"description": "beam: web thickness",
"type": "number",
"minimum": 0
}
},
"required": [
"profile",
"material",
"length_m"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪cnc_feeds_speeds(unit, machine, tool_diameter, flutes, chip_load, ...)
CNC spindle RPM and feed rate from tool diameter, flute count, chip load and cutting speed. Works for routers and mills, metric and imperial.
Input Schema
{
"type": "object",
"properties": {
"unit": {
"type": "string",
"enum": [
"metric",
"imperial"
]
},
"machine": {
"default": "router",
"type": "string",
"enum": [
"router",
"mill"
]
},
"tool_diameter": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Cutter diameter (mm or inch)"
},
"flutes": {
"default": 2,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"chip_load": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Chip load per tooth (mm or inch)"
},
"cutting_speed": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Cutting speed Vc (m/min or ft/min)"
}
},
"required": [
"unit",
"tool_diameter",
"chip_load",
"cutting_speed"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟢sheet_metal_gauge(mode, material, gauge, thickness_mm, width_mm, ...)
Convert sheet metal gauge to thickness (mm) or thickness to gauge, and compute sheet weight for steel, stainless, aluminum or galvanized steel.
Input Schema
{
"type": "object",
"properties": {
"mode": {
"default": "gauge",
"description": "gauge: from gauge number; mm: from thickness",
"type": "string",
"enum": [
"gauge",
"mm"
]
},
"material": {
"default": "steel",
"type": "string",
"enum": [
"steel",
"stainless",
"aluminum",
"galvanized"
]
},
"gauge": {
"description": "gauge mode: gauge number, e.g. 16",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"thickness_mm": {
"description": "mm mode: thickness in mm",
"type": "number",
"minimum": 0
},
"width_mm": {
"default": 1000,
"type": "number",
"minimum": 0
},
"length_mm": {
"default": 2000,
"type": "number",
"minimum": 0
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪tile_calculator(room_width_m, room_length_m, tile_width_mm, tile_length_mm, grout_mm, ...)
Tiles, boxes and cost for a room: room and tile dimensions, grout width, waste factor by layout pattern (straight, offset, diagonal, herringbone...), optional box size and prices.
Input Schema
{
"type": "object",
"properties": {
"room_width_m": {
"type": "number",
"exclusiveMinimum": 0
},
"room_length_m": {
"type": "number",
"exclusiveMinimum": 0
},
"tile_width_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"tile_length_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"grout_mm": {
"default": 3,
"type": "number",
"minimum": 0
},
"layout": {
"default": "straight",
"description": "Layout pattern (sets default waste factor)",
"type": "string",
"enum": [
"straight",
"offset",
"diagonal",
"herringbone",
"large-format",
"natural-stone"
]
},
"waste_percent": {
"description": "Overrides the layout default",
"type": "number",
"minimum": 0
},
"box_size": {
"default": 10,
"description": "Tiles per box",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"price_per_m2": {
"type": "number",
"minimum": 0
},
"price_per_box": {
"type": "number",
"minimum": 0
}
},
"required": [
"room_width_m",
"room_length_m",
"tile_width_mm",
"tile_length_mm"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪wallpaper_calculator(wall_width_m, wall_height_m, roll_preset, roll_length_m, roll_width_m, ...)
Wallpaper rolls needed for a wall, accounting for pattern repeat and openings. Use a standard roll preset (eu, us-single, us-double, commercial54) or custom roll dimensions.
Input Schema
{
"type": "object",
"properties": {
"wall_width_m": {
"type": "number",
"exclusiveMinimum": 0
},
"wall_height_m": {
"type": "number",
"exclusiveMinimum": 0
},
"roll_preset": {
"type": "string",
"enum": [
"us-single",
"us-double",
"eu",
"commercial54"
]
},
"roll_length_m": {
"description": "Custom roll length (overrides preset)",
"type": "number",
"minimum": 0
},
"roll_width_m": {
"description": "Custom roll width (overrides preset)",
"type": "number",
"minimum": 0
},
"pattern_repeat_m": {
"default": 0,
"description": "Pattern repeat length",
"type": "number",
"minimum": 0
},
"openings_m2": {
"default": 0,
"description": "Area of doors/windows to subtract",
"type": "number",
"minimum": 0
}
},
"required": [
"wall_width_m",
"wall_height_m"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪baluster_spacing_calculator(run_mm, baluster_width_mm, max_gap_mm)
Equal baluster/spindle spacing for a run: number of balusters, exact gap and positions. Enforces a maximum gap (e.g. the 4-inch / 100 mm sphere code rule).
Input Schema
{
"type": "object",
"properties": {
"run_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Total run length between posts"
},
"baluster_width_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"max_gap_mm": {
"default": 100,
"description": "Maximum allowed gap (100 mm = sphere rule, 102 mm = 4 in)",
"type": "number",
"minimum": 0
}
},
"required": [
"run_mm",
"baluster_width_mm"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪flooring_calculator(room_width_m, room_length_m, plank_width_mm, plank_length_mm, expansion_mm, ...)
Laminate/vinyl plank takeoff: planks, boxes and cost with offcut reuse between rows (best-fit), expansion gap, layout waste presets and direction.
Input Schema
{
"type": "object",
"properties": {
"room_width_m": {
"type": "number",
"exclusiveMinimum": 0
},
"room_length_m": {
"type": "number",
"exclusiveMinimum": 0
},
"plank_width_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"plank_length_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"expansion_mm": {
"default": 10,
"type": "number",
"minimum": 0
},
"layout": {
"default": "staggered",
"type": "string",
"enum": [
"straight",
"staggered",
"herringbone",
"diagonal"
]
},
"waste_percent": {
"description": "Overrides the layout default",
"type": "number",
"minimum": 0
},
"min_offcut_mm": {
"default": 300,
"description": "Offcuts shorter than this are not reused",
"type": "number",
"minimum": 0
},
"planks_per_box": {
"default": 8,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"direction": {
"default": "length",
"description": "Plank direction",
"type": "string",
"enum": [
"length",
"width"
]
},
"price_per_box": {
"type": "number",
"minimum": 0
},
"price_per_m2": {
"type": "number",
"minimum": 0
}
},
"required": [
"room_width_m",
"room_length_m",
"plank_width_mm",
"plank_length_mm"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪embroidery_resize(file_base64, scale_percent)
Resize an embroidery design file (PES or DST) by a scale percentage. Returns stitch stats before/after, a density safety verdict (safe within +/-15%) and the resized file as base64.
Input Schema
{
"type": "object",
"properties": {
"file_base64": {
"type": "string",
"minLength": 4,
"description": "Base64-encoded PES or DST file"
},
"scale_percent": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Target scale in percent, e.g. 80 for -20%"
}
},
"required": [
"file_base64",
"scale_percent"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪hoppus_volume(unit, circumference, length, qty, price_per_hoppus_unit)
Hoppus (quarter-girth) volume of round logs from mid-length circumference and length: (C/4)^2 x L. Returns Hoppus volume, true volume (x 4/pi), Hoppus tons (50 h ft3) and a board-feet approximation, with optional quantity and value per Hoppus unit.
Input Schema
{
"type": "object",
"properties": {
"unit": {
"default": "imperial",
"description": "imperial: circumference in inches, length in feet; metric: cm and m",
"type": "string",
"enum": [
"imperial",
"metric"
]
},
"circumference": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Circumference at mid-length (in or cm)"
},
"length": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Log length (ft or m)"
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"price_per_hoppus_unit": {
"description": "Optional value per Hoppus ft3/m3",
"type": "number",
"minimum": 0
}
},
"required": [
"circumference",
"length"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪log_volume(method, unit, diameter_small, diameter_mid, diameter_large, ...)
Cubic volume of a log by classical formula: Huber (mid diameter only), Smalian (both end diameters) or Newton (all three, most accurate). Metric (cm, m) or imperial (in, ft); returns volume in m3 and ft3.
Input Schema
{
"type": "object",
"properties": {
"method": {
"default": "huber",
"type": "string",
"enum": [
"huber",
"smalian",
"newton"
]
},
"unit": {
"default": "metric",
"description": "metric: diameters in cm, length in m; imperial: in and ft",
"type": "string",
"enum": [
"metric",
"imperial"
]
},
"diameter_small": {
"description": "Small-end diameter (smalian/newton)",
"type": "number",
"minimum": 0
},
"diameter_mid": {
"description": "Mid-length diameter (huber/newton)",
"type": "number",
"minimum": 0
},
"diameter_large": {
"description": "Large-end diameter (smalian/newton)",
"type": "number",
"minimum": 0
},
"length": {
"type": "number",
"exclusiveMinimum": 0
}
},
"required": [
"length"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪jas_log_scale(diameter_small_cm, diameter_long_cm, length_m, oval_adjust, qty)
Japanese Agricultural Standard (JAS) log scale: official diameter rounding (floor to 1 cm below 14 cm, even 2 cm at 14 cm and above), oval-log averaging, optional +2 cm ovality adjustment and the length allowance for logs over 6 m. Volume per log and totals in m3.
Input Schema
{
"type": "object",
"properties": {
"diameter_small_cm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Short-axis diameter in cm"
},
"diameter_long_cm": {
"description": "Long-axis diameter for oval logs (cm)",
"type": "number",
"minimum": 0
},
"length_m": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Log length in meters"
},
"oval_adjust": {
"default": false,
"description": "Add the +2 cm ovality adjustment",
"type": "boolean"
},
"qty": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"diameter_small_cm",
"length_m"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪timber_unit_converter(value, from, qty, price, price_per)
Convert timber quantities between m3, ft3, board feet, MBF, Hoppus ft3, Hoppus m3 and Hoppus tons, and translate a price quoted in any unit into $/m3 and $/MBF (1 MBF = 2.3597 m3).
Input Schema
{
"type": "object",
"properties": {
"value": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Quantity in the source unit"
},
"from": {
"type": "string",
"enum": [
"m3",
"ft3",
"bf",
"mbf",
"hft3",
"hm3",
"ht"
],
"description": "Source unit"
},
"qty": {
"default": 1,
"description": "Multiplier (number of lots)",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"price": {
"description": "Optional price per price_per unit",
"type": "number",
"minimum": 0
},
"price_per": {
"default": "mbf",
"type": "string",
"enum": [
"m3",
"ft3",
"bf",
"mbf",
"hft3",
"hm3",
"ht"
]
}
},
"required": [
"value",
"from"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪green_log_weight(species, basic_density_kg_m3, volume_m3, mc_pct)
Weight of a roundwood/log batch at any moisture content: W = volume x basic density x (1 + MC/100), per USDA Wood Handbook 2021 Ch.4. Presets for 14 verified species (acacia, rubberwood, eucalyptus, oak, teak, spruce...) or a custom basic density. Returns oven-dry mass, water mass and tonnes.
Input Schema
{
"type": "object",
"properties": {
"species": {
"description": "Species key, e.g. acacia-mangium, rubberwood, white-oak, teak",
"type": "string"
},
"basic_density_kg_m3": {
"description": "Custom basic density (oven-dry kg per green m3); overrides the species preset",
"type": "number",
"minimum": 0
},
"volume_m3": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Roundwood volume in m3 (Hoppus true, Huber or JAS volume)"
},
"mc_pct": {
"description": "Moisture content % oven-dry basis; defaults to the species' freshly-felled MC (~73% acacia, ~75% rubberwood)",
"type": "number",
"minimum": 0
}
},
"required": [
"volume_m3"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪stowage_factor(volume_m3, tonnes)
Stowage factor SF = cargo volume (m3) / cargo mass (tonnes), with classification against the IMO CSS Code Table 4.1 reference ranges for wood cargoes (sawn timber, tropical logs, plywood...).
Input Schema
{
"type": "object",
"properties": {
"volume_m3": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Total cargo volume in cubic metres"
},
"tonnes": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Total cargo mass in metric tonnes"
}
},
"required": [
"volume_m3",
"tonnes"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪container_loading(container, usable_cbm, payload_kg, piece_l_m, piece_w_m, ...)
How many uniform cartons fit in a shipping container before cube-out or weigh-out. Presets: 20GP (33.2 CBM nominal, 28,200 kg payload), 40GP (67.7 CBM, 26,700 kg), 40HC (76.4 CBM, 68 usable, 26,500 kg) — all editable. Returns max pieces by volume vs weight, the binding limit, balanced density (kg/m3) and containers needed for a planned quantity.
Input Schema
{
"type": "object",
"properties": {
"container": {
"default": "40hc",
"type": "string",
"enum": [
"20gp",
"40gp",
"40hc",
"custom"
]
},
"usable_cbm": {
"description": "Override usable/stowable volume (CBM)",
"type": "number",
"minimum": 0
},
"payload_kg": {
"description": "Override max payload (kg); route limits are often lower than the container maximum",
"type": "number",
"minimum": 0
},
"piece_l_m": {
"description": "Carton length (m)",
"type": "number",
"minimum": 0
},
"piece_w_m": {
"description": "Carton width (m)",
"type": "number",
"minimum": 0
},
"piece_h_m": {
"description": "Carton height (m)",
"type": "number",
"minimum": 0
},
"cbm_per_piece": {
"description": "Volume per carton in CBM (alternative to dimensions)",
"type": "number",
"minimum": 0
},
"kg_per_piece": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Mass per carton (kg)"
},
"planned_qty": {
"description": "Planned number of cartons (returns containers needed)",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"kg_per_piece"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪sawmill_recovery(input_volume_m3, output_volume_m3, log_rule_bf, actual_bf)
Sawmill recovery rate (lumber recovery factor): sawn volume out / roundwood volume in, benchmarked against FAO/EU/SE-Asia reference ranges. Also computes log-rule overrun/underrun: (actual BF - rule BF) / rule BF — Doyle underestimates small logs, so overrun is usually positive.
Input Schema
{
"type": "object",
"properties": {
"input_volume_m3": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Roundwood volume in (m3)"
},
"output_volume_m3": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sawn lumber volume out (m3)"
},
"log_rule_bf": {
"description": "Optional: board feet predicted by the log rule (Doyle/Scribner/International)",
"type": "number",
"minimum": 0
},
"actual_bf": {
"description": "Optional: board feet actually sawn — enables the overrun calculation",
"type": "number",
"minimum": 0
}
},
"required": [
"input_volume_m3",
"output_volume_m3"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪moisture_content(mode, wet_mass, dry_mass, start_mass, start_mc_pct, ...)
Wood moisture content (WH-2021 Ch.4 Eq. 4-1..4-4). Two modes: (1) sample-based MC_od/MC_wb from wet+dry masses; (2) drying outcome — mass + water lost when going from start MC to target MC. Optional Gb (kg/m³) returns MCmax and MCsink. Basis 'od' (oven-dry, industry default) or 'wb' (wet).
Input Schema
{
"type": "object",
"properties": {
"mode": {
"default": "sample",
"type": "string",
"enum": [
"sample",
"drying",
"max"
]
},
"wet_mass": {
"description": "Wet mass of sample (sample mode)",
"type": "number",
"minimum": 0
},
"dry_mass": {
"description": "Oven-dry mass of sample (sample mode)",
"type": "number",
"minimum": 0
},
"start_mass": {
"description": "Mass at start of drying (drying mode)",
"type": "number",
"minimum": 0
},
"start_mc_pct": {
"description": "MC at start of drying, %",
"type": "number",
"minimum": 0
},
"end_mc_pct": {
"description": "Target MC after drying, %",
"type": "number",
"minimum": 0
},
"basis": {
"default": "od",
"type": "string",
"enum": [
"od",
"wb"
]
},
"basic_density_kg_m3": {
"description": "Basic density kg/m³ for MCmax/MCsink (max mode)",
"type": "number",
"minimum": 0
}
},
"$schema": "https://json-schema.org/draft/2020-12/schema"
}🟡wood_shrinkage(species, custom_shrink_od_pct, custom_fsp_pct, start_mc_pct, end_mc_pct, ...)
Wood shrinkage from a start MC to an end MC (WH-2021 Eq. 4-9: S_x = S_od × (1 − x/FSP)). Direction: tangential (board width) or radial (board thickness) or volumetric. Picks a species from the wood-species table (16 verified species) or accepts custom S_od + FSP. MC is clamped to FSP — above FSP wood doesn't change dimension.
Input Schema
{
"type": "object",
"properties": {
"species": {
"description": "Species key, e.g. 'white-oak', 'rubberwood'",
"type": "string"
},
"custom_shrink_od_pct": {
"description": "Custom green→OD shrinkage %, used if no species",
"type": "number",
"minimum": 0
},
"custom_fsp_pct": {
"description": "Custom FSP %, default 30 (22 for teak)",
"type": "number",
"minimum": 0
},
"start_mc_pct": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Starting MC, %"
},
"end_mc_pct": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Target MC, %, must be ≤ start_mc_pct"
},
"dimension_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Original dimension in mm (width, thickness, or volume)"
},
"direction": {
"type": "string",
"enum": [
"tangential",
"radial",
"volumetric"
]
}
},
"required": [
"start_mc_pct",
"end_mc_pct",
"dimension_mm",
"direction"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪wood_emc(mode, temp_c, rh_pct, target_mc_pct, branch)
Equilibrium moisture content (EMC) from temperature and RH using the Hailwood–Horrobin sorption model (Simpson 1973 coefficients, desorption branch — WH-2021 Ch.4 Table 4-2). Optional reverse mode: target MC → required RH at the given temperature.
Input Schema
{
"type": "object",
"properties": {
"mode": {
"default": "emc",
"type": "string",
"enum": [
"emc",
"reverse"
]
},
"temp_c": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Air temperature, °C"
},
"rh_pct": {
"description": "Relative humidity, 0–100 (emc mode)",
"type": "number",
"minimum": 0
},
"target_mc_pct": {
"description": "Target MC % (reverse mode)",
"type": "number",
"minimum": 0
},
"branch": {
"default": "desorption",
"type": "string",
"enum": [
"desorption",
"adsorption"
]
}
},
"required": [
"temp_c"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪kiln_capacity(length_m, width_m, height_m, board_thickness_mm, sticker_thickness_mm, ...)
Kiln charge capacity: wood volume per batch (AH-188 / TechDrying). V_wood = D×R×C × t/(t+s) × f where t=board thickness, s=sticker thickness, f=fill factor (0.85–0.95). Returns wood volume in m³ and board feet (1 m³ = 423.77 BF).
Input Schema
{
"type": "object",
"properties": {
"length_m": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Stack length, m"
},
"width_m": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Stack width, m"
},
"height_m": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Stack height, m"
},
"board_thickness_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Average board thickness, mm"
},
"sticker_thickness_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sticker thickness, mm (default 19)"
},
"fill_factor": {
"description": "Stack fill factor 0–1, default 0.9",
"type": "number",
"minimum": 0
}
},
"required": [
"length_m",
"width_m",
"height_m",
"board_thickness_mm",
"sticker_thickness_mm"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪rough_sizing(mode, finished_mm, rough_mm, planing_mm, kerf_mm, ...)
Rough sizing — convert between finished (planed, kiln-dried) and rough-sawn dimensions before drying and planing. Adds planing allowance (default 2.5 mm/face) + saw kerf (default 2.2 mm band) and applies WH-2021 Eq. 4-9 shrinkage. Direction: tangential (board width) or radial (board thickness).
Input Schema
{
"type": "object",
"properties": {
"mode": {
"default": "forward",
"type": "string",
"enum": [
"forward",
"reverse"
]
},
"finished_mm": {
"description": "Finished dimension mm (forward mode)",
"type": "number",
"minimum": 0
},
"rough_mm": {
"description": "Rough-sawn dimension mm (reverse mode)",
"type": "number",
"minimum": 0
},
"planing_mm": {
"description": "Planing allowance per face, mm (default 2.5)",
"type": "number",
"minimum": 0
},
"kerf_mm": {
"description": "Saw kerf, mm (default 2.2 band)",
"type": "number",
"minimum": 0
},
"species": {
"description": "Species key for shrinkage (e.g. 'white-oak')",
"type": "string"
},
"custom_shrink_od_pct": {
"description": "Custom S_od % (used if no species)",
"type": "number",
"minimum": 0
},
"custom_fsp_pct": {
"description": "Custom FSP %, default 30",
"type": "number",
"minimum": 0
},
"finished_mc_pct": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Target finished MC, %"
},
"sawn_mc_pct": {
"type": "number",
"exclusiveMinimum": 0,
"description": "MC at which the wood is sawn, %"
},
"direction": {
"type": "string",
"enum": [
"tangential",
"radial"
]
}
},
"required": [
"finished_mc_pct",
"sawn_mc_pct",
"direction"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪firewood_calculator(value, from, loose_factor, solid_factor, species, ...)
Convert firewood volume between cord (128 ft3), stere/Raummeter (stacked m3), solid m3 (Festmeter), loose m3 and ft3, with optional weight estimate by wood species (dry/fresh).
Input Schema
{
"type": "object",
"properties": {
"value": {
"type": "number",
"exclusiveMinimum": 0
},
"from": {
"type": "string",
"enum": [
"stere",
"cord",
"loose",
"ft3"
],
"description": "Input unit: stere = 1 stacked m3, cord = 128 ft3, loose = bulk m3"
},
"loose_factor": {
"default": 1.4,
"description": "Loose m3 per stacked m3 (1.35-1.55 typical)",
"type": "number",
"exclusiveMinimum": 1
},
"solid_factor": {
"default": 0.7,
"description": "Solid m3 per stacked m3 (Festmeter/Raummeter, 0.65-0.75 typical) - the weight runs off this",
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1
},
"species": {
"description": "Optional species key for weight",
"type": "string",
"enum": [
"pine",
"spruce",
"fir",
"cedar",
"poplar",
"oak-red",
"oak-white",
"maple-hard",
"birch",
"ash",
"beech",
"walnut",
"cherry",
"mahogany",
"teak",
"mdf",
"plywood",
"oak-engineered"
]
},
"moisture": {
"default": "dry",
"description": "fresh = 1.5x weight",
"type": "string",
"enum": [
"dry",
"fresh"
]
}
},
"required": [
"value",
"from"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪rpm_calculator(unit, diameter, cutting_speed)
Spindle speed (RPM) from cutting speed: n = Vc*1000/(pi*D) metric, n = Vc*12/(pi*D) imperial. Metric takes diameter in mm and Vc in m/min; imperial takes diameter in inches and Vc in SFM. Includes a web_url with the calculation prefilled.
Input Schema
{
"type": "object",
"properties": {
"unit": {
"default": "metric",
"description": "Unit system",
"type": "string",
"enum": [
"metric",
"imperial"
]
},
"diameter": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Tool/workpiece diameter (metric: mm, imperial: inch)"
},
"cutting_speed": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Cutting speed (metric: m/min, imperial: SFM)"
}
},
"required": [
"diameter",
"cutting_speed"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪cutting_speed_calculator(unit, diameter, rpm)
Cutting speed from spindle speed: Vc = pi*D*n/1000 metric (m/min), SFM = pi*D*n/12 imperial. Always also returns the same speed converted to the other unit system. Includes a web_url with the calculation prefilled.
Input Schema
{
"type": "object",
"properties": {
"unit": {
"default": "metric",
"description": "Unit system",
"type": "string",
"enum": [
"metric",
"imperial"
]
},
"diameter": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Tool/workpiece diameter (metric: mm, imperial: inch)"
},
"rpm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Spindle speed in revolutions per minute"
}
},
"required": [
"diameter",
"rpm"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪timber_beam_capacity(span_mm, width_mm, height_mm, grade, load_type)
Allowable load on a simply supported rectangular timber beam (planning estimate, Eurocode 5 conventions, EN 338 grades C16-D40/D24-D40). Returns allowable UDL and center point load (gross and net of self-weight), governing mode (bending vs deflection at L/300), utilization, section properties. NOT a structural design - verify with an engineer. Includes a web_url with the beam prefilled.
Input Schema
{
"type": "object",
"properties": {
"span_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Clear span between supports in mm"
},
"width_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Beam width b in mm"
},
"height_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Beam depth h in mm (strong axis)"
},
"grade": {
"type": "string",
"enum": [
"C16",
"C18",
"C24",
"C30",
"C35",
"C40",
"D24",
"D30",
"D40"
],
"description": "Timber grade (EN 338)"
},
"load_type": {
"default": "udl",
"description": "Load type of interest",
"type": "string",
"enum": [
"udl",
"point"
]
}
},
"required": [
"span_mm",
"width_mm",
"height_mm",
"grade"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪glass_price_calculator(width_mm, height_mm, thickness_mm, quantity, price_per_m2, ...)
Cut-to-size glass cost and weight estimate: net area with optional waste allowance, weight (2.5 kg/m2 per mm of thickness), material cost from your price per m2, optional polished-edge work per running metre, total and per-piece cost. Includes a web_url with the quote prefilled.
Input Schema
{
"type": "object",
"properties": {
"width_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Pane width in mm"
},
"height_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Pane height in mm"
},
"thickness_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Glass thickness in mm (2-25)"
},
"quantity": {
"default": 1,
"description": "Number of identical panes",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"price_per_m2": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Glass price per square metre"
},
"edge_price_per_m": {
"default": 0,
"description": "Polished-edge work price per running metre",
"type": "number",
"minimum": 0
},
"waste_pct": {
"default": 0,
"description": "Cutting-waste allowance added on top of net area (%)",
"type": "number",
"minimum": 0,
"maximum": 50
}
},
"required": [
"width_mm",
"height_mm",
"thickness_mm",
"price_per_m2"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪manufacturing_yield(stages, target_output_m3)
Cumulative yield through a wood production chain (sawing -> drying -> machining -> finishing). Multiplies stage yields, shows per-stage loss and computes the roundwood volume needed for a target finished volume.
Input Schema
{
"type": "object",
"properties": {
"stages": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"label": {
"description": "Optional stage name",
"type": "string"
},
"yield_pct": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Share of stage input that becomes usable output, %"
}
},
"required": [
"yield_pct"
]
},
"description": "Production stages in process order"
},
"target_output_m3": {
"description": "Finished volume wanted, m3 (reverse mode)",
"type": "number",
"minimum": 0
}
},
"required": [
"stages"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪glue_consumption(bond_area_m2, edge_panel, face_lam, spread_gsm, faces, ...)
Wood adhesive quantity: bond area x spread (g/m2, TDS presets like PVAc D3 175, EGP 250, finger-joint PUR 530) x application faces x waste allowance. Also computes bond area for edge-glued panels (joints from board width) and face lamination lay-ups.
Input Schema
{
"type": "object",
"properties": {
"bond_area_m2": {
"description": "Total bond-line area, m2",
"type": "number",
"minimum": 0
},
"edge_panel": {
"description": "Edge-glued panel dimensions instead of a direct area",
"type": "object",
"properties": {
"panel_length_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"panel_width_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"board_width_mm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Sawn lamella width - joint count = ceil(width/board)-1"
},
"panel_thickness_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"panels": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"panel_length_mm",
"panel_width_mm",
"board_width_mm",
"panel_thickness_mm"
]
},
"face_lam": {
"description": "Face lamination lay-up instead of a direct area",
"type": "object",
"properties": {
"length_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"width_mm": {
"type": "number",
"exclusiveMinimum": 0
},
"layers": {
"type": "integer",
"minimum": 2,
"maximum": 9007199254740991
},
"sets": {
"default": 1,
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [
"length_mm",
"width_mm",
"layers"
]
},
"spread_gsm": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Spread rate g/m2 (PVAc D3 one face ~175, EGP ~250, finger PUR ~530)"
},
"faces": {
"default": "1",
"description": "1 = single-face, 2 = both mating faces",
"type": "string",
"enum": [
"1",
"2"
]
},
"waste_pct": {
"default": 5,
"description": "Application/squeeze-out waste, %",
"type": "number",
"minimum": 0,
"maximum": 100
},
"price_per_kg": {
"description": "Glue price per kg",
"type": "number",
"minimum": 0
},
"density_gcm3": {
"description": "Glue density g/cm3 to get litres (PVAc ~1.08)",
"type": "number",
"minimum": 0
}
},
"required": [
"spread_gsm"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪paint_coverage(area_m2, coats, coverage_m2_per_l, solids_pct, dft_microns, ...)
Wood finishing paint quantity. Technical route: theoretical coverage = 10 x %volume solids / DFT(um), multiplied by transfer efficiency (conventional spray 30-35%, airless ~50%, HVLP ~65-90%, brush/roller ~90%); or a data-sheet coverage in m2/L. Adds an optional extra % for carved/3D surfaces.
Input Schema
{
"type": "object",
"properties": {
"area_m2": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Surface to coat, m2 (flat projected area)"
},
"coats": {
"type": "integer",
"minimum": 1,
"maximum": 10,
"description": "Number of coats"
},
"coverage_m2_per_l": {
"description": "Data-sheet coverage m2/L (mode A)",
"type": "number",
"minimum": 0
},
"solids_pct": {
"description": "Volume solids % (mode B)",
"type": "number",
"minimum": 0
},
"dft_microns": {
"description": "Target dry film thickness um (mode B)",
"type": "number",
"minimum": 0
},
"transfer_eff_pct": {
"description": "Transfer efficiency % (mode B; HVLP ~70)",
"type": "number",
"minimum": 0
},
"shape_extra_pct": {
"default": 0,
"description": "Extra % for 3D surfaces",
"type": "number",
"minimum": 0,
"maximum": 100
},
"price_per_l": {
"description": "Coating price per litre",
"type": "number",
"minimum": 0
}
},
"required": [
"area_m2",
"coats"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪cbm_shipment(lines)
Packing CBM for cartons: per-line and lot volume (m3), total weight and lot density, with a cube-out / weigh-out verdict against the 40HC balanced density (390 kg/m3 - same presets as container loading).
Input Schema
{
"type": "object",
"properties": {
"lines": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"length_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"width_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"height_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"count": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"weight_kg": {
"description": "Gross weight per carton, kg",
"type": "number",
"minimum": 0
}
},
"required": [
"length_cm",
"width_cm",
"height_cm",
"count"
]
},
"description": "Carton lines"
}
},
"required": [
"lines"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}⚪bom_costing(lines, products, margin_pct, labor_per_product)
Bill-of-materials cost roll-up for furniture: buy quantity = net qty x (1 + waste%, verified presets: S4S lumber 18%, rough 28%, nested panels 10%, hardware 3%), line and total costs, cost per product and a selling price from a target margin (price = cost / (1 - margin)).
Input Schema
{
"type": "object",
"properties": {
"lines": {
"minItems": 1,
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"qty": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Net quantity per product"
},
"unit": {
"description": "Unit label (m3, m2, pcs...)",
"type": "string"
},
"unit_cost": {
"type": "number",
"exclusiveMinimum": 0,
"description": "Cost per unit"
},
"waste_pct": {
"default": 0,
"description": "Waste allowance %",
"type": "number",
"minimum": 0,
"maximum": 200
}
},
"required": [
"qty",
"unit_cost"
]
}
},
"products": {
"default": 1,
"description": "Products this BOM covers",
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"margin_pct": {
"description": "Target margin on selling price, %",
"type": "number",
"minimum": 0,
"maximum": 90
},
"labor_per_product": {
"description": "Direct labour per product",
"type": "number",
"minimum": 0
}
},
"required": [
"lines"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}Community
Evidence