AI-powered Rhino3D MCP bridge — connect Claude to Rhinoceros 3D
Project description
keratin
Connect Claude AI to Rhinoceros 3D.
keratin is a Model Context Protocol bridge for Rhino 7. It lets Claude create geometry, manage layers, run boolean operations, drive Grasshopper, and execute arbitrary RhinoScript — all from a conversation.
Part of the lineforge tool family.
How it works
keratin is two components that talk to each other over a local TCP socket:
Claude ──MCP──▶ keratin (host, Python 3) ──TCP:9876──▶ rhino_script.py (Rhino, IronPython 2.7)
rhino_script.pyruns inside Rhino as an IronPython script. It listens for commands and executes them safely on Rhino's main thread.keratin(the MCP server) runs on your machine and exposes 40+ tools to Claude via the Model Context Protocol.
Installation
Step 1 — Rhino-side script (via Rhino Package Manager)
In Rhino: Tools → Package Manager → search keratin → Install → Restart Rhino
Step 2 — MCP server (via pip)
pip install keratin
Step 3 — Configure your MCP client
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"rhino": {
"command": "keratin"
}
}
}
Claude Code:
claude mcp add rhino -- keratin
Step 4 — Load the listener in Rhino
The Yak package copies rhino_script.py to a known location on disk, but Rhino does not auto-execute Python scripts on install — only compiled plugins (.rhp) and Grasshopper assemblies load automatically. You need to start the listener once per Rhino session, or add it to Rhino's startup commands so it runs automatically.
The script is installed at:
%APPDATA%\McNeel\Rhinoceros\packages\7.0\keratin\0.1.2\rhino_script.py
Run once manually:
In the Rhino command line, type RunPythonScript and navigate to the path above.
Auto-start on every Rhino launch (recommended): Tools → Options → General → Startup Commands → add:
RunPythonScript "%APPDATA%\McNeel\Rhinoceros\packages\7.0\keratin\0.1.2\rhino_script.py"
Tool surface
| Category | Tools |
|---|---|
| Scene | get_document_summary, get_rhino_scene_info, get_rhino_layers, capture_rhino_viewport |
| Objects | get_objects, get_object_info, create_object, modify_object, delete_object, select_objects, add_rhino_object_metadata, get_rhino_objects_with_metadata, get_rhino_selected_objects |
| Layers | create_layer, delete_layer, get_or_set_current_layer |
| Geometry | boolean_union, boolean_difference, boolean_intersection, loft, extrude_curve, sweep1, offset_curve, pipe |
| Curves | trim_curve, join_curves, curve_domain, trim_curve_by_fraction |
| Jewelry | ring_blank, head_blank, section_profile, place_head_on_band, edge_selector_presets, safe_boolean_union, safe_boolean_difference, loft_sections |
| Grasshopper | grasshopper_add_components, grasshopper_get_definition_info, grasshopper_run_solver, grasshopper_clear_canvas, grasshopper_list_available_components |
| Code execution | execute_rhinoscript_python_code, execute_rhino_code |
| Discovery | list_rhino_commands, list_rhinoscript_functions, look_up_RhinoScriptSyntax |
Requirements
- Rhinoceros 3D 7 (IronPython 2.7)
- Python 3.10+ on the host machine
- Claude Desktop or Claude Code as the MCP client
Web server variant
For HTTP/WebSocket access instead of stdio:
keratin-web --host localhost --port 8000
Endpoints: POST /rhino/command, GET /rhino/scene, WS /ws
Diagnostics
# Check the Rhino TCP connection
python tools/ops/diagnose_rhino_connection.py
# View recent errors across all logs
python tools/ops/log_manager.py --since-minutes 60 --level ERROR
Logs are written to ./logs/ (server / rhino / diagnostics).
Building & publishing
PyPI (MCP server):
python -m build
python -m twine upload dist/*
Yak (Rhino Package Manager):
The Yak package bundles the Rhino-side IronPython listener (rhino_script.py) for distribution via Rhino's built-in Package Manager.
Prerequisites:
- Rhinoceros 7 installed (provides
yak.exe) - A McNeel account — register at https://www.rhino3d.com/my-account
Package contents (yak-package/ directory):
| File | Purpose |
|---|---|
manifest.yml |
Package metadata (name, version, author, description) |
rhino_script.py |
The IronPython listener that runs inside Rhino |
icon.png |
Package icon shown in Package Manager (128×128 px recommended) |
Build steps:
-
Update the version in
yak-package/manifest.ymlif needed. -
Build the
.yakarchive:
cd yak-package
"C:\Program Files\Rhino 7\System\yak.exe" build
This produces a file named keratin-<version>-any-any.yak in the current directory.
- Verify the package contents:
"C:\Program Files\Rhino 7\System\yak.exe" contents keratin-0.1.2-any-any.yak
Publish to the Yak feed:
# First-time login (opens browser for McNeel SSO)
"C:\Program Files\Rhino 7\System\yak.exe" login
# Push the package
"C:\Program Files\Rhino 7\System\yak.exe" push keratin-0.1.2-any-any.yak
The filename suffix
any-anymeans the package targets any platform and any Rhino version. After pushing, the package appears in Rhino's Package Manager within a few minutes.
Attribution
keratin is built on the shoulders of:
See THIRD_PARTY_NOTICES.md and the preserved license texts under third_party/.
Disclaimer
Not affiliated with McNeel & Associates. Use at your own risk. Always work on copies of important files.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file keratin-0.1.2.tar.gz.
File metadata
- Download URL: keratin-0.1.2.tar.gz
- Upload date:
- Size: 71.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fae3155f9ab157fc344d5b4c587177133c7d09162f865b42ee07dce2211bdf53
|
|
| MD5 |
d062308eec00a76ecf8edd6872d00309
|
|
| BLAKE2b-256 |
f0f15ec53ca77b4b32572df5504bf977108229c74cdee86c64864f5ebfc1fd24
|
File details
Details for the file keratin-0.1.2-py3-none-any.whl.
File metadata
- Download URL: keratin-0.1.2-py3-none-any.whl
- Upload date:
- Size: 79.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0432815ebb13037d0894874232b74ee6f6279b9614e8cd047b07e873446ffc0e
|
|
| MD5 |
f8e18f7b02c4087ad738320413fd6c4c
|
|
| BLAKE2b-256 |
4dd861632114e15f6922850fa05c5fa16be33750c766dd7effbe1c261149f9d6
|