sketchup-mcp2
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| SKETCHUP_MCP_HOST | No | The host address for the SketchUp MCP TCP server. | 127.0.0.1 |
| SKETCHUP_MCP_PORT | No | The port for the SketchUp MCP TCP server. | 9876 |
| SKETCHUP_MCP_TIMEOUT | No | Timeout in seconds for MCP operations. | 60 |
| SKETCHUP_MCP_LOG_LEVEL | No | Log level for the MCP server (e.g., DEBUG, INFO, WARNING, ERROR). | INFO |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| create_componentA | Create a primitive (cube / cylinder / cone / sphere) in SketchUp. All linear values are millimeters (mm). Minimum size per dimension: 0.1 mm for cube (thin stock like veneer is fine), 1.0 mm for sphere / cylinder / cone (tessellated types degenerate earlier). position is the bounding-box MIN corner (not the center); the same anchor is used by transform_component.position. Per-type dimensions: cube uses [x, y, z]; cylinder and cone use [0]=diameter, [2]=height ([1] is ignored); sphere uses [0]=diameter only. New geometry is wrapped in a SketchUp Group. Returns: JSON {id, name, type, bbox_mm{min,max}|null}. Read bbox_mm to verify the result before the next step. |
| delete_componentB | Delete a group or component by entity ID. Returns: JSON {ok: true}. |
| transform_componentA | Move, rotate and/or scale a group or component (mm / degrees).
These validations (3-element lists, non-zero scale) apply only to this typed tool — raw Ruby driven through eval_ruby bypasses them. Returns: JSON {id, name, type, bbox_mm{min,max}|null}. Read bbox_mm to verify the result; it is null for empty geometry. |
| get_selectionA | Get the entities currently selected in the SketchUp UI. Returns: JSON {entities: [...]} — groups/components are {id, name, type, layer, depth, bbox_mm|null}; other selected entities (edges, faces, ...) are {id, type} only. |
| set_materialA | Assign a material (color) to a group or component. material accepts a named color — red, green, blue, yellow, cyan, turquoise, magenta, purple, white, black, brown, wood, orange, gray, grey — or a 6-digit hex string like "#a05030" (#rrggbb). Anything else fails with error -32602. Named colors are case-insensitive. Painting affects only this instance (it is made unique first). That applies to groups/components; painting a raw face/edge id (obtainable via get_selection) colors the shared definition — all instances show it. Returns: JSON {id, name, type, bbox_mm{min,max}|null}. |
| export_sceneA | Export the current scene to a temp file on the SketchUp host. Formats: skp (native), obj / dae / stl (geometry), png / jpg (viewport render, default 1920×1080). The file is written on the machine running SketchUp — on a split-host setup the path is not directly readable here. Returns: JSON {path, format} plus a "warning" field when exporting skp from a never-saved model (SketchUp binds the live document to the export path — relay the warning to the user). |
| create_mortise_tenonA | Create a mortise-and-tenon joint between two boards. All dimensions in millimeters; offsets shift the joint from the board face's center. Defaults are sized for ~100 mm boards. The two boards must already touch/overlap along the joint axis. Returns: JSON {mortise: {id, name, type, bbox_mm|null}, tenon: {...}, boolean_cuts: {attempted, failed}} — non-zero failed means some cuts did not apply (likely non-manifold geometry); verify via bbox_mm. |
| create_dovetailA | Create a dovetail joint between two boards. All dimensions in millimeters; angle is in degrees, valid range (0, 60]. Offsets shift the joint from the board face's center. Defaults are sized for ~100 mm boards. The two boards must already touch/overlap along the joint axis. Returns: JSON {tail: {id, name, type, bbox_mm|null}, pin: {...}, boolean_cuts: {attempted, failed}} — non-zero failed means some cuts did not apply (likely non-manifold geometry); verify via bbox_mm. |
| create_finger_jointA | Create a finger joint (box joint) between two boards. All dimensions in millimeters; offsets shift the joint from the board face's center. Defaults are sized for ~100 mm boards. The two boards must already touch/overlap along the joint axis. Returns: JSON {board1: {id, name, type, bbox_mm|null}, board2: {...}, boolean_cuts: {attempted, failed}} — non-zero failed means some cuts did not apply (likely non-manifold geometry); verify via bbox_mm. |
| eval_rubyA | Evaluate arbitrary Ruby code in SketchUp. Enabled by default; the user can close the gate in the SketchUp
extension's Settings. When closed, the SketchUp side returns JSON-RPC
code -32010 with a user-facing message explaining how to re-enable it.
This wrapper surfaces that message as a plain string so the LLM can
repeat it to the user verbatim — without the Returns the .to_s of the LAST evaluated expression; stdout (puts) is NOT
captured. End scripts with an explicit expression — e.g. a final
|
| boolean_operationA | Perform a boolean operation (union / difference / intersection) on two solids. difference = target minus tool. Operating on an instance of a shared definition consumes only that instance — the result is a new group, sibling instances are untouched. Unreliable on non-manifold geometry. Returns: JSON {id, name, type, bbox_mm{min,max}|null}. Read bbox_mm to verify the result; it is null for empty geometry (e.g. a difference that consumed the whole body). |
| chamfer_edgeA | Chamfer (bevel) edges of a group/component by By default ALL edges are chamfered. Unreliable on non-manifold geometry. Returns: JSON {id, name, type, bbox_mm|null, edges_chamfered, stats{attempted, skipped_no_match, subtract_failed, succeeded}} — check stats.subtract_failed == 0 (failed cuts) and stats.skipped_no_match == 0 (edges consumed by earlier cuts). |
| fillet_edgeA | Round (fillet) edges of a group/component by By default ALL edges are filleted. Unreliable on non-manifold geometry. Returns: JSON {id, name, type, bbox_mm|null, edges_filleted, stats{attempted, skipped_no_match, subtract_failed, succeeded}} — check stats.subtract_failed == 0 (failed cuts) and stats.skipped_no_match == 0 (edges consumed by earlier cuts). |
| get_viewport_screenshotA | Capture the current SketchUp viewport; returns the PNG image plus a JSON text block {width, height, preset_used, style_used}. Useful for letting Claude visually verify the scene between steps. Parameters
If the connection drops mid-response the call is retried automatically; the viewport may briefly flicker in that rare case. |
| get_model_infoA | Get current SketchUp model info: file path, title, units, bounding box, entity count, layer list. Returns: JSON {path, title, units: "mm", bounding_box_mm|null, entity_count, layers[]}. |
| list_componentsA | List groups and component instances in the model (paginated). Each component is {id, name, type, layer, depth, bbox_mm} (detailed) or {id, name, type, layer, depth} (concise); bounds are world-coordinate mm. Set recursive=true to descend into nested components (bounded by max_depth, default 3). Returns: JSON {components[], total, offset, truncated} — if truncated, request the next page with offset += limit. |
| get_component_infoA | Detailed info for a single group or component instance by entity ID. Returns: JSON {id, name, type, layer, depth, bbox_mm|null}. |
| find_componentsA | Find components matching name substring, layer, and/or type. Name matching is case-insensitive substring; layer must match exactly. Searches recursively (bounded by max_depth). With no filters it returns all components up to max_depth (paginated) — same traversal as list_components. Returns: JSON {components[], total, offset, truncated} — if truncated, request the next page with offset += limit. |
| list_layersA | List all model layers (tags). Returns: JSON {layers: [{name, visible, color, id}]}. |
| create_layerA | Create a new layer (tag) with the given name. Returns: JSON {id, name, visible}. |
| undoA | Undo the last atomic operation in SketchUp. One MCP tool-call = one undo step. Returns: JSON {ok: true}. |
| get_versionA | Return the server version and Python↔Ruby compatibility verdict. Useful as a runtime sanity probe — always returns a payload, even when the connection or other tools surface errors. The result is a JSON string with fields: python_version, ruby_version, min_compatible_ruby, max_compatible_ruby, ruby_min_compatible_python, ruby_max_compatible_python, compatible (bool), error (string | null). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| sketchup_modeling_strategy | How to use SketchUp MCP tools effectively: pre-flight checks, typed-tools-vs-eval_ruby priority, units/angles conventions, verification after mutations, error recovery, known traps. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 22 tools
Most tools are clearly distinct (create_component vs transform_component vs delete_component; list_components vs get_component_info vs find_components). The three joint tools (create_mortise_tenon, create_dovetail, create_finger_joint) are similar in purpose but each targets a different joint type, so they are distinguishable. Some overlap exists between list_components and find_components with no filters, but descriptions clarify the difference.
The naming pattern is mostly consistent verb_noun: create_*, list_*, get_*, delete_*, transform_*, set_*, export_*, eval_*, boolean_operation, chamfer_edge, fillet_edge. Minor deviations: boolean_operation, chamfer_edge, and fillet_edge use noun_verb or bare noun forms instead of verb_noun, but the pattern is still readable and predictable.
22 tools is on the higher end but appropriate for a SketchUp MCP server covering modeling primitives, transformations, joints, booleans, edge operations, materials, layers, selection, scene export, and introspection. It is slightly heavy but each tool serves a distinct purpose in the 3D modeling workflow.
The tool surface covers core modeling operations: create, transform, delete, boolean ops, edge modifications, materials, layers, selection, and model info. Minor gaps include no explicit update/rename tool for components (though eval_ruby can cover it) and no direct tool for creating edges/faces from scratch beyond primitives, but the eval_ruby escape hatch fills many gaps.