rhinomcp 0.1.1.1__tar.gz → 0.1.1.2__tar.gz
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.
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/PKG-INFO +1 -1
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/pyproject.toml +1 -1
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp/server.py +42 -40
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp.egg-info/PKG-INFO +1 -1
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/README.md +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/setup.cfg +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp/__init__.py +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp.egg-info/SOURCES.txt +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp.egg-info/dependency_links.txt +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp.egg-info/entry_points.txt +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp.egg-info/requires.txt +0 -0
- {rhinomcp-0.1.1.1 → rhinomcp-0.1.1.2}/src/rhinomcp.egg-info/top_level.txt +0 -0
@@ -200,28 +200,10 @@ mcp = FastMCP(
|
|
200
200
|
|
201
201
|
# Global connection for resources (since resources can't access context)
|
202
202
|
_rhino_connection = None
|
203
|
-
_polyhaven_enabled = False # Add this global variable
|
204
203
|
|
205
204
|
def get_rhino_connection():
|
206
205
|
"""Get or create a persistent Rhino connection"""
|
207
|
-
global _rhino_connection
|
208
|
-
|
209
|
-
# If we have an existing connection, check if it's still valid
|
210
|
-
if _rhino_connection is not None:
|
211
|
-
try:
|
212
|
-
# First check if PolyHaven is enabled by sending a ping command
|
213
|
-
result = _rhino_connection.send_command("get_polyhaven_status")
|
214
|
-
# Store the PolyHaven status globally
|
215
|
-
_polyhaven_enabled = result.get("enabled", False)
|
216
|
-
return _rhino_connection
|
217
|
-
except Exception as e:
|
218
|
-
# Connection is dead, close it and create a new one
|
219
|
-
logger.warning(f"Existing connection is no longer valid: {str(e)}")
|
220
|
-
try:
|
221
|
-
_rhino_connection.disconnect()
|
222
|
-
except:
|
223
|
-
pass
|
224
|
-
_rhino_connection = None
|
206
|
+
global _rhino_connection
|
225
207
|
|
226
208
|
# Create a new connection if needed
|
227
209
|
if _rhino_connection is None:
|
@@ -236,29 +218,32 @@ def get_rhino_connection():
|
|
236
218
|
|
237
219
|
|
238
220
|
@mcp.tool()
|
239
|
-
def
|
240
|
-
"""Get detailed information about the current Rhino
|
221
|
+
def get_document_info(ctx: Context) -> str:
|
222
|
+
"""Get detailed information about the current Rhino document"""
|
241
223
|
try:
|
242
224
|
rhino = get_rhino_connection()
|
243
|
-
result = rhino.send_command("
|
225
|
+
result = rhino.send_command("get_document_info")
|
244
226
|
|
245
227
|
# Just return the JSON representation of what Rhino sent us
|
246
228
|
return json.dumps(result, indent=2)
|
247
229
|
except Exception as e:
|
248
|
-
logger.error(f"Error getting
|
249
|
-
return f"Error getting
|
230
|
+
logger.error(f"Error getting document info from Rhino: {str(e)}")
|
231
|
+
return f"Error getting document info: {str(e)}"
|
250
232
|
|
251
233
|
@mcp.tool()
|
252
|
-
def get_object_info(ctx: Context,
|
234
|
+
def get_object_info(ctx: Context, id: str = None, name: str = None) -> str:
|
253
235
|
"""
|
254
|
-
Get detailed information about a specific object in the Rhino
|
236
|
+
Get detailed information about a specific object in the Rhino document.
|
237
|
+
You can either provide the id or the object_name of the object to get information about.
|
238
|
+
If both are provided, the id will be used.
|
255
239
|
|
256
240
|
Parameters:
|
257
|
-
-
|
241
|
+
- id: The id of the object to get information about
|
242
|
+
- name: The name of the object to get information about
|
258
243
|
"""
|
259
244
|
try:
|
260
245
|
rhino = get_rhino_connection()
|
261
|
-
result = rhino.send_command("get_object_info", {"name":
|
246
|
+
result = rhino.send_command("get_object_info", {"id": id, "name": name})
|
262
247
|
|
263
248
|
# Just return the JSON representation of what Rhino sent us
|
264
249
|
return json.dumps(result, indent=2)
|
@@ -266,6 +251,16 @@ def get_object_info(ctx: Context, object_name: str) -> str:
|
|
266
251
|
logger.error(f"Error getting object info from Rhino: {str(e)}")
|
267
252
|
return f"Error getting object info: {str(e)}"
|
268
253
|
|
254
|
+
@mcp.tool()
|
255
|
+
def get_selected_objects_info(ctx: Context) -> str:
|
256
|
+
"""Get detailed information about the currently selected objects in Rhino"""
|
257
|
+
try:
|
258
|
+
rhino = get_rhino_connection()
|
259
|
+
result = rhino.send_command("get_selected_objects_info")
|
260
|
+
return json.dumps(result, indent=2)
|
261
|
+
except Exception as e:
|
262
|
+
logger.error(f"Error getting selected objects from Rhino: {str(e)}")
|
263
|
+
return f"Error getting selected objects: {str(e)}"
|
269
264
|
|
270
265
|
|
271
266
|
@mcp.tool()
|
@@ -288,7 +283,7 @@ def create_object(
|
|
288
283
|
generate_uvs: bool = True
|
289
284
|
) -> str:
|
290
285
|
"""
|
291
|
-
Create a new object in the Rhino
|
286
|
+
Create a new object in the Rhino document.
|
292
287
|
|
293
288
|
Parameters:
|
294
289
|
- type: Object type (CUBE, SPHERE, CYLINDER, PLANE, CONE, TORUS, EMPTY, CAMERA, LIGHT)
|
@@ -356,17 +351,21 @@ def create_object(
|
|
356
351
|
@mcp.tool()
|
357
352
|
def modify_object(
|
358
353
|
ctx: Context,
|
359
|
-
|
354
|
+
id: str = None,
|
355
|
+
name: str = None,
|
356
|
+
new_name: str = None,
|
360
357
|
location: List[float] = None,
|
361
358
|
rotation: List[float] = None,
|
362
359
|
scale: List[float] = None,
|
363
360
|
visible: bool = None
|
364
361
|
) -> str:
|
365
362
|
"""
|
366
|
-
Modify an existing object in the Rhino
|
363
|
+
Modify an existing object in the Rhino document.
|
367
364
|
|
368
365
|
Parameters:
|
369
|
-
-
|
366
|
+
- id: The id of the object to modify
|
367
|
+
- name: The name of the object to modify
|
368
|
+
- new_name: Optional new name for the object
|
370
369
|
- location: Optional [x, y, z] location coordinates
|
371
370
|
- rotation: Optional [x, y, z] rotation in radians
|
372
371
|
- scale: Optional [x, y, z] scale factors
|
@@ -376,8 +375,10 @@ def modify_object(
|
|
376
375
|
# Get the global connection
|
377
376
|
rhino = get_rhino_connection()
|
378
377
|
|
379
|
-
params = {"name": name}
|
378
|
+
params = {"id": id, "name": name}
|
380
379
|
|
380
|
+
if new_name is not None:
|
381
|
+
params["new_name"] = new_name
|
381
382
|
if location is not None:
|
382
383
|
params["location"] = location
|
383
384
|
if rotation is not None:
|
@@ -394,19 +395,20 @@ def modify_object(
|
|
394
395
|
return f"Error modifying object: {str(e)}"
|
395
396
|
|
396
397
|
@mcp.tool()
|
397
|
-
def delete_object(ctx: Context, name: str) -> str:
|
398
|
+
def delete_object(ctx: Context, id: str = None, name: str = None) -> str:
|
398
399
|
"""
|
399
|
-
Delete an object from the Rhino
|
400
|
+
Delete an object from the Rhino document.
|
400
401
|
|
401
402
|
Parameters:
|
402
|
-
-
|
403
|
+
- id: The id of the object to delete
|
404
|
+
- name: The name of the object to delete
|
403
405
|
"""
|
404
406
|
try:
|
405
407
|
# Get the global connection
|
406
408
|
rhino = get_rhino_connection()
|
407
409
|
|
408
|
-
result = rhino.send_command("delete_object", {"name": name})
|
409
|
-
return f"Deleted object: {name}"
|
410
|
+
result = rhino.send_command("delete_object", {"id": id, "name": name})
|
411
|
+
return f"Deleted object: {result['name']}"
|
410
412
|
except Exception as e:
|
411
413
|
logger.error(f"Error deleting object: {str(e)}")
|
412
414
|
return f"Error deleting object: {str(e)}"
|
@@ -416,9 +418,9 @@ def asset_creation_strategy() -> str:
|
|
416
418
|
"""Defines the preferred strategy for creating assets in Rhino"""
|
417
419
|
return """When creating 3D content in Rhino, always start by checking if integrations are available:
|
418
420
|
|
419
|
-
0. Before anything, always check the
|
421
|
+
0. Before anything, always check the document from get_document_info()
|
420
422
|
1. Use the method create_object() for basic primitives (CUBE, SPHERE, etc.)
|
421
|
-
2. When including an object into
|
423
|
+
2. When including an object into document, ALWAYS make sure that the name of the object is meanful.
|
422
424
|
3. After giving the tool location/scale/rotation information (via create_object() and modify_object()),
|
423
425
|
double check the related object's location, scale, rotation, and world_bounding_box using get_object_info(),
|
424
426
|
so that the object is in the desired location.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|