boolean_operation
Apply boolean operations (union, difference, intersection) to two 3D solids for merging or cutting geometry.
Instructions
Perform a boolean operation (union/difference/intersection) on two solids.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| target_id | Yes | ||
| tool_id | Yes | ||
| operation | No | union | |
| delete_originals | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/sketchup_mcp/tools.py:228-244 (handler)The 'boolean_operation' tool handler function (async). Uses @mcp.tool() decorator for registration. Accepts target_id, tool_id, operation (union/difference/intersection), and delete_originals. Delegates to _call() which sends the command to the SketchUp Ruby backend.
@mcp.tool() async def boolean_operation( ctx: Context, target_id: Annotated[str, Field(min_length=1)], tool_id: Annotated[str, Field(min_length=1)], operation: Literal["union", "difference", "intersection"] = "union", delete_originals: bool = False, ) -> str: """Perform a boolean operation (union/difference/intersection) on two solids.""" return await _call( ctx, "boolean_operation", target_id=target_id, tool_id=tool_id, operation=operation, delete_originals=delete_originals, ) - src/sketchup_mcp/tools.py:228-244 (schema)Inline schema/type definitions for boolean_operation: target_id and tool_id are strings (min_length=1), operation is Literal['union','difference','intersection'] defaulting to 'union', delete_originals is bool defaulting to False.
@mcp.tool() async def boolean_operation( ctx: Context, target_id: Annotated[str, Field(min_length=1)], tool_id: Annotated[str, Field(min_length=1)], operation: Literal["union", "difference", "intersection"] = "union", delete_originals: bool = False, ) -> str: """Perform a boolean operation (union/difference/intersection) on two solids.""" return await _call( ctx, "boolean_operation", target_id=target_id, tool_id=tool_id, operation=operation, delete_originals=delete_originals, ) - src/sketchup_mcp/tools.py:228-244 (registration)Registration via the @mcp.tool() decorator on line 228. The mcp instance is imported from sketchup_mcp.app (line 14), and tools.py is side-effect imported in app.py line 51 to register all tools.
@mcp.tool() async def boolean_operation( ctx: Context, target_id: Annotated[str, Field(min_length=1)], tool_id: Annotated[str, Field(min_length=1)], operation: Literal["union", "difference", "intersection"] = "union", delete_originals: bool = False, ) -> str: """Perform a boolean operation (union/difference/intersection) on two solids.""" return await _call( ctx, "boolean_operation", target_id=target_id, tool_id=tool_id, operation=operation, delete_originals=delete_originals, ) - src/sketchup_mcp/app.py:41-50 (helper)The FastMCP application instance 'mcp' that the @mcp.tool() decorator registers boolean_operation on. Created with FastMCP('SketchupMCP', ...).
mcp = FastMCP( "SketchupMCP", instructions="Sketchup integration through the Model Context Protocol", lifespan=server_lifespan, ) # Side-effect import: registers tool handlers on `mcp`. Must come AFTER `mcp` # is constructed (tools.py does `from sketchup_mcp.app import mcp`). Required # here so MCP hosts loading the published `[project.entry-points.mcp]` get a # FastMCP with tools registered, not an empty instance. - src/sketchup_mcp/tools.py:21-50 (helper)The _call() helper function that dispatches tool calls to the SketchUp Ruby backend via WebSocket connection. All tools (including boolean_operation) delegate to this function.
async def _call(ctx: Context, name: str, **kwargs) -> str: """Dispatch a tool call to SketchUp and shape the response for Claude. - Connection errors → human-readable string, server keeps running. - SketchUpError → ``format_error`` string. - Successful MCP-shaped result ({content: [{text: "..."}]}) → just the text. - Any other dict result → ``json.dumps``. """ try: sketchup = await get_connection() except ConnectionError as e: return f"SketchUp not running or extension not started: {e}" try: result = await sketchup.send_command(name, kwargs) except ConnectionError as e: # Cached connection was stale and reconnect inside send_command failed: # `_connect_or_raise` re-raises OSError as ConnectionError before the # send/recv try-block, so it escapes past the SketchUpError handler. return f"SketchUp not running or extension not started: {e}" except SketchUpError as e: return format_error(e, debug=config.LOG_LEVEL == "DEBUG") content = result.get("content") if isinstance(result, dict) else None if ( isinstance(content, list) and content and isinstance(content[0], dict) and "text" in content[0] ): return content[0]["text"] return json.dumps(result)