Kubova — 3D Container Loading
Pack cargo into containers & onto pallets; a verifiable 3D loading plan. Free tier + REST API.
사용해야 할까요
품질 및 안전성
도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.
컨텍스트 비용
이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.
설치
원클릭 설치
`claude_desktop_config.json` 파일에 다음을 추가하세요:
{
"mcpServers": {
"container-loading": {
"url": "https://kubova.com/mcp"
}
}
}원격 엔드포인트
https://kubova.com/mcpstreamable-http할 수 있는 일
도구 목록
도구 (4)
🟢pack_containers(cargos, container, containers, loadingMode, pallet, ...)
Pack a list of cargo SKUs into one or more shipping containers using the Kubova solver. Supports bulk loading (cartons straight into the container) and pallet loading (loadingMode:"pallet" + a pallet — cartons are stacked onto pallets first, then the pallets loaded). Per-SKU you can set allowed orientations, no-overstack/no-understack, and loading order. Returns per-container placements with x,y,z coordinates in cm, volume utilization, weight, a weightBalance object (centre of gravity + front/back & left/right weight split, flags an unbalanced load) for bulk loads, and any unplaced pieces.
입력 스키마
{
"type": "object",
"properties": {
"cargos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"shape": {
"type": "string",
"enum": [
"box",
"cylinder"
],
"default": "box"
},
"lengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"widthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"heightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"diameterCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"quantity": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000000,
"description": "Number of identical pieces of this SKU."
},
"weightKg": {
"type": "number",
"minimum": 0,
"description": "Weight of ONE piece in kg — NOT the row total. If a packing list shows both \"weight/piece\" and \"weight total\", use weight/piece (total = quantity × weightKg)."
},
"color": {
"type": "string",
"default": "#3b82f6"
},
"includeInLoading": {
"type": "boolean",
"default": true
},
"allowStacking": {
"type": "boolean",
"default": true
},
"allowRotation": {
"type": "boolean",
"default": true
},
"orientations": {
"type": "array",
"items": {
"type": "string",
"enum": [
"standard-0",
"standard-90",
"turnup-0",
"turnup-90",
"turnside-0",
"turnside-90"
]
},
"description": "Explicit allowed-pose subset; overrides allowRotation when set. standard = upright, turnup/turnside = tipped onto a face; 0/90 = yaw."
},
"noOverstack": {
"type": "boolean",
"description": "Nothing may rest on top of this SKU."
},
"noUnderstack": {
"type": "boolean",
"description": "Floor only — this SKU may not sit on other pieces."
},
"loadingOrder": {
"type": "string",
"enum": [
"optimized",
"rear",
"door"
],
"description": "Placement priority: rear = deepest (unloaded last), door = closest to the door (unloaded first)."
}
},
"required": [
"id",
"name",
"lengthCm",
"widthCm",
"heightCm",
"quantity",
"weightKg"
],
"additionalProperties": false
},
"minItems": 1,
"maxItems": 500
},
"container": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"innerLengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"innerWidthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"innerHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"doorWidthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"doorHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"maxPayloadKg": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000000000
}
},
"required": [
"id",
"name",
"innerLengthCm",
"innerWidthCm",
"innerHeightCm",
"doorWidthCm",
"doorHeightCm",
"maxPayloadKg"
],
"additionalProperties": false
},
"containers": {
"type": "array",
"items": {
"$ref": "#/properties/container"
},
"maxItems": 20
},
"loadingMode": {
"type": "string",
"enum": [
"bulk",
"pallet"
],
"description": "'bulk' (default) loads cartons straight into the container. 'pallet' first stacks cartons onto pallets, then loads the pallets — requires the `pallet` field."
},
"pallet": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"lengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000,
"description": "Pallet footprint length (cm)."
},
"widthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000,
"description": "Pallet footprint width (cm)."
},
"baseHeightCm": {
"type": "number",
"minimum": 0,
"maximum": 5000,
"description": "Pallet base self-height (cm), added below the cargo stack."
},
"maxStackHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000,
"description": "Max cargo stack height ON the pallet (cm), excluding the base."
},
"maxPayloadKg": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000000,
"description": "Max cargo weight per pallet (kg)."
},
"tareWeightKg": {
"type": "number",
"minimum": 0,
"maximum": 1000000,
"description": "Pallet self-weight (kg), added to container payload."
}
},
"required": [
"id",
"name",
"lengthCm",
"widthCm",
"baseHeightCm",
"maxStackHeightCm",
"maxPayloadKg",
"tareWeightKg"
],
"additionalProperties": false,
"description": "The pallet to stack onto. Required when loadingMode is \"pallet\"."
},
"options": {
"type": "object",
"properties": {
"loadingDirection": {
"type": "string",
"enum": [
"floor-to-top",
"right-to-left"
]
},
"maxContainers": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000
},
"deepOptimize": {
"type": "boolean",
"description": "Pallet mode only: run the exact optimizer for a tighter pallet plan (slower; Pro/Team plans)."
}
},
"additionalProperties": false
}
},
"required": [
"cargos"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢generate_report(cargos, container, containers, loadingMode, pallet, ...)
Generate a CAD-style PDF + 3D PNG report for a packing job. IMPORTANT: to keep the report consistent with a plan you already produced, pass the `result` object from your previous pack_containers call — the report then renders that exact plan instead of recomputing. Returns base64-encoded PDF + PNG per container.
입력 스키마
{
"type": "object",
"properties": {
"cargos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"shape": {
"type": "string",
"enum": [
"box",
"cylinder"
],
"default": "box"
},
"lengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"widthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"heightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"diameterCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"quantity": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000000,
"description": "Number of identical pieces of this SKU."
},
"weightKg": {
"type": "number",
"minimum": 0,
"description": "Weight of ONE piece in kg — NOT the row total. If a packing list shows both \"weight/piece\" and \"weight total\", use weight/piece (total = quantity × weightKg)."
},
"color": {
"type": "string",
"default": "#3b82f6"
},
"includeInLoading": {
"type": "boolean",
"default": true
},
"allowStacking": {
"type": "boolean",
"default": true
},
"allowRotation": {
"type": "boolean",
"default": true
},
"orientations": {
"type": "array",
"items": {
"type": "string",
"enum": [
"standard-0",
"standard-90",
"turnup-0",
"turnup-90",
"turnside-0",
"turnside-90"
]
},
"description": "Explicit allowed-pose subset; overrides allowRotation when set. standard = upright, turnup/turnside = tipped onto a face; 0/90 = yaw."
},
"noOverstack": {
"type": "boolean",
"description": "Nothing may rest on top of this SKU."
},
"noUnderstack": {
"type": "boolean",
"description": "Floor only — this SKU may not sit on other pieces."
},
"loadingOrder": {
"type": "string",
"enum": [
"optimized",
"rear",
"door"
],
"description": "Placement priority: rear = deepest (unloaded last), door = closest to the door (unloaded first)."
}
},
"required": [
"id",
"name",
"lengthCm",
"widthCm",
"heightCm",
"quantity",
"weightKg"
],
"additionalProperties": false
},
"minItems": 1,
"maxItems": 500
},
"container": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"innerLengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"innerWidthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"innerHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"doorWidthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"doorHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"maxPayloadKg": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000000000
}
},
"required": [
"id",
"name",
"innerLengthCm",
"innerWidthCm",
"innerHeightCm",
"doorWidthCm",
"doorHeightCm",
"maxPayloadKg"
],
"additionalProperties": false
},
"containers": {
"type": "array",
"items": {
"$ref": "#/properties/container"
},
"maxItems": 20
},
"loadingMode": {
"type": "string",
"enum": [
"bulk",
"pallet"
],
"description": "'bulk' (default) loads cartons straight into the container. 'pallet' first stacks cartons onto pallets, then loads the pallets — requires the `pallet` field."
},
"pallet": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"lengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000,
"description": "Pallet footprint length (cm)."
},
"widthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000,
"description": "Pallet footprint width (cm)."
},
"baseHeightCm": {
"type": "number",
"minimum": 0,
"maximum": 5000,
"description": "Pallet base self-height (cm), added below the cargo stack."
},
"maxStackHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000,
"description": "Max cargo stack height ON the pallet (cm), excluding the base."
},
"maxPayloadKg": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000000,
"description": "Max cargo weight per pallet (kg)."
},
"tareWeightKg": {
"type": "number",
"minimum": 0,
"maximum": 1000000,
"description": "Pallet self-weight (kg), added to container payload."
}
},
"required": [
"id",
"name",
"lengthCm",
"widthCm",
"baseHeightCm",
"maxStackHeightCm",
"maxPayloadKg",
"tareWeightKg"
],
"additionalProperties": false,
"description": "The pallet to stack onto. Required when loadingMode is \"pallet\"."
},
"options": {
"type": "object",
"properties": {
"loadingDirection": {
"type": "string",
"enum": [
"floor-to-top",
"right-to-left"
]
},
"maxContainers": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000
},
"deepOptimize": {
"type": "boolean",
"description": "Pallet mode only: run the exact optimizer for a tighter pallet plan (slower; Pro/Team plans)."
}
},
"additionalProperties": false
},
"result": {
"type": "object",
"additionalProperties": {},
"description": "OPTIONAL but strongly recommended: the exact `result` object returned by a prior pack_containers call, so the report renders THAT plan instead of repacking."
}
},
"required": [
"cargos"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢estimate_capacity(product, containers)
How many complete SETS of one product fit in a single container? A product is 1+ carton types with qtyPerSet each (e.g. a table shipping as 2 cartons: top + legs). All cartons of a set ride in the SAME container. Uses real 3D packing (not just volume math) and reports the binding limit (dimension / weight / volume) per container. Omit `containers` to evaluate the standard 20' DC, 40' DC and 40' HC.
입력 스키마
{
"type": "object",
"properties": {
"product": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"cartons": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"lengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"widthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"heightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"weightKg": {
"type": "number",
"minimum": 0,
"maximum": 1000000
},
"qtyPerSet": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 1000000,
"default": 1,
"description": "How many of THIS carton make up one set/product. Default 1."
},
"allowRotation": {
"type": "boolean",
"default": true
},
"allowStacking": {
"type": "boolean",
"default": true
}
},
"required": [
"name",
"lengthCm",
"widthCm",
"heightCm",
"weightKg"
],
"additionalProperties": false
},
"minItems": 1,
"maxItems": 500
}
},
"required": [
"cartons"
],
"additionalProperties": false
},
"containers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"maxLength": 200
},
"name": {
"type": "string",
"maxLength": 200
},
"innerLengthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"innerWidthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"innerHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"doorWidthCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"doorHeightCm": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 5000
},
"maxPayloadKg": {
"type": "number",
"exclusiveMinimum": 0,
"maximum": 1000000000
}
},
"required": [
"id",
"name",
"innerLengthCm",
"innerWidthCm",
"innerHeightCm",
"doorWidthCm",
"doorHeightCm",
"maxPayloadKg"
],
"additionalProperties": false
},
"maxItems": 20,
"description": "Containers to evaluate. Omit to use the standard catalogue (20' DC, 40' DC, 40' HC)."
}
},
"required": [
"product"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢verify_key
Verify the connection. Returns the authenticated account identity and plan.
입력 스키마
{
"type": "object",
"properties": {},
"$schema": "http://json-schema.org/draft-07/schema#"
}커뮤니티
증거