Skip to main content
Glama
duke0317

Image Processing MCP Server

by duke0317

batch_resize

Resize multiple images to specified dimensions while optionally maintaining aspect ratio and converting formats in batch processing workflows.

Instructions

批量调整图片大小

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
image_sourcesYes图片源列表,每个元素可以是文件路径或base64编码的图片数据
target_widthYes目标宽度(像素)
target_heightYes目标高度(像素)
keep_aspect_ratioNo是否保持宽高比
output_formatNo输出格式:PNG、JPEG、WEBP 等PNG

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Core implementation of the batch_resize tool handler. Processes a list of image sources in parallel, resizes each image using PIL (with optional aspect ratio preservation), encodes outputs to base64, and returns JSON results including success/failure stats.
    async def batch_resize(arguments: Dict[str, Any]) -> List[TextContent]:
        """
        批量调整多张图片的大小
        
        Args:
            arguments: 包含图片源列表和调整参数的字典
            
        Returns:
            List[TextContent]: 处理结果
        """
        try:
            # 参数验证
            image_sources = arguments.get("image_sources", [])
            if not image_sources:
                raise ValidationError("image_sources不能为空")
            
            width = arguments.get("width")
            height = arguments.get("height")
            maintain_aspect_ratio = arguments.get("maintain_aspect_ratio", True)
            resample_method = arguments.get("resample_method", "LANCZOS")
            output_format = arguments.get("output_format", DEFAULT_IMAGE_FORMAT)
            
            # 验证参数
            validate_numeric_range(width, MIN_IMAGE_SIZE, MAX_IMAGE_SIZE, "width")
            validate_numeric_range(height, MIN_IMAGE_SIZE, MAX_IMAGE_SIZE, "height")
            
            # 获取重采样方法
            resample_map = {
                "LANCZOS": Image.Resampling.LANCZOS,
                "BILINEAR": Image.Resampling.BILINEAR,
                "BICUBIC": Image.Resampling.BICUBIC,
                "NEAREST": Image.Resampling.NEAREST
            }
            resample = resample_map.get(resample_method, Image.Resampling.LANCZOS)
            
            processor = ImageProcessor()
            results = []
            failed_count = 0
            
            # 使用线程池进行并行处理
            def resize_single_image(image_source):
                try:
                    ensure_valid_image_source(image_source)
                    image = processor.load_image(image_source)
                    
                    if maintain_aspect_ratio:
                        # 保持宽高比
                        image.thumbnail((width, height), resample)
                        resized_image = image
                    else:
                        # 强制调整到指定尺寸
                        resized_image = image.resize((width, height), resample)
                    
                    # 输出图片
                    output_info = processor.output_image(resized_image, "batch_resize", output_format)
                    return output_info
                except Exception as e:
                    return f"ERROR: {str(e)}"
            
            # 并行处理
            with ThreadPoolExecutor(max_workers=min(len(image_sources), MAX_CONCURRENT_TASKS)) as executor:
                futures = [executor.submit(resize_single_image, source) for source in image_sources]
                
                for i, future in enumerate(futures):
                    result = future.result()
                    if result.startswith("ERROR:"):
                        failed_count += 1
                        results.append({
                            "index": i,
                            "success": False,
                            "error": result[7:]  # 移除"ERROR: "前缀
                        })
                    else:
                        results.append({
                            "index": i,
                            "success": True,
                            "result": result
                        })
            
            return [TextContent(
                type="text",
                text=json.dumps({
                    "success": True,
                    "message": f"批量调整完成,成功: {len(results) - failed_count}, 失败: {failed_count}",
                    "results": results,
                    "metadata": {
                        "total_images": len(image_sources),
                        "successful": len(results) - failed_count,
                        "failed": failed_count,
                        "target_size": f"{width}x{height}",
                        "maintain_aspect_ratio": maintain_aspect_ratio,
                        "resample_method": resample_method,
                        "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)
            )]
  • main.py:649-673 (registration)
    MCP tool registration for batch_resize using FastMCP @mcp.tool() decorator. Defines input schema via Annotated parameters, constructs arguments dict, and delegates execution to the advanced async handler.
    @mcp.tool()
    def batch_resize(
        image_sources: Annotated[list, Field(description="图片源列表,每个元素可以是文件路径或base64编码的图片数据")],
        target_width: Annotated[int, Field(description="目标宽度(像素)", ge=1)],
        target_height: Annotated[int, Field(description="目标高度(像素)", ge=1)],
        keep_aspect_ratio: Annotated[bool, Field(description="是否保持宽高比", default=True)],
        output_format: Annotated[str, Field(description="输出格式:PNG、JPEG、WEBP 等", default="PNG")]
    ) -> str:
        """批量调整图片大小"""
        try:
            arguments = {
                "image_sources": image_sources,
                "target_width": target_width,
                "target_height": target_height,
                "keep_aspect_ratio": keep_aspect_ratio,
                "output_format": output_format
            }
            result = safe_run_async(advanced_batch_resize(arguments))
            return result[0].text
        except Exception as e:
            return json.dumps({
                "success": False,
                "error": f"批量调整大小失败: {str(e)}"
            }, ensure_ascii=False, indent=2)
  • Input schema definition for batch_resize tool within get_advanced_tools(), specifying JSON schema for parameters including image_sources array, dimensions, aspect ratio, resample method, and output format.
    Tool(
        name="batch_resize",
        description="批量调整多张图片的大小",
        inputSchema={
            "type": "object",
            "properties": {
                "image_sources": {
                    "type": "array",
                    "description": "图片源列表(文件路径或base64编码)",
                    "items": {"type": "string"},
                    "minItems": 1,
                    "maxItems": 10
                },
                "width": {
                    "type": "integer",
                    "description": "目标宽度",
                    "minimum": MIN_IMAGE_SIZE,
                    "maximum": MAX_IMAGE_SIZE
                },
                "height": {
                    "type": "integer",
                    "description": "目标高度",
                    "minimum": MIN_IMAGE_SIZE,
                    "maximum": MAX_IMAGE_SIZE
                },
                "maintain_aspect_ratio": {
                    "type": "boolean",
                    "description": "是否保持宽高比",
                    "default": True
                },
                "resample_method": {
                    "type": "string",
                    "description": "重采样方法",
                    "enum": ["LANCZOS", "BILINEAR", "BICUBIC", "NEAREST"],
                    "default": "LANCZOS"
                },
                "output_format": {
                    "type": "string",
                    "description": "输出格式",
                    "enum": ["PNG", "JPEG", "WEBP"],
                    "default": "PNG"
                }
            },
            "required": ["image_sources", "width", "height"]
        }
    ),
Behavior2/5

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

With no annotations provided, the description carries full burden but only states what the tool does ('batch resize images') without disclosing behavioral traits. It doesn't mention whether this is a read-only or destructive operation, what permissions might be needed, how errors are handled, whether it modifies originals or creates copies, or any performance/rate limit considerations for batch processing.

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

Conciseness5/5

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

The description is a single, efficient phrase ('批量调整图片大小') that directly states the tool's purpose with zero waste. It's appropriately sized and front-loaded, though extremely brief.

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 the tool has 5 parameters, no annotations, but has an output schema and 100% schema coverage, the description is minimally adequate. However, for a batch processing tool that likely has performance implications and error handling considerations, the description should provide more context about what 'batch' means operationally and how it differs from single-image alternatives.

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 5 parameters thoroughly. The 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 extra context about parameter interactions or usage patterns.

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 '批量调整图片大小' (Batch resize images) clearly states the verb (resize) and resource (images) with the batch operation scope. It distinguishes from the sibling 'resize_image' which appears to be a single-image version, though this distinction isn't explicitly stated in the description itself.

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 like 'resize_image' (for single images) or other image manipulation siblings. There's no mention of prerequisites, performance considerations, or when batch processing is preferred over individual operations.

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