An AI agent that can only resize images is a script. An agent that can decide to resize, then compress, then remove the background, then convert the format โ all without a human in the loop โ is a pipeline.
At Agent Media Tools, every image and media tool is also a REST endpoint. That means any autonomous agent โ Hermes, Claude, GPT, or your own code โ can chain them together on the fly. This guide shows you how to build image processing pipelines that run unattended, with real code examples for agents, scripts, and cron jobs.
Single-shot tool calls are easy. But the real world rarely throws one operation at you:
The difference between a manual script and an agent pipeline is autonomy. The agent examines the image, decides which operations it needs, chains them together, and only reports back when it's done โ or when something broke.
These are the core image processing endpoints on Agent Media Tools that agents can chain:
/api/resize-image โ Resize to exact dimensions or percentage. Supports JPG, PNG, WebP, AVIF output./api/compress-image โ Shrink file size with configurable quality (1โ100). Outputs JPEG or WebP./api/remove-background โ AI background removal using BiRefNet. Returns PNG with transparency./api/convert-image โ Convert between JPG, PNG, WebP, AVIF, TIFF, GIF./api/apply-filter โ Apply grayscale, blur, sharpen, sepia, invert, brightness, contrast.Each accepts an image_url or direct upload. Because the output of one call is a URL, the next call can consume it immediately โ no intermediate file handling required.
This is the most straightforward pattern. An agent gets an image URL and runs it through a sequence of operations, passing the result URL from one step to the next.
import requests
BASE = "https://agentmediatools.com/api"
SOURCE = "https://example.com/product-photo.jpg"
# Step 1: Resize to 800px wide
r1 = requests.post(f"{BASE}/resize-image", json={
"image_url": SOURCE,
"width": 800,
"format": "png"
})
result1 = r1.json()
# result1.url is now a processed image URL
print(f"Resized: {result1['url']}")
# Step 2: Remove background
r2 = requests.post(f"{BASE}/remove-background", json={
"image_url": result1["url"]
})
result2 = r2.json()
print(f"BG removed: {result2['url']}")
# Step 3: Compress
r3 = requests.post(f"{BASE}/compress-image", json={
"image_url": result2["url"],
"quality": 80,
"format": "webp"
})
result3 = r3.json()
print(f"Compressed: {result3['url']}")
# URL ready for CDN, email, or database
final_url = result3["url"]
run_workflow_easy)If your agent speaks MCP (Model Context Protocol), you can chain operations in a single meta-call using run_workflow_easy. This is the preferred pattern for autonomous agents โ one invocation, up to 12 steps, conditional error handling.
Here's what the agent sends to the MCP tool:
{
"steps": [
{
"id": "resize",
"tool": "resize_image",
"arguments": {
"image_url": "https://example.com/raw.jpg",
"width": 1200,
"format": "png"
}
},
{
"id": "compress",
"tool": "compress_image",
"arguments": {
"image_url": "$steps.resize.url",
"quality": 75,
"format": "webp"
}
},
{
"id": "bg_remove",
"tool": "remove_background",
"arguments": {
"image_url": "$steps.compress.url"
}
},
{
"id": "final",
"tool": "convert_image",
"arguments": {
"image_url": "$steps.bg_remove.url",
"format": "png"
}
}
]
}
The agent references $steps.STEP_ID.path to pass results downstream. If any step fails (and continue_on_error isn't set), the entire workflow halts and reports which step broke โ the agent can then decide to retry, skip, or escalate.
The agent can present the final URL to the user, store it, or pass it to another agent. No bash scripts, no temp directories, no manual curl commands.
For long-running or batch workloads, use the async job queue. Submit each image as a job, get a webhook callback when processing finishes, and chain the next step from the webhook handler.
This pattern works well with the Webhook Inbox feature โ create an inbox, submit jobs with the inbox URL as callback, and poll results when they arrive.
# Create a webhook inbox to receive callbacks
curl -X POST https://agentmediatools.com/api/webhook-inbox/create
# Response: { "inbox_url": "https://agentmediatools.com/hooks/jNh3k...", "token": "..." }
# Submit an async resize job with the inbox as callback
curl -X POST https://agentmediatools.com/api/jobs \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tool": "resize-image",
"args": { "image_url": "...", "width": 800 },
"webhook": "https://agentmediatools.com/hooks/jNh3k..."
}'
When the job completes, the webhook fires with the result URL. Your agent picks it up, submits the next operation, and so on. This is how you process hundreds of images overnight without a human checking in.
The most powerful pipeline isn't a fixed sequence โ it's one where the agent decides what to do based on the image itself. Here's a pattern:
1. Agent receives image โ checks file size with /api/analyze-image
2. If size > 1MB โ compress to quality 70
3. If dimensions > 2000px โ resize to 1200px
4. IF user requested "no background" โ call /api/remove-background
5. Always โ convert to WebP, deliver final URL
This conditional branching is easy to implement in any agent framework. The agent inspects metadata (size, dimensions, format), then decides which tools to call and in what order. The result is an adaptive pipeline that handles whatever the user throws at it.
Let's tie it all together with a complete example. An AI agent watches a shared folder, processes new product photos, and delivers them to a CDN.
import os, json, requests
from pathlib import Path
BASE = "https://agentmediatools.com/api"
WATCH_DIR = Path("./incoming")
DONE_DIR = Path("./processed")
DONE_DIR.mkdir(exist_ok=True)
for photo in WATCH_DIR.glob("*.jpg"):
print(f"Processing {photo.name}...")
# Upload, get URL back
with open(photo, "rb") as f:
upload = requests.post(f"{BASE}/resize-image",
files={"image": f},
data={"width": 1200, "format": "png"}
)
data = upload.json()
current_url = data["url"]
# Remove background
bg = requests.post(f"{BASE}/remove-background",
json={"image_url": current_url}
)
current_url = bg.json()["url"]
# Compress for web
comp = requests.post(f"{BASE}/compress-image",
json={"image_url": current_url, "quality": 80, "format": "webp"}
)
final_url = comp.json()["url"]
print(f"โ
{photo.name} โ {final_url}")
photo.rename(DONE_DIR / photo.name)
Real pipelines fail sometimes. Build retry into your agent:
MAX_RETRIES = 3
for attempt in range(MAX_RETRIES):
try:
r = requests.post(f"{BASE}/resize-image", json={...}, timeout=30)
r.raise_for_status()
break
except (requests.ConnectionError, requests.Timeout) as e:
if attempt == MAX_RETRIES - 1:
raise # Give up
time.sleep(2 ** attempt) # Exponential backoff
For the MCP run_workflow_easy tool, set continue_on_error: true on optional steps and check each step's status in the result. The agent sees exactly which step failed and can decide to retry just that step.
image_url over file uploads in multi-step pipelines โ URLs are instant, uploads take bandwidth.format on the resize endpoint. Saves one round trip.Start building autonomous image pipelines today. Free tools at agentmediatools.com โ no credit card, no signup for most operations. Premium unlocks async jobs, higher limits, and API keys for unattended agents.
Try the tools โMore guides at agentmediatools.com/blog