freeform-modeling-mcp 1.0.30 → 1.0.32

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/.cursor/mcp.json CHANGED
@@ -7,8 +7,7 @@
7
7
  "src/cli.ts",
8
8
  "start",
9
9
  "--stdio"
10
- ],
11
- "cwd": "D:\\wain\\mcp-server"
10
+ ]
12
11
  },
13
12
  "aholo-sdk-mcp": {
14
13
  "type": "stdio",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freeform-modeling-mcp",
3
- "version": "1.0.30",
3
+ "version": "1.0.32",
4
4
  "description": "KooMaster MCP Server with WebSocket Bridge",
5
5
  "main": "index.cjs",
6
6
  "type": "module",
@@ -231,7 +231,7 @@ export const placeKjlAssetTool = {
231
231
  name: 'place_kjl_asset',
232
232
  description: 'Places a 3D model from the KJL(酷家乐) asset library into the current scene with specified position, rotation, and scale. Before placing, analyze the model\'s bounding box dimensions to determine proper orientation - elongated objects like wall panels may require 90° rotation based on intended function. Ensure bottoms align with the ground plane (z=0) by setting z-value to half the model\'s height. After placement, verify no clipping with existing objects and confirm dimensions match real-world proportions.',
233
233
  parameters: z.object({
234
- modelId: z.number().describe('The unique ID of the model to place. This ID can be obtained from the batch_search_kjl_assets function results. Use the exact ID value returned by the search.'),
234
+ modelId: z.string().describe('The unique ID of the model to place. This ID can be obtained from the batch_search_kjl_assets function results. Use the exact ID value returned by the search.'),
235
235
  name: z.string().describe('Specify a name for the placed model. This name will be used for subsequent identification and reference to the model, such as when applying materials or performing transformation operations. Use descriptive names for easy identification, such as "dining_table", "office_chair", etc.'),
236
236
  originalDimensions: z.array(z.number()).describe('The original [width, height, depth] dimensions of the model as provided in the batch_search_kjl_assets results. These values must be obtained from the asset search results.'),
237
237
 
@@ -239,6 +239,7 @@ export const placeKjlAssetTool = {
239
239
  location: z.array(z.number()).describe('[x, y, z] center position coordinates for the imported model'),
240
240
  targetDimensions: z.array(z.number()).describe('The target [width, height, depth] dimensions for the model after importing. These values specify the absolute size the model should be scaled to in the scene.'),
241
241
  rotation: z.array(z.number()).optional().describe('Optional [x, y, z] rotation in degrees. Following the Z-up coordinate system: rotation around X-axis tilts the object left/right (like nodding sideways), rotation around Y-axis tilts the object forward/backward (like nodding), and rotation around Z-axis rotates the object in the horizontal plane (like spinning on the ground). Positive values follow the right-hand rule: point thumb in positive axis direction, fingers show positive rotation direction.'),
242
+ assetUrl: z.string().optional().describe('Optional GLB URL of the asset. Required when placing a Lux3d-generated model; omit for regular KJL catalog assets.'),
242
243
  }),
243
244
  execute: async (args, context: Context): Promise<ContentResult> => {
244
245
  try {
@@ -281,10 +282,11 @@ export const replaceKjlAssetTool = {
281
282
  description: 'Replaces an existing object in the scene with a new 3D model from the KJL(酷家乐) asset library. The replacement maintains the position, rotation, aligning the centers of both models. After replacement, review the scene to ensure no intersections or clipping with other objects.',
282
283
  parameters: z.object({
283
284
  targetName: z.string().describe('The name of the existing object in the scene that will be replaced. This must exactly match the name of a placed object.'),
284
- newModelId: z.number().describe('The unique ID of the new model that will replace the existing object. This ID should be obtained from the batch_search_kjl_assets function results.'),
285
+ newModelId: z.string().describe('The unique ID of the new model that will replace the existing object. This ID should be obtained from the batch_search_kjl_assets function results.'),
285
286
  newName: z.string().describe('Specify a name for the replacement model. This name will be used for subsequent identification and reference, such as when applying materials or performing transformation operations. Use descriptive names for easy identification.'),
286
287
  originalDimensions: z.array(z.number()).describe('The original [width, height, depth] dimensions of the new model as provided in the batch_search_kjl_assets results. These values must be obtained from the asset search results.'),
287
288
  targetDimensions: z.array(z.number()).optional().describe('The target [width, height, depth] dimensions for the model after importing. These values specify the absolute size the model should be scaled to in the scene.'),
289
+ assetUrl: z.string().optional().describe('Optional GLB URL of the asset. Required when placing a Lux3d-generated model; omit for regular KJL catalog assets.'),
288
290
  }),
289
291
  execute: async (args, context: Context): Promise<ContentResult> => {
290
292
  try {
@@ -40,7 +40,7 @@ function isUnsupportedModelUrl(url: string): boolean {
40
40
 
41
41
  export const importGeneratedAssetTool = {
42
42
  name: 'import_generated_asset',
43
- description: 'Import a generated GLB/GLTF 3D model into the Koomaster scene from any source that provides a publicly reachable model URL. Converts GLB/GLTF to OBJ and places it asynchronously; poll with poll_import_status.',
43
+ description: 'Import a generated GLB/GLTF 3D model into the Koomaster scene from any source that provides a publicly reachable model URL. Converts GLB/GLTF to OBJ and places it asynchronously; poll with poll_import_status. Use place_kjl_asset (new import) or replace_kjl_asset (swap existing object) with modelId + assetUrl ONLY when the model is Lux3D-generated AND a modelId is available; if there is no modelId, still use this tool.',
44
44
  parameters: z.object({
45
45
  name: z.string().describe('The name to give to the imported object in the scene'),
46
46
  model_url: z.string().describe('Public HTTP(S) URL of a completed GLB/GLTF model. Do not pass archive or other mesh formats such as .zip/.obj/.fbx.'),
Binary file