Skip to main content
Glama

sketchup-mcp-bridge

A robust Model Context Protocol (MCP) server that lets an AI client (e.g. Claude Code) drive SketchUp Pro 2026 on a Windows host — including from WSL.

Verified working on SketchUp engine 26.1.256. MIT license.


Why This Exists

The most popular existing tool (mhyrr/sketchup-mcp) has two failure modes this project fixes by design:

  1. Persistent-socket desync — the original client held one socket open and sent a ping without reading its reply. SketchUp responded "Method not found", which was then mis-read as the response to the next command, so every other call failed with "Communication error with Sketchup: Method not found". Fix: connect-per-command — a fresh TCP connection is opened for each MCP tool call and closed immediately after the response.

  2. Write-hang — the original Ruby server mutated the model inside the timer loop. A mutation that raised inside an open start_operation left a dangling transaction and hung the entire server (subsequent writes timed out). Fix: every eval is wrapped in start_operation / commit_operation with a guaranteed abort_operation on error; the timer loop is "immortal" — no exception can escape it.

Also note: install from source / git, not a stale PyPI build. Some published builds crash with FastMCP.__init__() got an unexpected keyword argument 'description'; this repo uses instructions= (the current FastMCP API).


Related MCP server: SketchUp MCP Server

Architecture

Claude Code (WSL / any host)
        │  MCP stdio transport
        ▼
 Python MCP server  (FastMCP, run via uvx)
        │  TCP connect-per-command  →  127.0.0.1:9876
        ▼
 Ruby TCP server  (UI.start_timer loop inside SketchUp)
        │
        ▼
  SketchUp Pro 2026 model

Two components:

  • Ruby extension — runs a TCP server on 127.0.0.1:9876 inside SketchUp. Built around a UI.start_timer accept loop on the main thread so Ruby API calls are safe. One request per connection.

  • Python MCP server — a FastMCP server (uvx-installable) that acts as a connect-per-command TCP client; each tool call opens, uses, and closes one TCP connection.


Wire Protocol

Each exchange is a single JSON line terminated by \n.

Request:

{"id": 1, "cmd": "eval", "args": {"code": "Sketchup.version"}}

Success response:

{"id": 1, "ok": true, "result": "26.1.256"}

Error response:

{"id": 1, "ok": false, "error": "NameError: undefined local variable ..."}

The Ruby server closes the socket after writing the response. The Python client opens a fresh connection for every command. This is deliberate — it eliminates all desync issues.


Tools

Tool

Arguments

Description

eval_ruby

code: str

Execute arbitrary Ruby in the active model; returns result.to_s

get_scene_info

Model title, entity count, active length unit, model bounds, selection size

get_selection

Selected entities — entityID, typename, bounding box

screenshot

Renders the current view to a PNG on the host and returns it as an image


Installation

1. SketchUp Extension (.rbz)

Get the extension — either download the prebuilt .rbz (easiest):

https://github.com/Shattenjagger/sketchup-mcp-bridge/releases/latest/download/su_mcp_bridge.rbz

This asset is rebuilt automatically on every push to master.

…or build it from source:

python3 scripts/build_rbz.py
# → dist/su_mcp_bridge.rbz  (plain zip, no `zip` binary required)

Install in SketchUp:

  1. Window → Extension Manager → Install Extension

  2. Select dist/su_mcp_bridge.rbz

  3. Accept the unsigned-extension prompt

  4. Restart SketchUp

Start the server each session:

Extensions → SketchUp MCP Bridge → Start Server

The Ruby Console will print:

[SUMCPBridge] listening on 127.0.0.1:9876

There is no autostart — you need to start the server at the beginning of each SketchUp session.


2. Python MCP Server (via uvx)

Register with Claude Code (user scope):

claude mcp add sketchup --scope user -- \
  uvx --from git+https://github.com/Shattenjagger/sketchup-mcp-bridge \
  sketchup-mcp-bridge --port 9876

For a local checkout, substitute --from /path/to/local/clone.

Then restart Claude Code so it picks up the new MCP tools.

Configuration flags and environment variables:

Flag

Env var

Default

Description

--host

SKETCHUP_MCP_HOST

localhost

Host where SketchUp is running

--port

SKETCHUP_MCP_PORT

9876

TCP port the Ruby server listens on

--screenshot-dir

SKETCHUP_MCP_SCREENSHOT_DIR

none (required for screenshot)

WSL path to a host-side temp dir (e.g. /mnt/c/Users/<you>/AppData/Local/Temp); screenshot raises an error if unset


WSL + Windows Networking

If Claude Code runs in WSL and SketchUp on the Windows host, the Ruby extension binds 127.0.0.1 on the host — which is not reachable from WSL under default NAT networking.

Enable mirrored networking (requires Windows 11 22H2+):

Add the following to C:\Users\<you>\.wslconfig:

[wsl2]
networkingMode=mirrored

Then shut down WSL and reopen it:

wsl --shutdown

After that, the host's localhost:9876 is reachable from WSL without any port forwarding.

Screenshot directory: there is no default. You must set --screenshot-dir (or SKETCHUP_MCP_SCREENSHOT_DIR) to a WSL path that maps to a Windows temp directory, for example:

--screenshot-dir /mnt/c/Users/<you>/AppData/Local/Temp

(or any WSL-visible directory on the Windows host). The screenshot tool raises a clear error if this is not configured.


Security

eval_ruby executes arbitrary Ruby in your SketchUp process with full SketchUp API access — there is no sandbox. The Ruby server binds loopback only (127.0.0.1) and is intended as a local, single-user developer tool on your own machine.

Do not expose port 9876 to a network. Do not use this in a shared or multi-user environment.


Development

Python environment is managed with uv.

# Run tests
uv run pytest          # 14 tests

# Rebuild the extension after Ruby changes
python3 scripts/build_rbz.py
# Then reinstall dist/su_mcp_bridge.rbz in SketchUp and restart SketchUp

License

MIT — see LICENSE.

Available Tools

4 tools
eval_rubyA

Execute arbitrary Ruby in the active SketchUp model and return result.to_s.

ParametersJSON Schema
NameRequiredDescriptionDefault
codeYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/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 safety burden. It usefully discloses that it runs in the active model context and that the result is stringified via to_s, but it never warns that arbitrary Ruby can mutate or destroy the model, nor mentions error handling or sandboxing.

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?

A single front-loaded sentence with no filler; every clause earns its place by naming the language, the execution context, and the return format.

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?

The output schema covers return values, so the description needn't explain them. However, for an unannotated arbitrary-code-execution tool sitting beside read-only siblings, the omission of side-effect and permission context leaves a meaningful gap.

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 schema only gives a bare 'Code' string parameter. The description partially compensates by specifying the language (Ruby) and the eval return convention (result.to_s), but adds no detail on multi-line input, evaluation scope, or error behavior.

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 a specific verb (Execute) and resource (arbitrary Ruby in the active SketchUp model), and clarifies the return handling (result.to_s). It is trivially distinguishable from the read-only siblings get_scene_info, get_selection, and screenshot.

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?

There is no explicit guidance on when to use this tool versus the sibling inspection tools, nor any exclusions or preconditions. Usage is only implied by the tool's nature, so an agent gets no routing help.

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

get_scene_infoB

Return model title, entity count, active units, bounds, and selection size.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. 'Return' implies a safe read, but there is no disclosure of cost, state requirements, or whether the model must be loaded. Beyond the implied read-only nature, nothing behavioral is added that the output schema doesn't already cover.

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?

A single front-loaded sentence with zero waste that immediately tells the agent what comes back.

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?

An output schema exists, so the description needn't restate return values — and in fact it mostly duplicates them. For a simple zero-parameter read tool this is adequate, but the absence of any usage context against three siblings leaves a gap.

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 tool takes zero parameters, so the baseline of 4 applies; there is no parameter semantics to compensate for and the schema is trivially complete.

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?

Specific verb 'Return' plus an enumerated list of what the scene info contains (title, entity count, active units, bounds, selection size). The field list distinguishes it from siblings like get_selection, though the overlap with 'selection size' isn't explicitly called out.

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 indication of when to call this versus eval_ruby, get_selection, or screenshot. The description states only what is returned, leaving the agent to infer that this is the general scene-inspection entry point.

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

get_selectionA

Return the currently selected entities (entityID, typename, bbox).

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description has to carry the behavioral burden. "Return" implies a read-only, side-effect-free operation, which is useful, but nothing is said about what happens when nothing is selected, whether the result is empty or an error, or what coordinate space/units bbox uses. Partial behavioral coverage only.

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?

A single front-loaded sentence with no filler; the operation and its return contents are conveyed immediately with zero wasted words.

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?

An output schema exists, so the description need not enumerate return values in depth, and for a zero-parameter read tool this is nearly sufficient. The only real gap is the undefined empty/no-selection behavior, which slightly under-specifies an otherwise simple tool.

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 tool takes zero parameters, so per the rubric the baseline is 4. There is nothing for the description to disambiguate, and the field names it lists belong to the return value rather than to inputs.

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?

"Return the currently selected entities" states a specific verb (return) and resource (current selection), with the returned fields (entityID, typename, bbox) named inline. The sibling tools (eval_ruby, get_scene_info, screenshot) are so different that no explicit differentiation is needed, though the description never actually mentions them.

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?

There is no statement of when to use this tool versus alternatives, nor any prerequisite or state condition (e.g. "requires an active selection"). The read-a-selection use case is only implied by the word "selected"; an agent gets no explicit routing guidance.

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

screenshotA

Capture the current SketchUp view and return it as an image.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. 'Current view' implies a non-mutating read and 'return it as an image' discloses the response type, but nothing is said about image format/encoding, resolution, or any side effects. Adequate but thin for a zero-annotation tool.

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?

A single front-loaded sentence with zero waste; the verb and output type lead.

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?

With no output schema and no annotations, the description does mention that an image is returned, which is useful. However, it omits format/encoding details an agent may need to consume the result, leaving a modest gap.

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 tool takes zero parameters, so the baseline is 4. The description correctly implies no configuration is required and adds nothing misleading about inputs.

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?

States a specific verb ('Capture') and resource ('the current SketchUp view') plus the return form ('as an image'). It is clearly distinguishable from siblings like get_scene_info and get_selection, though it never names them.

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?

Usage is implied: capture a visual of the viewport when you need to see it. There is no explicit when-to-use or when-not guidance, and no alternatives are named (e.g., preferring get_scene_info for structured data).

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. 4 tool updatesv0.1.0
    • First observedeval_ruby
    • First observedget_scene_info
    • First observedget_selection
    • First observedscreenshot

TDQS

A3.7/5.0

Scored across 4 tools

Disambiguation5/5

Each tool serves a clearly distinct purpose: eval_ruby executes arbitrary code, get_scene_info returns model metadata, get_selection returns selected entities, and screenshot captures the viewport. There is no overlap or ambiguity in when to use each tool.

Naming Consistency4/5

Three tools use a verb_noun pattern (eval_ruby, get_scene_info, get_selection), but 'screenshot' is a single noun-verb hybrid that breaks the pattern slightly. The set is still mostly predictable and readable.

Tool Count5/5

Four tools is a lean, well-scoped set for a bridge server. Each tool earns its place: one general execution tool plus three focused observation helpers.

Completeness4/5

The eval_ruby escape hatch allows arbitrary model modifications, so most SketchUp operations are reachable. However, the lack of structured write/update/delete tools for specific entity types means agents must rely on raw Ruby rather than dedicated operations.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables direct interaction and control of SketchUp through Claude AI using the Model Context Protocol and a TCP socket connection. It allows for prompt-assisted 3D modeling, component manipulation, and the execution of arbitrary Ruby code within the SketchUp environment.
    10
    MIT
  • A
    license
    B
    quality
    C
    maintenance
    Enables controlling SketchUp from MCP-compatible clients via a stdio Python server that bridges to a Ruby plugin, supporting component operations, material assignment, scene export, arbitrary Ruby evaluation, and wood joinery tools.
    10
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Connects MCP-aware AI clients to a live SketchUp session so models can be built and edited through natural-language prompts. Exposes typed tools for geometry creation, materials, booleans, edge chamfers/fillets, joinery, scene export, model introspection, viewport screenshots, and an optional arbitrary-Ruby escape hatch.
    24
    MIT