Skip to main content
Glama
duke0317

Image Processing MCP Server

by duke0317

create_polaroid

Adds a Polaroid-style border and optional shadow effect to images, supporting various input sources and output formats for retro photo transformations.

Instructions

创建宝丽来风格效果

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
image_sourceYes图片源,可以是文件路径或base64编码的图片数据
border_widthNo宝丽来边框宽度(像素)
shadowNo是否添加阴影效果
output_formatNo输出格式:PNG、JPEG、WEBP 等PNG

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Core handler function that implements the Polaroid effect: loads image, adds white border with extended bottom, optional rotation, adds subtle shadow, outputs as base64.
    async def create_polaroid(arguments: Dict[str, Any]) -> List[TextContent]:
        """
        创建宝丽来照片效果
        
        Args:
            arguments: 包含图片源和宝丽来参数的字典
            
        Returns:
            List[TextContent]: 处理结果
        """
        try:
            # 参数验证
            image_source = arguments.get("image_source")
            ensure_valid_image_source(image_source)
            
            border_width = arguments.get("border_width", 40)
            bottom_border = arguments.get("bottom_border", 80)
            border_color = arguments.get("border_color", "#FFFFFF")
            rotation = arguments.get("rotation", 0)
            output_format = arguments.get("output_format", DEFAULT_IMAGE_FORMAT)
            
            # 验证参数
            validate_numeric_range(border_width, 10, 100, "border_width")
            validate_numeric_range(bottom_border, 20, 200, "bottom_border")
            validate_color_hex(border_color)
            validate_numeric_range(rotation, -15, 15, "rotation")
            
            # 加载图片
            processor = ImageProcessor()
            image = processor.load_image(image_source)
            
            # 创建宝丽来边框
            polaroid_width = image.width + 2 * border_width
            polaroid_height = image.height + border_width + bottom_border
            
            # 创建白色背景
            border_rgb = tuple(int(border_color[i:i+2], 16) for i in (1, 3, 5))
            polaroid = Image.new("RGB", (polaroid_width, polaroid_height), border_rgb)
            
            # 粘贴原图片
            polaroid.paste(image, (border_width, border_width))
            
            # 应用旋转
            if rotation != 0:
                # 扩展画布以容纳旋转后的图片
                diagonal = int(((polaroid_width ** 2 + polaroid_height ** 2) ** 0.5))
                expanded = Image.new("RGBA", (diagonal, diagonal), (0, 0, 0, 0))
                
                # 将宝丽来图片粘贴到扩展画布的中心
                offset_x = (diagonal - polaroid_width) // 2
                offset_y = (diagonal - polaroid_height) // 2
                expanded.paste(polaroid, (offset_x, offset_y))
                
                # 旋转
                rotated = expanded.rotate(rotation, expand=True, fillcolor=(0, 0, 0, 0))
                
                # 裁剪到合适大小
                bbox = rotated.getbbox()
                if bbox:
                    polaroid = rotated.crop(bbox)
            
            # 添加轻微的阴影效果
            shadow_offset = 5
            shadow_size = (polaroid.width + shadow_offset * 2, polaroid.height + shadow_offset * 2)
            final_image = Image.new("RGBA", shadow_size, (0, 0, 0, 0))
            
            # 创建阴影
            shadow = Image.new("RGBA", polaroid.size, (128, 128, 128, 100))
            shadow = shadow.filter(ImageFilter.GaussianBlur(radius=3))
            final_image.paste(shadow, (shadow_offset, shadow_offset), shadow)
            
            # 粘贴宝丽来图片
            if polaroid.mode != "RGBA":
                polaroid = polaroid.convert("RGBA")
            final_image.paste(polaroid, (0, 0), polaroid)
            
            # 转换为base64
            output_info = processor.output_image(final_image, "border", output_format)
            
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": True,
                    "message": "成功创建宝丽来效果",
                    "data": {
                        **output_info,
                        "metadata": {
                            "original_size": f"{image.width}x{image.height}",
                            "polaroid_size": f"{final_image.width}x{final_image.height}",
                            "border_width": border_width,
                            "bottom_border": bottom_border,
                            "border_color": border_color,
                            "rotation": rotation,
                            "format": output_format
                        }
                    }
                }, ensure_ascii=False)
            )]
            
        except ValidationError as e:
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": False,
                    "error": f"参数验证失败: {str(e)}"
                }, ensure_ascii=False)
            )]
        except Exception as e:
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": False,
                    "error": f"创建宝丽来效果失败: {str(e)}"
                }, ensure_ascii=False)
            )]
  • JSON schema definition for create_polaroid tool inputs, including validation rules for parameters like border_width, bottom_border, etc.
    Tool(
        name="create_polaroid",
        description="创建宝丽来照片效果",
        inputSchema={
            "type": "object",
            "properties": {
                "image_source": {
                    "type": "string",
                    "description": "图片源(文件路径或base64编码)"
                },
                "border_width": {
                    "type": "integer",
                    "description": "边框宽度(像素)",
                    "minimum": 10,
                    "maximum": 100,
                    "default": 40
                },
                "bottom_border": {
                    "type": "integer",
                    "description": "底部边框宽度(像素)",
                    "minimum": 20,
                    "maximum": 200,
                    "default": 80
                },
                "border_color": {
                    "type": "string",
                    "description": "边框颜色(十六进制格式)",
                    "default": "#FFFFFF"
                },
                "rotation": {
                    "type": "number",
                    "description": "旋转角度(度)",
                    "minimum": -15,
                    "maximum": 15,
                    "default": 0
                },
                "output_format": {
                    "type": "string",
                    "description": "输出格式",
                    "enum": ["PNG", "JPEG", "WEBP"],
                    "default": "PNG"
                }
            },
            "required": ["image_source"]
        }
    )
  • main.py:624-646 (registration)
    MCP tool registration using @mcp.tool() decorator. Wraps the effects handler, adapts parameters, and handles errors.
    @mcp.tool()
    def create_polaroid(
        image_source: Annotated[str, Field(description="图片源,可以是文件路径或base64编码的图片数据")],
        border_width: Annotated[int, Field(description="宝丽来边框宽度(像素)", ge=1, default=20)],
        shadow: Annotated[bool, Field(description="是否添加阴影效果", default=True)],
        output_format: Annotated[str, Field(description="输出格式:PNG、JPEG、WEBP 等", default="PNG")]
    ) -> str:
        """创建宝丽来风格效果"""
        try:
            arguments = {
                "image_source": image_source,
                "border_width": border_width,
                "shadow": shadow,
                "output_format": output_format
            }
            result = safe_run_async(effects_create_polaroid(arguments))
            return result[0].text
        except Exception as e:
            return json.dumps({
                "success": False,
                "error": f"创建宝丽来效果失败: {str(e)}"
            }, ensure_ascii=False, indent=2)
  • main.py:65-72 (registration)
    Import of the create_polaroid handler from tools.effects into main.py for use in MCP tool wrappers.
    from tools.effects import (
        add_border as effects_add_border,
        create_silhouette as effects_create_silhouette,
        add_shadow  as effects_add_shadow,
        add_watermark as effects_add_watermark,
        apply_vignette as effects_apply_vignette,
        create_polaroid as effects_create_polaroid
    )
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. The description only states what the tool creates ('宝丽来风格效果') but doesn't disclose any behavioral traits: whether this modifies the original image, creates a new file, what permissions are needed, performance characteristics, or error conditions. For a tool with 4 parameters and no annotation coverage, this is a significant gap.

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?

The description is extremely concise - a single phrase '创建宝丽来风格效果' that states the core purpose. There's zero wasted language. However, it's arguably too concise given the tool's complexity and lack of other documentation, bordering on under-specification rather than optimal conciseness.

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 that there's an output schema (though not provided here), the description doesn't need to explain return values. However, for an image processing tool with 4 parameters, no annotations, and many sibling alternatives, the description is minimally adequate but has clear gaps in usage guidance and behavioral context. It provides the basic purpose but lacks the completeness needed for optimal agent understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 4 parameters with good descriptions. The tool description adds no additional parameter semantics beyond what's in the schema. The baseline of 3 is appropriate when the schema does the heavy lifting, though the description doesn't compensate with any parameter context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description '创建宝丽来风格效果' (Create Polaroid-style effect) states what the tool does with a specific verb ('创建' - create) and resource ('宝丽来风格效果' - Polaroid-style effect). However, it doesn't distinguish this tool from its many sibling image processing tools, particularly those like 'add_border' or 'add_shadow' that might implement similar visual effects. The purpose is clear but lacks sibling differentiation.

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?

The description provides no guidance on when to use this tool versus alternatives. With many sibling tools for image manipulation (add_border, add_shadow, apply_vignette, etc.), there's no indication of when this specific Polaroid effect is appropriate versus combining other tools. No context, prerequisites, or exclusions are mentioned.

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/duke0317/ps-mcp'

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