Doop
Doop is an open-source multiplayer design canvas and design MCP for Claude Code, Codex, and any AI agent. Design side by side with agents — free in beta.
A free, open-source macOS app. Describe an image, then say what to change. A small agent on your Mac plans each message. No account, no cloud.
DesignPython · SwiftGitHub @rootonchairOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Chat to create and edit images on your Mac, built on MLX. Keeps your Mac usable while it works.
Taken from the repository README
Loading the full README.
Read the full README ↗Use chat to make and edit images fully on your Mac. dMLX is a native macOS app and a local engine. The engine uses MLX and mflux. A small agent on your Mac plans each message.
You can use your Mac while dMLX works.
Status: v0.1 beta 4. dMLX makes only images (it generates and edits them). Video is planned. The app is not notarized yet. Refer to the release notes and the known issues.
Each example is a chat in the app, with Auto set. The agent selected the model. For a removal, the first message makes an image and the second message removes something from it.
"remove all the text from the window" · Qwen Image 2.1 · about 5 min
"remove the coffee mug" · FLUX.2 Klein 4B · 36 s
"remove the person" · FLUX.2 Klein 4B · 40 s
A Portrait image with a title · Qwen Image 2.1 · about 4 min
A Landscape image with words · Qwen Image 2.1 · about 4 min
For exact words in an image, the agent usually selects Qwen Image 2.1. This model is slow, it needs about 9.5 GB of free memory, and its license does not permit commercial use. FLUX.2 Klein 4B is fast, but it does not always spell words correctly.
You can write in simple words how to change a result. You can also show your request on the image first. Open Crop / Draw below a result. Crop the image. Paint marks on it. Erase the marks that are not correct. Click Attach edited image. Then write what to do. The app does not change the original image.
| 1 · Crop | 2 · Paint a mark | 3 · Erase an incorrect mark |
|---|---|---|
| The dark area is not in the prepared image. | The circle shows the area to change. The line onto the table is an error. | Erase removes only paint. The image below the paint does not change. |
4 · Attach and ask. Attach edited image puts the prepared image in the message box. The agent gets the prepared image, a note that tells it the image is image 1 after Crop / Draw, and your words. The marks are part of the prepared image. Write "remove the marks" in your message, or the result can keep them. The prepared image is one of the 3 images that you can attach.
| Before (the prepared image 1) | After (image 2, "Edited from the prepared image 1") |
|---|---|
The result has the size and the framing of the cropped area, not of the full image 1.
All screenshots show the app on a 24 GB Mac. The agent model is Qwen3-VL 8B.
After you send a message, the chat shows it with "Planning…" while the agent decides. You can type your next message. You can send it when the plan is complete.
With two images in the chat, the message "make them match" gets a question. The agent does not guess. You can answer the question, click Create new or Edit current, or send a different request.
The message "give the teapot the same weathered wood as the boat" edits the teapot. It uses the boat as a reference ("Edited from image 2 · v1 + 1 reference").
The teapot is the latest image. The message "make the boat red" edits the boat in image 1. If the message refers to older images, the agent examines them.
If you send a greeting or thanks, the agent replies in the chat. It does not make an image.
You can attach a maximum of 3 images with the paper clip or with drag and drop. The message "a lighthouse on a cliff at dusk, painted like this" uses the attached watercolor as the style.
Variations adds v2, v3 and more to a result. Click v1 or v2 to show a version. You can edit each version. The save button writes the image to Pictures/dMLX with its prompt and seed.
For a title in the image, the agent selected Qwen Image 2.1, because this model is the best at text in images. This model needed 9.5 GB, but only 9.2 GB was available without slowing down the Mac. Thus the engine refused the job. Try anyway runs the job in the mode that uses the least memory. If the Mac becomes slow, the engine stops the job.
Use the search field to find community versions of the supported families. You can also paste a Hugging Face repo. Before the download, dMLX makes sure that it can use the repo. It also shows the download size and the license.
You can see the installed models, remove models, and set the default model. If you set Auto, the agent selects the model.
The agent plans each message that you send. The agent:
If the agent is not sure, it asks one short question. You can answer the question or send a different request. After you send a message, the chat shows it with Planning…. The app never discards the message. You can continue to type.
Where the agent runs. By default the agent runs on your Mac. In the first-run setup, or in Settings → Intelligence → Agent, you can use an AI service that you already have instead:
| Service | What you need | Notes |
|---|---|---|
| Claude (Anthropic) | An API key | Opus 5.5, Sonnet 5.5 or Haiku 5.5. Anthropic charges your account. |
| ChatGPT (OpenAI) | An API key (a ChatGPT subscription is not an API key) | Pick a model from your account's list. OpenAI charges your account. |
| Ollama | Ollama on this Mac | Free. Pick a model that can see images. |
| Other service | Its address, and a key if it needs one | Any service with an OpenAI-compatible API, for example LM Studio or OpenRouter. |
With a service, your messages and the images in the chat go to that service to plan each message. The images are still made on your Mac. The app keeps the API key in the macOS Keychain; the engine keeps it in memory only. Before it saves your choice, the app sends one small test request.
The agent makes its decisions from its instructions and tools, not from fixed rules in the code. The code only refuses a request that cannot run, for example an image that does not exist or an edit with no image.
| Agent model | Download | Peak memory | Per message | Notes |
|---|---|---|---|---|
| Qwen3-VL 8B | 5.8 GB | 6.2 GB | ~7 s | Default for 24 GB and more |
| Ministral 3 3B | 2.8 GB | 4.2 GB | ~5.5 s | Default for less than 24 GB |
| Qwen3-VL 4B | 3.1 GB | 3.7 GB | ~3.5 s | Uses the least memory; seldom examines older images |
These values are from an M5 with 24 GB (2026-11-01). The engine loads the agent only while the agent plans.
The engine removes the agent from memory before the image job starts. If there is no agent model, the engine
uses simple rules to route messages. For more data, refer to
docs/benchmarks/agent-models.md and tasks/.
dMLX-<version>-macos-arm64.dmg from the dMLX website or from
GitHub Releases, which also has a .zip of the same app..dmg and drag dMLX.app onto the Applications folder.xattr -dr com.apple.quarantine /Applications/dMLX.app.Select dMLX → Uninstall dMLX…, or Settings → General → Uninstall dMLX…. dMLX shows how much space it
uses, and after you confirm, it deletes all of its models, your chats and images, its settings and its API
keys. Then it moves dMLX.app to the Trash. Save the images that you want to keep before you start.
If you drag dMLX.app to the Trash, macOS keeps the models and your data. To delete them after that, delete
~/Library/Application Support/dMLX. To delete only one model, use Remove… in Settings → Models.
| Model | Does | License | Download | Notes |
|---|---|---|---|---|
| FLUX.2 Klein 4B (4-bit) | generate, edit, a maximum of 3 images | Apache-2.0 | 4.6 GB | The default; ~20–40 s per image |
| Z-Image Turbo (4-bit) | generate | Apache-2.0 | 5.9 GB | Optional; more photographic detail |
| Qwen Image 2.1 Base (4-bit) | generate, edit, a maximum of 10 images in a set order | Qwen Research License (non-commercial) | ~10.6 GB | Experimental; best for exact words in the image; ~4 min per image; needs ~9.5 GB of free memory |
Settings → Models → Add Model… shows community versions of the supported families (FLUX.2 Klein
4B/9B, FLUX.3 Klein, Z-Image Turbo/base, Qwen Image 2.1 Base, ERNIE Image Turbo, MOSS Image, Boogu Image Turbo, Iris 3B Turbo, Krea 2 Turbo). It also
accepts any Hugging Face repo in mflux format. One adapter runs all of these families from mflux's own
model classes, so a new mflux family needs a table entry and a memory measurement
(docs/benchmarks/families.md).
Before dMLX downloads a repo, it does a check of the family, size and license. If a license has
restrictions, dMLX asks you to accept it. Remove… deletes the files of a model. dMLX puts the weights in
its own folder, ~/Library/Application Support/dMLX/models-cache, in the standard Hugging Face layout, so
Uninstall dMLX… can delete all of them. The app bundle never contains weights. When dMLX starts, it moves
its models from the shared Hugging Face cache (~/.cache/huggingface) into its own folder. This includes models
from versions before 0.1.0 beta 5, and models that another tool downloaded first. dMLX does not download them
again, but the other tool does if it needs them. In Auto,
the engine uses Qwen Image 2.1 only if the agent selects it for a message.
Before each job, the engine calculates the memory that the job needs. The engine compares this value with the memory that it can use without a need for macOS to compress or swap other apps. The engine also keeps a reserve of memory for the system. Then it selects one of these strategies:
| Strategy | When | What stays loaded |
|---|---|---|
| eager | a large quantity of free memory | all parts; they stay in memory for the next requests |
| phase-free | some free memory | image model and decoder; the engine removes the text encoder after it reads the prompt |
| sequential | low free memory | one large part at a time |
| streamed | very low free memory | one block at a time; the engine reads each block from disk immediately before it runs (~25% slower; a 1024² image in ~1.5 GB) |
On Macs with less than 32 GB, FLUX.2 Klein decodes in exact bands (about 1.1 GB at 1024², not 8.6 GB). If
no strategy fits, the engine refuses the job and shows a clear message. Try anyway runs the job in the
mode that uses the least memory. While a job runs, the engine monitors memory pressure and swap-ins. The
engine stops the job before the Mac starts to hang. The engine removes the agent from memory before each
image job. Then the engine waits until that memory is free again. For more data, refer to
dmlx-spec.md §8, docs/benchmarks/b1.md,
b2.md and agent-16gb.md.
# engine (Python 3.13, uv)
cd engine && uv sync --extra local-llm && uv run pytest
# app (Swift 6 toolchain / Xcode 16+)
cd app && swift test
tools/dev/run_app.sh # runs the app; the engine starts from ../engine via uv
# release bundle (relocatable Python and engine inside the .app, ad-hoc signed), as a .dmg and a .zip
tools/bundle_app.sh --dmg --zip
To score the agent with the routing eval and placeholder images, run this command:
cd engine && uv run --extra local-llm python -m dmlx.prompting.agent_eval --model qwen3-vl-8b-instruct-4bit
To run the engine without the app, use these commands:
cd engine && uv run dmlx serve --port 8642
curl -s localhost:8642/v1/images/generations -H 'content-type: application/json' \
-d '{"prompt":"a rowboat on a lake at dawn","size":"1024x1024"}' | jq '.dmlx'
| Method | Path | Notes |
|---|---|---|
| POST | /v1/images/generations | OpenAI-compatible; stream: true returns server-sent events |
| POST | /v1/images/edits | multipart (OpenAI style) or JSON with source_id / reference_ids |
| POST | /v1/workflows | workflow with validation and capability checks; supports streaming |
| POST | /v1/workflows/route | what to do with a chat message; "plan": true asks the agent |
| GET | /v1/capabilities | operations and input limits of each model |
| POST | /v1/prompts/compile | prompt enhancement preview |
| POST | /v1/uploads | stores an image and gives an id for later references |
| GET | /v1/results/{id} · /meta | PNG with the prompt and seed in the file · its metadata |
| GET/DELETE | /v1/jobs/{id} · /events | status · cancel · events |
| POST | /v1/jobs/{id}/retry | runs a failed workflow again from the failed step |
| GET | /v1/models | catalog with downloaded / loaded state |
| POST | /admin/models/{id}/pull · load · unload | download, pin, free |
| GET | /admin/memory | memory budget, pressure, loaded parts |
| GET/POST | /admin/prompt-assistant · /select · /pull | agent models: status, select, download |
Events: queued, plan, loading{component}, encoding, step{step,total}, decoding,
image{result_id}, done{result_ids, report}, error{code,message}, cancelled.
The app sets these values in Settings → Intelligence. If you use the engine without the app, set these environment variables.
| Variable | Use |
|---|---|
DMLX_PROMPT_ASSISTANT_MODEL | Agent model id (for example, ministral-3-3b-instruct-2512-4bit) |
DMLX_PROMPT_ASSISTANT=off | Sets the agent to off |
DMLX_ROUTER_BASE_URL, DMLX_ROUTER_MODEL, DMLX_ROUTER_API_KEY, DMLX_ROUTER_TIMEOUT | Routes messages without the agent, through any OpenAI-compatible chat server (HTTPS, or HTTP on loopback) |
DMLX_ROUTER_PROVIDER=local-llm, DMLX_LOCAL_LLM_MODEL_PATH, DMLX_LOCAL_LLM_REVISION | Routes messages without the agent, through a local Qwen checkpoint ("Local Qwen MLX" in the app) |
DMLX_PROMPT_BASE_URL, DMLX_PROMPT_MODEL, DMLX_PROMPT_API_KEY, DMLX_PROMPT_TIMEOUT | Prompt enhancement through an OpenAI-compatible server |
DMLX_HOME | The data folder (default ~/Library/Application Support/dMLX). The models go in its models-cache folder |
HF_HUB_CACHE | If you set it, the engine downloads models to this Hugging Face cache, and does not move models |
If you set API keys in the app, the app keeps them in the macOS Keychain. When the agent plans, the engine also does a check of its answer. The images that the answer names must exist. An edit must use 1–3 images. The answer can use only workflows that an installed model can run. If the answer is still not valid after one retry, the app asks the user and does not guess.
engine/ Python engine (FastAPI + MLX via mflux), the planning agent, evals, tests
app/ SwiftUI app (DMLXKit library + app target), tests
tools/ bundle_app.sh (release), dev/ helpers (run_app.sh, the scripted dev harness)
docs/ release notes, known issues, benchmarks, screenshots
tasks/ open and finished agent tasks, with their results
All code in this repository uses the Apache-2.0 license. Model weights have their own licenses. The default models use Apache-2.0. The optional Qwen Image 2.1 uses the Qwen Research License (non-commercial).