{
  "openapi": "3.1.1",
  "info": {
    "title": "Kerfwise Cabinet Builder API",
    "version": "1.0.0",
    "summary": "Parametric cabinet → every part with cut sizes, edge banding, drilling and hardware.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://kerfwisecabinetbuilder.usefulweb.app"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Parametric cabinet → every part with cut sizes, edge banding, drilling and hardware.",
        "description": "Give a cabinet type (base, wall, tall, drawer bank, blind corner, diagonal corner base or wall cabinet, L-shaped corner, angled end, quarter-round end shelf, open shelf, wardrobe, bookshelf, desk, table, bed frame) with its size, back panel, doors, drawers, shelves and joinery, and get the complete parts list with finished and cut sizes, grain direction, edge banding per edge, hinge and shelf-pin drilling, hardware and a front view. The same engine powers the Kerfwise app.\n\nMethodology:\n- Carcass: sides run full height, so side height = cabinet height − plinth height; top, bottom and fixed shelves sit between the sides (length = inner width = width − 2 × panel thickness), plus 2 × dado depth (T/3) for dado joints or 2 × rabbet depth (T/2) for rabbets.\n- Back panels: grooved = (inner width + 2 × groove depth) × (inner height + 2 × groove depth) and the shelves lose groove set-back + back thickness of depth; inset = inner width × inner height; nailed = outer size − 2 mm, and the carcass depth includes the back.\n- Doors: full overlay = width / n − gap by carcass height − gap (gap 3 mm = 1.5 mm reveal per edge); inset = (opening − (n + 1) × gap) / n. Hinges per door by height: ≤ 900 mm → 2, ≤ 1600 → 3, ≤ 2000 → 4, else 5, placed 100 mm from the ends; Ø35 × 13 mm cup 22.5 mm from the edge with two Ø8 dowel holes 45 mm apart, mounting plates on the side 37 mm from the front.\n- Drawers: slide length = largest standard length ≤ inner depth − 10 mm; box length = nominal slide length; box width = opening − 25.4 mm (side-mount, 12.7 mm per side) or opening − 42 mm + 2 × side thickness (undermount); box height = front height − 40 mm (side) / − 47 mm (undermount). Front/back length: butt or dowel = box width − 2t, dado = + t, dovetail = full box width.\n- Adjustable shelves: inner width − 2 mm, 20 mm set back, on Ø5 holes at 32 mm pitch in two rows (37 mm from the front, rear row on the 32 mm grid). Fasteners: 50 mm from each end, ≤ 150 mm apart (dowels, confirmat, screws, pocket screws), cams 2–3 per joint.\n- Cut size = finished size − edge-banding thickness on each banded edge (L1/L2 run along the length and reduce the width; W1/W2 reduce the length) when deduction is on.\n- Shaped cabinets (diagonal corner, L-shaped corner, angled end, quarter-round end): the plan footprint is a polygon. End panels run through at the corners, wall-side backs (carcass material) butt against them; panel ends that meet a front at an angle are bevelled (angle and long point in the notes). Bottom, top and shelves are the footprint inset by the panel thickness (+1 mm and −20 mm front set-back for adjustable shelves) and get a cut outline for CNC nesting. Diagonal doors use +45° angled hinges; the L-shaped corner uses a bi-fold connector or two doors with a corner post.\n\nDimensions follow common European frameless practice and the stated rules. Always check hardware manufacturers’ planning data for the exact hinges and slides you buy, and verify critical sizes before cutting expensive material.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "kerfwise_cabinet_builder",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KerfwiseCabinetBuilderInput"
              },
              "examples": {
                "example1": {
                  "summary": "Kitchen base cabinet 600, grooved back, legs, 1 door",
                  "value": {
                    "type": "base",
                    "width": 600,
                    "height": 870,
                    "depth": 560,
                    "backType": "groove",
                    "grooveDepth": 8,
                    "plinthType": "legs",
                    "plinthHeight": 150,
                    "doorCount": 1,
                    "shelfCount": 1,
                    "carcassJoint": "dowel",
                    "topType": "rails"
                  }
                },
                "example2": {
                  "summary": "Drawer bank 800 with undermount slides and dovetails",
                  "value": {
                    "type": "drawer",
                    "width": 800,
                    "height": 870,
                    "depth": 560,
                    "drawerCount": 4,
                    "slideType": "under",
                    "drawerJoint": "dovetail",
                    "carcassJoint": "confirmat"
                  }
                },
                "example3": {
                  "summary": "Wardrobe 1000 × 2200, cam joints, 2 doors",
                  "value": {
                    "type": "wardrobe",
                    "width": 1000,
                    "height": 2200,
                    "depth": 600,
                    "carcassJoint": "cam",
                    "plinthType": "board",
                    "plinthHeight": 80
                  }
                },
                "example4": {
                  "summary": "Dining table 1600 × 900 with mortise & tenon aprons",
                  "value": {
                    "type": "table",
                    "width": 1600,
                    "depth": 900,
                    "height": 750,
                    "materialId": "oakpanel-27",
                    "frameJoint": "mortise-tenon"
                  }
                },
                "example5": {
                  "summary": "Diagonal corner base 900 × 900 with a 45° door",
                  "value": {
                    "type": "diagonal",
                    "width": 900,
                    "returnWidth": 900,
                    "height": 870,
                    "depth": 560,
                    "carcassJoint": "dowel"
                  }
                },
                "example6": {
                  "summary": "L-shaped corner base with bi-fold doors",
                  "value": {
                    "type": "l-corner",
                    "width": 1000,
                    "returnWidth": 900,
                    "cornerDoors": "bifold",
                    "handle": "profile"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KerfwiseCabinetBuilderResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "KerfwiseCabinetBuilderInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "type": {
            "title": "Cabinet type",
            "type": "string",
            "enum": [
              "base",
              "wall",
              "tall",
              "drawer",
              "corner",
              "diagonal",
              "diagonal-wall",
              "l-corner",
              "angled-end",
              "round-end",
              "open",
              "wardrobe",
              "bookshelf",
              "desk",
              "table",
              "bed"
            ],
            "default": "base"
          },
          "width": {
            "title": "Width",
            "description": "Outer width (table/desk: top length).",
            "type": "number",
            "minimum": 150,
            "maximum": 4000,
            "default": 600,
            "x-unit": "mm"
          },
          "height": {
            "title": "Height",
            "description": "Outer height incl. plinth, without worktop. Empty = type default.",
            "type": "number",
            "minimum": 150,
            "maximum": 3000,
            "x-unit": "mm"
          },
          "depth": {
            "title": "Depth",
            "description": "Outer depth. Empty = type default.",
            "type": "number",
            "minimum": 100,
            "maximum": 2500,
            "x-unit": "mm"
          },
          "materialId": {
            "title": "Carcass material",
            "type": "string",
            "enum": [
              "mel-18",
              "oak-18",
              "birch-15",
              "mdf-19",
              "walnut-19",
              "oakpanel-27",
              "hdf-8",
              "hdf-3",
              "wt-slab-20"
            ],
            "default": "mel-18"
          },
          "frontMaterialId": {
            "title": "Front material",
            "type": "string",
            "enum": [
              "mel-18",
              "oak-18",
              "birch-15",
              "mdf-19",
              "walnut-19",
              "oakpanel-27",
              "hdf-8",
              "hdf-3",
              "wt-slab-20"
            ],
            "default": "oak-18"
          },
          "backType": {
            "title": "Back panel",
            "type": "string",
            "enum": [
              "groove",
              "inset",
              "nailed",
              "none"
            ],
            "default": "groove"
          },
          "grooveDepth": {
            "title": "Groove depth",
            "type": "number",
            "minimum": 0,
            "maximum": 20,
            "default": 8,
            "x-unit": "mm"
          },
          "topType": {
            "title": "Top",
            "type": "string",
            "enum": [
              "full",
              "rails"
            ],
            "default": "full"
          },
          "plinthType": {
            "title": "Plinth / toe kick",
            "type": "string",
            "enum": [
              "legs",
              "board",
              "none"
            ],
            "default": "legs"
          },
          "plinthHeight": {
            "title": "Plinth height",
            "type": "number",
            "minimum": 0,
            "maximum": 300,
            "default": 150,
            "x-unit": "mm"
          },
          "doorCount": {
            "title": "Doors",
            "description": "Empty = type default.",
            "type": "integer",
            "minimum": 0,
            "maximum": 4
          },
          "doorStyle": {
            "title": "Door style",
            "type": "string",
            "enum": [
              "overlay",
              "inset"
            ],
            "default": "overlay"
          },
          "drawerCount": {
            "title": "Drawers",
            "description": "Empty = type default. With doors, drawers go on top (150 mm each).",
            "type": "integer",
            "minimum": 0,
            "maximum": 8
          },
          "slideType": {
            "title": "Drawer slides",
            "type": "string",
            "enum": [
              "side",
              "under"
            ],
            "default": "side"
          },
          "shelfCount": {
            "title": "Shelves",
            "description": "Empty = type default.",
            "type": "integer",
            "minimum": 0,
            "maximum": 12
          },
          "adjustableShelves": {
            "title": "Adjustable shelves (32 mm system holes)",
            "type": "boolean",
            "default": true
          },
          "faceFrame": {
            "title": "Face frame",
            "type": "boolean",
            "default": false
          },
          "carcassJoint": {
            "title": "Carcass joinery",
            "type": "string",
            "enum": [
              "butt",
              "dowel",
              "confirmat",
              "pocket",
              "cam",
              "dado",
              "rabbet"
            ],
            "default": "dowel"
          },
          "frameJoint": {
            "title": "Frame / apron joinery",
            "type": "string",
            "enum": [
              "pocket",
              "dowel",
              "mortise-tenon",
              "butt"
            ],
            "default": "pocket"
          },
          "drawerJoint": {
            "title": "Drawer box joinery",
            "type": "string",
            "enum": [
              "butt",
              "dado",
              "dovetail",
              "dowel"
            ],
            "default": "dado"
          },
          "handle": {
            "title": "Handles",
            "type": "string",
            "enum": [
              "bar128",
              "bar160",
              "knob",
              "cup",
              "profile",
              "push",
              "none"
            ],
            "default": "bar128"
          },
          "returnWidth": {
            "title": "Corner: second leg length",
            "description": "Diagonal and L-shaped corner cabinets: length along the adjoining wall. Empty = same as the width.",
            "type": "number",
            "minimum": 300,
            "maximum": 2000,
            "x-unit": "mm"
          },
          "cornerDoors": {
            "title": "L-shaped corner doors",
            "type": "string",
            "enum": [
              "bifold",
              "two"
            ],
            "default": "bifold"
          },
          "endAngle": {
            "title": "Angled end: angle to the wall",
            "type": "number",
            "minimum": 30,
            "maximum": 90,
            "default": 60,
            "x-unit": "°"
          },
          "bandingDeduct": {
            "title": "Deduct edge-banding thickness from cut sizes",
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "width"
        ]
      },
      "KerfwiseCabinetBuilderResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "required": [
              "type",
              "size",
              "dimensions",
              "parts",
              "hardware",
              "totals",
              "warnings",
              "project",
              "openInApp"
            ],
            "properties": {
              "type": {
                "type": "string"
              },
              "size": {
                "type": "object",
                "properties": {
                  "w": {
                    "type": "number"
                  },
                  "h": {
                    "type": "number"
                  },
                  "d": {
                    "type": "number"
                  }
                }
              },
              "dimensions": {
                "type": "object",
                "description": "Key derived dimensions (carcass height, inner sizes, door/back sizes, slide length …)."
              },
              "parts": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "label",
                    "name",
                    "L",
                    "W",
                    "T",
                    "cutL",
                    "cutW",
                    "material",
                    "grain",
                    "edges",
                    "holes"
                  ],
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "group": {
                      "type": "string"
                    },
                    "L": {
                      "type": "number"
                    },
                    "W": {
                      "type": "number"
                    },
                    "T": {
                      "type": "number"
                    },
                    "cutL": {
                      "type": "number"
                    },
                    "cutW": {
                      "type": "number"
                    },
                    "material": {
                      "type": "string"
                    },
                    "grain": {
                      "type": "boolean"
                    },
                    "edges": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "holes": {
                      "type": "integer"
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "shape": {
                      "enum": [
                        "rect",
                        "polygon"
                      ]
                    },
                    "outline": {
                      "type": "array",
                      "description": "Cut outline of shaped parts [u, v] in mm (u from the W1 end, v from the L1 edge).",
                      "items": {
                        "type": "array",
                        "items": {
                          "type": "number"
                        }
                      }
                    }
                  }
                }
              },
              "hardware": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "qty": {
                      "type": "number"
                    },
                    "unit": {
                      "type": "string"
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "totals": {
                "type": "object",
                "properties": {
                  "parts": {
                    "type": "integer"
                  },
                  "holes": {
                    "type": "integer"
                  },
                  "areaM2": {
                    "type": "number"
                  },
                  "bandingM": {
                    "type": "number"
                  }
                }
              },
              "warnings": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "project": {
                "type": "object",
                "description": "Kerfwise project JSON containing this cabinet (open it in the app or pass it to kerfwise-cut-list)."
              },
              "openInApp": {
                "type": "string"
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}