@vcad/mcp 0.10.0-main.128 → 0.10.0-main.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.mjs +29 -184
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,4 +6,4 @@ vcad's MCP server as a self-contained bundle (server + BRep kernel WASM).
|
|
|
6
6
|
{ "mcpServers": { "vcad": { "command": "npx", "args": ["-y", "@vcad/mcp"] } } }
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
Built from
|
|
9
|
+
Built from c0f41c513a664c5cad95f6b53a04977718e67e65 at 2026-10-21T15:14:39.035Z. Source: https://github.com/ecto/vcad
|
package/index.mjs
CHANGED
|
@@ -12304,6 +12304,7 @@ var init_dist = __esm({
|
|
|
12304
12304
|
importUrdfBuffer: wasmModule7.importUrdfBuffer,
|
|
12305
12305
|
importUrdfBufferWithOptions: wasmModule7.importUrdfBufferWithOptions,
|
|
12306
12306
|
urdfCommentedFloatingJoint: wasmModule7.urdfCommentedFloatingJoint,
|
|
12307
|
+
buildSheetMetalDocument: wasmModule7.buildSheetMetalDocument,
|
|
12307
12308
|
inlineMeshImports: wasmModule7.inlineMeshImports,
|
|
12308
12309
|
exportProjectedViewToDxf: wasmModule7.exportProjectedViewToDxf,
|
|
12309
12310
|
offsetSectionMesh: wasmModule7.offsetSectionMesh,
|
|
@@ -12967,6 +12968,17 @@ var init_dist = __esm({
|
|
|
12967
12968
|
* a commented-out floating joint means the author expected the simulator
|
|
12968
12969
|
* to supply the free base.
|
|
12969
12970
|
*/
|
|
12971
|
+
/**
|
|
12972
|
+
* Build a sheet-metal document (base flange + ordered flanges, hems, jogs,
|
|
12973
|
+
* bend relief) from a `sheet_metal_create` request, in the kernel
|
|
12974
|
+
* (`vcad_eval::sheet_build`). Throws on malformed input.
|
|
12975
|
+
*/
|
|
12976
|
+
buildSheetMetalDocument(args) {
|
|
12977
|
+
if (typeof this.kernel.buildSheetMetalDocument !== "function") {
|
|
12978
|
+
throw new Error("sheet-metal document builder not available - rebuild the kernel WASM");
|
|
12979
|
+
}
|
|
12980
|
+
return JSON.parse(this.kernel.buildSheetMetalDocument(JSON.stringify(args)));
|
|
12981
|
+
}
|
|
12970
12982
|
/**
|
|
12971
12983
|
* Inline STL meshes into `doc` in place: each `MeshImport` node keyed in
|
|
12972
12984
|
* `meshes` (node id -> STL bytes) becomes an `ImportedMesh` (metres -> mm,
|
|
@@ -41508,6 +41520,18 @@ var init_CHANGELOG = __esm({
|
|
|
41508
41520
|
"file-io"
|
|
41509
41521
|
]
|
|
41510
41522
|
},
|
|
41523
|
+
{
|
|
41524
|
+
id: "2026-10-21-mac-labs-toggle",
|
|
41525
|
+
version: "0.10.0",
|
|
41526
|
+
date: "2026-10-21",
|
|
41527
|
+
category: "feat",
|
|
41528
|
+
title: "Labs toggle for in-development Mac workspaces",
|
|
41529
|
+
summary: "Electronics, Manufacture (CNC Studio) and simulation in the Mac app now sit behind Settings \u25B8 Labs, off by default, so the default app is Design plus Agent.",
|
|
41530
|
+
features: [
|
|
41531
|
+
"desktop",
|
|
41532
|
+
"settings"
|
|
41533
|
+
]
|
|
41534
|
+
},
|
|
41511
41535
|
{
|
|
41512
41536
|
id: "2026-10-21-mac-exports-photoreal",
|
|
41513
41537
|
version: "0.10.0",
|
|
@@ -79822,154 +79846,6 @@ var init_dfm2 = __esm({
|
|
|
79822
79846
|
});
|
|
79823
79847
|
|
|
79824
79848
|
// src/tools/sheet-metal.ts
|
|
79825
|
-
function buildSheetMetalDoc(base, flanges, hems, jogs, bendRelief) {
|
|
79826
|
-
const doc = createDocument();
|
|
79827
|
-
const nodes = {};
|
|
79828
|
-
const shopProfile = base.shop_profile !== void 0 ? { shop_profile: base.shop_profile } : {};
|
|
79829
|
-
const engravings = base.engravings !== void 0 && base.engravings.length > 0 ? { engravings: base.engravings } : {};
|
|
79830
|
-
const baseNode = base.outline !== void 0 ? {
|
|
79831
|
-
id: 0,
|
|
79832
|
-
name: "Base flange (polygon)",
|
|
79833
|
-
op: {
|
|
79834
|
-
type: "SheetMetalBaseFlangePolygon",
|
|
79835
|
-
outline: base.outline,
|
|
79836
|
-
holes: base.holes,
|
|
79837
|
-
thickness: base.thickness,
|
|
79838
|
-
material: base.material,
|
|
79839
|
-
...shopProfile,
|
|
79840
|
-
...engravings
|
|
79841
|
-
}
|
|
79842
|
-
} : {
|
|
79843
|
-
id: 0,
|
|
79844
|
-
name: "Base flange",
|
|
79845
|
-
op: {
|
|
79846
|
-
type: "SheetMetalBaseFlangeRect",
|
|
79847
|
-
width: base.width ?? 0,
|
|
79848
|
-
depth: base.depth ?? 0,
|
|
79849
|
-
thickness: base.thickness,
|
|
79850
|
-
material: base.material,
|
|
79851
|
-
...shopProfile,
|
|
79852
|
-
...engravings
|
|
79853
|
-
}
|
|
79854
|
-
};
|
|
79855
|
-
nodes["0"] = baseNode;
|
|
79856
|
-
let parent = 0;
|
|
79857
|
-
let nextId3 = 1;
|
|
79858
|
-
flanges.forEach((f) => {
|
|
79859
|
-
const id = nextId3++;
|
|
79860
|
-
nodes[String(id)] = {
|
|
79861
|
-
id,
|
|
79862
|
-
name: `Edge flange ${id}`,
|
|
79863
|
-
op: {
|
|
79864
|
-
type: "SheetMetalEdgeFlange",
|
|
79865
|
-
parent,
|
|
79866
|
-
panel_id: f.panel_id ?? 0,
|
|
79867
|
-
edge_index: f.edge_index,
|
|
79868
|
-
length: f.length,
|
|
79869
|
-
angle: f.angle ?? Math.PI / 2,
|
|
79870
|
-
// Omit radius when unspecified — the kernel defaults to thickness,
|
|
79871
|
-
// or the shop's fixed radius under a shop profile.
|
|
79872
|
-
...f.radius !== void 0 ? { radius: f.radius } : {},
|
|
79873
|
-
direction: f.direction ?? "Up",
|
|
79874
|
-
...f.manual_k !== void 0 ? { manual_k: f.manual_k } : {}
|
|
79875
|
-
}
|
|
79876
|
-
};
|
|
79877
|
-
parent = id;
|
|
79878
|
-
});
|
|
79879
|
-
hems.forEach((h) => {
|
|
79880
|
-
const id = nextId3++;
|
|
79881
|
-
nodes[String(id)] = {
|
|
79882
|
-
id,
|
|
79883
|
-
name: `Hem ${id}`,
|
|
79884
|
-
op: {
|
|
79885
|
-
type: "SheetMetalHem",
|
|
79886
|
-
parent,
|
|
79887
|
-
panel_id: h.panel_id ?? 0,
|
|
79888
|
-
edge_index: h.edge_index,
|
|
79889
|
-
kind: h.kind ?? "Closed",
|
|
79890
|
-
length: h.length,
|
|
79891
|
-
gap: h.gap ?? 0,
|
|
79892
|
-
direction: h.direction ?? "Up"
|
|
79893
|
-
}
|
|
79894
|
-
};
|
|
79895
|
-
parent = id;
|
|
79896
|
-
});
|
|
79897
|
-
jogs.forEach((j) => {
|
|
79898
|
-
const id = nextId3++;
|
|
79899
|
-
nodes[String(id)] = {
|
|
79900
|
-
id,
|
|
79901
|
-
name: `Jog ${id}`,
|
|
79902
|
-
op: {
|
|
79903
|
-
type: "SheetMetalJog",
|
|
79904
|
-
parent,
|
|
79905
|
-
panel_id: j.panel_id ?? 0,
|
|
79906
|
-
edge_index: j.edge_index,
|
|
79907
|
-
offset: j.offset,
|
|
79908
|
-
length: j.length,
|
|
79909
|
-
...j.radius !== void 0 ? { radius: j.radius } : {},
|
|
79910
|
-
direction: j.direction ?? "Up"
|
|
79911
|
-
}
|
|
79912
|
-
};
|
|
79913
|
-
parent = id;
|
|
79914
|
-
});
|
|
79915
|
-
if (bendRelief) {
|
|
79916
|
-
const id = nextId3++;
|
|
79917
|
-
nodes[String(id)] = {
|
|
79918
|
-
id,
|
|
79919
|
-
name: "Bend relief",
|
|
79920
|
-
op: {
|
|
79921
|
-
type: "SheetMetalBendRelief",
|
|
79922
|
-
parent,
|
|
79923
|
-
...bendRelief.width_mm !== void 0 ? { width: bendRelief.width_mm } : {},
|
|
79924
|
-
...bendRelief.depth_mm !== void 0 ? { depth: bendRelief.depth_mm } : {}
|
|
79925
|
-
}
|
|
79926
|
-
};
|
|
79927
|
-
parent = id;
|
|
79928
|
-
}
|
|
79929
|
-
doc.nodes = nodes;
|
|
79930
|
-
doc.roots = [{ root: parent, material: "default" }];
|
|
79931
|
-
return doc;
|
|
79932
|
-
}
|
|
79933
|
-
function normaliseEngravings(raw) {
|
|
79934
|
-
return raw.map((e, i) => {
|
|
79935
|
-
const o = e ?? {};
|
|
79936
|
-
if (o.type === "Text" || o.type === void 0 && typeof o.text === "string") {
|
|
79937
|
-
if (typeof o.text !== "string" || o.text.length === 0) {
|
|
79938
|
-
throw new Error(`engravings[${i}]: Text needs a non-empty \`text\``);
|
|
79939
|
-
}
|
|
79940
|
-
const height = Number(o.height);
|
|
79941
|
-
if (!(height > 0)) {
|
|
79942
|
-
throw new Error(`engravings[${i}]: Text needs \`height\` > 0 (cap height, mm)`);
|
|
79943
|
-
}
|
|
79944
|
-
return {
|
|
79945
|
-
type: "Text",
|
|
79946
|
-
text: o.text,
|
|
79947
|
-
x: Number(o.x ?? 0),
|
|
79948
|
-
y: Number(o.y ?? 0),
|
|
79949
|
-
height,
|
|
79950
|
-
angle: Number(o.angle ?? 0)
|
|
79951
|
-
};
|
|
79952
|
-
}
|
|
79953
|
-
if (o.type === "Polyline" || Array.isArray(o.points)) {
|
|
79954
|
-
const points = Array.isArray(o.points) ? o.points.map((p) => {
|
|
79955
|
-
if (Array.isArray(p) && p.length >= 2)
|
|
79956
|
-
return { x: Number(p[0]), y: Number(p[1]) };
|
|
79957
|
-
if (p && typeof p === "object" && "x" in p && "y" in p) {
|
|
79958
|
-
const q2 = p;
|
|
79959
|
-
return { x: Number(q2.x), y: Number(q2.y) };
|
|
79960
|
-
}
|
|
79961
|
-
return null;
|
|
79962
|
-
}).filter((p) => p !== null) : [];
|
|
79963
|
-
if (points.length < 2) {
|
|
79964
|
-
throw new Error(`engravings[${i}]: Polyline needs >= 2 points`);
|
|
79965
|
-
}
|
|
79966
|
-
return { type: "Polyline", points };
|
|
79967
|
-
}
|
|
79968
|
-
throw new Error(
|
|
79969
|
-
`engravings[${i}]: expected {type: "Text", text, x, y, height} or {type: "Polyline", points}`
|
|
79970
|
-
);
|
|
79971
|
-
});
|
|
79972
|
-
}
|
|
79973
79849
|
function renderedOf(engine, doc) {
|
|
79974
79850
|
const scene = engine.evaluate(doc);
|
|
79975
79851
|
for (const part of scene.parts) {
|
|
@@ -79989,37 +79865,7 @@ function textResult13(payload) {
|
|
|
79989
79865
|
};
|
|
79990
79866
|
}
|
|
79991
79867
|
function sheetMetalCreate(input, engine) {
|
|
79992
|
-
const
|
|
79993
|
-
const normalisePoint = (p) => {
|
|
79994
|
-
if (Array.isArray(p) && p.length >= 2)
|
|
79995
|
-
return { x: Number(p[0]), y: Number(p[1]) };
|
|
79996
|
-
if (p && typeof p === "object" && "x" in p && "y" in p) {
|
|
79997
|
-
const o = p;
|
|
79998
|
-
return { x: Number(o.x), y: Number(o.y) };
|
|
79999
|
-
}
|
|
80000
|
-
return null;
|
|
80001
|
-
};
|
|
80002
|
-
const normaliseLoop = (loop) => {
|
|
80003
|
-
if (!Array.isArray(loop)) return [];
|
|
80004
|
-
return loop.map(normalisePoint).filter((p) => p !== null);
|
|
80005
|
-
};
|
|
80006
|
-
const outline = Array.isArray(a.outline) ? normaliseLoop(a.outline) : void 0;
|
|
80007
|
-
const holes = Array.isArray(a.holes) ? a.holes.map(normaliseLoop) : void 0;
|
|
80008
|
-
const base = {
|
|
80009
|
-
width: Number(a.width),
|
|
80010
|
-
depth: Number(a.depth),
|
|
80011
|
-
thickness: Number(a.thickness),
|
|
80012
|
-
material: typeof a.material === "string" ? a.material : "al-soft",
|
|
80013
|
-
outline,
|
|
80014
|
-
holes,
|
|
80015
|
-
...typeof a.shop_profile === "string" && a.shop_profile.length > 0 ? { shop_profile: a.shop_profile } : {},
|
|
80016
|
-
...Array.isArray(a.engravings) ? { engravings: normaliseEngravings(a.engravings) } : {}
|
|
80017
|
-
};
|
|
80018
|
-
const flanges = Array.isArray(a.flanges) ? a.flanges : [];
|
|
80019
|
-
const hems = Array.isArray(a.hems) ? a.hems : [];
|
|
80020
|
-
const jogs = Array.isArray(a.jogs) ? a.jogs : [];
|
|
80021
|
-
const bendRelief = a.bend_relief === true ? {} : a.bend_relief && typeof a.bend_relief === "object" ? a.bend_relief : void 0;
|
|
80022
|
-
const doc = buildSheetMetalDoc(base, flanges, hems, jogs, bendRelief);
|
|
79868
|
+
const doc = engine.buildSheetMetalDocument(input ?? {});
|
|
80023
79869
|
const rendered = renderedOf(engine, doc);
|
|
80024
79870
|
const documentId = registerSession(doc);
|
|
80025
79871
|
const errors = rendered.violations.filter(
|
|
@@ -80287,7 +80133,6 @@ var sheetMetalCreateSchema, sheetMetalUnfoldSchema, sheetMetalMaterialsSchema, s
|
|
|
80287
80133
|
var init_sheet_metal2 = __esm({
|
|
80288
80134
|
"src/tools/sheet-metal.ts"() {
|
|
80289
80135
|
"use strict";
|
|
80290
|
-
init_dist2();
|
|
80291
80136
|
init_session2();
|
|
80292
80137
|
init_tool_def();
|
|
80293
80138
|
sheetMetalCreateSchema = {
|
|
@@ -87005,8 +86850,8 @@ var init_server3 = __esm({
|
|
|
87005
86850
|
init_order_feed();
|
|
87006
86851
|
init_animate();
|
|
87007
86852
|
PKG_VERSION = (() => {
|
|
87008
|
-
if ("0.10.0-main.
|
|
87009
|
-
return "0.10.0-main.
|
|
86853
|
+
if ("0.10.0-main.129") {
|
|
86854
|
+
return "0.10.0-main.129";
|
|
87010
86855
|
}
|
|
87011
86856
|
try {
|
|
87012
86857
|
const req = createRequire2(import.meta.url);
|
|
@@ -87015,8 +86860,8 @@ var init_server3 = __esm({
|
|
|
87015
86860
|
return "0.0.0";
|
|
87016
86861
|
}
|
|
87017
86862
|
})();
|
|
87018
|
-
BUILD_SHA = "
|
|
87019
|
-
BUILD_TIME = "2026-10-21T15:
|
|
86863
|
+
BUILD_SHA = "c0f41c513a664c5cad95f6b53a04977718e67e65";
|
|
86864
|
+
BUILD_TIME = "2026-10-21T15:14:39.035Z";
|
|
87020
86865
|
SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
|
|
87021
86866
|
VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
|
|
87022
86867
|
INSTANCE_ID = randomUUID7().slice(0, 8);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vcad/mcp",
|
|
3
|
-
"version": "0.10.0-main.
|
|
3
|
+
"version": "0.10.0-main.129",
|
|
4
4
|
"description": "vcad MCP server — parametric CAD + PCB design tools for AI agents (self-contained: bundled server + kernel WASM)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://vcad.io",
|
|
21
21
|
"vcadBuild": {
|
|
22
|
-
"sha": "
|
|
23
|
-
"builtAt": "2026-10-21T15:
|
|
22
|
+
"sha": "c0f41c513a664c5cad95f6b53a04977718e67e65",
|
|
23
|
+
"builtAt": "2026-10-21T15:14:39.035Z"
|
|
24
24
|
}
|
|
25
25
|
}
|