A plugin for executing Model Context Protocol (MCP) server in Rhinoceros. It provides Rhino's functionality as MCP tools and enables efficient communication with MCP clients.
This plugin exposes Rhino's functionality to MCP clients using the official Model Context Protocol C# SDK. It adopts the Streamable HTTP protocol and runs the MCP SDK in an isolated execution environment using AssemblyLoadContext, ensuring stable integration with Rhino.
The project consists of the following libraries:
RhinoMCPServer.Common: Common foundation for MCP tools (interfaces, tool management, etc.)RhinoMCPServer.Plugin: Main Rhino plugin implementationRhinoMCPServer.McpHost: MCP SDK isolated execution environment (runs within AssemblyLoadContext)RhinoMCPTools.Basic: Basic geometry operation toolsRhinoMCPTools.Misc: Utility toolsRhinoMCPTools.Grasshopper: Grasshopper integration tools
graph TB
subgraph MCP Client
X[Claude Desktop etc...]
end
subgraph MCP Server
subgraph Plugin
A[RhinoMCPServer.Plugin<br>Main Plugin]
end
subgraph Common
B[RhinoMCPServer.Common<br>MCP Tool Foundation]
end
subgraph "Isolated Execution Environment (AssemblyLoadContext)"
F[RhinoMCPServer.McpHost<br>MCP SDK Runtime]
end
subgraph "MCP Tools (Dynamically Extensible)"
C[RhinoMCPTools.Basic<br>Basic Geometry Tools]
D[RhinoMCPTools.Misc<br>Utility Tools]
E[RhinoMCPTools.Grasshopper<br>Grasshopper Component Operations]
end
end
A --> B
A --> F
C --> B
D --> B
E --> B
X -->|"Streamable HTTP"| F
classDef plugin fill:#949,stroke:#333,stroke-width:2px;
classDef common fill:#595,stroke:#333,stroke-width:2px;
classDef tools fill:#559,stroke:#333,stroke-width:2px;
classDef host fill:#959,stroke:#333,stroke-width:2px;
class A plugin;
class B common;
class C,D,E tools;
class F host;
MCP tools are dynamically loaded from DLLs, which means:
- New tools can be added by simply including new DLLs
- Easy addition and removal of plugins
- New tools are automatically recognized upon server restart
movie.mp4
movie2.mp4
movie3.mp4
movie4.mp4
- Rhino 8 or later
- .NET 8.0 Runtime
- Enter
StartMCPServerin Rhino's command line - Port number configuration
- Default: 3001 (automatically used when pressing Enter)
- Custom: Any port number can be entered
- After server startup, it waits for MCP client connections on the specified port
The server operates using the Streamable HTTP protocol. To connect with MCP clients such as Claude Desktop, use the MCP server that bridges standard I/O to HTTP.
Endpoint: POST http://localhost:{port}/mcp
Basic geometry operation and drafting tools.
-
linear_dimension
- Function: Creates a linear dimension between two points
- Parameters:
start(object, required) - Start point coordinatesx(number, required) - X coordinatey(number, required) - Y coordinatez(number, optional, default: 0) - Z coordinate
end(object, required) - End point coordinatesx(number, required) - X coordinatey(number, required) - Y coordinatez(number, optional, default: 0) - Z coordinate
offset(number, optional, default: 1.0) - Offset distance for dimension linescale(number, optional, default: 1.0) - Dimension scale value (must be greater than 0)
-
set_dimension_scale
- Function: Sets the dimension scale of dimension objects
- Parameters:
guids(array of string, required) - Array of GUIDs of the dimension objects to modifyscale(number, required) - The new dimension scale value (must be greater than 0)
-
sphere
- Function: Create a sphere in Rhino
- Parameters:
radius(number, required) - Sphere radius (in current Rhino units)x(number, optional, default: 0) - X coordinate of sphere centery(number, optional, default: 0) - Y coordinate of sphere centerz(number, optional, default: 0) - Z coordinate of sphere center
-
circle
- Function: Create a circle from center point and radius
- Parameters:
center(object, required) - Center point of the circlex(number, required) - X coordinatey(number, required) - Y coordinatez(number, optional, default: 0) - Z coordinate
radius(number, required) - Circle radius (must be greater than 0)
-
rectangle
- Function: Create a rectangle from center point, width (x-direction), and height (y-direction)
- Parameters:
center(object, required) - Center point of the rectanglex(number, required) - X coordinatey(number, required) - Y coordinatez(number, optional, default: 0) - Z coordinate
width(number, required) - Width of the rectangle (x-direction, must be greater than 0)height(number, required) - Height of the rectangle (y-direction, must be greater than 0)
-
polyline
- Function: Create a polyline from specified points
- Parameters:
points(array, required) - Array of points defining polyline vertices (minimum 2 points required)- Parameters for each point:
x(number, required) - X coordinatey(number, required) - Y coordinatez(number, optional, default: 0) - Z coordinate
- Parameters for each point:
-
move_objects
- Function: Move specified Rhino objects along a vector
- Parameters:
guids(array of string, required) - Array of GUIDs of the objects to movevector(object, required) - Movement vectorx(number, required) - X component of movement distancey(number, required) - Y component of movement distancez(number, optional, default: 0) - Z component of movement distance
-
get_geometry_info
- Function: Get geometric information of a Rhino object
- Parameters:
guid(string, required) - GUID of the target Rhino object
- Return value: Detailed information based on object type
- For Polyline:
points(array) - Array of vertex coordinateslength(number) - Total length of the polylineis_closed(boolean) - Whether the polyline is closedsegment_count(number) - Number of segmentspoint_count(number) - Number of vertices
- For Circle:
center(object) - Center point coordinatesradius(number) - Radiuscircumference(number) - Circumferencediameter(number) - Diameterplane(object) - Circle's plane information
- For Surface:
is_periodic(boolean) - Whether the surface is periodicis_singular(boolean) - Whether the surface has singularitiesdomain(object) - Parameter domainbounding_box(object) - Bounding box
- For Brep:
face_count(number) - Number of facesedge_count(number) - Number of edgesvertex_count(number) - Number of verticesis_solid(boolean) - Whether it's a solidis_manifold(boolean) - Whether it's manifoldarea(number) - Surface areavolume(number) - Volume (only for solids)
- For Polyline:
-
create_layer
- Function: Create a new layer in Rhino
- Parameters:
full_path(string, required) - Full path of the layer to create (e.g., 'Parent::Child::Grandchild')color(string, optional) - Color of the layer in hex format (e.g., '#FF0000')visible(boolean, optional, default: true) - Whether the layer is visiblelocked(boolean, optional, default: false) - Whether the layer is locked
-
change_object_layer_by_full_path
- Function: Change an object's layer by specifying the layer's full path
- Parameters:
guid(string, required) - GUID of the target Rhino objectlayer_full_path(string, required) - Full path of the target layer (e.g., 'Parent::Child::Grandchild')
-
change_object_layer_by_index
- Function: Change an object's layer by specifying the layer index
- Parameters:
guid(string, required) - GUID of the target Rhino objectlayer_index(number, required) - Index of the target layer
-
list_layers
- Function: Retrieve information about all layers in the document
- Parameters: None
- Return value: Array of layer information
full_path(string) - Full path of the layerindex(number) - Layer indexid(string) - Layer IDcolor(string) - Layer color in hex formatvisible(boolean) - Layer visibility statelocked(boolean) - Layer locked state
-
delete_object
- Function: Delete a Rhino object with specified GUID
- Parameters:
guid(string, required) - GUID of the object to delete
-
delete_objects
- Function: Deletes multiple Rhino objects by their GUIDs
- Parameters:
guids(array of string, required) - Array of GUIDs of the objects to delete
-
set_text_dot_size
- Function: Sets the font height of text dots
- Parameters:
guids(array of string, required) - Array of GUIDs of the text dots to modifyfont_height(number, required) - New font height (minimum value: 1)
-
set_user_text
- Function: Set user text attributes for a Rhino object
- Parameters:
guid(string, required) - GUID of the target Rhino objectkey(string, required) - Key for the user text attributevalue(string, required) - Value to set
-
set_object_name
- Function: Set the name of a Rhino object
- Parameters:
guid(string, required) - GUID of the target Rhino objectname(string, required) - Name to set for the object
-
get_object_name
- Function: Get the name of a Rhino object
- Parameters:
guid(string, required) - GUID of the target Rhino object
- Return value:
name(string) - Object's name (empty string if not set)
-
get_object_attributes
- Function: Get the attributes of a Rhino object
- Parameters:
guid(string, required) - GUID of the target Rhino object
- Return value: Object's attribute information
name(string) - Object's namelayer_index(number) - Layer indexlayer_name(string) - Layer nameobject_color(object) - Object's colorr(number) - Red component (0-255)g(number) - Green component (0-255)b(number) - Blue component (0-255)a(number) - Alpha value (0-255)
color_source(string) - Color sourceplot_color(object) - Plot colorr(number) - Red component (0-255)g(number) - Green component (0-255)b(number) - Blue component (0-255)a(number) - Alpha value (0-255)
plot_weight(number) - Plot line weightvisible(boolean) - Visibility statemode(string) - Object mode (Normal/Locked/Hidden etc.)object_type(string) - Object typeuser_text(object) - User text attributes (key-value pairs)
-
capture_viewport
- Function: Captures the specified Rhino viewport as an image
- Parameters:
viewportName(string, optional) - The name of the viewport to capture (uses active viewport if not specified)width(number, optional) - The width of the captured image in pixels (uses current viewport width if not specified)height(number, optional) - The height of the captured image in pixels (uses current viewport height if not specified)format(string, optional, enum: ["png", "jpg"], default: "png") - The image format to useshow_object_labels(boolean, optional, default: true) - Whether to display simple symbol labels (A, B, C..., AA, AB...) for objects in the viewportfont_height(number, optional, default: 20.0) - Font size for the labels
-
raycast_from_screen
- Function: Performs a raycast from screen coordinates and returns information about the hit object
- Parameters:
x(number, required) - Normalized X coordinate (0.0 to 1.0)y(number, required) - Normalized Y coordinate (0.0 to 1.0)viewportName(string, optional) - Name of the viewport to use (uses active viewport if not specified)
- Return value:
hit(boolean) - Whether an object was hitobject_info(object, only when hit) - Information about the hit objectguid(string) - Object's GUIDtype(string) - Geometry typehit_point(object) - Hit point coordinates (x, y, z)layer(number) - Layer index
Utility tools.
- echo
- Function: Echo back input text (for health check)
- Parameters:
message(string, required) - Text to echo back
Grasshopper integration tools.
-
get_canvas_components
- Function: Retrieve information about all components on the Grasshopper canvas
- Parameters:
include_params(boolean, optional, default: false) - Whether to include parameter information
- Return value: Array of component information
guid(string) - Component's GUIDname(string) - Component namenickname(string) - Component's nicknamedescription(string) - Component descriptioncategory(string) - Categorysubcategory(string) - Subcategoryposition(object) - Position on canvasx(number) - X coordinatey(number) - Y coordinate
parameters(object, included when include_params is true)input(array) - Array of input parametersname(string) - Parameter namenickname(string) - Parameter nicknamedescription(string) - Parameter descriptiontype_name(string) - Parameter type name
output(array) - Array of output parametersname(string) - Parameter namenickname(string) - Parameter nicknamedescription(string) - Parameter descriptiontype_name(string) - Parameter type name
-
get_available_components
- Function: Get a list of available Grasshopper components
- Parameters:
filter(string, optional) - Filter components by namecategory(string, optional) - Filter components by category
- Return value: Array of component information
name(string) - Component namedescription(string) - Component descriptiontype_name(string) - Component type nameis_param(boolean) - Whether it's a parameter componentcategory(string) - Categorysub_category(string) - Subcategory
-
create_component
- Function: Create a specified Grasshopper component on the canvas
- Parameters:
type_name(string, required) - Fully qualified name of the component to createx(number, optional, default: 0) - X coordinate on canvasy(number, optional, default: 0) - Y coordinate on canvas
- Return value: Created component information
guid(string) - Component's GUIDname(string) - Component nameposition(object) - Placement positionx(number) - X coordinatey(number) - Y coordinate
parameters(object) - Parameter informationinput(array) - Array of input parametersoutput(array) - Array of output parameters
-
delete_component
- Function: Delete a component from the canvas
- Parameters:
component_id(string, required) - GUID of the component to delete
-
get_component_info
- Function: Retrieves detailed information about a specific Grasshopper component, including its parameters and connection states
- Parameters:
component_id(string, required) - GUID of the component to get information for
- Return value:
info(object) - Basic component informationguid(string) - Component's GUIDname(string) - Component namenickname(string) - Nicknamedescription(string) - Descriptioncategory(string) - Categorysubcategory(string) - Subcategoryposition(object) - Position on canvas (x, y)
parameters(object) - Parameter informationinput(array) - Input parameters with connection infooutput(array) - Output parameters with connection info
-
get_runtime_messages
- Function: Retrieves runtime messages from specified Grasshopper components
- Parameters:
component_ids(array of string, required) - Array of component GUIDs to retrieve messages from
- Return value:
results(array) - Message information for each componentid(string) - Component's GUIDname(string) - Component namenickname(string) - Nicknamemessages(array) - Array of runtime messageslevel(string) - Message level ("error", "warning", "remark")message(string) - Message content
-
connect_component_wire
- Function: Connect a wire between two component parameters
- Parameters:
source_param_id(string, required) - GUID of the source parametertarget_param_id(string, required) - GUID of the target parameter
-
disconnect_component_wire
- Function: Disconnect a wire between component parameters
- Parameters:
source_param_id(string, required) - GUID of the source parametertarget_param_id(string, required) - GUID of the target parameter
-
configure_number_slider
- Function: Configure settings for a number slider component
- Parameters:
slider_id(string, required) - GUID of the slider componentvalue(number, required) - Value to setminimum(number, optional) - Minimum value settingmaximum(number, optional) - Maximum value setting
-
set_panel_text
- Function: Set text for a panel component
- Parameters:
panel_id(string, required) - GUID of the panel componenttext(string, required) - Text to set
-
load_grasshopper_file
- Function: Loads a GHX/GH file into Grasshopper as a new document and runs the solution
- Parameters:
file_path(string, required) - Absolute path to the .ghx or .gh file to load
-
save_grasshopper_file
- Function: Saves the active Grasshopper document to a GHX/GH file
- Parameters:
file_path(string, required) - Absolute path to save the file (.ghx or .gh)overwrite(boolean, optional, default: false) - Whether to overwrite an existing file
-
get_solution_status
- Function: Retrieves the solution status and all runtime messages from every component in the active Grasshopper document
- Parameters:
include_messages(boolean, optional, default: true) - Whether to include detailed messages for each component
Server logs are saved in:
logs/MCPRhinoServer_.logwithin the plugin directory
This project is released under the MIT License. Please refer to the LICENSE file for details.