Skip to main content
Glama
RobertCoop

OpenSCAD MCP Server

by RobertCoop

OpenSCAD MCP Server

PyPI CI Python MCP License

A Model Context Protocol (MCP) server that lets AI assistants design 3D-printable parts and assemblies in OpenSCAD: render with a stated scale, measure exact geometry, check assemblies for interference and clearance, extract holes and features, judge printability, and export. Built with FastMCP for Python; OpenSCAD 2021.01 is the supported floor and dev snapshots are used when present.

Prerequisites

  • OpenSCAD installed on your system

  • uv (recommended) or Python 3.10+

Related MCP server: 3D MCP Server

Installation

The server is published on PyPI as openscad-mcp, so uv runs it with no clone and no virtualenv: uvx openscad-mcp. uv keeps a cached copy; uv tool upgrade openscad-mcp (or uvx openscad-mcp@latest) pulls a new release, and uvx openscad-mcp@0.6.1 pins one.

Claude Code

Add the server with a single command:

claude mcp add openscad --transport stdio -- uvx openscad-mcp

Or, if OpenSCAD is not on your PATH:

claude mcp add openscad --transport stdio \
  --env OPENSCAD_PATH=/path/to/openscad -- uvx openscad-mcp

Use the --scope flag to control where the configuration is saved:

Scope

Flag

Effect

Local (default)

--scope local

Available only to you in the current project

Project

--scope project

Shared with the team via .mcp.json

User

--scope user

Available to you across all projects

The repository is also a Claude Code plugin (skill plus server): /plugin marketplace add robertcoop/openscad-mcp then /plugin install openscad-mcp@openscad-mcp.

Claude Desktop

Add to your configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "openscad": {
      "command": "uvx",
      "args": ["openscad-mcp"],
      "env": {
        "OPENSCAD_PATH": "/usr/bin/openscad"
      }
    }
  }
}

Then restart Claude Desktop.

Cursor / Windsurf / VS Code

Add a .mcp.json file to your project root:

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

Manual / Standalone

# From PyPI (no install required)
uvx openscad-mcp

# The development version, straight from GitHub
uvx --from git+https://github.com/robertcoop/openscad-mcp.git openscad-mcp

# Or clone and run locally
git clone https://github.com/robertcoop/openscad-mcp.git
cd openscad-mcp
uv run openscad-mcp

# Run an assembly check file from a shell or a Makefile (exit code 0/1/2)
uvx openscad-mcp check checks.yaml --allow /path/to/project

Available Tools

Every tool response carries errors, warnings and hints parsed from OpenSCAD's output. Check them: OpenSCAD exits 0 on a failed assert() or an unknown module and draws a blank scene.

Rendering

Tool

Description

render

Images with a text digest before each one (camera, view direction, scale, bbox). mode=views (one image per view, or a custom camera), mode=section (exact cross-section with a scale bar), mode=parts (each part in its own colour, isolate ghosts the rest), mode=compare (before/after). grounded=true gives an orthographic view with a stated mm/px scale; annotate=true adds a scale bar, axis triad and bbox dimensions

Assemblies

Tool

Description

check

Relations between named parts, exported separately and never unioned: mode=interference (clear / contact / interference with penetration depth and a witness point), clearance (exact minimum distance with closest points), contact (area, normal, plane; `kind=static

Parts are given inline as parts=[{name, code, place?, frame?, ghost?, mass_g?, motion?}] or in a check file (frames, quality, parts, checks, model). Any number in a rule may be a SCAD expression string (point: "[BOLT_R, 0, BASE_H]") evaluated in the model's scope, so checks follow the parameters rather than a copy of them. openscad-mcp check <file.yaml> runs a check file from the shell with a meaningful exit code, so make check is one call.

Export & Model Management

Tool

Description

export_model

Export to STL, 3MF, AMF, OFF, NEF3, DXF, SVG, PDF or CSG. With parts=[...] every part is exported in its assembly position and bundled into one 3MF with named objects (or a directory of STLs)

model

`action=create

Measurement & Validation

Tool

Description

measure

Exact numbers from the geometry: model (bbox, volume, area, components, watertight, mesh_health), parts, section (contours; the offset may be an expression in the model's scope), mass (grams; with parts= and about_axis= the assembly mass, centre of mass and inertia about an axis, with mass_g overrides for purchased parts), probe (solid/air and which part at points; ray crossings; line of sight along a polyline), features (holes from the CSG tree: axis, diameter, depth, through/blind, undersize at $fn, fit names), printability (overhang patches with unsupported reach, thickness distribution vs nozzle, islands, support estimate; facts only), orientation (candidate orientations, no winner chosen), anchors (BOSL2 anchor frames in the assembly frame). Accepts an existing STL/SVG via mesh

validate

mode=syntax, geometry, predicates (with sweep={variable, values} reporting the crossing), includes (references resolved or not, plus the BOSL2 lint: a module from a used file placed by attach() is silently put at CENTER; autofix=true applies the rewrite when it is safe), printability (rules from the design-rule reference over measured facts)

scad_eval

Evaluate expressions in a model's variable scope and get typed values (number, vector, string, bool, range, undef)

reference

Sourced engineering data with confidence labels: fits (also bidirectional: diameter_mm=3.3 names the hole, shaft_mm+bore_mm names the fit), metric fasteners, heat-set inserts, bearings, magnets, joints, a purchased-parts catalog with BOSL2 modules and clearance masks, FDM design rules, materials, OpenSCAD cheatsheet, conventions

get_libraries

Discover installed OpenSCAD libraries

check_openscad

Verify OpenSCAD installation, version and capabilities

Project Support

Tool

Description

get_project_files

List .scad files and their references; mode=trace follows a constant through the project (what depends on it, what it depends on)

clear_cache

Clear the render cache

Usage Examples

Once connected, ask your AI assistant:

  • "Render a cube with rounded edges"

  • "Show me the front and top of this model with a scale bar"

  • "What is the volume and are there any cavities?"

  • "Cut a section through the lid at z = 12 and tell me the wall thickness"

  • "Colour the body and lid differently and ghost the body"

  • "What clearance should I use for an M3 screw and a press-fit 608 bearing?"

  • "Compare the model before and after changing the radius to 15"

  • "Export my gear model to STL"

The server also publishes MCP resources (openscad://conventions, openscad://cheatsheet, openscad://reference/{topic}) and server instructions with the coordinate and assembly conventions it expects. A Claude Code skill lives in skills/openscad-design/SKILL.md and the repo can be installed as a Claude Code plugin (.claude-plugin/).

Tool Parameters

API.md documents every tool and every parameter. Four parameters account for most of the questions:

  • parts — a list of {"name": ..., "code": ..., "place": ...} objects, accepted by render(mode="parts"), measure(mode="parts"), check and export_model. code is the statement that instantiates the part (lid();) and place is an optional OpenSCAD transform wrapped around it (translate([0,0,20])). Each part is exported on its own, so its identity survives; an assembly is never unioned. measure(mode="parts") measures each part in its placed position (the response says frame: "assembly"), the same grammar check, render and export_model use.

  • qualitydraft, normal, high, or an integer $fn. It sets $fn/$fa/$fs for the run. It is a correctness knob, not only a speed one: check reports a distance smaller than the tessellation error bound as UNRESOLVED rather than guessing, and the fix is a higher quality.

  • variables — a dict injected as OpenSCAD variables. In the wrapped modes (section, parts, scad_eval) they are appended to the wrapped module body rather than passed with -D, and they are injected at file scope as well, so a constant derived inside an included file still sees them. This is how you set a $preview guard variable for an export.

  • include_paths — extra directories added to OPENSCADPATH. When MCP_ALLOWED_PATHS is set, every entry is validated against it, as is every file OpenSCAD actually reads.

Exactly one of scad_content or scad_file is required by every tool that takes source. All parameter parsers accept multiple input formats (JSON strings, lists, dicts, CSV) for AI assistant compatibility.

Each image costs roughly 640 vision tokens at 800x600, and image sizes are clamped to 1568 px on the long edge, above which vision models downscale anyway. Ask for the views that answer a question rather than all of them. Auto-fit renders (grounded=false) have no recoverable absolute scale, which the digest states.

Configuration

Environment Variables

Variable

Description

Default

OPENSCAD_PATH

Path to OpenSCAD executable

Auto-detected

MCP_TEMP_DIR

Temporary file directory

/tmp/openscad-mcp

MCP_TRANSPORT

Transport type: stdio, http, sse

stdio

MCP_HOST

Host for HTTP/SSE transport

localhost

MCP_PORT

Port for HTTP/SSE transport

8000

MCP_MAX_CONCURRENT_RENDERS

Max parallel renders

5

MCP_RENDER_TIMEOUT

Render timeout in seconds

300

MCP_CACHE_ENABLED

Enable render caching

true

MCP_CACHE_SIZE_MB

Max cache size in MB

500

MCP_CACHE_TTL_HOURS

Cache TTL in hours

24

MCP_LOG_LEVEL

Logging level

INFO

MCP_MAX_FILE_SIZE_MB

Max SCAD file size

10

MCP_ALLOWED_PATHS

Directories scripts may read from (os.pathsep-separated)

unset = no validation

MCP_MAX_MEMORY_MB

Address-space limit per OpenSCAD process (POSIX), 0 disables

4096

MCP_MAX_IMAGE_WIDTH / MCP_MAX_IMAGE_HEIGHT

Render size clamp (aspect preserved)

1568

MCP_HARD_WARNINGS

Pass --hardwarnings to OpenSCAD (see Security)

false

YAML Configuration

Create a config.yaml for advanced configuration:

server:
  name: "OpenSCAD MCP Server"
  version: "0.1.0"
  transport: stdio

rendering:
  max_concurrent: 5
  timeout_seconds: 300
  default_color_scheme: Cornfield

cache:
  enabled: true
  max_size_mb: 500
  ttl_hours: 24

security:
  rate_limit: 60
  max_file_size_mb: 10
  allowed_paths:          # null = no path validation at all (a warning is logged)
    - /home/me/projects/parts
  max_memory_mb: 4096

Security

Threat model

The server runs OpenSCAD on source it is handed. OpenSCAD can read any file the process can read, through include <>, use <>, import() and surface(), and can return what it read as echo output or as geometry. The guarantees below hold only when allowed_paths is configured. Out of the box it is unset, no path validation is performed, and the server logs a warning at startup saying so.

What is enforced:

  • Path validation on arguments: scad_file, include_paths (in every tool) and export output_path must lie inside allowed_paths. Containment uses resolved paths, so symlinks and .. cannot escape.

  • Path validation on the dependency closure: every file OpenSCAD actually read is recorded with -d and checked after the run. If any lies outside allowed_paths, the standard library directories, or the server temp dir, the output (image, mesh, echo text) is withheld and the call fails. This closes the include <...>-as-data and surface(file=...) channels.

  • Memory ceiling: each OpenSCAD process runs under RLIMIT_AS (max_memory_mb, default 4 GB) on POSIX hosts. OpenSCAD has no ceiling of its own; a small minkowski() can otherwise consume all host memory.

  • Timeout: timeout_seconds, default 300 s; partial stderr is kept.

  • Echo channel bounds: echo_output is capped (200 lines, 2000 chars per line) and labelled as untrusted content from the rendered file.

  • File size limits, variable name validation (^\$?[a-zA-Z_][a-zA-Z0-9_]*$) and model name validation (no path traversal) as before.

What is not enforced: no OS-level sandbox (no network isolation, no filesystem namespace). For untrusted input run the server inside a container or under Landlock/bubblewrap with only the project directory mounted.

Why --hardwarnings is off

--hardwarnings stops OpenSCAD at the first warning but still exits 0, so it produced blank renders and silently truncated echo_output with no indication. Warnings now reach the assistant through the structured warnings, errors and hints fields on every tool response instead. Set MCP_HARD_WARNINGS=true to restore the flag.

Development

# Clone the repo
git clone https://github.com/robertcoop/openscad-mcp.git
cd openscad-mcp

# Install dependencies (the dev extra; there is no dependency-groups table,
# so `uv sync --dev` would remove pytest, ruff, black and mypy)
uv sync --extra dev

# Run the server
uv run openscad-mcp

# Run the assembly checker on a check file
uv run openscad-mcp check examples/checks/turntable.yaml

# Run tests
uv run pytest

# Lint & format. The tree carries pre-existing findings, so expect noise;
# CI gates only on `ruff check --select F,E9,B src/openscad_mcp/`.
uv run ruff check src/ tests/
uv run black --check src/ tests/

# Type check (also not clean today)
uv run mypy src/

Project Structure

openscad-mcp/
├── src/openscad_mcp/
│   ├── server.py            # FastMCP server, the 12 tools, rendering, cache, CLI
│   ├── assembly.py          # Part/Frame/Assembly model and the check-file grammar
│   ├── checks.py            # RuleEngine: the rules a check file can ask for
│   ├── geom.py              # Mesh kernel: BVH, tri-tri distance, winding number, sweeps
│   ├── csgfeatures.py       # CSG-dump parser: holes, bosses, cross-part alignment
│   ├── massprops.py         # Mass, centre of mass, inertia by tetrahedra
│   ├── printability.py      # Overhangs, wall thickness, islands, orientation candidates
│   ├── analysis.py          # Static analysis: BOSL2 $var shadowing lint, constant tracing
│   ├── parts_catalog.py     # Purchased-parts catalog loader and self-check
│   ├── parts/*.scad         # One generated BOSL2 file per catalogued part
│   ├── threemf.py           # Multi-object 3MF writer
│   ├── wrappers.py          # Source-level wrappers: include hoisting, variable injection
│   ├── diagnostics.py       # stderr -> Diagnostics; -d deps parsing; repair hints
│   ├── camera.py            # Orthographic camera model, fit, annotation, spatial digest
│   ├── mesh.py              # Stdlib STL/SVG analysis: welding, components, volumes
│   ├── reference.py         # Sourced engineering data: fits, fasteners, inserts, DFM
│   ├── types.py             # Pydantic models and enums
│   └── utils/config.py      # Configuration with env/YAML/dotenv support
├── tests/                   # ~1,500 tests; 80% coverage floor
├── evals/                   # Deterministic geometry eval harness, 15 tasks
├── examples/checks/         # A worked check file and its model
├── skills/openscad-design/  # Claude Code skill: the design loop
└── .claude-plugin/          # Claude Code plugin manifest

Testing

# Run all tests with coverage (about 1,500 tests, roughly a minute)
uv run pytest

# Run specific markers: unit, config, integration, slow, performance, edge, render
uv run pytest -m unit
uv run pytest -m performance
uv run pytest -m "not slow"

# Run a single file, without the coverage gate
uv run pytest tests/test_helpers.py -v --no-cov

Most tests mock the OpenSCAD subprocess, so no OpenSCAD installation is needed to run the suite. A mock that stands in for a render has to write both output files OpenSCAD would have written: the -o target and the -d dependency file that the cache manifest is built from. Tests that do need the real binary skip themselves when it is absent.

CI runs the suite on Python 3.10 and 3.12 with OpenSCAD 2021.01 and BOSL2 installed, under xvfb-run because PNG export on 2021.01 needs a display. It also builds the wheel, installs it in a clean environment, and asserts that a client sees exactly 12 tools. Coverage floor: 80%.

Troubleshooting

OpenSCAD Not Found

# Check if OpenSCAD is installed
which openscad        # Linux/macOS
where openscad.exe    # Windows

# Set the path explicitly
export OPENSCAD_PATH=/path/to/openscad

Server Not Connecting

# Verify the server starts correctly
uvx openscad-mcp

# In Claude Code, check MCP status
/mcp

Render Timeout

Increase the timeout:

export MCP_RENDER_TIMEOUT=600

"Path not allowed" / "outside the allowed paths"

MCP_ALLOWED_PATHS is set and the file is not under one of its roots. The check covers arguments and, separately, every file OpenSCAD actually opened, so a model that lives inside an allowed root but does include <../shared/lib.scad> outside it is refused and the output is withheld. Add both roots:

export MCP_ALLOWED_PATHS="$HOME/cad:$HOME/cad-shared"

Leaving the variable unset disables path validation entirely, which the server logs a warning about at startup. See Threat model.

An export or a measurement comes back empty

The usual cause is a $preview guard: a file that instantiates its geometry only inside if ($preview) renders in the GUI and exports nothing, because $preview is false for a render to a file. Pass the guard variable explicitly:

measure(scad_file="part.scad", variables={"$preview": true})

A difference() whose first child is smaller than what follows also yields nothing. validate(mode="syntax") will not catch either one; the exit code is 0 in both cases.

check rows say UNRESOLVED

The distance in question is smaller than the tessellation error of the mesh, so the answer would be an artefact of $fn rather than of the design. Re-run with quality="high" or an explicit integer $fn. Every row reports the quality.fn it was computed at.

A result looks stale

Renders are cached under ~/.cache/openscad-mcp/, keyed on every render parameter plus a manifest of every file OpenSCAD read. Editing an included file normally invalidates the entry, but if a response says cached: true and the number disagrees with the source, clear it:

clear_cache()

Renders fail on a headless machine

OpenSCAD 2021.01 needs a display to export PNG even in headless mode. Run the server under a virtual framebuffer:

xvfb-run -a uv run openscad-mcp

Exports, measurements and checks produce meshes rather than images and do not need a display.

Contributing

  1. Fork the repository

  2. Create a feature branch (git checkout -b feature/my-feature)

  3. Make your changes with tests

  4. Ensure tests pass (uv run pytest)

  5. Open a Pull Request

Commit style: feat:, fix:, docs:, refactor:, chore:

CONTRIBUTING.md covers the module map, how the tests mock OpenSCAD, the design rules that should not be undone, and how to add a parts-catalog entry or a check rule.

License

MIT — see LICENSE

Acknowledgments

  • OpenSCAD — Programmable CAD software. Everything here is a wrapper around its CLI.

  • FastMCP — Python MCP framework

  • Model Context Protocol — The MCP specification

  • BOSL2 — Used, not vendored, by the purchased-parts catalog and by the BOSL2 anchor probe. BSD-2-Clause; install it separately.

  • Dimensional data in reference and parts is cited entry by entry, with a confidence label on every number. See src/openscad_mcp/parts/README.md.

Available Tools

12 tools
checkA

Relations between named parts, exported separately (never unioned), cached, in the assembly frame. parts=[{name, code, place?, frame?, ghost?, mass_g?, motion?}] (code "lid();", place "translate(P)") or check_file= (YAML/JSON: frames, quality, parts, checks, model). mode "interference": clear|contact|interference with penetration depth and witness point (flush contact is contact). "clearance": exact minimum distance, closest points, min_mm. "contact": area, normal, plane; kind=static|sliding. "alignment": coaxial hole stacks across parts, offsets, orphans. "motion": sweep moving= about axis/center over range deg, or along vector over range mm; full turns add a certificate. "rules": every rule in the check file; exit_code 0/1/2. Any number or vector in a rule or motion may be a SCAD expression string ("[BOLT_R, 0, BASE_H]") evaluated in the model's scope. quality: draft|normal|high or $fn, echoed per row; distances inside the tessellation error bound are UNRESOLVED. volume=true cross-checks with OpenSCAD's intersection volume.

ParametersJSON Schema
NameRequiredDescriptionDefault
axisNo
kindNo
modeNointerference
pairsNoall
partsNo
rangeNo
stepsNo
centerNo
checksNo
framesNo
min_mmNo
movingNo
vectorNo
volumeNo
againstNoall
qualityNo
scad_fileNo
variablesNo
check_fileNo
scad_contentNo
tolerance_mmNo
include_pathsNo
response_formatNoconcise

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and does so richly: it discloses caching, 'never unioned', UNRESOLVED distances inside tessellation error bounds, exit_code 0/1/2, full-turn certificates, and SCAD expression evaluation in model scope. This goes well beyond the raw schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The text is dense and information-rich with no fluff, but it is structured as a single run-on paragraph mixing mode definitions, inline type hints, and examples. Bullet points or mode-separated blocks would make parsing significantly easier.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core invocation paths, all mode semantics, expression evaluation, and edge-case behavior like UNRESOLVED and exit codes, while an output schema handles return-shape details. Still, several input parameters are left unexplained, so the agent may need to guess at their meaning.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It successfully explains mode values, the parts record structure, check_file contents, quality options, and volume behavior. However, many schema properties such as pairs, against, steps, tolerance_mm, response_format, and include_paths remain undocumented, leaving partial compensation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific purpose: checking relations between named parts in an assembly, and enumerates six distinct modes (interference, clearance, contact, alignment, motion, rules). It clearly distinguishes this from simple syntax validation, though it never explicitly contrasts with sibling tools like check_openscad.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear internal usage context: choose a mode such as 'interference' or 'clearance', supply parts or a check_file, and interpret exit codes. However, it does not explicitly say when to prefer this tool over siblings like check_openscad, scad_eval, or measure, so cross-tool selection guidance is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_openscadA

Verify OpenSCAD installation and return version info.

Args: include_paths: Include searched paths in response ctx: MCP context for logging

Returns: Dict with OpenSCAD installation information

ParametersJSON Schema
NameRequiredDescriptionDefault
include_pathsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description is the only source. It discloses the return type and the effect of include_paths, but does not explain what happens if OpenSCAD is not installed or any potential errors. The read-only nature is implied but not explicitly stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with its purpose. The Args/Returns format is structured and free of redundant information. Every sentence contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple tool with one optional parameter and an output schema, the description covers purpose, parameter semantics, and return type. Missing details about error behavior when OpenSCAD is absent, which would be relevant for a verification tool, but overall it is sufficient for basic invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It explains 'include_paths' as 'Include searched paths in response', adding meaningful semantic meaning beyond the boolean schema. This fully clarifies the parameter's effect.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states 'Verify OpenSCAD installation and return version info' with a specific verb and resource. This clearly distinguishes it from sibling tools focused on model/render operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance is given about when to use this tool or alternatives. It does not mention prerequisites, typical use cases, or when to avoid using it. The usage is only implied by the verb 'verify'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

clear_cacheA

Delete all cached render files and report freed space.

Removes every cached image and its dependency manifest from the configured cache directory. Does nothing (and still reports success) when the cache is disabled or the directory does not exist.

Args: ctx: MCP context for logging

Returns: Dict with success status, cleared_files count, and freed_bytes

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly discloses the edge-case behavior: 'Does nothing (and still reports success) when the cache is disabled or the directory does not exist.' It also explains the return value (Dict with success status, cleared_files count, and freed_bytes). It does not mention permission requirements or potential side effects, but for a cache-clearing operation, this is sufficient. The description goes beyond a simple 'clears cache' and gives non-obvious behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured: a one-line summary followed by a detailed explanation, and clearly labeled Args and Returns sections. It is concise with no fluff. The main purpose is front-loaded, and the edge-case note is placed early. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that there are no parameters and an output schema is present (as indicated by 'Has output schema: true'), the description is complete. It explains the exact behavior, including the no-op edge case, and states what the return value contains. There is nothing an agent needs to know to call it correctly that is missing. The description does not need to repeat return format details since an output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema is empty (0 parameters), so schema description coverage is 100% vacuously. The description mentions an 'Args: ctx: MCP context for logging', which is likely an internal argument, not a user-facing parameter. With no user parameters to explain, the description adds no additional parameter semantics but is not deficient. The baseline for 0 parameters is 4, and the description does not contradict or omit anything relevant.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action: 'Delete all cached render files and report freed space.' It specifies the resource (cached render files) and the exact scope ('every cached image and its dependency manifest'). It is distinct from all sibling tools, which handle checking, exporting, rendering, etc., with no ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly compare against alternative tools or state when to prefer this one. However, the purpose is so specific and self-contained that usage is implied by the name and description. It does not provide when-not-to-use guidance beyond noting behavior when cache is disabled, which is more behavioral than usage guidance. No explicit alternatives are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_modelA

Export OpenSCAD code or file to a mesh, 2D, or CSG format. With parts=[{name, code, place?}] every part is exported separately (in its assembly position) and bundled into one 3MF with named objects, or into a directory of STLs when output_format="stl"; a manifest is returned.

Mesh exports (stl, 3mf, amf, off, nef3) also return a "mesh_health" block from OpenSCAD's CGAL statistics: "manifold" is true, false, or null when OpenSCAD did not perform the check. A non-manifold result usually means parts touch along an edge or face; overlap them slightly.

Args: scad_content: OpenSCAD code to export (mutually exclusive with scad_file) scad_file: Path to OpenSCAD file (mutually exclusive with scad_content) output_format: "stl", "3mf", "amf", "off", "nef3" (3D), "dxf", "svg", "pdf" (2D), or "csg" (evaluated CSG tree). Default "stl". output_path: Path to write the exported file. If not specified, a temp directory is used. variables: Variables to pass to OpenSCAD via -D flags include_paths: Additional include paths for OpenSCAD via the OPENSCADPATH environment variable ctx: MCP context for logging

Returns: Dict with success status, output_path, format, file_size_bytes, mesh_health (mesh formats), warnings, errors, and hints

ParametersJSON Schema
NameRequiredDescriptionDefault
partsNo
qualityNo
scad_fileNo
variablesNo
output_pathNo
scad_contentNo
include_pathsNo
output_formatNostl

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and delivers rich behavioral detail. It discloses the return dict structure, temporary output_path behavior, parts bundling into 3MF or STLs, manifest return, and mesh_health semantics including the meaning of manifold true/false/null and the typical cause of non-manifold results. It even advises overlap adjustments, which agents can act on.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but appropriately so for an 8-parameter tool with no schema descriptions. It front-loads the core purpose and parts behavior, then adds mesh_health guidance, then systematically documents parameters. No sentence is filler, though the first paragraph could be tightened by moving parts details into the Args section.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no annotations, 0% schema coverage, and an output schema already present, the description is largely complete: it covers return values, error hints, format choices, and typical failure causes. The omission of the 'quality' parameter is the most notable gap, and it also does not mention prerequisites like OpenSCAD installation, though sibling check_openscad may cover that.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it largely does: it explains scad_content/scad_file mutual exclusivity, output_format values with default, output_path fallback, variables via -D, include_paths via OPENSCADPATH, and parts structure in the intro. The main gap is the 'quality' parameter, which is never described, and 'parts' is not restated in the Args block, leaving that schema field partially uncovered.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Export OpenSCAD code or file to a mesh, 2D, or CSG format.' It clearly names the output families and even details the parts-bundling behavior, which makes the tool's function unmistakable. This distinguishes it from siblings like render, measure, and validate, which focus on other stages of the pipeline.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives strong context about what the tool does and how it behaves, such as mutual exclusivity of scad_content and scad_file, and the parts export mode. However, it never explicitly contrasts this tool with sibling tools or says when to use export_model over alternatives like render or model. Usage is implied by the verb 'export' rather than stated as guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_librariesA

Discover installed OpenSCAD libraries on the system.

Searches standard OpenSCAD library paths for the current platform, plus the OPENSCADPATH environment variable. For each found library directory, lists subdirectories as libraries and reports file counts, README presence, and main entry files.

This is a read-only operation that does not require OpenSCAD to be installed.

Args: ctx: MCP context for logging

Returns: Dict with success status, library_paths searched, and libraries list with name, path, file_count, has_readme, and main_files for each library

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the read-only nature, that OpenSCAD is not required, that standard paths and OPENSCADPATH are searched, and that it lists subdirectories with file counts, README presence, and main entry files. This covers key behavioral traits without contradicting anything.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with a one-sentence summary. It uses paragraphs effectively and every sentence adds value. The Returns section is somewhat redundant given the output schema, but it does not bloat excessively.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple, read-only tool with a rich output schema. The description provides enough context about what paths are searched, what data is returned, and the read-only nature. It lacks edge-case details like error handling, but for this complexity level it is adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters, so the baseline is 4. The description adds that the only argument, ctx, is used for MCP logging, which is meaningful but minimal. No further parameter semantics are needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Discover installed OpenSCAD libraries on the system,' using a specific verb and resource. It clearly distinguishes this from sibling tools like check_openscad, rendering, and model management tools. The scope is further clarified by mentioning standard library paths and OPENSCADPATH.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool: to discover libraries on the system, including via OPENSCADPATH. It explicitly notes it is read-only and does not require OpenSCAD to be installed, which signals a low-risk discovery operation. However, it does not explicitly name alternatives or exclusions, so it falls short of full guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_project_filesA

mode="files": every .scad under project_dir with size/mtime and the include/use/import/surface references of each. mode="trace": the constant dependency graph for symbol= (lexical, file-scope constants only): its definition, what depends on it (direction="downstream") or what it depends on ("upstream"), by depth, and the part files that use them. project_dir must be inside allowed_paths when configured.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNofiles
symbolNo
directionNodownstream
project_dirYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses retrieval details (size, mtime, references, dependency graph) and constraints (allowed_paths). However, it does not explicitly state that this is a read-only operation or describe any side effects or rate limits. It is transparent about information returned but not fully explicit about behavior beyond queries.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single paragraph but packed with essential details in two sentences. It front-loads mode-specific behavior and constraints. While long, it is efficient and avoids redundancy, though a more structured layout (e.g., bullets) could improve scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (two modes, multiple parameters), the description covers key aspects: what is returned, depth, direction, and path constraints. Since an output schema exists, it doesn't need to detail return format. However, it lacks information on edge cases (e.g., empty projects, invalid symbol) and performance implications, leaving minor gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description is the sole source of parameter meaning. It thoroughly explains 'mode' with its two values, defines 'symbol' as the constant to trace, clarifies 'direction' as downstream/upstream, and explains 'project_dir' with the allowed_paths constraint. This adds substantial value beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: listing .scad files and tracing constant dependency graphs. It specifies the two modes (files, trace) and distinguishes the resource and actions. However, it is dense and might be better split, but it is unambiguous and distinct from siblings like get_libraries or check.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what the tool does and the modes, implying when to use it (for file listing or dependency tracing). It mentions the allowed_paths constraint but does not explicitly state when not to use it or compare with alternatives. It lacks a clear 'use this when' vs. sibling differentiation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

measureA

Exact numbers from a model's geometry (mm). Prefer this over judging a picture. parts=[{name, code, place?, material?, mass_g?}] names assembly parts; coordinates are then in the assembly frame. mode "model": bbox, volume, area, solid/cavity counts, watertight, mesh_health (2D: area/perimeter). "parts": per part plus assembly bbox. "section": cut contours at section_axis=section_offset (mm or an expression). "mass": grams for material/density; with parts= and about_axis=[[point],[dir]] the assembly mass, centre of mass and inertia about the axis (mass_g overrides purchased parts). "probe": points -> solid|air and which part, rays=[[ox,oy,oz,dx,dy,dz]] -> crossings, polyline -> line of sight and blocker. "features": holes from the CSG tree: axis, diameter, depth, undersize at $fn, fit names. "printability": overhang patches with unsupported reach, thickness vs nozzle, islands (layer_height_mm), support estimate; facts only. "orientation": candidate orientations, no winner. "anchors": BOSL2 anchors of part="module();". mesh=existing STL/SVG. quality: draft| normal|high or $fn. response_format: concise|detailed.

ParametersJSON Schema
NameRequiredDescriptionDefault
meshNo
modeNomodel
partNo
raysNo
partsNo
pointsNo
qualityNo
materialNo
polylineNo
nozzle_mmNo
scad_fileNo
variablesNo
about_axisNo
orientationNo
scad_contentNo
section_axisNoz
density_g_cm3No
include_pathsNo
section_offsetNo
layer_height_mmNo
response_formatNoconcise

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so thoroughly: it discloses units, coordinate frames, override semantics ('mass_g overrides purchased parts'), and output caveats ('facts only', 'no winner'). This gives an agent an accurate model of behavior beyond the bare tool name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and every clause adds information, with the core purpose front-loaded before the mode catalogue. It is concise for the amount of behavior covered, though a single wall of text with no line breaks or bullets makes it harder to scan than it could be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 21-parameter tool with no annotations and no schema descriptions, this is a strong effort: it covers units, modes, source mesh, and response formats. It is not fully complete because the model-source parameters (scad_file, scad_content, variables, include_paths) are never explained, which an agent would need to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate; it explains the meaning of most parameters (parts, mode, section_axis/offset, about_axis, points, rays, polyline, quality, response_format). However, several schema parameters are left unexplained, including scad_file, scad_content, variables, include_paths, and orientation, so the compensation is not complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line 'Exact numbers from a model's geometry (mm)' states the tool's function with a specific resource and unit, and the mode list (model, parts, section, mass, probe, etc.) defines its scope precisely. This clearly separates measurement from visual or export tools like render or export_model.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Prefer this over judging a picture' explicitly tells an agent when to choose this tool, and the mode descriptions give direct selection criteria (e.g., use 'mass' for grams, 'section' for cut contours). It does not name sibling alternatives or state exclusions, but the contextual guidance is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

modelA

Manage .scad files in a workspace: action = "create" | "get" | "update" | "list" | "delete". name is the file name (".scad" added); content is the source for create/update. Every response carries an "etag" (content hash) so a later update can be checked against the version last read. template="part:" with action="create" writes a purchased-part module from the parts catalog (see reference(topic="parts")) instead of content. workspace defaults to the server temp models directory; when allowed_paths is configured the workspace must lie inside it.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNo
actionYes
contentNo
templateNo
workspaceNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full disclosure burden. It does this well by revealing the etag/content-hash workflow, automatic '.scad' suffixing, template branching, and workspace path restrictions. It does not detail overwrite or delete side effects, but the key behavioral traits are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four dense sentences with no filler. The action list is front-loaded, and every subsequent clause adds a distinct behavioral fact: file suffix, etag, template mode, and workspace restrictions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a multi-action CRUD tool with no annotations, this is quite complete: it covers parameter semantics, the etag workflow, speculative template usage, and security constraints. It leaves per-action parameter requirements slightly implicit (e.g., which parameters delete or list need), but the output schema and clear prose keep the gap minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must explain all parameters in prose. It does: action is enumerated, name includes the '.scad' suffix rule, content is the source for create/update, template defines catalog-part creation and precedence over content, and workspace covers defaults and allowed_paths. Every parameter is given meaningful semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Manage .scad files in a workspace,' then enumerates the full action set: create, get, update, list, delete. This clearly differentiates it from sibling tools like render, measure, and export_model, which do entirely different things.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides concrete usage context: it explains the template alternative for catalog parts, the default workspace behavior, and the allowed_paths restriction. It does not explicitly name sibling alternatives or state when not to use this tool, but the context is clear enough for correct selection in most cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

referenceA

Sourced engineering data for 3D-printed parts, each entry with a confidence label (standard / consensus / calibrate). topics: fits (clearances per side and diametral, $slop), fasteners (metric screws, clearance and tap holes), inserts (heat-set), bearings, magnets, joints (dovetail, snap, press, hinge; BOSL2 module names), parts (purchased-part catalog: envelope, mount pattern, shaft, mass, a BOSL2 module with named anchors and a clearance mask; write it with model(action=create, template="part:")), conventions, cheatsheet, dfm (FDM design rules), materials. query filters entries. topic="fits" with diameter_mm=3.3 names what that hole is (top 3 with deltas); with shaft_mm and bore_mm it names the fit class.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryNo
topicNoconventions
bore_mmNo
detailedNo
shaft_mmNo
diameter_mmNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; it discloses confidence labels, filtering semantics, top-3 result behavior, and cross-tool guidance for writing part models. It does not state read-only or discuss auth/rate limits, but as a reference tool the disclosed behavior is sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The content is dense and informative but presented as one run-on paragraph without bullet structure; topics are packed into parentheses and examples are tacked on at the end. It is not poorly worded, but it could be much clearer with front-loaded formatting.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a lookup tool with an output schema, the description covers a large number of topics, gives parameter examples, and provides cross-tool instructions. The main gap is the undocumented 'detailed' parameter and lack of explicit exclusion guidance, but overall the agent has enough to operate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds meaning for topic, diameter_mm, shaft_mm, and bore_mm through examples, and for query by saying it filters entries. However, at 0% schema coverage, it still fails to explain the 'detailed' parameter and leaves query syntax largely implicit.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the tool as a source of engineering reference data for 3D-printed parts, lists its topic coverage, and explains the query/topic behavior. It lacks an explicit verb like 'query' or 'lookup' and does not contrast with siblings, but the purpose is clear from the content and examples.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides concrete usage cues, e.g. topic='fits' with diameter_mm names a hole and shaft_mm/bore_mm determines a fit class. It does not explicitly name alternatives or mention when not to use the tool, but the examples and topic list give clear conditions for use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

renderB

Images of a model, each preceded by a text digest (view direction, camera, scale, bbox) and followed by metadata with errors/warnings/ hints. Check those: OpenSCAD draws a blank scene and exits 0 on a failed assert or unknown module. mode "views": one image per view (default ["isometric"]; front back left right top bottom isometric dimetric) or a custom camera_position. "section": exact cut at section_axis=section_offset (mm, or an expression in the model's scope). "parts": parts=[{name, code, place?, color?, ghost?, explode?}] in stable colours; isolate=name ghosts the rest. "compare": before/after via variables_after or scad_content_after. grounded=true gives an orthographic view with an exact mm/px scale; annotate=true adds scale bar, axis triad and bbox size; look_at=part | [x,y,z] | {min,max} frames that box; callouts=[{label, at}] label points. Auto-fit views have no absolute scale. quality: draft|normal| high. image_size default 800x600 (~640 tokens per image).

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNoviews
partsNo
viewsNo
isolateNo
look_atNo
qualityNo
annotateNo
calloutsNo
groundedNo
camera_upNo
scad_fileNo
variablesNo
image_sizeNo
color_schemeNoCornfield
scad_contentNo
section_axisNoz
camera_targetNo
include_pathsNo
section_offsetNo
camera_positionNo
variables_afterNo
scad_content_afterNo

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It openly conveys that output includes a text digest and metadata, that OpenSCAD draws a blank scene and exits 0 on failed asserts/unknown modules, that auto-fit views have no absolute scale, and that image_size impacts token usage. These are meaningful behavioral traits beyond simple function, though it does not explicitly state read-only status or rate limits, so a 4 fits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence in the description contributes substantive information—there is no fluff. However, it is one long dense paragraph with no bullet points, headers, or separation of modes, which makes it harder to parse. For a tool with 22 parameters, structured formatting would help, so it earns a 3.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (22 parameters, no output schema, no annotations), the description covers a large amount of core behavior: output structure, error caveats, all main modes, and many parameters. But it leaves out several parameters and does not explain the full relationship between inputs (e.g., scad_file vs scad_content, variables) or any return format details beyond the textual metadata. It is sufficient for basic use but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does add meaning to many parameters: views defaults and choices, section expression syntax, parts structure, compare mechanism via variables_after/scad_content_after, grounded scale, annotate contents, look_at forms, callouts, quality values, and image_size token estimate. However, it omits several parameters such as camera_up, include_paths, color_scheme, and camera_target, leaving them to inference, so a 4 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the tool produces images of a model with a text digest and metadata, and enumerates the main modes (views, section, parts, compare). It is specific about the resource and output format, but it does not explicitly mention how it differs from siblings like export_model or model, so it loses a point for lacking sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives within-tool guidance on when to use different modes and parameters (e.g., grounded=true for orthographic views, compare for before/after), but it never addresses when to choose render versus an alternative sibling tool. There is no mention of alternatives or exclusions, so cross-tool usage guidance is absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scad_evalA

Evaluate OpenSCAD expressions and return typed values (number, vector, string, bool, range, undef). With scad_content/scad_file the expressions run in that model's variable and function scope, so "wall*2 + clearance" or "len(hole_positions)" work; without a model they run standalone. Numbers carry OpenSCAD's 6 significant digits. No geometry is evaluated.

ParametersJSON Schema
NameRequiredDescriptionDefault
scad_fileNo
variablesNo
expressionsYes
scad_contentNo
include_pathsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses numeric precision (6 significant digits), scope behavior, and the boundary 'No geometry is evaluated.' It does not explicitly state whether the tool is side-effect-free or mention error handling, but it covers key execution behaviors.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences with no filler. The core purpose leads, followed by scope context, a precision note, and a boundary statement. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with five parameters and no annotations, the description does not fully document the roles of variables and include_paths, nor does it mention error behavior or security implications. The output schema covers return types, but the input-side gaps make it only adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description should compensate for all parameters. It explains the role of scad_content/scad_file and implies expressions, but says nothing about variables (how they map into expressions) or include_paths (what they resolve). This leaves two of five parameters semantically underdocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Evaluate OpenSCAD expressions and return typed values' – a specific verb and resource with a clear list of result types. It also explicitly states 'No geometry is evaluated,' which differentiates it from sibling tools like render and measure.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains when to pass scad_content/scad_file versus running standalone, which is useful context. However, it does not name alternative tools or explicitly state when not to use this tool, leaving the agent to infer exclusion from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validateA

Check a model. "valid" is false whenever an ERROR was reported, whatever OpenSCAD's exit code was. mode: "syntax": parse and evaluate without geometry (fast): errors, warnings, echo_output, hints, unresolved_includes with locations. "geometry": export the mesh and report findings: not watertight, non-manifold, several solids, cavities, empty; with the numbers. "predicates": predicates=["W > 10", ...] evaluated in the model's own scope; each must be true. sweep={variable, values:[..]} re-runs them per value and reports the first failure and the crossing. "includes": every include/use/import/surface reference with its resolved path, plus the BOSL2 lint: a module from a use<>d file placed by attach()/position() is silently put at CENTER; findings carry a fix plan, applied to the file when autofix=true and safe. "printability": rules from reference(topic=dfm) over measure(mode=printability) facts in orientation=; profile= {overhang_deg, nozzle_mm, max_unsupported_reach_mm, min_wall_mm} overrides thresholds. Findings carry magnitude and location.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNosyntax
sweepNo
autofixNo
profileNo
scad_fileNo
variablesNo
predicatesNo
orientationNo
scad_contentNo
include_pathsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses important behavioral details beyond the schema: 'valid' is false whenever an ERROR was reported regardless of OpenSCAD exit code; syntax mode returns errors/warnings/echo_output/hints/unresolved_includes with locations; geometry mode reports specific mesh findings with numbers; predicates mode re-runs per sweep value and reports first failure and crossing; includes mode includes a BOSL2 lint with autofix behavior. This is substantial behavioral context, though it does not cover all edge cases (e.g., exact output shape, error handling for invalid mode values).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and structured as a mode-by-mode list, which is appropriate for a multi-mode tool. It front-loads the core behavior ('valid' is false on ERROR) and then each mode gets a compact explanation. It is longer than a typical description, but the complexity of the tool justifies the length; every sentence adds information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the main modes, their outputs, and key parameters, and an output schema exists to define return values. It does not explicitly state prerequisites (e.g., whether scad_file or scad_content is required), nor does it detail all parameter interactions (e.g., how variables interact with predicates). However, for a tool with 10 optional parameters and an output schema, the description is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden of explaining parameters. It explains mode values, sweep, predicates, autofix, profile, orientation, and measure(mode=printability) facts. It does not explicitly explain scad_file, scad_content, variables, or include_paths, but the mode descriptions imply their roles (e.g., includes mode resolves include/use/import/surface references). Given 10 parameters and 0% schema coverage, the description compensates well but not completely.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear verb-resource pair ('Check a model') and then enumerates five distinct modes (syntax, geometry, predicates, includes, printability), each with a specific purpose. This distinguishes validate from siblings like check_openscad, scad_eval, export_model, and measure by showing it is a multi-mode model checker.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what each mode does and when it would be relevant (e.g., 'syntax' for fast parse/geometry-free checks, 'geometry' for mesh export findings, 'printability' for DFM rules). It does not explicitly name sibling tools as alternatives or state when not to use validate, but the mode breakdown gives clear context for selecting the right mode.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 19 tool updatesv0.6.1
    • Removedanalyze_model
    • Addedcheck
    • Removedcompare_renders
    • Removedcreate_model
    • Removeddelete_model
    • Changedexport_model2 fields changed
      • addedInput schema / properties / parts
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / quality
        Added value: +{
        +  "default": null,
        +  "title": "Quality"
        +}
    • Removedget_model
    • Changedget_project_files3 fields changed
      • addedInput schema / properties / direction
        Added value: +{
        +  "default": "downstream",
        +  "type": "string"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "default": "files",
        +  "type": "string"
        +}
      • addedInput schema / properties / symbol
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
    • Removedlist_models
    • Addedmeasure
    • Addedmodel
    • Addedreference
    • Addedrender
    • Removedrender_perspectives
    • Removedrender_single
    • Addedscad_eval
    • Removedupdate_model
    • Addedvalidate
    • Removedvalidate_scad
  2. 15 tool updatesv0.3.0
    • Addedanalyze_model
    • Changedcheck_openscad1 field changed
      • removedInput schema / properties / include_paths / title
        Removed value: -"Include Paths"
    • Addedclear_cache
    • Addedcompare_renders
    • Addedcreate_model
    • Addeddelete_model
    • Addedexport_model
    • Addedget_libraries
    • Addedget_model
    • Addedget_project_files
    • Addedlist_models
    • Addedrender_perspectives
    • Changedrender_single14 fields changed
      • removedInput schema / properties / auto_center / title
        Removed value: -"Auto Center"
      • removedInput schema / properties / camera_position / title
        Removed value: -"Camera Position"
      • removedInput schema / properties / camera_target / title
        Removed value: -"Camera Target"
      • removedInput schema / properties / camera_up / title
        Removed value: -"Camera Up"
      • removedInput schema / properties / color_scheme / title
        Removed value: -"Color Scheme"
      • removedInput schema / properties / image_size / title
        Removed value: -"Image Size"
      • addedInput schema / properties / include_paths
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • removedInput schema / properties / output_format
        Removed value: -{
        -  "anyOf": [
        -    {
        -      "type": "string"
        -    },
        -    {
        -      "type": "null"
        -    }
        -  ],
        -  "default": "auto",
        -  "title": "Output Format"
        -}
      • addedInput schema / properties / quality
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • removedInput schema / properties / scad_content / title
        Removed value: -"Scad Content"
      • removedInput schema / properties / scad_file / title
        Removed value: -"Scad File"
      • removedInput schema / properties / variables / title
        Removed value: -"Variables"
      • removedInput schema / properties / view / title
        Removed value: -"View"
      • changedOutput schema / (root)
        Previous value: -{
        -  "additionalProperties": true,
        -  "type": "object"
        -}New value: +null
    • Addedupdate_model
    • Addedvalidate_scad
  3. 2 tool updates
    • First observedcheck_openscad
    • First observedrender_single

TDQS

A3.9/5.0

Scored across 12 tools

Disambiguation4/5

Each tool targets a clearly different concern: environment checks, library discovery, expression evaluation, export, rendering, measurement, validation, assembly analysis, and reference data. Some minor overlap exists between measure's watertight/mesh_health output and validate's geometry checks, and between model action=list and get_project_files, but the descriptions make the intended use distinguishable.

Naming Consistency3/5

The naming convention is mixed: several tools use verb_noun forms like export_model and get_project_files, while render, measure, validate, and check are bare verbs, and model and reference are nouns. The names are still readable and mostly predictable, but there is no single consistent naming convention across the set.

Tool Count5/5

Twelve tools is well within the ideal range for a specialized CAD server, and each tool covers a substantial portion of the OpenSCAD workflow without feeling redundant. The count feels deliberate rather than bloated or sparse.

Completeness5/5

The tool surface covers the full lifecycle: model file management, project analysis, expression evaluation, rendering, export, measurement, validation, assembly relation checks, reference data lookup, and cache maintenance. No obvious dead ends remain for modeling, analyzing, or verifying designs.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers