Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

Almond MCP for Rhino

0.7.0-rc.1 — structural analysis pre-release. The Structure workspace now runs Almond's own 3D frame solver: floor and placed-model loads, EN 1990 combinations, rigid/simple joints, stability (αcr, sway imperfections, P-Δ), EN 1993-1-1 member checks, per-curve sections (almond:section) and the Almond Results panel for every member, support and combination. Concrete, timber and aluminium are indicative. Start with the Structure workspace tutorial; release notes and the pre-release checklist are in docs/release-0.7.md. Install from Rhino's Package Manager with Include pre-releases ticked; the stable release remains 0.6.0.

0.6.0 — Almond workspace release. Run Almond in Rhino for a dockable Neo Swiss menu with Models and Structural Validation. AlmondLibrary opens models directly; AlmondStructure (or AlmondKaramba) opens the analysis workspace. Models retain compact tiles, Light/Original detail and shared-block viewport placement. The structural workspace runs Almond's built-in native solver (no Karamba needed: floor and placed-model loads, EN 1990 combinations, rigid/simple connections, stability, a live viewport overlay) or, optionally, Karamba3D; both add selection capture, explicit assumptions, support/load diagram toggles, mapped utilization and an exportable result record. See docs/native-solver.md.

The active IKEA catalogue, source links and four supplier-specific MCP tools are retired. Existing local downloads and historical scene records are retained. Karamba and the generated model/source libraries remain available. See the Rhino quickstart and release infrastructure. Viewport dragging was confirmed by the user on rc.6. Stable 0.6.0 passed its Rhino smoke test and is published on Rhino Package Manager (almondbridge) and PyPI (almond-mcp).

Run almond-mcp library --open for the local Neo Swiss interface: 47 Meshy models, 7 drawing elements, linked SVG/DXF views, downloads, and source evidence in one searchable catalogue. The same index is exposed through the MCP tool search_asset_repository and almond://repository/{asset_id} resources. See the Object Archive guide.

All 50 generated models now carry embedded asset passports and ship with the Python package, including their sidecar contracts and previews. New MCP tools recommend assets with reasons and check rotated clearance envelopes before placement. See the release guide for the workflow, packaging, verification and remaining Rhino integration checks. The drafting update adds a ten-model SVG/DXF pilot, custom GLB drawing generation, source discovery and drawing revision checks.

Almond

Almond exposes Rhino 8 and a semantic design layer as MCP tools: curated furniture/drawing/diagram libraries with spatial contracts, audited Karamba capsules, structured retrieval (SQLite FTS5 + R-tree scene ledger), script execution over a TCP bridge, and publishing into Chestnut.

What Almond is

Most Rhino MCP servers give the model a single power: run a script. That demos well, but generation is blind — the model has no memory of what is already in the scene, no real-world dimensions, no constraints, and no way to check its own work. The result is geometry that looks plausible and measures wrong.

Almond is a semantic layer around Rhino, built so a language model can design with spatial awareness and produce high-detail, high-fidelity output:

  • A persistent scene ledger (SQLite) — scenes, rooms, placed instances, delta-based revisions. The model queries the current state instead of guessing it.
  • Curated asset libraries with spatial contracts — every furniture and drawing asset carries its real catalogue dimensions plus an authored contract: anchor point, floor footprint, functional clearances (e.g. 900 mm in front of a bookcase), collision shape, placement priority. Placement respects ergonomics, not just bounding boxes.
  • Structured retrieval — FTS5 natural-language search and R-tree spatial indexes, isolated per library, returning compact asset cards sized for a model's context window.
  • Layout validation — an R-tree broad-phase overlap and room-containment check the model can run before committing a layout.
  • Audited Karamba capsules — typed input/output contracts (ALMOND_IN_*/ALMOND_OUT_*) over structural Grasshopper definitions, so generated structures get real displacement/utilization feedback.
  • Drawing recipes — layer hierarchies, plot weights, and linetype standards applied as one command, so output reads as an architectural drawing rather than raw curves.
  • Script execution and GLB publishing — the raw execute_rhino_script power is still there, plus one-call publishing of selected geometry into Chestnut with physics metadata.

The design goal: the model composes from verified parts and validated layouts instead of hallucinating geometry.

Two pieces work together:

  • almond-mcp (this Python package, on PyPI) — the MCP server Claude talks to. Holds the semantic layer; needs no Rhino SDK.
  • almondbridge (a Rhino 8 plugin, on the Rhino Package Manager) — listens on 127.0.0.1:5000 (local only) inside Rhino and executes what the server sends. Starts automatically with Rhino.

Setting up with an AI assistant?

Paste this to your assistant (Claude, Codex, etc.) — it prevents the two most common failure modes (installing a different "Rhino MCP" product, and needlessly upgrading Rhino):

Install Almond MCP from https://github.com/liangjunglj-cpu/almond-mcp by following that repo's AGENTS.md exactly. The Rhino plugin is almondbridge on the Rhino 8 Package Manager (& "C:\Program Files\Rhino 8\System\Yak.exe" install almondbridge); the server is almond-mcp on PyPI, registered as uvx almond-mcp. Do not install any other "Rhino MCP" implementation, and do not upgrade Rhino — every Rhino 8 service release is supported.

Setup, step by step

Fresh machine to working in about five minutes. You need Rhino 8 on Windows and a Claude that supports MCP (Claude Desktop or Claude Code).

  1. Install the bridge. In Rhino 8 run _PackageManager, search almondbridge, install, restart Rhino. You should see RhinoAlmondBridge: TCP listener started on port 5000 in the command history — no command needed. (AlmondMCPStatus checks it any time.)

  2. Install uv (Python not required — uv manages everything):

    winget install astral-sh.uv
    
  3. Register the server with Claude.

    • Claude Desktop: edit %APPDATA%\Claude\claude_desktop_config.json:

      {
        "mcpServers": {
          "Almond": {
            "command": "uvx",
            "args": ["almond-mcp"]
          }
        }
      }
      
    • Claude Code: claude mcp add Almond -- uvx almond-mcp

  4. Restart Claude. The Almond tools (execute_rhino_script, search_generated_assets, create_design_scene, …) appear in the tool list. First run creates %LOCALAPPDATA%\Almond with the library manifests and the scene database.

  5. Check the plumbing (Rhino open):

    uvx almond-mcp doctor
    
  6. Populate the asset libraries (optional — everything except model placement works without it). The manifests ship with the package, but the model files are 3D Warehouse content that cannot legally be redistributed (see THIRD-PARTY-NOTICES.md), so each user downloads them from the original source pages:

    uvx almond-mcp fetch-assets --open   # opens each missing model's source page
    uvx almond-mcp fetch-assets          # re-run to verify sha256 checksums
    

    Save each download into the library's models/ folder under the exact file name shown; the command verifies every checksum.

  7. Optional extras: Karamba3D 3.1 enables validate_structure (found at runtime — never bundled); point RHINO_MCP_LIBRARY_DIR at your own Grasshopper definition library to expose it via list_library.

CLI

almond-mcp               start the MCP server (also: almond-mcp serve)
almond-mcp fetch-assets  report missing/invalid model files and their sources
almond-mcp doctor        check directories, manifests, state DB, bridge port
almond-mcp paths         print every resolved directory

Directory resolution order: RHINO_MCP_* environment variable → repository checkout (development) → %LOCALAPPDATA%\Almond (installed). Overridable locations:

Environment variable Default folder
RHINO_MCP_LIBRARY_DIR Grasshopperfiles (your GH/Karamba definitions)
RHINO_MCP_DRAWING_ASSET_DIR DrawingAssetfiles
RHINO_MCP_DIAGRAM_ASSET_DIR DiagramAssetfiles
RHINO_MCP_DRAWING_RECIPE_DIR DrawingRecipes
RHINO_MCP_GENERATED_ASSET_DIR GeneratedAssetfiles
RHINO_MCP_CAPSULE_DIR capsules
RHINO_MCP_STATE_DB %LOCALAPPDATA%\Almond\almond_state.sqlite3

Rhino to Chestnut

After execute_rhino_script returns the GUIDs it created, publish only those objects with:

publish_to_chestnut(
  guids=[...],
  asset_name="Timber Pavilion"
)

This preferred tool applies semantic defaults automatically. Its optional behavior presets are architecture, object, and animated. Use the lower-level tool only when explicit physics control is needed:

publish_objects_to_chestnut(
  guids=[...],
  asset_name="Timber Pavilion",
  asset_id="timber-pavilion-01",
  body_type="static",
  collider="box",
  preserve_scale=true,
  mass=0
)

The tool:

  1. asks Rhino 8 to export the supplied GUIDs as GLB;
  2. explicitly maps Rhino Z-up to glTF Y-up;
  3. uploads the GLB and its source/physics metadata to Chestnut;
  4. creates or updates the stable asset_id; and
  5. removes the temporary GLB after publishing.

Reusing an asset_id updates the geometry while Chestnut placements continue to reference the same asset URL.

Chestnut defaults to the deployed service at https://chestnut-mnvo.onrender.com. Override it before starting the MCP server when local development is required:

$env:CHESTNUT_URL = "http://127.0.0.1:3000"
almond-mcp

Architectural drawing asset library

Representation-only entourage and graphic proxies live in the independent drawing asset library. They have a dedicated search:

search_drawing_assets(query="landscape tree")
get_drawing_asset(asset_id="context-tree-chinese-elm-a708cff4")
place_drawing_asset(
  asset_id="context-tree-chinese-elm-a708cff4",
  x=12000,
  y=8000
)

Audited drawing recipes are stored separately in DrawingRecipes. The first recipe creates a technical-axon layer hierarchy with plot weights and custom hidden/overhead linetypes:

list_drawing_recipes()
get_drawing_recipe(recipe_id="technical_axon_v1")
apply_drawing_style(recipe_id="technical_axon_v1")
create_generation_plan(
  goal="Produce a technical axonometric",
  scope="drawing"
)

Generated asset library (open, redistributable)

The optional drawing library describes community models that each user must download themselves. GeneratedAssetfiles/ is different: 47 (and growing) architectural models generated with Meshy from Almond's own prompts, owned by the project and released under CC BY 4.0, so they ship with the repository and the 0.6 wheel for offline use. Categories:

Group Assets
Entourage standing / walking / sitting person, deciduous and conifer tree, sedan car, bicycle
Site furniture park bench, street lamp, bollard, bike hoop, litter bin
Building components round and square column, glass balustrade (doors, windows and stairs are deliberately excluded: they need exact dimensions, so model them directly)
Fixtures and appliances toilet, pedestal basin, bathtub, shower enclosure, range cooker, fridge-freezer
Generic furniture three-seat sofa, dining table and chair, double bed, desk, office chair
Design-idiom furniture bent-birch stool, table, trolley, webbed and cantilevered armchairs; moulded-plywood, shell and leather lounge chairs with ottoman; freeform coffee table, slatted bench, mesh task chair; loose-cover sofa, cube and track shelving, wire side table
Lighting spherical pendant, arc floor lamp, balanced-arm task lamp

Every GLB is normalised by tools/build_generated_assets.py: scaled to its catalogue height, bottom-centre on the origin, measured (never nominal) bounds in the manifest, one ALMOND::<material_id> material so import_asset_contract's restore step gives it the canonical Almond material, and a .almond.json contract beside it.

search_generated_assets(query="bench", max_height_mm=1000)
get_generated_asset(asset_id="gen-park-bench-1")
place_generated_asset(asset_id="gen-park-bench-1", x_mm=2400, y_mm=800, rotation_degrees=90)
register_scene_instance(scene_id=..., asset_id="gen-park-bench-1", ...)  # then validate_scene_layout

To extend the library, add an entry to GeneratedAssetfiles/catalogue.json (prompt, nominal size, material, clearances), generate it with Meshy (the recipe is recorded in the catalogue: nano-banana concept image → meshy-t2 smart-topology mesh, untextured), save the GLB as GeneratedAssetfiles/raw/<asset_id>.glb, record the task ids in provenance.json, and run the build script. Provenance and licensing are documented in docs/licensing-audit.md.

Structural validation with reports

validate_structure(guids, structure_type, load_kn, material) checks generated geometry through three pathways in strict order of confidence — real Karamba 3.1 FEA (api, high), audited capsule templates (medium), or span-rule heuristics (rule_based, low) — and always labels which one ran. Pass criteria: deflection ≤ span/250 and utilization below yield. Every run is recorded in the local state database; export_structural_report() renders the history to a Markdown report (inputs, pathway, span/deflection/utilization/reactions, warnings, PASS/FAIL). Details: docs/structural-validation.md.

On top of the solver, a construction knowledge layer (get_construction_guidance, Constructionfiles/manifest.json) grounds generated structures in real building assemblies: 23 curated systems (wood joist floors to precast tees, platform framing to steel rigid frames) with span ranges, depth rules of thumb, member spacings, and element roles distilled from Ching's Building Construction Illustrated (4th ed.). Call it before generating to pick a system and size members like a builder would; validate_structure then appends a construction_check that flags spans no real system covers — so geometry that merely solves numerically but could not be constructed as drawn is caught too. Details: docs/construction-guidance.md.

Materials and cross-application exchange

Almond carries a curated PBR material library (list_materials) and stamps geometry with machine-readable material metadata (assign_material): a physically-based Rhino material plus almond:* user text (material_id, ue_material_slot, base colour, metallic, roughness, opacity — and, for structural members, structural_role / construction_system / structural_material, declaring in construction terms what each object is). GLB export then carries real PBR channels, and Datasmith imports the user text as Unreal asset metadata — so imports remap to your master materials by slot name instead of being guessed from display colours.

The same metadata makes assets portable between applications:

export_asset_contract(guids=[...], asset_id="canopy-01")   # GLB + .almond.json
import_asset_contract(contract_path="...", x_mm=0, y_mm=0) # into any Rhino doc
get_blender_helper_script(action="export", asset_id="bench-01")

An asset contract travels beside the GLB carrying what the file format drops — real dimensions, anchor, clearances, and each object's Almond material_id. On import Almond collapses the duplicate materials glTF creates, restores canonical colours (glTF round trips shift them), re-attaches the metadata, places the asset by its anchor, and verifies the measured size against the contract. get_blender_helper_script returns Python to run in Blender (through blender-mcp) so Blender joins the workflow without a dedicated bridge. Background and measurements: docs/cross-app-blender.md.

Karamba capsules

Audited capsule manifests (capsules/*.capsule.json) declare typed input/output contracts for structural Grasshopper definitions using reserved ALMOND_IN_* / ALMOND_OUT_* nicknames — beams, trusses, frames, shells, gridshells, membranes, canopies, and high-rises. See capsules/AUTHORING.md to bind your own definitions. Karamba3D itself is user-installed; the bridge finds it at runtime via reflection.

Structured retrieval and scene state

Almond builds a local SQLite database from the asset manifests at startup. The database provides:

  • library-isolated dimensional and category filters;
  • FTS5 natural-language retrieval;
  • R-tree asset and scene-instance spatial indexes;
  • stable scene, room, asset, and instance handles;
  • delta-based scene revisions; and
  • dependency-ordered generation plans.

Search and list tools return compact asset cards. Full provenance, footprints, clearances, and source metadata are returned only by get_generated_asset. Geometry and Grasshopper files remain local.

Useful tools:

get_retrieval_status()
create_design_scene(name="Apartment test")
upsert_design_room(
  scene_id="scene_...",
  name="Living room",
  bounds_mm=[0, 0, 0, 6000, 4500, 2800]
)
register_scene_instance(
  scene_id="scene_...",
  room_id="room_...",
  asset_id="gen-sofa-3-seat-1",
  x_mm=3000,
  y_mm=3900
)
validate_scene_layout(scene_id="scene_...")
create_generation_plan(
  goal="Generate and furnish a compact house",
  scope="house",
  scene_id="scene_..."
)

The current spatial validator is an R-tree world-AABB broad phase plus room containment. Oriented-footprint, functional-clearance, and automatic resolution passes can build on the same persistent scene ledger.

Development

git clone <repo> almond-mcp
cd almond-mcp
uv run pytest          # 23 tests, no Rhino required
uv run almond-mcp doctor

On OneDrive-synced folders set UV_LINK_MODE=copy (OneDrive rejects uv's hardlinks). Licensing: LICENSE (MIT), THIRD-PARTY-NOTICES.md, and docs/licensing-audit.md for what may and may not be distributed.

Drawing pilot — 0.6.0rc2

Almond now exports traceable mesh silhouettes as scaled SVG, full-size DXF and A3 SVG sheets. Ten generated models have bundled plan/front/right views; other library models and custom static GLBs can be processed on demand. Generation evidence and geometry hashes travel with the drawings, and an audit detects changed outputs or stale source geometry. Six architectural reference directories are searchable without DETAIL access.

See drafting workflow and limits and open the pilot gallery. These are mesh outlines for layout/entourage; section assemblies and hidden-line drafting remain future work.

Compact Rhino library placement (0.6.0rc13)

The docked archive now uses small, two-column thumbnails. Drag a model into a viewport, or choose Place and pick an insertion point. Light detail targets 20,000 triangles on heavier models; Original retains the source mesh. Repeated objects share Rhino blocks and materials. Source records and transformation/reduction metadata stay attached to each placed object. The prepared candidate requires an interactive Rhino placement check before publication; see docs/rhino-archive-quickstart.md.

Metadata

Release files for almond-mcp 0.7.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for almond-mcp 0.7.0rc1
File Size Uploaded
almond_mcp-0.7.0rc1.tar.gz 47.9 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for almond-mcp 0.7.0rc1
File Interpreter ABI Platform
almond_mcp-0.7.0rc1-py3-none-any.whl Python 3 none any Details

Total release size: 93.1 MB

Release files / almond_mcp-0.7.0rc1.tar.gz

Download URL almond_mcp-0.7.0rc1.tar.gz
Size 47.9 MB
Tags Source
SHA-256 checksum
How to use checksums
e4c304ecab3ffb471ed05dd5b89cc0e508e2f0119242de086917eec0998d9151
BLAKE2b-256 checksum
How to use checksums
8d251deb18b1fc83e650eeedf4deba201f6425387a0caed497f516f356fdcd4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / almond_mcp-0.7.0rc1-py3-none-any.whl

Download URL almond_mcp-0.7.0rc1-py3-none-any.whl
Size 45.2 MB
Tags Python 3
SHA-256 checksum
How to use checksums
9189cd46b5f4685b2f49f20c0f34e14365173603f5f4ff0e3262948e01e06a85
BLAKE2b-256 checksum
How to use checksums
f13ea9a741fd14566ec193fc6fdb1548ef71827b7805e07c6f807150ee35a729
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.7.0rc1 This release

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page