Skip to main content
Glama
rahulgarg123

OpenSCAD MCP Server

by rahulgarg123

render_openscad

Convert OpenSCAD 3D modeling code into PNG images using headless rendering. Specify code, output path, and optional camera parameters to generate visualizations without a graphical interface.

Instructions

Render OpenSCAD code to PNG using OpenSCAD in headless mode

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
codeYesThe OpenSCAD code to render
output_pathYesPath where the rendered PNG image should be saved
cameraNoCamera parameters: translate_x,y,z,rot_x,y,z,dist or eye_x,y,z,center_x,y,z

Implementation Reference

  • Main handler for the 'render_openscad' tool call. Validates input arguments, invokes the rendering logic, formats the response including success status and output file path.
    private async handleRenderOpenSCAD(args: any): Promise<{ content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> }> { try { const { code, output_path, camera } = args; if (!code || typeof code !== 'string') { throw new Error('OpenSCAD code is required and must be a string'); } if (!output_path || typeof output_path !== 'string') { throw new Error('Output path is required and must be a string'); } const result = await this.renderOpenSCAD(code, output_path, camera); // Return text response with file path information let responseText = `OpenSCAD rendering ${result.success ? 'completed successfully' : 'failed'}\n\nOutput:\n${result.stdout}${result.stderr ? '\n\nErrors/Warnings:\n' + result.stderr : ''}`; if (result.success) { responseText += `\n\nRendered image saved to: ${output_path}`; } if (result.error) { responseText += `\n\nError: ${result.error}`; } return { content: [{ type: 'text', text: responseText }] }; } catch (error) { return { content: [ { type: 'text', text: `Error rendering OpenSCAD: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } }
  • Core rendering function that executes OpenSCAD binary with provided code, handles temporary files, camera params, and returns rendering result.
    private async renderOpenSCAD(code: string, outputPath: string, camera?: string): Promise<OpenSCADResult> { const tempDir = tmpdir(); const timestamp = Date.now(); const inputFile = join(tempDir, `openscad_input_${timestamp}.scad`); try { // Write OpenSCAD code to temporary file await fs.writeFile(inputFile, code, 'utf8'); // Build command arguments: input file, --render flag, output file const args = [inputFile, '--render', '--autocenter', '--viewall','--imgsize=640,480','--backend=manifold', '-o', outputPath]; // Add camera parameters if provided if (camera) { args.push('--camera', camera); } // Execute OpenSCAD with 10 minute timeout const { stdout, stderr } = await execFileAsync(OPENSCAD_BINARY, args, { timeout: 600000, // 10 minutes }); // Check if output file was created successfully const outputExists = await fs.access(outputPath).then(() => true).catch(() => false); // Clean up temporary input file only await this.cleanupFiles([inputFile]); return { stdout: stdout || '', stderr: stderr || '', success: outputExists, }; } catch (error) { // Clean up temporary input file even on error await this.cleanupFiles([inputFile]); return { stdout: '', stderr: '', success: false, error: error instanceof Error ? error.message : String(error), }; } }
  • Input schema defining parameters for the render_openscad tool: code (required string), output_path (required string), camera (optional string).
    inputSchema: { type: 'object', properties: { code: { type: 'string', description: 'The OpenSCAD code to render', }, output_path: { type: 'string', description: 'Path where the rendered PNG image should be saved', }, camera: { type: 'string', description: 'Camera parameters: translate_x,y,z,rot_x,y,z,dist or eye_x,y,z,center_x,y,z', }, }, required: ['code', 'output_path'], },
  • src/index.ts:46-73 (registration)
    Registration of the render_openscad tool in the ListToolsRequestSchema handler, including name, description, and input schema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'render_openscad', description: 'Render OpenSCAD code to PNG using OpenSCAD in headless mode', inputSchema: { type: 'object', properties: { code: { type: 'string', description: 'The OpenSCAD code to render', }, output_path: { type: 'string', description: 'Path where the rendered PNG image should be saved', }, camera: { type: 'string', description: 'Camera parameters: translate_x,y,z,rot_x,y,z,dist or eye_x,y,z,center_x,y,z', }, }, required: ['code', 'output_path'], }, }, ], }; });
  • src/index.ts:75-81 (registration)
    Dispatch registration in CallToolRequestSchema handler that routes 'render_openscad' calls to the handleRenderOpenSCAD method.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name === 'render_openscad') { return await this.handleRenderOpenSCAD(request.params.arguments || {}); } throw new Error(`Unknown tool: ${request.params.name}`); });
Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rahulgarg123/openscad-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server