@vcad/mcp 0.9.4-main.16 → 0.9.4-main.17

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 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 63c1a040cf3352ca640144ec217f3f96271180c9 at 2026-07-24T17:21:48.535Z. Source: https://github.com/ecto/vcad
9
+ Built from cfb504c93d13b7e0339f79b4b8863ffeb1ca83b1 at 2026-07-24T20:18:23.601Z. Source: https://github.com/ecto/vcad
package/index.mjs CHANGED
@@ -151,6 +151,14 @@ __export(vcad_kernel_wasm_exports, {
151
151
  ecadVerifySubstitution: () => ecadVerifySubstitution,
152
152
  emSimulate: () => emSimulate,
153
153
  embroideryDesignToMesh: () => embroideryDesignToMesh,
154
+ enclosure_component_extents: () => enclosure_component_extents,
155
+ enclosure_connectors: () => enclosure_connectors,
156
+ enclosure_derive_board: () => enclosure_derive_board,
157
+ enclosure_features: () => enclosure_features,
158
+ enclosure_fit: () => enclosure_fit,
159
+ enclosure_mounting_holes: () => enclosure_mounting_holes,
160
+ enclosure_outline_aabb: () => enclosure_outline_aabb,
161
+ enclosure_to_world: () => enclosure_to_world,
154
162
  estimatePrintCost: () => estimatePrintCost,
155
163
  estimate_cost_for_process: () => estimate_cost_for_process,
156
164
  eulerXyzDegToQuat: () => eulerXyzDegToQuat,
@@ -1530,6 +1538,184 @@ function embroideryDesignToMesh(design_json) {
1530
1538
  }
1531
1539
  return takeFromExternrefTable0(ret[0]);
1532
1540
  }
1541
+ function enclosure_component_extents(meshes_json, pcb_json) {
1542
+ let deferred4_0;
1543
+ let deferred4_1;
1544
+ try {
1545
+ const ptr0 = passStringToWasm0(meshes_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1546
+ const len0 = WASM_VECTOR_LEN;
1547
+ const ptr1 = passStringToWasm0(pcb_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1548
+ const len1 = WASM_VECTOR_LEN;
1549
+ const ret = wasm.enclosure_component_extents(ptr0, len0, ptr1, len1);
1550
+ var ptr3 = ret[0];
1551
+ var len3 = ret[1];
1552
+ if (ret[3]) {
1553
+ ptr3 = 0;
1554
+ len3 = 0;
1555
+ throw takeFromExternrefTable0(ret[2]);
1556
+ }
1557
+ deferred4_0 = ptr3;
1558
+ deferred4_1 = len3;
1559
+ return getStringFromWasm0(ptr3, len3);
1560
+ } finally {
1561
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
1562
+ }
1563
+ }
1564
+ function enclosure_connectors(pcb_json, outline_json) {
1565
+ let deferred4_0;
1566
+ let deferred4_1;
1567
+ try {
1568
+ const ptr0 = passStringToWasm0(pcb_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1569
+ const len0 = WASM_VECTOR_LEN;
1570
+ const ptr1 = passStringToWasm0(outline_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1571
+ const len1 = WASM_VECTOR_LEN;
1572
+ const ret = wasm.enclosure_connectors(ptr0, len0, ptr1, len1);
1573
+ var ptr3 = ret[0];
1574
+ var len3 = ret[1];
1575
+ if (ret[3]) {
1576
+ ptr3 = 0;
1577
+ len3 = 0;
1578
+ throw takeFromExternrefTable0(ret[2]);
1579
+ }
1580
+ deferred4_0 = ptr3;
1581
+ deferred4_1 = len3;
1582
+ return getStringFromWasm0(ptr3, len3);
1583
+ } finally {
1584
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
1585
+ }
1586
+ }
1587
+ function enclosure_derive_board(cavity_json, standoffs_json, options_json) {
1588
+ let deferred5_0;
1589
+ let deferred5_1;
1590
+ try {
1591
+ const ptr0 = passStringToWasm0(cavity_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1592
+ const len0 = WASM_VECTOR_LEN;
1593
+ const ptr1 = passStringToWasm0(standoffs_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1594
+ const len1 = WASM_VECTOR_LEN;
1595
+ const ptr2 = passStringToWasm0(options_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1596
+ const len2 = WASM_VECTOR_LEN;
1597
+ const ret = wasm.enclosure_derive_board(ptr0, len0, ptr1, len1, ptr2, len2);
1598
+ var ptr4 = ret[0];
1599
+ var len4 = ret[1];
1600
+ if (ret[3]) {
1601
+ ptr4 = 0;
1602
+ len4 = 0;
1603
+ throw takeFromExternrefTable0(ret[2]);
1604
+ }
1605
+ deferred5_0 = ptr4;
1606
+ deferred5_1 = len4;
1607
+ return getStringFromWasm0(ptr4, len4);
1608
+ } finally {
1609
+ wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
1610
+ }
1611
+ }
1612
+ function enclosure_features(positions, indices) {
1613
+ let deferred4_0;
1614
+ let deferred4_1;
1615
+ try {
1616
+ const ptr0 = passArrayF64ToWasm0(positions, wasm.__wbindgen_malloc);
1617
+ const len0 = WASM_VECTOR_LEN;
1618
+ const ptr1 = passArray32ToWasm0(indices, wasm.__wbindgen_malloc);
1619
+ const len1 = WASM_VECTOR_LEN;
1620
+ const ret = wasm.enclosure_features(ptr0, len0, ptr1, len1);
1621
+ var ptr3 = ret[0];
1622
+ var len3 = ret[1];
1623
+ if (ret[3]) {
1624
+ ptr3 = 0;
1625
+ len3 = 0;
1626
+ throw takeFromExternrefTable0(ret[2]);
1627
+ }
1628
+ deferred4_0 = ptr3;
1629
+ deferred4_1 = len3;
1630
+ return getStringFromWasm0(ptr3, len3);
1631
+ } finally {
1632
+ wasm.__wbindgen_free(deferred4_0, deferred4_1, 1);
1633
+ }
1634
+ }
1635
+ function enclosure_fit(input_json) {
1636
+ let deferred3_0;
1637
+ let deferred3_1;
1638
+ try {
1639
+ const ptr0 = passStringToWasm0(input_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1640
+ const len0 = WASM_VECTOR_LEN;
1641
+ const ret = wasm.enclosure_fit(ptr0, len0);
1642
+ var ptr2 = ret[0];
1643
+ var len2 = ret[1];
1644
+ if (ret[3]) {
1645
+ ptr2 = 0;
1646
+ len2 = 0;
1647
+ throw takeFromExternrefTable0(ret[2]);
1648
+ }
1649
+ deferred3_0 = ptr2;
1650
+ deferred3_1 = len2;
1651
+ return getStringFromWasm0(ptr2, len2);
1652
+ } finally {
1653
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1654
+ }
1655
+ }
1656
+ function enclosure_mounting_holes(pcb_json) {
1657
+ let deferred3_0;
1658
+ let deferred3_1;
1659
+ try {
1660
+ const ptr0 = passStringToWasm0(pcb_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1661
+ const len0 = WASM_VECTOR_LEN;
1662
+ const ret = wasm.enclosure_mounting_holes(ptr0, len0);
1663
+ var ptr2 = ret[0];
1664
+ var len2 = ret[1];
1665
+ if (ret[3]) {
1666
+ ptr2 = 0;
1667
+ len2 = 0;
1668
+ throw takeFromExternrefTable0(ret[2]);
1669
+ }
1670
+ deferred3_0 = ptr2;
1671
+ deferred3_1 = len2;
1672
+ return getStringFromWasm0(ptr2, len2);
1673
+ } finally {
1674
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1675
+ }
1676
+ }
1677
+ function enclosure_outline_aabb(outline_json) {
1678
+ let deferred3_0;
1679
+ let deferred3_1;
1680
+ try {
1681
+ const ptr0 = passStringToWasm0(outline_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1682
+ const len0 = WASM_VECTOR_LEN;
1683
+ const ret = wasm.enclosure_outline_aabb(ptr0, len0);
1684
+ var ptr2 = ret[0];
1685
+ var len2 = ret[1];
1686
+ if (ret[3]) {
1687
+ ptr2 = 0;
1688
+ len2 = 0;
1689
+ throw takeFromExternrefTable0(ret[2]);
1690
+ }
1691
+ deferred3_0 = ptr2;
1692
+ deferred3_1 = len2;
1693
+ return getStringFromWasm0(ptr2, len2);
1694
+ } finally {
1695
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1696
+ }
1697
+ }
1698
+ function enclosure_to_world(x, y, z, placement_json) {
1699
+ let deferred3_0;
1700
+ let deferred3_1;
1701
+ try {
1702
+ const ptr0 = passStringToWasm0(placement_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1703
+ const len0 = WASM_VECTOR_LEN;
1704
+ const ret = wasm.enclosure_to_world(x, y, z, ptr0, len0);
1705
+ var ptr2 = ret[0];
1706
+ var len2 = ret[1];
1707
+ if (ret[3]) {
1708
+ ptr2 = 0;
1709
+ len2 = 0;
1710
+ throw takeFromExternrefTable0(ret[2]);
1711
+ }
1712
+ deferred3_0 = ptr2;
1713
+ deferred3_1 = len2;
1714
+ return getStringFromWasm0(ptr2, len2);
1715
+ } finally {
1716
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
1717
+ }
1718
+ }
1533
1719
  function estimatePrintCost(volume_mm3, infill_density, wall_count, line_width, material_name) {
1534
1720
  const ptr0 = passStringToWasm0(material_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
1535
1721
  const len0 = WASM_VECTOR_LEN;
@@ -11283,6 +11469,7 @@ var init_dist = __esm({
11283
11469
  antennaAnalyze: wasmModule7.antennaAnalyze,
11284
11470
  photonicsSimulate: wasmModule7.photonicsSimulate,
11285
11471
  neutronicsSimulate: wasmModule7.neutronicsSimulate,
11472
+ latticeGaugeSimulate: wasmModule7.latticeGaugeSimulate,
11286
11473
  analyzeStaticsBox: wasmModule7.analyzeStaticsBox,
11287
11474
  analyzeStaticsMesh: wasmModule7.analyzeStaticsMesh
11288
11475
  }, compiledWasmModule);
@@ -11643,6 +11830,19 @@ var init_dist = __esm({
11643
11830
  }
11644
11831
  return fn(specJson, paramsJson);
11645
11832
  }
11833
+ /**
11834
+ * Lattice gauge theory Monte Carlo (quenched SU(2)/SU(3) Wilson
11835
+ * action): plaquette, Wilson loops, string tension, Polyakov order
11836
+ * parameter, flux-tube profile, field snapshots — jackknife errors
11837
+ * throughout; see `vcad-kernel-qcd`.
11838
+ */
11839
+ latticeGaugeSimulate(specJson) {
11840
+ const fn = this.kernel.latticeGaugeSimulate;
11841
+ if (typeof fn !== "function") {
11842
+ throw new Error("latticeGaugeSimulate is not exported by this kernel WASM build \u2014 rebuild packages/kernel-wasm");
11843
+ }
11844
+ return fn(specJson);
11845
+ }
11646
11846
  topologyOptimizeBox(min, max, spec) {
11647
11847
  const fn = this.kernel.topologyOptimizeBox;
11648
11848
  if (typeof fn !== "function") {
@@ -40609,6 +40809,21 @@ var init_CHANGELOG = __esm({
40609
40809
  "validate_for_fab"
40610
40810
  ]
40611
40811
  },
40812
+ {
40813
+ id: "2026-07-24-lattice-gauge-mcp",
40814
+ version: "0.9.4",
40815
+ date: "2026-07-24",
40816
+ category: "feat",
40817
+ title: "Lattice gauge theory simulation",
40818
+ summary: "New simulate_lattice_gauge tool: quenched SU(2)/SU(3) Monte Carlo \u2014 confinement, string tension, deconfinement, flux tubes and instantons, with jackknife error bars on every number.",
40819
+ features: [
40820
+ "simulation",
40821
+ "physics"
40822
+ ],
40823
+ mcpTools: [
40824
+ "simulate_lattice_gauge"
40825
+ ]
40826
+ },
40612
40827
  {
40613
40828
  id: "2026-07-23-router-post-route-legalization",
40614
40829
  version: "0.9.4",
@@ -51637,6 +51852,10 @@ var init_tool_metadata = __esm({
51637
51852
  title: "Simulate Neutron Shield",
51638
51853
  annotations: RO
51639
51854
  },
51855
+ simulate_lattice_gauge: {
51856
+ title: "Simulate Lattice Gauge Theory",
51857
+ annotations: RO
51858
+ },
51640
51859
  analyze_tolerance_stackup: {
51641
51860
  title: "Analyze Tolerance Stackup",
51642
51861
  annotations: RO
@@ -70402,6 +70621,128 @@ var init_neutronics = __esm({
70402
70621
  }
70403
70622
  });
70404
70623
 
70624
+ // src/tools/qcd.ts
70625
+ function textResult11(payload) {
70626
+ return {
70627
+ content: [
70628
+ {
70629
+ type: "text",
70630
+ text: JSON.stringify(payload, null, 2)
70631
+ }
70632
+ ]
70633
+ };
70634
+ }
70635
+ var simSpecSchema, toolDefs36;
70636
+ var init_qcd = __esm({
70637
+ "src/tools/qcd.ts"() {
70638
+ "use strict";
70639
+ init_tool_def();
70640
+ simSpecSchema = {
70641
+ type: "object",
70642
+ required: [
70643
+ "dims",
70644
+ "beta",
70645
+ "thermalization_sweeps",
70646
+ "measurement_sweeps",
70647
+ "overrelax_per_heatbath",
70648
+ "bin_size",
70649
+ "max_wilson_extent",
70650
+ "seed",
70651
+ "hot_start"
70652
+ ],
70653
+ description: "Lattice simulation spec. Deterministic per seed. Direction 3 is time \u2014 shorten it (e.g. [6,6,6,2]) for finite temperature / deconfinement studies.",
70654
+ properties: {
70655
+ gauge: {
70656
+ type: "string",
70657
+ enum: ["Su2", "Su3"],
70658
+ description: "Gauge group. Su2 (default): quaternion links, exact Kennedy-Pendleton heatbath, fastest. Su3: the real QCD gauge group, Cabibbo-Marinari updates, ~6x cost per link."
70659
+ },
70660
+ dims: {
70661
+ type: "array",
70662
+ items: { type: "number" },
70663
+ minItems: 4,
70664
+ maxItems: 4,
70665
+ description: "Lattice extents [n0,n1,n2,n3], each >= 2. 4^4-8^4 are seconds-scale; 12^4+ is where the cost gate starts to bite."
70666
+ },
70667
+ beta: {
70668
+ type: "number",
70669
+ description: "Inverse coupling beta = 2N/g^2 (Wilson action). SU(2): strong coupling < ~1.5, crossover ~2.2-2.5, weak > 4. SU(3): strong < ~4, deconfinement at N_t=2 near 5.1, weak > 7."
70670
+ },
70671
+ thermalization_sweeps: {
70672
+ type: "number",
70673
+ description: "Discarded equilibration sweeps (>= 1). 50 is typical."
70674
+ },
70675
+ measurement_sweeps: {
70676
+ type: "number",
70677
+ description: "Measured sweeps. Must give >= 2 full jackknife bins (>= 5 bins to mint claims). 100-200 is typical."
70678
+ },
70679
+ overrelax_per_heatbath: {
70680
+ type: "number",
70681
+ description: "Overrelaxation sweeps interleaved per heatbath sweep (1-3 decorrelates much faster per unit work)."
70682
+ },
70683
+ bin_size: {
70684
+ type: "number",
70685
+ description: "Jackknife bin size in measurements (10-20 typical)."
70686
+ },
70687
+ max_wilson_extent: {
70688
+ type: "number",
70689
+ description: "Largest square Wilson loop W(r,t) to measure; 0 = plaquette only. Capped at half the smallest lattice extent."
70690
+ },
70691
+ seed: { type: "number" },
70692
+ hot_start: {
70693
+ type: "boolean",
70694
+ description: "Start from random links instead of cold (identity)."
70695
+ },
70696
+ smear: {
70697
+ type: "object",
70698
+ required: ["alpha", "iterations"],
70699
+ description: "APE spatial smearing applied to a measurement copy before loop observables (lifts the string-tension signal at intermediate coupling; plaquette stays unsmeared). alpha 0.5, 2-3 iterations is customary.",
70700
+ properties: {
70701
+ alpha: { type: "number" },
70702
+ iterations: { type: "number" }
70703
+ }
70704
+ },
70705
+ measure_temporal_loops: {
70706
+ type: "boolean",
70707
+ description: "Also measure spatial x temporal Wilson loops and derive the static quark potential V(r) (+ Cornell fit when >= 3 points resolve)."
70708
+ },
70709
+ measure_polyakov: {
70710
+ type: "boolean",
70711
+ description: "Measure <|L|>, the Polyakov-loop deconfinement order parameter (small = confined, O(1) = deconfined)."
70712
+ },
70713
+ flux_tube: {
70714
+ type: "object",
70715
+ required: ["separation"],
70716
+ description: "Measure the chromoelectric flux-tube profile between a static quark-antiquark pair at this separation (lattice units, spatial axis 0): the connected (Polyakov-pair x action-density) 3D excess field plus the pair correlator whose decay with separation IS confinement. Use a short time axis (N_t 2-4).",
70717
+ properties: { separation: { type: "number" } }
70718
+ },
70719
+ snapshot_cooling: {
70720
+ type: "number",
70721
+ description: "Export a rendering FieldSnapshot (action density per site + complex Polyakov field per spatial site) of the final configuration after this many cooling sweeps (0 = raw vacuum boil; 20-30 = classical lumps). SU(2) runs with cooling >= 1 also report the clover topological charge (near-integer = instanton content)."
70722
+ }
70723
+ }
70724
+ };
70725
+ toolDefs36 = [
70726
+ {
70727
+ name: "simulate_lattice_gauge",
70728
+ pack: null,
70729
+ description: "Lattice gauge theory Monte Carlo (quenched Wilson action, SU(2) or SU(3)): confinement from first principles on a laptop-scale 4D lattice. Returns the average plaquette, Wilson loops, Creutz ratios + static potential + Cornell fit (the string tension sigma*a^2), the Polyakov deconfinement order parameter, and optionally viewport-ready field snapshots (action density, Polyakov field, cooled topological charge) and the static-pair flux-tube profile \u2014 every observable a binned-jackknife mean +- error, bit-deterministic per seed. Fail-closed: starved statistics refuse to mint vcad.qcd-claims/1 (raise measurement_sweeps); logs require loops resolved >= 3-sigma from zero. Honesty bounds ride every claim: quenched (no dynamical fermions), lattice units at fixed coupling (no continuum limit) \u2014 model physics, not physical-QCD numbers. Cost ~ volume x sweeps (x6 for SU(3)); 6^4 with 150 sweeps runs in seconds. Recipes: confinement demo = Su2, [6,6,6,4], beta 2.2, flux_tube {separation 2}; deconfinement = [6,6,6,2], measure_polyakov, beta scan across ~1.88 (Su2) / ~5.1 (Su3); instantons = Su2, beta 2.4, snapshot_cooling 30.",
70730
+ inputSchema: {
70731
+ type: "object",
70732
+ required: ["spec"],
70733
+ properties: { spec: simSpecSchema }
70734
+ },
70735
+ handler: (args, ctx) => {
70736
+ const a = args;
70737
+ const out = ctx.engine.latticeGaugeSimulate(JSON.stringify(a.spec));
70738
+ return textResult11(out);
70739
+ },
70740
+ behavior: behavior({})
70741
+ }
70742
+ ];
70743
+ }
70744
+ });
70745
+
70405
70746
  // src/tools/physics.ts
70406
70747
  function limitClaim(id, description, subject, limit, actual, unit, basis, converged) {
70407
70748
  if (!converged || !Number.isFinite(actual)) {
@@ -70523,7 +70864,7 @@ function predictPhysicsTool(args, engine) {
70523
70864
  ]
70524
70865
  };
70525
70866
  }
70526
- var PHYSICS_DOMAIN, ORACLE, TIER_RESOLUTION, regionSchema3, predictPhysicsSchema, round52, toolDefs36;
70867
+ var PHYSICS_DOMAIN, ORACLE, TIER_RESOLUTION, regionSchema3, predictPhysicsSchema, round52, toolDefs37;
70527
70868
  var init_physics2 = __esm({
70528
70869
  "src/tools/physics.ts"() {
70529
70870
  "use strict";
@@ -70636,7 +70977,7 @@ var init_physics2 = __esm({
70636
70977
  }
70637
70978
  };
70638
70979
  round52 = (v) => Number(v.toPrecision(5));
70639
- toolDefs36 = [
70980
+ toolDefs37 = [
70640
70981
  {
70641
70982
  name: "predict_physics",
70642
70983
  pack: null,
@@ -70878,7 +71219,7 @@ function applySetParam(doc, node, path, value) {
70878
71219
  }
70879
71220
  cursor[parts[parts.length - 1]] = value;
70880
71221
  }
70881
- var lastReports, mechanicalProcessEnum, pcbProcessEnum, processEnum, dfmCheckSchema, dfmExplainSchema, dfmSuggestFixSchema, dfmApplyFixSchema, toolDefs37;
71222
+ var lastReports, mechanicalProcessEnum, pcbProcessEnum, processEnum, dfmCheckSchema, dfmExplainSchema, dfmSuggestFixSchema, dfmApplyFixSchema, toolDefs38;
70882
71223
  var init_dfm2 = __esm({
70883
71224
  "src/tools/dfm.ts"() {
70884
71225
  "use strict";
@@ -70975,7 +71316,7 @@ var init_dfm2 = __esm({
70975
71316
  },
70976
71317
  required: ["issue_id"]
70977
71318
  };
70978
- toolDefs37 = [
71319
+ toolDefs38 = [
70979
71320
  {
70980
71321
  name: "dfm_check",
70981
71322
  pack: "dfm",
@@ -71174,7 +71515,7 @@ function renderedOf(engine, doc) {
71174
71515
  "document has no sheet-metal part (evaluation produced no sheetMetal bundle)"
71175
71516
  );
71176
71517
  }
71177
- function textResult11(payload) {
71518
+ function textResult12(payload) {
71178
71519
  return {
71179
71520
  content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
71180
71521
  };
@@ -71216,7 +71557,7 @@ function sheetMetalCreate(input, engine) {
71216
71557
  const errors = rendered.violations.filter(
71217
71558
  (v) => v.severity === "Error"
71218
71559
  ).length;
71219
- return textResult11({
71560
+ return textResult12({
71220
71561
  document_id: documentId,
71221
71562
  model: rendered.model,
71222
71563
  flat: {
@@ -71232,7 +71573,7 @@ function sheetMetalUnfold(input, engine) {
71232
71573
  const doc = getSession(String(a.document_id ?? ""));
71233
71574
  const rendered = renderedOf(engine, doc);
71234
71575
  const includeDxf = a.include_dxf !== false;
71235
- return textResult11({
71576
+ return textResult12({
71236
71577
  flat_pattern: rendered.flatPattern,
71237
71578
  ...includeDxf ? { dxf: rendered.dxf } : {},
71238
71579
  note: "The DXF is a fab-ready merged silhouette: one closed exterior LWPOLYLINE plus hole loops on CUT, DASHED bend centerlines (on the allowance midline) on BEND_UP/BEND_DOWN, and any surface markings as open polylines on ENGRAVE (select the laser-marking/engraving service for that layer in the fab's UI). DXF carries no bend angles \u2014 you enter those in the fab's UI. For zero data entry, export the folded body as STEP instead (export_cad with a .step filename); bends are auto-detected by the shop, but radii/K must match their tooling at model time (use shop_profile in sheet_metal_create)."
@@ -71240,7 +71581,7 @@ function sheetMetalUnfold(input, engine) {
71240
71581
  }
71241
71582
  function sheetMetalMaterials(_input, engine) {
71242
71583
  const materials = engine.getSheetMetalMaterials();
71243
- return textResult11({
71584
+ return textResult12({
71244
71585
  materials,
71245
71586
  note: 'Pass any `name` (e.g. `"al-soft"`, `"steel-mild"`) as the `material` field of `sheet_metal_create`. Aliases like `"aluminum"`, `"stainless"`, `"6061-T6"` also resolve.'
71246
71587
  });
@@ -71249,13 +71590,13 @@ function sheetMetalBendTable(input, engine) {
71249
71590
  const a = input ?? {};
71250
71591
  if (typeof a.shop_profile === "string" && a.shop_profile.length > 0) {
71251
71592
  const catalog = engine.getSheetMetalShopCatalog(a.shop_profile);
71252
- return textResult11({
71593
+ return textResult12({
71253
71594
  catalog,
71254
71595
  note: `Published catalog for ${catalog.name} (retrieved ${catalog.retrieved}). inside_radius_mm is FIXED per material/thickness \u2014 pass shop_profile: "${catalog.id}" to sheet_metal_create and omit per-bend radius to use it.`
71255
71596
  });
71256
71597
  }
71257
71598
  const table = engine.getSheetMetalBendTable();
71258
- return textResult11({
71599
+ return textResult12({
71259
71600
  table,
71260
71601
  note: "K-factors are interpolated by closest R/t for the chosen material. To override K for a specific bend, pass `manual_k` on that flange in sheet_metal_create."
71261
71602
  });
@@ -71277,7 +71618,7 @@ function sheetMetalCheck(input, engine) {
71277
71618
  const errors = result.violations.filter(
71278
71619
  (v) => v.severity === "Error"
71279
71620
  ).length;
71280
- return textResult11({
71621
+ return textResult12({
71281
71622
  shop: result.shop,
71282
71623
  violations: result.violations,
71283
71624
  shop_ready: result.violations.length === 0,
@@ -71329,7 +71670,7 @@ function sheetMetalNest(input, engine) {
71329
71670
  footprints,
71330
71671
  params
71331
71672
  );
71332
- return textResult11({
71673
+ return textResult12({
71333
71674
  parts: footprints,
71334
71675
  result,
71335
71676
  summary: `${result.placements.length} placements across ${result.sheets_used} sheet(s); ${result.utilization_pct.toFixed(1)}% utilization${result.unplaceable.length > 0 ? `; ${result.unplaceable.length} unplaceable (oversize)` : ""}.`
@@ -71342,7 +71683,7 @@ function sheetMetalSequence3(input, engine) {
71342
71683
  if (!steps) {
71343
71684
  throw new Error("document has no sheet-metal part");
71344
71685
  }
71345
- return textResult11({
71686
+ return textResult12({
71346
71687
  count: steps.length,
71347
71688
  steps,
71348
71689
  note: "Form each bend in order. compensated_angle_rad is the angle to dial in on the brake \u2014 springs back to angle_rad once released."
@@ -71365,7 +71706,7 @@ function sheetMetalSuggestFix(input, engine) {
71365
71706
  violation: v,
71366
71707
  fix: suggestFix(v)
71367
71708
  }));
71368
- return textResult11({
71709
+ return textResult12({
71369
71710
  shop: result.shop,
71370
71711
  count: suggestions.length,
71371
71712
  suggestions,
@@ -71468,13 +71809,13 @@ function sheetMetalCost(input, engine) {
71468
71809
  if (!result) {
71469
71810
  throw new Error("document has no sheet-metal part");
71470
71811
  }
71471
- return textResult11({
71812
+ return textResult12({
71472
71813
  breakdown: result.breakdown,
71473
71814
  rates: result.rates,
71474
71815
  summary: `${result.breakdown.currency} ${result.breakdown.total_each.toFixed(2)} each @ qty ${result.breakdown.quantity} (mass ${result.breakdown.mass_kg_each.toFixed(3)} kg, ${result.breakdown.cut_length_m.toFixed(2)} m cut, ${result.breakdown.bends} bend(s)).`
71475
71816
  });
71476
71817
  }
71477
- var sheetMetalCreateSchema, sheetMetalUnfoldSchema, sheetMetalMaterialsSchema, sheetMetalBendTableSchema, sheetMetalCheckSchema, sheetMetalNestSchema, sheetMetalSequenceSchema, sheetMetalSuggestFixSchema, sheetMetalCostSchema, toolDefs38;
71818
+ var sheetMetalCreateSchema, sheetMetalUnfoldSchema, sheetMetalMaterialsSchema, sheetMetalBendTableSchema, sheetMetalCheckSchema, sheetMetalNestSchema, sheetMetalSequenceSchema, sheetMetalSuggestFixSchema, sheetMetalCostSchema, toolDefs39;
71478
71819
  var init_sheet_metal2 = __esm({
71479
71820
  "src/tools/sheet-metal.ts"() {
71480
71821
  "use strict";
@@ -71735,7 +72076,7 @@ var init_sheet_metal2 = __esm({
71735
72076
  },
71736
72077
  required: ["document_id"]
71737
72078
  };
71738
- toolDefs38 = [
72079
+ toolDefs39 = [
71739
72080
  {
71740
72081
  name: "sheet_metal_create",
71741
72082
  pack: "sheet_metal",
@@ -71980,7 +72321,7 @@ function simulateStrike(input, engine) {
71980
72321
  }
71981
72322
  return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
71982
72323
  }
71983
- var cents, MATERIAL_ALIASES, simulateStrikeSchema, round22, round4, toolDefs39;
72324
+ var cents, MATERIAL_ALIASES, simulateStrikeSchema, round22, round4, toolDefs40;
71984
72325
  var init_acoustics = __esm({
71985
72326
  "src/tools/acoustics.ts"() {
71986
72327
  "use strict";
@@ -72054,7 +72395,7 @@ var init_acoustics = __esm({
72054
72395
  };
72055
72396
  round22 = (x) => Math.round(x * 100) / 100;
72056
72397
  round4 = (x) => Math.round(x * 1e4) / 1e4;
72057
- toolDefs39 = [
72398
+ toolDefs40 = [
72058
72399
  {
72059
72400
  name: "simulate_strike",
72060
72401
  pack: "sheet_metal",
@@ -72205,7 +72546,7 @@ function importStep(input, engine) {
72205
72546
  ]
72206
72547
  };
72207
72548
  }
72208
- var MAX_STEP_BYTES, importStepSchema, toolDefs40;
72549
+ var MAX_STEP_BYTES, importStepSchema, toolDefs41;
72209
72550
  var init_import = __esm({
72210
72551
  "src/tools/import.ts"() {
72211
72552
  "use strict";
@@ -72237,7 +72578,7 @@ var init_import = __esm({
72237
72578
  }
72238
72579
  }
72239
72580
  };
72240
- toolDefs40 = [
72581
+ toolDefs41 = [
72241
72582
  {
72242
72583
  name: "import_step",
72243
72584
  pack: null,
@@ -72365,7 +72706,7 @@ function importEagle(_input) {
72365
72706
  "Eagle (.brd) import is not yet supported. Export your board from Eagle as KiCad (File > Export > KiCad .kicad_pcb) and use import_kicad instead."
72366
72707
  );
72367
72708
  }
72368
- var MAX_PCB_BYTES, importKicadSchema, importEagleSchema, toolDefs41;
72709
+ var MAX_PCB_BYTES, importKicadSchema, importEagleSchema, toolDefs42;
72369
72710
  var init_import_pcb = __esm({
72370
72711
  "src/tools/import-pcb.ts"() {
72371
72712
  "use strict";
@@ -72406,7 +72747,7 @@ var init_import_pcb = __esm({
72406
72747
  }
72407
72748
  }
72408
72749
  };
72409
- toolDefs41 = [
72750
+ toolDefs42 = [
72410
72751
  {
72411
72752
  name: "import_kicad",
72412
72753
  pack: "ecad",
@@ -72502,7 +72843,7 @@ Compressed URL param: ${encoded.length} bytes`
72502
72843
  ]
72503
72844
  };
72504
72845
  }
72505
- var openInBrowserSchema, toolDefs42;
72846
+ var openInBrowserSchema, toolDefs43;
72506
72847
  var init_share = __esm({
72507
72848
  "src/tools/share.ts"() {
72508
72849
  "use strict";
@@ -72526,7 +72867,7 @@ var init_share = __esm({
72526
72867
  }
72527
72868
  }
72528
72869
  };
72529
- toolDefs42 = [
72870
+ toolDefs43 = [
72530
72871
  {
72531
72872
  name: "open_in_browser",
72532
72873
  pack: null,
@@ -72851,7 +73192,7 @@ function batchReset(input) {
72851
73192
  };
72852
73193
  }
72853
73194
  }
72854
- var simulations, MAX_TRAJECTORY, envRecords, batchGroups, createRobotEnvSchema, gymStepSchema, gymResetSchema, gymObserveSchema, gymCloseSchema, batchCreateEnvsSchema, batchStepSchema, batchResetSchema, toolDefs43;
73195
+ var simulations, MAX_TRAJECTORY, envRecords, batchGroups, createRobotEnvSchema, gymStepSchema, gymResetSchema, gymObserveSchema, gymCloseSchema, batchCreateEnvsSchema, batchStepSchema, batchResetSchema, toolDefs44;
72855
73196
  var init_gym = __esm({
72856
73197
  "src/tools/gym.ts"() {
72857
73198
  "use strict";
@@ -73003,7 +73344,7 @@ var init_gym = __esm({
73003
73344
  },
73004
73345
  required: ["batch_id"]
73005
73346
  };
73006
- toolDefs43 = [
73347
+ toolDefs44 = [
73007
73348
  {
73008
73349
  name: "create_robot_env",
73009
73350
  pack: "physics",
@@ -73361,7 +73702,7 @@ async function renderMolecule(input) {
73361
73702
  return fail(err7);
73362
73703
  }
73363
73704
  }
73364
- var loadStructureSchema, inspectMoleculeSchema, configSchema, minimizeEnergySchema, mdRunSchema, designMaterialSchema, homogenizeMaterialSchema, renderMoleculeSchema, CPK, DEFAULT_RADIUS, toolDefs44;
73705
+ var loadStructureSchema, inspectMoleculeSchema, configSchema, minimizeEnergySchema, mdRunSchema, designMaterialSchema, homogenizeMaterialSchema, renderMoleculeSchema, CPK, DEFAULT_RADIUS, toolDefs45;
73365
73706
  var init_atoms2 = __esm({
73366
73707
  "src/tools/atoms.ts"() {
73367
73708
  "use strict";
@@ -73496,7 +73837,7 @@ var init_atoms2 = __esm({
73496
73837
  S: 1.05,
73497
73838
  P: 1.07
73498
73839
  };
73499
- toolDefs44 = [
73840
+ toolDefs45 = [
73500
73841
  {
73501
73842
  name: "load_structure",
73502
73843
  pack: "atoms",
@@ -74704,7 +75045,7 @@ function errorResult(text) {
74704
75045
  isError: true
74705
75046
  };
74706
75047
  }
74707
- var recordSimulationSchema, SVG_SCALE2, MAX_STEPS, MIN_STEPS, DEFAULT_WIDTH_PX2, MIN_WIDTH_PX, MAX_WIDTH_PX, DEFAULT_FPS, MIN_FPS, MAX_FPS, toolDefs45;
75048
+ var recordSimulationSchema, SVG_SCALE2, MAX_STEPS, MIN_STEPS, DEFAULT_WIDTH_PX2, MIN_WIDTH_PX, MAX_WIDTH_PX, DEFAULT_FPS, MIN_FPS, MAX_FPS, toolDefs46;
74708
75049
  var init_record2 = __esm({
74709
75050
  "src/tools/record.ts"() {
74710
75051
  "use strict";
@@ -74768,7 +75109,7 @@ var init_record2 = __esm({
74768
75109
  DEFAULT_FPS = 30;
74769
75110
  MIN_FPS = 1;
74770
75111
  MAX_FPS = 60;
74771
- toolDefs45 = [
75112
+ toolDefs46 = [
74772
75113
  {
74773
75114
  name: "record_simulation",
74774
75115
  pack: "physics",
@@ -74861,7 +75202,7 @@ ${text}`
74861
75202
  ]
74862
75203
  };
74863
75204
  }
74864
- var getChangelogSchema, toolDefs46;
75205
+ var getChangelogSchema, toolDefs47;
74865
75206
  var init_changelog2 = __esm({
74866
75207
  "src/tools/changelog.ts"() {
74867
75208
  "use strict";
@@ -74901,7 +75242,7 @@ var init_changelog2 = __esm({
74901
75242
  }
74902
75243
  }
74903
75244
  };
74904
- toolDefs46 = [
75245
+ toolDefs47 = [
74905
75246
  {
74906
75247
  name: "get_changelog",
74907
75248
  pack: null,
@@ -75050,7 +75391,7 @@ function getSimVersion(input) {
75050
75391
  ]
75051
75392
  };
75052
75393
  }
75053
- var getSimReplaySchema, getSimVersionSchema, toolDefs47;
75394
+ var getSimReplaySchema, getSimVersionSchema, toolDefs48;
75054
75395
  var init_sim_replay = __esm({
75055
75396
  "src/tools/sim-replay.ts"() {
75056
75397
  "use strict";
@@ -75078,7 +75419,7 @@ var init_sim_replay = __esm({
75078
75419
  },
75079
75420
  required: ["env_id"]
75080
75421
  };
75081
- toolDefs47 = [
75422
+ toolDefs48 = [
75082
75423
  {
75083
75424
  name: "get_sim_replay",
75084
75425
  pack: null,
@@ -75197,7 +75538,7 @@ async function getOrderFeed(input, store, user) {
75197
75538
  version: version2
75198
75539
  });
75199
75540
  }
75200
- var toUsd4, getOrderFeedSchema, toolDefs48;
75541
+ var toUsd4, getOrderFeedSchema, toolDefs49;
75201
75542
  var init_order_feed = __esm({
75202
75543
  "src/tools/order-feed.ts"() {
75203
75544
  "use strict";
@@ -75216,7 +75557,7 @@ var init_order_feed = __esm({
75216
75557
  },
75217
75558
  required: ["document_id"]
75218
75559
  };
75219
- toolDefs48 = [
75560
+ toolDefs49 = [
75220
75561
  {
75221
75562
  name: "get_order_feed",
75222
75563
  pack: "fabricate",
@@ -76118,7 +76459,7 @@ ${issues.map((i) => i.problem).join("\n")}`
76118
76459
  note: "Rollout compiled to the document timeline. Preview with render_sequence, ship with export_video."
76119
76460
  });
76120
76461
  }
76121
- var MAX_FRAMES, MAX_GEO_SAMPLES, MAX_VERIFY_FRAMES, INLINE_GLB_MAX_BASE64, DEFAULT_WIDTH_PX3, MIN_WIDTH_PX2, MAX_WIDTH_PX2, SVG_SCALE3, KEYFRAMES_DESCRIPTION, animateSchema, renderSequenceSchema, CAMERA_NODE, exportVideoSchema, ffmpegAvailable, timelineFromSimulationSchema, toolDefs49;
76462
+ var MAX_FRAMES, MAX_GEO_SAMPLES, MAX_VERIFY_FRAMES, INLINE_GLB_MAX_BASE64, DEFAULT_WIDTH_PX3, MIN_WIDTH_PX2, MAX_WIDTH_PX2, SVG_SCALE3, KEYFRAMES_DESCRIPTION, animateSchema, renderSequenceSchema, CAMERA_NODE, exportVideoSchema, ffmpegAvailable, timelineFromSimulationSchema, toolDefs50;
76122
76463
  var init_animate = __esm({
76123
76464
  "src/tools/animate.ts"() {
76124
76465
  "use strict";
@@ -76270,7 +76611,7 @@ var init_animate = __esm({
76270
76611
  },
76271
76612
  required: ["env_id", "document_id"]
76272
76613
  };
76273
- toolDefs49 = [
76614
+ toolDefs50 = [
76274
76615
  {
76275
76616
  name: "animate",
76276
76617
  pack: null,
@@ -77115,6 +77456,7 @@ var init_server3 = __esm({
77115
77456
  init_antenna();
77116
77457
  init_photonics();
77117
77458
  init_neutronics();
77459
+ init_qcd();
77118
77460
  init_physics2();
77119
77461
  init_loon_macros();
77120
77462
  init_dfm2();
@@ -77133,8 +77475,8 @@ var init_server3 = __esm({
77133
77475
  init_order_feed();
77134
77476
  init_animate();
77135
77477
  PKG_VERSION = (() => {
77136
- if ("0.9.4-main.16") {
77137
- return "0.9.4-main.16";
77478
+ if ("0.9.4-main.17") {
77479
+ return "0.9.4-main.17";
77138
77480
  }
77139
77481
  try {
77140
77482
  const req = createRequire2(import.meta.url);
@@ -77143,8 +77485,8 @@ var init_server3 = __esm({
77143
77485
  return "0.0.0";
77144
77486
  }
77145
77487
  })();
77146
- BUILD_SHA = "63c1a040cf3352ca640144ec217f3f96271180c9";
77147
- BUILD_TIME = "2026-07-24T17:21:48.535Z";
77488
+ BUILD_SHA = "cfb504c93d13b7e0339f79b4b8863ffeb1ca83b1";
77489
+ BUILD_TIME = "2026-07-24T20:18:23.601Z";
77148
77490
  SHORT_SHA = BUILD_SHA === "unknown" ? "unknown" : BUILD_SHA.slice(0, 7);
77149
77491
  VERSION_WITH_BUILD = SHORT_SHA === "unknown" ? PKG_VERSION : `${PKG_VERSION}+${SHORT_SHA}`;
77150
77492
  INSTANCE_ID = randomUUID6().slice(0, 8);
@@ -77204,8 +77546,8 @@ var init_server3 = __esm({
77204
77546
  ...toolDefs34,
77205
77547
  ...toolDefs35,
77206
77548
  ...toolDefs36,
77207
- ...toolDefs2,
77208
77549
  ...toolDefs37,
77550
+ ...toolDefs2,
77209
77551
  ...toolDefs38,
77210
77552
  ...toolDefs39,
77211
77553
  ...toolDefs40,
@@ -77215,11 +77557,12 @@ var init_server3 = __esm({
77215
77557
  ...toolDefs44,
77216
77558
  ...toolDefs45,
77217
77559
  ...toolDefs46,
77560
+ ...toolDefs47,
77218
77561
  ...toolDefs20,
77219
77562
  ...toolDefs19,
77220
- ...toolDefs47,
77221
77563
  ...toolDefs48,
77222
- ...toolDefs49
77564
+ ...toolDefs49,
77565
+ ...toolDefs50
77223
77566
  ];
77224
77567
  LIST_TOOL_ORDER = [
77225
77568
  // ── Session lifecycle ──────────────────────────────────────
@@ -77290,6 +77633,7 @@ var init_server3 = __esm({
77290
77633
  "solve_thermal",
77291
77634
  "analyze_structure",
77292
77635
  "simulate_neutron_shield",
77636
+ "simulate_lattice_gauge",
77293
77637
  "analyze_tolerance_stackup",
77294
77638
  "simulate_circuit",
77295
77639
  "tune_circuit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vcad/mcp",
3
- "version": "0.9.4-main.16",
3
+ "version": "0.9.4-main.17",
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": "63c1a040cf3352ca640144ec217f3f96271180c9",
23
- "builtAt": "2026-07-24T17:21:48.535Z"
22
+ "sha": "cfb504c93d13b7e0339f79b4b8863ffeb1ca83b1",
23
+ "builtAt": "2026-07-24T20:18:23.601Z"
24
24
  }
25
25
  }
Binary file