from pathlib import Path
import numpy as np
import rembg
from fastmcp import FastMCP
from PIL import Image
# Initialize the FastMCP server
mcp = FastMCP("Toolkits")
@mcp.tool
def generate_favicons(source_path: str = "logo.png") -> str:
"""
Generate favicons of sizes 16, 32, 192, 512 from a source image.
Args:
source_path: Path to the source image (default: logo.png).
"""
path = Path(source_path)
if not path.exists():
return f"Error: Source image {source_path} not found. Please provide a valid path or ensure logo.png exists."
sizes = [16, 32, 192, 512]
output_dir = path.parent / "favicons"
output_dir.mkdir(exist_ok=True)
generated_files = []
try:
with Image.open(path) as img:
for size in sizes:
# Use LANCZOS for high-quality downsampling
favicon = img.resize((size, size), Image.Resampling.LANCZOS)
output_path = output_dir / f"favicon-{size}.png"
favicon.save(output_path, "PNG")
generated_files.append(str(output_path))
# Also generate a standard favicon.ico (containing 16x16 and 32x32)
ico_path = output_dir / "favicon.ico"
img.save(ico_path, format="ICO", sizes=[(16, 16), (32, 32)])
generated_files.append(str(ico_path))
files_str = "\n".join(generated_files)
return f"Favicons generated successfully in {output_dir}/:\n{files_str}"
except Exception as e:
return f"Error generating favicons: {str(e)}"
@mcp.tool
def remove_background(image_path: str) -> str:
"""
Remove the background from an image.
Args:
image_path: Path to the image file to process.
"""
path = Path(image_path)
if not path.exists():
return f"Error: File {image_path} not found."
try:
with Image.open(path) as img:
# Convert to RGBA if necessary
if img.mode != "RGBA":
img = img.convert("RGBA")
# Remove background
output_image = rembg.remove(img)
# Create output path
output_path = path.parent / f"{path.stem}_no_bg.png"
# Save as PNG to preserve transparency
if isinstance(output_image, bytes):
output_path.write_bytes(output_image)
elif isinstance(output_image, np.ndarray):
Image.fromarray(output_image).save(output_path, "PNG")
else:
output_image.save(output_path, "PNG")
return f"Background removed successfully!\nSaved to: {output_path}"
except Exception as e:
return f"Error removing background: {str(e)}"
@mcp.tool
def optimize_image(
image_path: str, quality: int = 80, max_width: int | None = None
) -> str:
"""
Optimize an image by reducing its file size while maintaining quality.
Args:
image_path: Path to the image file to optimize.
quality: Compression quality (1-100, default 80).
max_width: Optional maximum width to resize the image to.
"""
path = Path(image_path)
if not path.exists():
return f"Error: File {image_path} not found."
try:
with Image.open(path) as img:
# Resize if max_width is provided
if max_width and img.width > max_width:
height = int((max_width / img.width) * img.height)
img = img.resize((max_width, height), Image.Resampling.LANCZOS)
# Create output path
output_path = path.parent / f"{path.stem}_optimized{path.suffix}"
# Save with optimization
img.save(output_path, quality=quality, optimize=True)
original_size = path.stat().st_size
new_size = output_path.stat().st_size
reduction = (original_size - new_size) / original_size * 100
return f"Image optimized successfully!\nSaved to: {output_path}\nOriginal size: {original_size / 1024:.2f} KB\nNew size: {new_size / 1024:.2f} KB\nReduction: {reduction:.2f}%"
except Exception as e:
return f"Error optimizing image: {str(e)}"
if __name__ == "__main__":
mcp.run()