rhinomcp 0.1.1.4__tar.gz → 0.1.2.0__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.4 → rhinomcp-0.1.2.0}/PKG-INFO +1 -1
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/pyproject.toml +1 -1
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/__init__.py +3 -2
- rhinomcp-0.1.1.4/src/rhinomcp/prompts/assert_creation_strategy.py → rhinomcp-0.1.2.0/src/rhinomcp/prompts/assert_general_strategy.py +12 -8
- rhinomcp-0.1.2.0/src/rhinomcp/resources/rhinoscriptsyntax_resource.py +59 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/create_object.py +11 -10
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/create_objects.py +1 -1
- rhinomcp-0.1.2.0/src/rhinomcp/tools/select_objects.py +53 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp.egg-info/PKG-INFO +1 -1
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp.egg-info/SOURCES.txt +4 -3
- rhinomcp-0.1.1.4/src/rhinomcp/prompts/assert_query_strategy.py +0 -10
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/README.md +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/setup.cfg +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/server.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/delete_object.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/execute_rhinoscript_python_code.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/get_document_info.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/get_object_info.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/get_selected_objects_info.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/modify_object.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp/tools/modify_objects.py +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp.egg-info/dependency_links.txt +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp.egg-info/entry_points.txt +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp.egg-info/requires.txt +0 -0
- {rhinomcp-0.1.1.4 → rhinomcp-0.1.2.0}/src/rhinomcp.egg-info/top_level.txt +0 -0
@@ -5,8 +5,7 @@ __version__ = "0.1.0"
|
|
5
5
|
# Expose key classes and functions for easier imports
|
6
6
|
from .server import RhinoConnection, get_rhino_connection, mcp, logger
|
7
7
|
|
8
|
-
from .prompts.
|
9
|
-
from .prompts.assert_query_strategy import assert_query_strategy
|
8
|
+
from .prompts.assert_general_strategy import asset_general_strategy
|
10
9
|
|
11
10
|
from .tools.create_object import create_object
|
12
11
|
from .tools.create_objects import create_objects
|
@@ -17,4 +16,6 @@ from .tools.get_selected_objects_info import get_selected_objects_info
|
|
17
16
|
from .tools.modify_object import modify_object
|
18
17
|
from .tools.modify_objects import modify_objects
|
19
18
|
from .tools.execute_rhinoscript_python_code import execute_rhinoscript_python_code
|
19
|
+
from .tools.select_objects import select_objects
|
20
20
|
|
21
|
+
from .resources.rhinoscriptsyntax_resource import get_rhinoscriptsyntax_resource
|
@@ -2,20 +2,24 @@ from rhinomcp.server import mcp
|
|
2
2
|
|
3
3
|
|
4
4
|
@mcp.prompt()
|
5
|
-
def
|
5
|
+
def asset_general_strategy() -> str:
|
6
6
|
"""Defines the preferred strategy for creating assets in Rhino"""
|
7
|
-
return """
|
7
|
+
return """
|
8
|
+
|
9
|
+
QUERY STRATEGY:
|
10
|
+
- if the id of the object is known, use the id to query the object.
|
11
|
+
- if the id is not known, use the name of the object to query the object.
|
8
12
|
|
9
|
-
|
10
|
-
|
13
|
+
|
14
|
+
CREATION STRATEGY:
|
15
|
+
|
16
|
+
0. Before anything, always check the document from get_document_info().
|
17
|
+
1. If the execute_rhinoscript_python_code() function is not able to create the objects, use the create_objects() function.
|
11
18
|
2. If there are multiple objects, use the method create_objects() to create multiple objects at once. Do not attempt to create them one by one if they are more than 10.
|
12
19
|
3. When including an object into document, ALWAYS make sure that the name of the object is meanful.
|
13
|
-
4. Try to include as many objects as possible accurately and efficiently. If the command is not able to include
|
14
|
-
so many data, try to create the objects in batches.
|
20
|
+
4. Try to include as many objects as possible accurately and efficiently. If the command is not able to include so many data, try to create the objects in batches.
|
15
21
|
|
16
22
|
When creating rhinoscript python code:
|
17
23
|
- do not hallucinate, only use the syntax that is supported by rhinoscriptsyntax or Rhino,Geometry.
|
18
|
-
- document the code that you are writing.
|
19
|
-
- when creating objects, ALWAYS make sure that the name of the object is meanful.
|
20
24
|
- double check the code if any of the code is not correct, and fix it.
|
21
25
|
"""
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import mcp.types as types
|
2
|
+
from rhinomcp.server import mcp
|
3
|
+
from pydantic import FileUrl
|
4
|
+
|
5
|
+
|
6
|
+
import os
|
7
|
+
from pathlib import Path
|
8
|
+
|
9
|
+
# Define path to static folder
|
10
|
+
STATIC_FOLDER = Path("./static")
|
11
|
+
|
12
|
+
|
13
|
+
@mcp.tool()
|
14
|
+
def get_rhinoscriptsyntax_resource(category: str) -> str:
|
15
|
+
"""
|
16
|
+
Return the RhinoScriptsyntax for a specific category.
|
17
|
+
|
18
|
+
Parameters:
|
19
|
+
- category: The category of the RhinoScriptsyntax to get.
|
20
|
+
|
21
|
+
The following categories are available:
|
22
|
+
- application
|
23
|
+
- block
|
24
|
+
- compat
|
25
|
+
- curve
|
26
|
+
- dimension
|
27
|
+
- document
|
28
|
+
- geometry
|
29
|
+
- grips
|
30
|
+
- group
|
31
|
+
- hatch
|
32
|
+
- layer
|
33
|
+
- light
|
34
|
+
- line
|
35
|
+
- linetype
|
36
|
+
- material
|
37
|
+
- mesh
|
38
|
+
- object
|
39
|
+
- plane
|
40
|
+
- pointvector
|
41
|
+
- selection
|
42
|
+
- surface
|
43
|
+
- toolbar
|
44
|
+
- transformation
|
45
|
+
- userdata
|
46
|
+
- userinterface
|
47
|
+
- utility
|
48
|
+
- view
|
49
|
+
"""
|
50
|
+
|
51
|
+
for file_path in STATIC_FOLDER.glob("*.py"):
|
52
|
+
if file_path.name == f"{category}.py":
|
53
|
+
try:
|
54
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
55
|
+
return f.read()
|
56
|
+
except Exception as e:
|
57
|
+
print(f"Error reading {file_path}: {e}")
|
58
|
+
|
59
|
+
|
@@ -27,7 +27,10 @@ def create_object(
|
|
27
27
|
- scale: Optional [x, y, z] scale factors
|
28
28
|
|
29
29
|
The params dictionary is type-specific.
|
30
|
-
For POINT, the params dictionary should
|
30
|
+
For POINT, the params dictionary should contain the following keys:
|
31
|
+
- x: x coordinate of the point
|
32
|
+
- y: y coordinate of the point
|
33
|
+
- z: z coordinate of the point
|
31
34
|
|
32
35
|
For LINE, the params dictionary should contain the following keys:
|
33
36
|
- start: [x, y, z] start point of the line
|
@@ -39,6 +42,7 @@ def create_object(
|
|
39
42
|
For CURVE, the params dictionary should contain the following keys:
|
40
43
|
- points: List of [x, y, z] control points that define the curve
|
41
44
|
- degree: Degree of the curve (default is 3, if user asked for smoother curve, degree can be higher)
|
45
|
+
If the curve is closed, the first and last points should be the same.
|
42
46
|
|
43
47
|
For BOX, the params dictionary should contain the following keys:
|
44
48
|
- width: Width of the box along X axis of the object
|
@@ -52,7 +56,7 @@ def create_object(
|
|
52
56
|
A message indicating the created object name.
|
53
57
|
|
54
58
|
Examples of params:
|
55
|
-
- POINT: {
|
59
|
+
- POINT: {"x": 0, "y": 0, "z": 0}
|
56
60
|
- LINE: {"start": [0, 0, 0], "end": [1, 1, 1]}
|
57
61
|
- POLYLINE: {"points": [[0, 0, 0], [1, 1, 1], [2, 2, 2]]}
|
58
62
|
- CURVE: {"points": [[0, 0, 0], [1, 1, 1], [2, 2, 2]], "degree": 3}
|
@@ -62,19 +66,16 @@ def create_object(
|
|
62
66
|
try:
|
63
67
|
# Get the global connection
|
64
68
|
rhino = get_rhino_connection()
|
65
|
-
|
66
|
-
trans = translation or [0, 0, 0]
|
67
|
-
rot = rotation or [0, 0, 0]
|
68
|
-
sc = scale or [1, 1, 1]
|
69
|
-
|
69
|
+
|
70
70
|
command_params = {
|
71
71
|
"type": type,
|
72
|
-
"translation": trans,
|
73
|
-
"rotation": rot,
|
74
|
-
"scale": sc,
|
75
72
|
"params": params
|
76
73
|
}
|
77
74
|
|
75
|
+
if translation is not None: command_params["translation"] = translation
|
76
|
+
if rotation is not None: command_params["rotation"] = rotation
|
77
|
+
if scale is not None: command_params["scale"] = scale
|
78
|
+
|
78
79
|
if name: command_params["name"] = name
|
79
80
|
if color: command_params["color"] = color
|
80
81
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
from mcp.server.fastmcp import Context
|
2
|
+
import json
|
3
|
+
from rhinomcp.server import get_rhino_connection, mcp, logger
|
4
|
+
from typing import Any, List, Dict
|
5
|
+
|
6
|
+
|
7
|
+
@mcp.tool()
|
8
|
+
def select_objects(
|
9
|
+
ctx: Context,
|
10
|
+
filters: Dict[str, Any] = {},
|
11
|
+
filters_type: str = "and",
|
12
|
+
) -> str:
|
13
|
+
"""
|
14
|
+
Select objects in the Rhino document.
|
15
|
+
|
16
|
+
Parameters:
|
17
|
+
- filters: A dictionary containing the filters. The filters parameter is necessary, unless it's empty, in which case all objects will be selected.
|
18
|
+
- filters_type: The type of the filters, it's "and" or "or", default is "and"
|
19
|
+
|
20
|
+
The filters dictionary can contain the following keys:
|
21
|
+
- name: The name of the object
|
22
|
+
- color: The color of the object, for example [255, 0, 0]
|
23
|
+
|
24
|
+
Additionaly, rhino allows to have user custom attributes, which can be used to filters the objects.
|
25
|
+
For example, if the object has a user custom attribute called "category", the filters dictionary can contain:
|
26
|
+
- category: custom_attribute_value
|
27
|
+
|
28
|
+
Example:
|
29
|
+
filters = {
|
30
|
+
"name": "object_name",
|
31
|
+
"category": "custom_attribute_value"
|
32
|
+
},
|
33
|
+
filters_type = "or"
|
34
|
+
|
35
|
+
|
36
|
+
Returns:
|
37
|
+
A number indicating the number of objects that have been selected.
|
38
|
+
"""
|
39
|
+
try:
|
40
|
+
# Get the global connection
|
41
|
+
rhino = get_rhino_connection()
|
42
|
+
command_params = {
|
43
|
+
"filters": filters,
|
44
|
+
"filters_type": filters_type
|
45
|
+
}
|
46
|
+
|
47
|
+
result = rhino.send_command("select_objects", command_params)
|
48
|
+
|
49
|
+
return f"Selected {result['count']} objects"
|
50
|
+
except Exception as e:
|
51
|
+
logger.error(f"Error selecting objects: {str(e)}")
|
52
|
+
return f"Error selecting objects: {str(e)}"
|
53
|
+
|
@@ -8,8 +8,8 @@ src/rhinomcp.egg-info/dependency_links.txt
|
|
8
8
|
src/rhinomcp.egg-info/entry_points.txt
|
9
9
|
src/rhinomcp.egg-info/requires.txt
|
10
10
|
src/rhinomcp.egg-info/top_level.txt
|
11
|
-
src/rhinomcp/prompts/
|
12
|
-
src/rhinomcp/
|
11
|
+
src/rhinomcp/prompts/assert_general_strategy.py
|
12
|
+
src/rhinomcp/resources/rhinoscriptsyntax_resource.py
|
13
13
|
src/rhinomcp/tools/create_object.py
|
14
14
|
src/rhinomcp/tools/create_objects.py
|
15
15
|
src/rhinomcp/tools/delete_object.py
|
@@ -18,4 +18,5 @@ src/rhinomcp/tools/get_document_info.py
|
|
18
18
|
src/rhinomcp/tools/get_object_info.py
|
19
19
|
src/rhinomcp/tools/get_selected_objects_info.py
|
20
20
|
src/rhinomcp/tools/modify_object.py
|
21
|
-
src/rhinomcp/tools/modify_objects.py
|
21
|
+
src/rhinomcp/tools/modify_objects.py
|
22
|
+
src/rhinomcp/tools/select_objects.py
|
@@ -1,10 +0,0 @@
|
|
1
|
-
from rhinomcp.server import mcp
|
2
|
-
|
3
|
-
|
4
|
-
@mcp.prompt()
|
5
|
-
def assert_query_strategy() -> str:
|
6
|
-
"""Defines the preferred strategy for querying Object or Objects in Rhino"""
|
7
|
-
return """When querying Object or Objects in Rhino:
|
8
|
-
- if the id of the object is known, use the id to query the object.
|
9
|
-
- if the id is not known, use the name of the object to query the object.
|
10
|
-
"""
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|