Skip to content

jscad-mcp

@caliperhq/jscad-mcp is an MCP server that renders .jscad files to PNG using the OpenJSCAD geometry kernel and returns the images directly into Claude’s context — closing the perception loop so Claude can see what it builds.

A live web viewer runs alongside the server. Every render Claude produces is pushed to the viewer in real time via SSE, so you always see exactly what Claude sees.

Voronoi panel rendered via jscad-mcp

For a gallery of what it can do, see jscad-mcp-example — 13 demos with walkthroughs, iteration GIFs, and “Try in browser” links.

  • Node 18–22 recommended (Node 24 needs an extra step — see below)
  • Native build tools for headless-gl (no GPU needed, but native bindings are required):
Terminal window
# Debian / Ubuntu
apt install libxi-dev libxmu-dev libgl1-mesa-dev libglu1-mesa-dev build-essential
# Fedora / RHEL
dnf install libXi-devel libXmu-devel mesa-libGL-devel mesa-libGLU-devel
# Gentoo
emerge x11-libs/libXi x11-libs/libXmu media-libs/mesa
# macOS (via Homebrew)
xcode-select --install
Terminal window
npm install -g @caliperhq/jscad-mcp

Or run without installing:

Terminal window
npx @caliperhq/jscad-mcp

headless-gl 6.x does not compile on Node 24 with GCC 14+ due to a missing #include <cstdint> in the bundled ANGLE library. Either use nvm to switch to Node 20 LTS for the install step, or patch and rebuild after install:

Terminal window
npm install -g @caliperhq/jscad-mcp
cd $(npm root -g)/@caliperhq/jscad-mcp
sed -i 's/#include <vector>/#include <vector>\n#include <cstdint>/' node_modules/gl/angle/src/common/angleutils.h
npm rebuild gl

Add to your claude_desktop_config.json:

{
"mcpServers": {
"jscad": {
"command": "jscad-mcp",
"args": []
}
}
}

If you installed locally, point at the entry script instead:

{
"mcpServers": {
"jscad": {
"command": "node",
"args": ["/path/to/jscad-mcp/src/index.js"]
}
}
}
Terminal window
claude mcp add --scope user jscad jscad-mcp

Or with a local clone:

Terminal window
claude mcp add --scope user jscad node /path/to/jscad-mcp/src/index.js

Install the bundled Claude Code skills for the best experience — they teach Claude the render-verify loop and the full JSCAD API:

Terminal window
SKILLS_DIR="$HOME/.claude/skills"
PKG_DIR="$(npm root -g)/@caliperhq/jscad-mcp"
mkdir -p "$SKILLS_DIR"
cp -r "$PKG_DIR/skills/jscad-mcp" "$SKILLS_DIR/"
cp -r "$PKG_DIR/skills/jscad" "$SKILLS_DIR/"
cp -r "$PKG_DIR/skills/jscad-wiki" "$SKILLS_DIR/"
cp -r "$PKG_DIR/skills/jscad-examples" "$SKILLS_DIR/"

Rendering

ToolDescription
take_standard_viewsRender iso, front, side, and top in one call
take_imageRender from a specific azimuth, elevation, zoom, and target
sliceCross-section view: cut along x/y/z plane, camera auto-oriented

Named parts

ToolDescription
list_partsList named parts with bounding boxes
highlightRender with one named part lit up, the rest faded
label_partsRender with a legend mapping part names to screen positions

Session / diagnostics

ToolDescription
open_viewerOpen the web viewer in the default browser
echoVerify the MCP connection
render_testConfirm the render pipeline works (no input needed)

All tools accept either file (absolute path to a .jscad) or code (inline JSCAD source). Render tools also accept optional width / height (pixels), a named resolution preset (thumbnail, small, normal (default, 800×600), large, high-quality), and showGrid / showAxis toggles.

The server starts a local web viewer on launch; the browser opens automatically on the first render.

  • 3D canvas — interactive view via @jscad/regl-renderer with correct per-solid colors. Drag to rotate, scroll to zoom, shift-drag to pan.
  • File browser.jscad and .js files rooted at your project directory
  • Parts panel — named parts listed with color dots; click to isolate or show all
  • Thumbnail strip — every render Claude makes appears here in real time
  • Grid / axis toggles — bottom-left corner; state saved to localStorage
  • Editor link — opens the full @jscad/web editor in a new tab, pre-loaded with the current file

Files use CommonJS and export a main() function:

'use strict'
const { primitives, booleans } = require('@jscad/modeling')
const { cuboid, cylinder } = primitives
const { subtract } = booleans
const main = () => subtract(
cuboid({ size: [40, 40, 20] }),
cylinder({ radius: 10, height: 22 })
)
module.exports = { main }

Export a parts map alongside main to unlock list_parts, highlight, the parts panel in the web viewer, and part-aware label overlays:

'use strict'
const { primitives, transforms } = require('@jscad/modeling')
const { cuboid } = primitives
const { translate } = transforms
const body = () => cuboid({ size: [40, 30, 20] })
const lid = () => translate([0, 0, 20], cuboid({ size: [40, 30, 5] }))
module.exports = {
main: () => [body(), lid()],
parts: { body: body(), lid: lid() }
}
  • Evaluates .jscad files in-process using @jscad/modeling
  • Renders using @jscad/regl-renderer + headless-gl — pure software rendering, no GPU required
  • Returns base64-encoded PNG images as MCP image content blocks
  • Geometry JSON is also served to the web viewer’s live 3D canvas
  • Renders are cached in .jscad-cache/ at the project root