> product // imagebot // the making of
ImageBot
how it was made.
ImageBot started as a single MCP server in November 2025 and grew into a full generation platform: API, brand kits, a virtual photo shoot planner, a WordPress plugin, and 73 image types. Six months of real build work across three repos, none of it dramatised, the fixes and timeouts included.
The short version
It started with a single MCP tool: give Claude an API key and it could generate images. That was useful enough on day one, but the real shape of ImageBot emerged over the next sprint: a generation engine with brand extraction, a credit system, a photo shoot planner, and a WordPress plugin that drops generated images straight into the Media Library. The sprint-based commit log reads like a construction site: the foundations go in fast, then weeks of fixing what breaks under real use.
// the build log · mined from the commit history, nothing dramatised
An MCP server that generates images
The initial release landed on 7 November 2025: one MCP Image Generator, deployable to Cloudflare Workers. Within weeks it gained OAuth, a SQLite-backed Durable Object for token storage, and an admin dashboard. Steady, unglamorous work, but it proved the idea was deployable.
Sprint 1–3: API, WASM post-processing, album generation
Three sprints in one day on 6 March: the image generation API on Cloudflare Workers, a WASM-based post-processing pipeline, and album generation with templates and style anchoring. The architecture was settled fast and the foundation held.
Auth, brand kits, credits, the SPA
Sprints 4 through 15 in a single commit on 12 March: full-stack SPA, authentication, brand kit extraction, a credits system, and a run of UX fixes. The next day a CLI tool landed, service account credit bypass was added, and the domain was resolved: a brief stop at depict.au, then corrected to imagebot.au.
WordPress plugin, AI Photo Director, Virtual Photo Shoot
The WordPress plugin shipped on 15 March: v1.0.0, one repo, one commit. The day after, the engine gained an AI Photo Director, a dedicated /shoot page with image-type groupings, Quick Generate, and a shot-list builder with per-group controls. Seven commits in a single day, each fixing something real that the previous version exposed.
67 to 73 image types, Website Planner, reference images
A sprint block on 23 March added a Website Planner workflow and chart and diagram types, bringing the total to 73 generation types. The next day, reference URL support landed alongside logo relevance tuning for Gemini graphic types: the model now had something to anchor on.
Bug sprint: SSE thumbnails, social-card text, brand colour filtering
Four fixes on 3 April addressed real failures: social cards were injecting placeholder text into generated images, the brand extractor was picking up CMS default colours instead of actual brand colours, the base64 payload in one workflow step was hitting Cloudflare's 1 MiB limit, and preview thumbnails were switched to streaming SSE with per-thumbnail timeouts and error states.
GPT Image 2, timeouts, DO memory limits, security
Twenty commits on 24 April alone: GPT Image 2 was wired in for text-heavy image types, symmetric timeouts were applied across all Gemini and OpenAI fetches, and the Durable Object path for text-heavy generation was fixed to stay under the 128 MB isolate memory limit. Dogfood SQL scripts were added for fleet health and weekly usage visibility. In May, a security and billing fix pass addressed CORS allowlist enforcement and refund idempotency.
git log: “Fix social-card injecting placeholder text into images (#20) (#35)”
One of four reliability fixes shipped on 3 April: the kind of bug you only find when real images start coming back wrong.
// the roads not taken
Tried, measured, set aside: the judgement lives here as much as in what shipped.
depict.au → imagebot.au
The engine was briefly deployed under the domain depict.au before being corrected to imagebot.au, two commits on the same day capturing the decision and the fix.
Brand colour extraction, filtered for real colours
The original brand extractor was pulling CMS default colours instead of actual brand colours. A targeted fix was shipped after real use exposed the failure.
Want something built like this?
This is how we work: in the open, measured, honest about the dead ends.