@robobffs/imagelab-cli
v0.3.0
Published
Drive ImageLab from the terminal — generate images over the hardened ImageLab API.
Downloads
30
Readme
imagelab CLI
Drive ImageLab from the terminal — generate images over the hardened ImageLab API. Org-billed; generations attributed to the user who owns the API key land in that user's Library.
This package ships two binaries: the
imagelabCLI and theimagelab-mcpMCP server (see below). For the team/agent overview across all three surfaces (API + CLI + MCP) and the full threat model, seedocs/AGENT-SURFACES.md.
Install
npm install -g @robobffs/imagelab-cli # then `imagelab …`
# or run ad hoc:
npx @robobffs/imagelab-cli whoamiAuthentication
The CLI reads your API key from the IMAGELAB_API_KEY environment variable. Nothing is written to disk or a keychain — set the env var per session (or persist it yourself).
# PowerShell (current session)
$env:IMAGELAB_API_KEY = "il_live_..."
# PowerShell (persist for your user)
[Environment]::SetEnvironmentVariable("IMAGELAB_API_KEY", "il_live_...", "User")# bash / zsh
export IMAGELAB_API_KEY="il_live_..."Mint a key in ImageLab → Profile → API keys.
Never paste your key into a chat, ticket, or commit. Revoke keys after demos.
Commands
imagelab whoami # validate the key, show identity (alias: imagelab auth status)
imagelab styles [--family <f>] # list style slugs to pass to `gen`
imagelab gen --style <slug> --prompt "<text>" [options]
imagelab list [options] # recent generations in your Library
imagelab status <id> # show one generation's state (recovers a timed-out gen)
imagelab pull <id> [--out file] # download a completed generation's image
imagelab batch --file <jsonl> # resumable, money-safe bulk generation
imagelab ref add <file> # upload a reference image, print a reusable id
imagelab --versionCharacter / mascot lock (--ref)
Attach a reference image so a generation matches it (e.g. lock a mascot across a
campaign). On gen, --ref takes a local PNG/JPEG/WebP path (uploaded inline) or
an existing reference id; repeat up to 10. --ref-intent is reference (guide a
new image, default) or edit (transform the ref).
imagelab gen --style <slug> --prompt "..." --ref ./frankie.png --aspect 9:16 --out post.pngTo reuse one reference across a batch (and keep resume money-safe), upload once
and pass the id — batch lines accept reference uuids only:
imagelab ref add ./frankie.png # → reference id: 3f2a…
# JSONL line: {"style":"…","prompt":"…","ref":["3f2a…"]}Needs
references:writeon your key (in the default scope set; re-mint older keys).
styles
Lists the catalog (slug, family, name). Pass --family <name> to filter. The slug column is what you give gen --style.
list
Recent generations. A user-bound key sees only its own; org keys see org-wide. Defaults to completed only.
| Flag | Description |
|------|-------------|
| --project <slug> | filter to a project (or all for org-wide) |
| --status <s> | pending · complete · failed (default complete) |
| --limit <n> | max rows (1–100) |
| --starred | only starred generations |
status / pull
status <id> shows a generation's state — and is the recovery command if a gen timed out or was Ctrl-C'd (the image keeps rendering server-side). pull <id> downloads a completed image (atomically; --out defaults to <id>.png, --force to overwrite). pull on a still-pending gen exits 4 (retry later); on a failed gen, 3.
gen
| Flag | Description |
|------|-------------|
| --style <slug> | required — style slug |
| --prompt <text> | required — the subject to render |
| --size <size> | 1024x1024 (default) · 1024x1536 · 1536x1024 |
| --aspect <ratio> | marketing/social ratio, mutually exclusive with --size: 1:1 · 4:5 · 9:16 · 2:3 · 16:9 · 1.91:1 · 3:2. Generated at the nearest native gpt-image-2 size, then center-cropped to the exact ratio. You're billed on the native size (the crop is free). |
| --quality <q> | low · medium · high (default) |
| --project <uuid> | destination project id. API keys carry no active-project cookie, so without this the generation lands at the org/owner root (your default Library), not a project |
| --out <file> | download the finished image to this path (atomic; needs --force to overwrite) |
| --timeout <sec> | max seconds to wait for completion (default 180) |
imagelab gen --style anime-t1-ghibli-hand-paint --prompt "a robot tending a rooftop garden" --out garden.png
# request a 9:16 vertical for social (generated 1024x1536, cropped to 864x1536):
imagelab gen --style anime-t1-ghibli-hand-paint --prompt "a robot tending a rooftop garden" --aspect 9:16 --out garden-9x16.pngGeneration is async: the CLI submits, prints Generation started: <id>, then polls until the image completes. The submit carries an Idempotency-Key, so a dropped connection or retry never bills a second image. If you Ctrl-C or hit --timeout, the job keeps running server-side — retrieve it later with imagelab status <id> then imagelab pull <id>.
batch
Generate many images from a JSONL file — one {style, prompt, size?, aspect?, quality?, project?, out?} object per line (size and aspect are mutually exclusive). Resumable and money-safe: each item gets a deterministic Idempotency-Key, so re-running the same file replays (skips completed items, $0.00) instead of double-billing. A manifest.jsonl is written to --out-dir to track progress; submits are paced under the server's per-actor rate cap.
| Flag | Description |
|------|-------------|
| --file <jsonl> | required — input file, one generation object per line |
| --out-dir <dir> | directory for images + manifest.jsonl (default .) |
| --concurrency <n> | parallel in-flight generations, 1–3 (default 3; the server caps in-flight generations at 3 per user) |
| --timeout <sec> | per-item max wait for completion (default 180) |
| --force | overwrite existing images; continue against a manifest from a changed file |
imagelab batch --file prompts.jsonl --out-dir ./outCost: a batch of N items costs ≈ N × per-image price. The CLI validates the whole file before spending; start small. A re-run of an unchanged file re-bills nothing.
Global flags
| Flag | Description |
|------|-------------|
| --json | machine-readable JSON on stdout; all progress goes to stderr |
| --base-url <url> | override the API base URL (env IMAGELAB_BASE_URL; default prod) |
MCP server (imagelab-mcp)
The same package ships a stdio MCP server so AI agents (Claude Desktop, ChatGPT desktop, etc.) can drive ImageLab directly. It exposes five tools — generate_image, get_generation, list_generations, list_styles, list_projects — each gated to your key's scopes (a tool only appears if the key can use it).
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"imagelab": {
"command": "imagelab-mcp",
"env": { "IMAGELAB_API_KEY": "il_live_..." }
}
}
}Generation is paid and async: generate_image returns a generation id immediately (poll get_generation for completion + the image URL), or pass wait: true to block until done. By default tools return the image URL; get_generation writes a file only when you pass save_path (confined to IMAGELAB_MCP_OUT_DIR or the server cwd — path traversal is rejected).
| Env var | Purpose |
|---------|---------|
| IMAGELAB_API_KEY | required — your key |
| IMAGELAB_BASE_URL | override the API base URL (default prod) |
| IMAGELAB_MCP_OUT_DIR | base dir for save_path writes (default cwd) |
| IMAGELAB_MCP_MAX_GENERATIONS | session spend backstop — max generations per server run (default 25) |
Security: tool prompts may be model-authored — treat them as untrusted. The server caps generations per session and never writes outside its allowed dir. Don't paste your key into chat; use the
envblock above.
Exit codes
| Code | Meaning |
|------|---------|
| 0 | success |
| 1 | general / validation error |
| 2 | auth missing or invalid |
| 3 | generation failed server-side |
| 4 | timed out while still running (not a failure — job continues) |
| 5 | network / base URL unreachable |
| 130 | interrupted (SIGINT) |
