inpaint_image
Edit specific image regions by regenerating masked areas based on text prompts to modify or remove objects.
Instructions
Edit specific regions of an image using a mask. White areas in the mask will be regenerated based on the prompt.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| image_url | Yes | URL of the source image (use upload_file for local images) | |
| mask_url | Yes | URL of the mask image (white=edit, black=keep). Use upload_file for local masks. | |
| prompt | Yes | What to generate in the masked area (e.g., 'a red sports car', 'green grass') | |
| model | No | Inpainting model. Options: fal-ai/flux-kontext-lora/inpaint, fal-ai/flux-krea-lora/inpainting | fal-ai/flux-kontext-lora/inpaint |
| negative_prompt | No | What to avoid in the generated area | |
| seed | No | Seed for reproducible results |
Implementation Reference
- The main handler function that executes the inpaint_image tool: resolves model ID, prepares Fal.ai arguments, executes via queue_strategy with timeout handling, processes response, extracts output image URL, and formats success/error messages.async def handle_inpaint_image( arguments: Dict[str, Any], registry: ModelRegistry, queue_strategy: QueueStrategy, ) -> List[TextContent]: """Handle the inpaint_image tool for masked region editing.""" model_input = arguments.get("model", "fal-ai/flux-kontext-lora/inpaint") try: model_id = await registry.resolve_model_id(model_input) except ValueError as e: return [ TextContent( type="text", text=f"❌ {e}. Use list_models to see available options.", ) ] fal_args: Dict[str, Any] = { "image_url": arguments["image_url"], "mask_url": arguments["mask_url"], "prompt": arguments["prompt"], } # Add optional parameters if "negative_prompt" in arguments: fal_args["negative_prompt"] = arguments["negative_prompt"] if "seed" in arguments: fal_args["seed"] = arguments["seed"] logger.info("Starting inpainting with %s: '%s'", model_id, arguments["prompt"][:50]) try: result = await asyncio.wait_for( queue_strategy.execute_fast(model_id, fal_args), timeout=90, ) except asyncio.TimeoutError: logger.error("Inpainting timed out for %s", model_id) return [ TextContent( type="text", text="❌ Inpainting timed out after 90 seconds. Please try again.", ) ] except Exception as e: logger.exception("Inpainting failed: %s", e) return [ TextContent( type="text", text=f"❌ Inpainting failed: {e}", ) ] # Check for error in response if "error" in result: error_msg = result.get("error", "Unknown error") logger.error("Inpainting failed for %s: %s", model_id, error_msg) return [ TextContent( type="text", text=f"❌ Inpainting failed: {error_msg}", ) ] # Extract the result image URL images = result.get("images", []) if images: output_url = images[0].get("url") if isinstance(images[0], dict) else images[0] else: image_data = result.get("image", {}) if isinstance(image_data, dict): output_url = image_data.get("url") else: output_url = result.get("image_url") if not output_url: logger.warning("Inpainting returned no image. Result: %s", result) return [ TextContent( type="text", text="❌ Inpainting completed but no image was returned.", ) ] response = "🖌️ Inpainting completed!\n\n" response += f"**Prompt**: {arguments['prompt']}\n\n" response += f"**Result**: {output_url}" return [TextContent(type="text", text=response)]
- Input schema and Tool definition for inpaint_image, defining parameters (image_url, mask_url, prompt, model, etc.) with descriptions, defaults, and required fields for MCP validation.Tool( name="inpaint_image", description="Edit specific regions of an image using a mask. White areas in the mask will be regenerated based on the prompt.", inputSchema={ "type": "object", "properties": { "image_url": { "type": "string", "description": "URL of the source image (use upload_file for local images)", }, "mask_url": { "type": "string", "description": "URL of the mask image (white=edit, black=keep). Use upload_file for local masks.", }, "prompt": { "type": "string", "description": "What to generate in the masked area (e.g., 'a red sports car', 'green grass')", }, "model": { "type": "string", "default": "fal-ai/flux-kontext-lora/inpaint", "description": "Inpainting model. Options: fal-ai/flux-kontext-lora/inpaint, fal-ai/flux-krea-lora/inpainting", }, "negative_prompt": { "type": "string", "description": "What to avoid in the generated area", }, "seed": { "type": "integer", "description": "Seed for reproducible results", }, }, "required": ["image_url", "mask_url", "prompt"], }, ),
- src/fal_mcp_server/server.py:61-85 (registration)TOOL_HANDLERS dictionary registers the 'inpaint_image' tool name to its handler function handle_inpaint_image, enabling dispatch in the call_tool method.TOOL_HANDLERS = { # Utility tools (no queue needed) "list_models": handle_list_models, "recommend_model": handle_recommend_model, "get_pricing": handle_get_pricing, "get_usage": handle_get_usage, "upload_file": handle_upload_file, # Image generation tools "generate_image": handle_generate_image, "generate_image_structured": handle_generate_image_structured, "generate_image_from_image": handle_generate_image_from_image, # Image editing tools "remove_background": handle_remove_background, "upscale_image": handle_upscale_image, "edit_image": handle_edit_image, "inpaint_image": handle_inpaint_image, "resize_image": handle_resize_image, "compose_images": handle_compose_images, # Video tools "generate_video": handle_generate_video, "generate_video_from_image": handle_generate_video_from_image, "generate_video_from_video": handle_generate_video_from_video, # Audio tools "generate_music": handle_generate_music, }