Model Context Protocol server for Rhino 3D CAD software, providing tools for document management, geometry operations, Grasshopper automation, scripting, and user interaction
RhinoAI exposes 11 tools with mixed quality. Most have descriptions (9/11), but many lack proper parameter documentation. Schemas are present but incomplete: several tools use generic object types without field definitions (e.g., 'doc' parameter is {type:object} with minimal description). Tool naming is inconsistent, internal router tools use '_router_' prefix, mixing concerns. Error handling is minimal; no recovery guidance or actionable error messages visible. Composition is reasonable (tools are single-purpose), but parameter descriptions often omit constraints, ranges, and format details. No tool annotations (readOnlyHint, destructiveHint) despite clear risk levels.
Router-internal: stop the MCP listener on the given port and close its associated doc without saving.
Router-internal: schedule a graceful Rhino exit via _Exit. Returns immediately; the actual quit fires shortly after on the UI thread.
Router-internal: create a new RhinoDoc and start an MCP listener bound to it. Returns { port }.
Ask the Rhino user to choose among options when you need a decision you cannot make yourself. Pass EVERY question you need answered in this one call: the Rhino AI panel shows them one page at a time (radio for single choice, checkboxes for multi) and returns them as a single reply. This tool does NOT wait for the answers: it poses the questions and returns immediately. Only on success, STOP and end your turn; on failure, fix the input and retry; the user's answers arrive as their next message, then continue.
Close the current Rhino document. If path is given, save to that .3dm path first; otherwise discard unsaved changes.
Generic object parameters lack field definitions. 'doc' and 'rhDoc' parameters are typed as {type:object} with minimal description, forcing LLMs to guess structure. Should document required/optional fields, e.g., {type:object, properties:{id:{type:string}, name:{type:string}}}.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels. Tools marked DESTRUCTIVE (_router_close_listener, _router_quit_app, close_doc, g1_clear_canvas, g1_delete_component) should declare destructiveHint:true to guide agent caution.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 60 | 2026-07-28+ | v2 |
Place sliders + components and wire them in one call. References between objects use caller-supplied 'key' strings; the tool returns the key→Guid map. Failures in any step do not abort the rest; results report per-step status. Wire src/dst use the same selector semantics as 'g1_connect'.
Remove every object from the active GH1 canvas. Destructive — requires confirm=true.
Wire an output parameter to an input parameter on the active GH1 canvas. 'src' and 'dst' may be a numeric index or a Name/NickName. For pure params (e.g. a slider) pass '' or '0'.
Wire multiple output→input connections in one call. Same selector semantics as 'g1_connect' (numeric index or Name/NickName; '' or '0' for pure params). A failed wire does not stop later ones; per-wire results are returned. solve runs once at the end.
Delete a Grasshopper component on the active GH1 canvas.
Give the user a reusable Rhino command. After every call the new or changed command is usable immediately. Use this when the user wants to create a reusable tool ('create me a command', 'make me a tool for this'). Rhino 9 or later only.
Router-internal tools (_router_*) expose implementation details and should not be user-facing. If they must exist, document why they are exposed and add strict permission gates. Otherwise, hide them from the tool list.
Parameter descriptions lack format/constraint details. E.g., 'port' in _router_close_listener has no range (valid 1 - 65535?). 'commandName' in manage_plugin_commands says 'no spaces' but no regex or length limit. Enums and ranges should be explicit.
No error handling guidance visible. Tools like g1_apply_graph say 'Failures in any step do not abort the rest' but do not document error response format or recovery steps. LLMs need actionable error messages.