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