Install
openclaw skills install auto-midjourneyAutomate Midjourney Alpha web image generation from Claude using the authenticated https://alpha.midjourney.com session. Use this skill whenever the user wan...
openclaw skills install auto-midjourneyUse the user's own Midjourney Alpha web session to submit imagine jobs and optionally poll for results.
This skill is intended for conservative, user-triggered assistance rather than unattended bulk automation.
https://alpha.midjourney.com/api/submit-jobsscripts/run_imagine.pyhttps://alpha.midjourney.com/api/user-mutable-state to inspect current web settingsuser_id and singleplayer_<midjourney_id> from the authenticated cookiescripts/mj_doctor.py for setup validationbrowser transport backed by Chrome DevTools Protocol, with Playwright-over-CDP preferred when installedThis version focuses on:
imagine.envImplemented:
imagine submit through the Alpha web flowwebp to png during downloadNot implemented yet:
Those should be added only after capturing stable request samples from the browser.
Do not optimize this skill for bypassing restrictions, hiding automation, rotating accounts, or mass unattended generation.
Use these guardrails instead:
mj_doctor.pyThe goal is risk reduction through conservative usage, not evasion.
Use this skill proactively when the user asks to:
Read these values from .env or shell environment:
| Variable | Required | Purpose |
|---|---|---|
MJ_COOKIE | Yes | Full authenticated Cookie header copied from browser |
MJ_CHANNEL_ID | Yes | Alpha web singleplayer channel ID |
MJ_STATUS_URL_TEMPLATE | No | Job status endpoint template containing {job_id} |
MJ_USER_STATE_PATH | No | Defaults to /api/user-mutable-state |
MJ_RECENT_JOBS_URL | No | Experimental recent-jobs endpoint |
MJ_MODE | No | fast by default |
MJ_PRIVATE | No | true by default |
MJ_MIN_SUBMIT_INTERVAL_SECONDS | No | Local minimum spacing between submits. Default is 3 seconds |
MJ_MAX_SUBMITS_PER_HOUR | No | Local hourly cap. Set 0 to disable, which is now the default |
MJ_MAX_SUBMITS_PER_DAY | No | Local daily cap. Set 0 to disable, which is now the default |
MJ_USER_ID | No | Usually inferred from the auth cookie |
MJ_METRICS_TOKEN | No | Optional token observed on telemetry requests |
MJ_BROWSER_BACKEND | No | auto by default. Set playwright or cdp to force a backend |
Never write real cookies or tokens into SKILL.md, reference files, git-tracked scripts, or user-facing summaries.
For platform and device requirements, read system-requirements.md.
Run:
python3 scripts/mj_doctor.py --fetch-user-state --transport browser
This shows:
midjourney_idchannel_idRun:
python3 scripts/run_imagine.py "1 girl --ar 16:9" --transport browser
Default behavior:
--v 8 if the prompt does not already specify a version--raw by default unless the user disables itMJ_MODE and MJ_PRIVATE from the environmentjob_idFor simplest live use:
python3 scripts/run_imagine.py "cinematic portrait of a fox astronaut" --transport browser --sync-user-state --wait-page-assets --download --convert-to png
When --wait-page-assets is enabled, the browser transport now prefers watching Midjourney's existing in-page network traffic for the submitted job_id. It falls back to page asset probing only if the low-impact watcher does not yield 4 images.
If a working status endpoint has been captured and stored in MJ_STATUS_URL_TEMPLATE, run:
python3 scripts/run_imagine.py "cinematic portrait of a fox astronaut --ar 16:9" --wait
Use dry-run first when changing payload structure:
python3 scripts/run_imagine.py "robot barista in tokyo alley" --dry-run
This validates prompt normalization and payload generation without sending a live request.
Run:
python3 scripts/run_imagine.py "silver perfume bottle on black glass" --preset product --sync-user-state
Preset definitions live in config/presets.example.json.
When the user wants better prompt wording, templates, or parameter tradeoffs, read prompt-craft.md.
Run:
python3 scripts/mj_prompt_helper.py --template product --subject "premium silver perfume bottle" --camera "front three-quarter angle" --surface "black glass surface" --lighting "controlled softbox rim light" --background "dark charcoal background" --mood "minimal luxury beauty campaign" --preset product_clean_square --quality-profile final_v8_q4 --json
This produces a V8-friendly prompt string and a ready-to-run run_imagine.py command.
Run:
python3 scripts/get_user_state.py --transport browser
This reads the same user-mutable-state endpoint the web app uses and returns values such as:
settings.speedsettings.visibilityabilitiesmacrospython3 scripts/submit_job.py "minimalist glass monolith --ar 16:9 --v 8"
python3 scripts/poll_job.py "<job_id>"
python3 scripts/get_user_state.py --transport browser
python3 scripts/mj_doctor.py --fetch-user-state --transport browser
python3 scripts/list_recent_jobs.py --amount 10
python3 scripts/run_imagine.py "fashion editorial, silver fabric, studio light --ar 3:4" --transport browser --sync-user-state --wait-page-assets --download --convert-to png
python3 scripts/batch_generate.py config/prompts.example.txt --transport browser --sync-user-state --convert-to png
Use conservative fixed spacing and batch cooldowns when needed:
python3 scripts/batch_generate.py config/prompts.example.txt --transport browser --sync-user-state --convert-to png --batch-size 5 --submit-interval-seconds 120 --batch-cooldown-seconds 600
Apply an opt-in quality profile to the whole batch:
python3 scripts/batch_generate.py config/prompts.example.txt --transport browser --sync-user-state --quality-profile final_v8_q4 --convert-to png
python3 scripts/convert_downloads.py outputs
Or write converted files into a separate directory:
python3 scripts/convert_downloads.py outputs --output-dir outputs/png-converted
If you want to rebuild PNGs from a saved result manifest instead of local files:
python3 scripts/convert_downloads.py outputs/live-test/recent-job.json --output-dir outputs/png-rebuilt
This waits for the submitted job_id to appear in the browser page resource list, verifies that 4 Midjourney CDN image URLs exist, and downloads the returned image files into outputs/<job_id>/.
Create a text file with one prompt per line, then run:
python3 scripts/batch_generate.py prompts.txt --transport browser --sync-user-state --download-dir outputs/batch
This submits prompts one by one, waits for each job_id to produce page resource URLs, and downloads the returned image files before moving to the next prompt.
python3 scripts/run_imagine.py "fashion editorial, silver fabric, studio light --ar 3:4" --sync-user-state --wait-recent-jobs --download
When the user does not specify MJ flags:
--v 8--raw--hd--q 4 as an opt-in final-pass override rather than a default for the current V8-focused flowDo not silently override explicit user flags.
When you use this skill, report back in this structure:
Prompt: <final prompt sent>
Job ID: <job_id or "not returned">
Mode: <fast/relax/etc>
Visibility: <private/public>
Status: <submitted / polled / failed / dry-run>
Notes: <missing status endpoint, saved JSON path, or next step>
For day-to-day use, prefer this sequence:
python3 scripts/mj_doctor.py --fetch-user-state --transport browserpython3 scripts/run_imagine.py "<prompt>" --transport browser --sync-user-statepython3 scripts/run_imagine.py "<prompt>" --transport browser --sync-user-state --wait-page-assets --downloadThis reduces manual mistakes and keeps you in a low-frequency workflow. On this machine, browser transport is the preferred live path because raw HTTP requests are blocked by Cloudflare.
Treat a generation as verified only when all of these are true:
job_idjob_idNormal Midjourney imagine behavior is a 4-image grid. Depending on the endpoint response, you may get one grid image file rather than four separately cropped files. This skill currently verifies and downloads the returned image assets as provided by Midjourney.
After the user captures more browser requests, extend in this order:
POST https://proxima.midjourney.com/ is currently treated as telemetry ingestionPOST /api/v1/traces is currently treated as tracing/observability dataGET /api/user-mutable-state is useful for reading current speed and visibility defaultsDo not mistake telemetry endpoints for job-status APIs.
The skill includes an experimental recent-jobs reader based on public GitHub reverse-engineering notes. Treat it as best-effort support rather than a stable API contract.