Kraken Discord Bot (All-in-One)
Your ComfyUI box, now a Discord image bot — one token, one node
- generated_image
The name isn't a metaphor. This node is a Discord bot.
Paste a bot token, pick a checkpoint, queue the workflow, and suddenly anyone in your server can type !generate a dragon over a mountain at dawn --cinematic --fog and get an image back in the same channel, wrapped in a neat embed with the seed, CFG, and generation time. No external API, no webhook glue, no separate process to babysit. It runs on your own GPU, inside ComfyUI. If your goal is "friends can generate on my hardware without me hand-holding," this is the shortest path from zero to working bot I've seen.
How it works
Under the hood this is a real discord.py client living in a background thread. When you queue the node it starts the bot, loads your checkpoint and LoRAs, then blocks waiting for the next !generate. Each command becomes a full generation: prompt encoding, sampling with the sampler you picked, VAE decode, then posting the image back with an embed. Then it goes back to waiting.
The part that surprises people: this node never "finishes." It tells ComfyUI to always re-execute (IS_CHANGED returns the current time), so it holds one execution slot for as long as you leave it queued. One generation at a time, with a configurable per-user cooldown (30 seconds by default) and a max queue of 10 - because if you don't rate-limit, "free image bot" turns into "my GPU is melting."
The inputs that matter
Most of them are defaults you set once. The two that actually matter:
- discord_token - required. Paste your bot token here. Once queued, the node saves it to a local config file and the field shows "Token Loaded" instead - which means your token never gets baked into a workflow JSON you might share. That's the right instinct; tokens living inside workflow files is how people leak them.
- checkpoint - the model for generation. Drop it into
models/checkpointsand pick it from the list.
Then set default_steps, default_cfg, default_width/height, sampler_name, and scheduler as your safe baseline - users override all of these per-command with flags (--steps 30, --seed 123). denoise defaults to 1.0; with no image input, lower values just make noise - leave it.
Worth knowing in the optional section: lora_1/2/3 with per-slot lora_X_strength, use_civitai_triggers (auto-fetches a LoRA's trigger words and recommended strengths from CivitAI by file hash - genuinely handy, since forgetting a trigger word is the classic LoRA failure), upscale_model (enables --upscale), rate_limit_seconds, max_queue_size, and allowed_channels (comma-separated channel IDs to lock the bot down to specific rooms). The civitai_api_status field just shows "No Key" or "Key Loaded" - a CivitAI key is optional and only used for trigger fetching.
Output
It posts to Discord, and it also returns a generated_image (IMAGE) so you can archive locally - wire it into a Save Image node for a permanent copy. On a generation error it returns a blank 64×64 tensor and sends the error text to the user in Discord, which beats silently dying.
Discord-side setup (the part that trips everyone)
Before the node responds at all, you need a bot that's allowed to read messages:
- Create an application in the Discord Developer Portal, add a Bot, and enable Message Content Intent under Privileged Gateway Intents - the #1 reason a bot "installs fine but never responds."
- Generate an OAuth2 invite URL with the
botscope and theSend Messages,Embed Links,Attach Files,Read Message Historypermissions, then invite it to your server.
Installing it
ComfyUI Manager: search "Kraken Discord Bot" and hit Install. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/krakenunbound/kraken-discord-bot.git
cd kraken-discord-bot
pip install -r requirements.txt
Restart ComfyUI. Base requirements are just discord.py and requests. Two optional extras matter: --enhance needs transformers + accelerate, and --upscale needs spandrel - on portable ComfyUI, .\python_embeded\python.exe -m pip install transformers accelerate spandrel.
Where people get burned
- The node blocks your queue. While it waits for commands, that's your one GPU task. Don't queue it alongside a big batch expecting parallelism.
--enhanceis a big download. First use pulls Qwen2-VL-2B-Instruct (~4GB) and needs spare VRAM. It unloads after each call, but the first one is slow and the second one reloads it.--upscalesilently no-ops without a model. The flag only works if anupscale_modelis selected in the node; otherwise it just logs a warning.- It's built for the classic checkpoint path - SD 1.5 / SDXL lineage via checkpoint + CLIP + the stock LoRA loader. A Flux GGUF or a pure UNET-loader workflow isn't what this node drives.
- It's young and obscure. Zero Google impressions, one release, no community to lean on. Treat it as a weekend project that works rather than a battle-tested tool - when something breaks, the ComfyUI console is your debugging home.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| discord_token | STRING | — | |
| checkpoint | COMBO | 1 options: none | |
| default_negative | STRING | ugly, blurry, low quality, distorted | — |
| default_steps | INT | 201–100 | — |
| default_cfg | FLOAT | 7.01–30 | — |
| default_width | INT | 1024512–2048 | — |
| default_height | INT | 1024512–2048 | — |
| sampler_name | COMBO | euler_ancestral | 44 options: euler, euler_cfg_pp, euler_ancestral, euler_ancestral_cfg_pp, heun, heunpp2, +38 |
| scheduler | COMBO | normal | 9 options: simple, sgm_uniform, karras, exponential, ddim_uniform, beta, +3 |
| denoise | FLOAT | 1.000–1 | — |
| lora_1opt | COMBO | None | 1 options: None |
| lora_1_strengthopt | FLOAT | 1.00-2–2 | — |
| lora_2opt | COMBO | None | 1 options: None |
| lora_2_strengthopt | FLOAT | 1.00-2–2 | — |
| lora_3opt | COMBO | None | 1 options: None |
| lora_3_strengthopt | FLOAT | 1.00-2–2 | — |
| use_civitai_triggersopt | BOOLEAN | true | — |
| civitai_api_statusopt | STRING | No Key | — |
| upscale_modelopt | COMBO | None | 1 options: None |
| rate_limit_secondsopt | INT | 300–300 | — |
| max_queue_sizeopt | INT | 101–100 | — |
| allowed_channelsopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| generated_image | IMAGE | — |