Guide · 6 steps · ~20 minutes

How to give an AI agent real image capability

Wiring up a generation endpoint takes ten minutes. Building an agent that produces usable assets without burning your credits, drifting stylistically or retrying its own bugs takes a few more decisions. These are the six that matter, in the order you have to make them.

01

Decide who is choosing: the model, or your code

This one decision determines the whole shape. If the model decides which operation to run based on what the user asked, you want MCP — the tools arrive with schemas and the model picks. If your code already knows the sequence, use the REST endpoints; a protocol layer between your function and a POST request buys you nothing.

Model chooses → MCP

Code chooses → REST

Both, in the same product → both, same key

02

Give it a credential it cannot leak

The key goes in an environment variable or a client-managed secret, never in a file the agent might commit. Keys are individually revocable, so issue a separate one per surface — one for your editor, one for CI, one for production — and you can kill any of them without touching the others.

IMAGEMCP_API_KEY in env

x-api-key header for MCP

One key per surface

03

Teach it that outputs are inputs

Every tool returns a hosted URL and accepts one. That single convention is what makes chaining free: generate returns a URL, edit takes that URL and returns another, background removal takes that one, and so on. The agent never touches bytes, so a five-step pipeline costs the same context as one step.

generate → url

edit(url) → url

remove_background(url) → url

04

Batch everything that does not depend on the last result

Most image work in a real pipeline is embarrassingly parallel — twenty product photos, six avatars, four aspect ratios of one concept. Sequential calls make it feel slow for no reason. multicall takes a list of tool calls and runs them concurrently in a single round trip.

Sequential: 20 round trips

multicall: 1 round trip

Same credits either way

05

Put the budget in writing

An agent with a spending tool needs the same care as one with a deploy tool. Checking the balance is free, so make it the first step of any batch. Cap how many images one run may produce. State when it should stop and ask. Written constraints are followed far more reliably than implied ones.

get_user_info before a batch

Cap batch size explicitly

Draft cheap, finalise expensive

06

Make failure a decision, not a retry loop

Three failures matter and each needs a different response. Out of credits: stop and report — retrying cannot help. Model unavailable: fall back to the default model. Bad arguments: that is a bug in what the agent sent, and an identical retry fails identically. An agent that retries everything three times turns one bad call into three charges.

No credits → stop

Bad model → fall back

Bad args → fix, do not retry

A worked pipeline, end to end

Six product photos arrive from a supplier. They need to be catalogue-ready. This is the whole run — check, batch, chain, compress — with nothing held in memory.

const api = "https://api.imagemcpserver.com";
const auth = { Authorization: `Bearer ${key}`,
               "Content-Type": "application/json" };

// 1 — free call: can we afford this?
const { user } = await post("/auth/user-data");
if (user.credits < 6 * 24) {
  throw new Error("not enough credits");
}

// 2 — batch the cutouts, in parallel
const { results } = await post("/playground/multicall", {
  requests: photos.map((p) => ({
    tool: "remove_background",
    args: { image: p.url },
  })),
});

// 3 — chain: each cutout feeds the upscale
const upscaled = await post("/playground/multicall", {
  requests: results.map((r) => ({
    tool: "upscale_image",
    args: { image: r.url, scale: "4x" },
  })),
});

// 4 — ship it light
const final = await post("/playground/multicall", {
  requests: upscaled.results.map((r) => ({
    tool: "compress_image",
    args: { image: r.url, quality: 80,
            targetFormat: "webp" },
  })),
});

3 round trips, not 18

Each stage is one batched request instead of six sequential ones.

0 bytes in memory

Only URLs move between stages. The agent never buffers an image.

144 credits, known in advance

6 × (8 + 15 + 1). Checked against the balance before anything ran.

18 log entries

Every call recorded with its tool and exact cost, auditable afterwards.

Five mistakes that cost real money

Retrying every failure three times

One bad argument becomes three charges. Retry transient failures; fix the rest.

Upscaling before cutting out

You pay to reconstruct detail in a background you then delete. Cut out first, always.

Iterating on a premium model

Draft on the fast tier. Only re-run the approved prompt on the expensive one.

No reference image in a batch

Twenty images, twenty art directions. The fix costs nothing and takes one field.

Writing uncompressed output to a repo

A generated PNG is not a shipped asset. One credit stands between the two.

Agent pipeline questions

Should the agent hold image bytes in memory?

No. Every call returns a hosted URL and accepts one as input, so the agent passes references between steps rather than base64 blobs. That keeps the context window free for reasoning instead of pixels, and makes a five-step chain no heavier than a one-step call.

How do I stop an agent looping on image generation?

Give it a budget in words, make it check the balance first, and cap the batch size. The three account-level tools are free to call, so an agent can always know what it can afford before it starts spending.

What should the agent do when a call fails?

Read the error and adapt rather than retry blindly. Insufficient credits should stop the run and report; an unavailable model should fall back to the default; a malformed input is a bug in the agent’s own arguments and retrying identically will fail identically.

How do I keep a batch of images visually consistent?

Generate one, approve it, then pass its URL in referenceImages for everything else in the batch. This matters more than model choice and more than prompt length.

Can this run without a human in the loop at all?

Yes, and that is the interesting case — a nightly job that fills missing assets, a build step that generates any Open Graph image a route is lacking. Write the constraints down, cap the spend, and read the request log afterwards.

Next