Skip to main content
Glama

process_image

Apply post-processing operations to images including resizing, background removal, and outline addition for game asset preparation.

Instructions

Apply post-processing operations to an image.

Args:
    image_base64: Base64 encoded input image
    operations: List of operations to apply: "resize", "remove_background", "add_outline"
    resize_width: Target width for resize operation
    resize_height: Target height for resize operation
    outline_color: Hex color for outline (e.g., "#000000")
    outline_thickness: Thickness of outline in pixels
    save_to_file: Whether to save processed image to disk

Returns:
    JSON with processed image as base64

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
image_base64Yes
operationsYes
resize_widthNo
resize_heightNo
outline_colorNo#000000
outline_thicknessNo
save_to_fileNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The primary handler function for the 'process_image' tool. It decodes the input base64 image, applies the specified operations by calling helper functions (resize_image, remove_background, add_outline), encodes the result back to base64, and returns JSON. The @mcp.tool() decorator handles registration.
    @mcp.tool()
    async def process_image(
        image_base64: str,
        operations: List[str],
        resize_width: Optional[int] = None,
        resize_height: Optional[int] = None,
        outline_color: str = "#000000",
        outline_thickness: int = 1,
        save_to_file: bool = False
    ) -> str:
        """Apply post-processing operations to an image.
        
        Args:
            image_base64: Base64 encoded input image
            operations: List of operations to apply: "resize", "remove_background", "add_outline"
            resize_width: Target width for resize operation
            resize_height: Target height for resize operation
            outline_color: Hex color for outline (e.g., "#000000")
            outline_thickness: Thickness of outline in pixels
            save_to_file: Whether to save processed image to disk
        
        Returns:
            JSON with processed image as base64
        """
        import base64
        image_bytes = base64.b64decode(image_base64)
        
        for op in operations:
            if op == "resize" and resize_width and resize_height:
                image_bytes = resize_image(image_bytes, resize_width, resize_height)
            elif op == "remove_background":
                image_bytes = remove_background(image_bytes)
            elif op == "add_outline":
                # Parse hex color
                color = outline_color.lstrip("#")
                r, g, b = tuple(int(color[i:i+2], 16) for i in (0, 2, 4))
                image_bytes = add_outline(image_bytes, color=(r, g, b, 255), thickness=outline_thickness)
        
        result = {
            "success": True,
            "image_base64": image_to_base64(image_bytes),
            "operations_applied": operations
        }
        
        if save_to_file:
            output_dir = ensure_directory(OUTPUT_DIR / "processed")
            fname = generate_filename(prefix="processed")
            file_path = output_dir / fname
            file_path.write_bytes(image_bytes)
            result["file_path"] = str(file_path)
        
        return json.dumps(result, indent=2)
  • Helper function used by process_image for the 'resize' operation. Loads the image from bytes, resizes it using PIL, and returns new PNG bytes.
    def resize_image(
        image_bytes: bytes,
        width: int,
        height: int,
        resample: int = Image.Resampling.NEAREST
    ) -> bytes:
        """Resize an image to the specified dimensions."""
        img = Image.open(BytesIO(image_bytes))
        resized = img.resize((width, height), resample=resample)
        buffer = BytesIO()
        resized.save(buffer, format="PNG")
        return buffer.getvalue()
  • Helper function used by process_image for the 'remove_background' operation. Converts image to RGBA and sets near-white pixels to transparent.
    def remove_background(image_bytes: bytes, threshold: int = 10) -> bytes:
        """Simple background removal by making near-white pixels transparent."""
        img = Image.open(BytesIO(image_bytes)).convert("RGBA")
        data = img.getdata()
        
        new_data = []
        for item in data:
            # If pixel is close to white, make it transparent
            if item[0] > 255 - threshold and item[1] > 255 - threshold and item[2] > 255 - threshold:
                new_data.append((255, 255, 255, 0))
            else:
                new_data.append(item)
        
        img.putdata(new_data)
        buffer = BytesIO()
        img.save(buffer, format="PNG")
        return buffer.getvalue()
  • Helper function used by process_image for the 'add_outline' operation. Detects edges by checking transparent neighbors and adds colored outline pixels.
    def add_outline(
        image_bytes: bytes,
        color: Tuple[int, int, int, int] = (0, 0, 0, 255),
        thickness: int = 1
    ) -> bytes:
        """Add an outline around non-transparent pixels."""
        img = Image.open(BytesIO(image_bytes)).convert("RGBA")
        
        # Create outline image
        outline = Image.new("RGBA", img.size, (0, 0, 0, 0))
        
        pixels = img.load()
        outline_pixels = outline.load()
        
        for y in range(img.height):
            for x in range(img.width):
                if pixels[x, y][3] > 0:  # Non-transparent pixel
                    # Check neighbors
                    for dy in range(-thickness, thickness + 1):
                        for dx in range(-thickness, thickness + 1):
                            nx, ny = x + dx, y + dy
                            if 0 <= nx < img.width and 0 <= ny < img.height:
                                if pixels[nx, ny][3] == 0:  # Transparent neighbor
                                    outline_pixels[x, y] = color
                                    break
        
        # Composite outline under original
        result = Image.alpha_composite(outline, img)
        buffer = BytesIO()
        result.save(buffer, format="PNG")
        return buffer.getvalue()
Behavior2/5

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

With no annotations provided, the description carries full burden. It mentions that the tool applies operations and returns JSON with base64, but lacks details on permissions, rate limits, side effects (e.g., file saving implications), or error handling. It partially describes behavior but misses key aspects for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well-structured with clear sections (Args, Returns) and bullet-like formatting. Sentences are efficient, though the parameter list is lengthy but necessary. It's appropriately sized for a tool with many parameters, with minimal fluff.

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?

Given 7 parameters, no annotations, and an output schema (which covers return values), the description is moderately complete. It explains parameters well but lacks behavioral context (e.g., file saving details, error cases). For a complex image-processing tool, more guidance on usage and constraints would improve completeness.

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?

Schema description coverage is 0%, so the description must compensate. It provides meaningful explanations for all 7 parameters, including examples (e.g., operations list, hex color format) and clarifies dependencies (e.g., resize parameters for resize operation). This adds significant value beyond the bare schema.

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?

The description clearly states the tool's purpose: 'Apply post-processing operations to an image.' It specifies the verb ('apply') and resource ('image'), but doesn't differentiate from siblings like 'generate_sprite' or 'generate_icons' which might also process images. The purpose is clear but lacks sibling distinction.

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 guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'generate_sprite' or 'generate_icons', nor does it specify prerequisites or exclusions. Usage is implied by the description but not explicitly stated.

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

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/tuannguyen14/ComfyAI-MCP-GameAssets'

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