get_rendered_component
Retrieve a rendered image of a design component from Penpot by specifying its ID, enabling AI assistants to access visual design assets for automated workflows.
Instructions
Return a rendered component image by its ID.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| component_id | Yes |
Implementation Reference
- penpot_mcp/server/mcp_server.py:389-394 (handler)Primary handler function for the 'get_rendered_component' tool. Retrieves the pre-rendered image from the in-memory cache using the component ID as key. Registered as an MCP tool when resources are exposed as tools.@self.mcp.tool() def get_rendered_component(component_id: str) -> Image: """Return a rendered component image by its ID.""" if component_id in self.rendered_components: return self.rendered_components[component_id] raise Exception(f"Component with ID {component_id} not found")
- penpot_mcp/server/mcp_server.py:155-160 (registration)Alternative registration of the same handler function as a dynamic MCP resource at URI 'rendered-component://{component_id}', providing image/png content. Used when resources are not exposed as tools.@self.mcp.resource("rendered-component://{component_id}", mime_type="image/png") def get_rendered_component(component_id: str) -> Image: """Return a rendered component image by its ID.""" if component_id in self.rendered_components: return self.rendered_components[component_id] raise Exception(f"Component with ID {component_id} not found")
- Helper code within the 'get_object_tree' tool that generates the rendered image using 'export_object' and stores it in the self.rendered_components cache with MD5 hash of file_id:object_id as the key. This populates the cache used by get_rendered_component.image_id = hashlib.md5(f"{file_id}:{object_id}".encode()).hexdigest() self.rendered_components[image_id] = image # Image URI preferences: # 1. HTTP server URL if available # 2. Fallback to MCP resource URI image_uri = f"render_component://{image_id}"
- Supporting 'export_object' tool that performs the actual rendering/export of Penpot objects to images via the Penpot API. Called by 'get_object_tree' to generate images stored for later retrieval by 'get_rendered_component'.def export_object( file_id: str, page_id: str, object_id: str, export_type: str = "png", scale: int = 1) -> Image: """Export a Penpot design object as an image. Args: file_id: The ID of the Penpot file page_id: The ID of the page containing the object object_id: The ID of the object to export export_type: Image format (png, svg, etc.) scale: Scale factor for the exported image """ temp_filename = None try: import tempfile temp_dir = tempfile.gettempdir() temp_filename = os.path.join(temp_dir, f"{object_id}.{export_type}") output_path = self.api.export_and_download( file_id=file_id, page_id=page_id, object_id=object_id, export_type=export_type, scale=scale, save_to_file=temp_filename ) with open(output_path, "rb") as f: file_content = f.read() image = Image(data=file_content, format=export_type) # If HTTP server is enabled, add the image to the server if self.image_server and self.image_server.is_running: image_id = hashlib.md5(f"{file_id}:{page_id}:{object_id}".encode()).hexdigest() # Use the current image_server_url to ensure the correct port image_url = self.image_server.add_image(image_id, file_content, export_type) # Add HTTP URL to the image metadata image.http_url = image_url return image except Exception as e: if isinstance(e, CloudFlareError): raise Exception(f"CloudFlare Protection: {str(e)}") else: raise Exception(f"Export failed: {str(e)}") finally: if temp_filename and os.path.exists(temp_filename): try: os.remove(temp_filename) except Exception as e: print(f"Warning: Failed to delete temporary file {temp_filename}: {str(e)}") @self.mcp.tool()
- penpot_mcp/server/mcp_server.py:88-93 (registration)Conditional registration logic in server constructor that determines whether to register get_rendered_component as a tool (when RESOURCES_AS_TOOLS=True) or as a resource (when False).if config.RESOURCES_AS_TOOLS: self._register_resources(resources_only=True) self._register_tools(include_resource_tools=True) else: self._register_resources(resources_only=False) self._register_tools(include_resource_tools=False)