Local/private image generation through Draw Things' gRPC server. This plugin intentionally does not replace Hermes Agent's default cloud image generation provider. Use it only when the user explicitly asks for Draw Things, local image generation, or a local model/LoRA such as Qwen Image, Z Image, ERNIE, FLUX, RealVisXL, Juggernaut, or FaceID/IP-Adapter workflows.
- Lists Draw Things models, LoRAs, ControlNets/IP-Adapters, upscalers, and textual inversions via gRPC
Echo. - Generates images via gRPC
GenerateImage. - Resolves friendly aliases such as
qwen-image-2512,z-image-turbo,ernie-image,realvisxl, andqwen-lightning. - Supports configurable default model and default LoRA selection.
- Applies layered model defaults for steps, sampler, CFG, LoRA weight, and related settings.
- Saves output images locally.
This plugin does not download every Draw Things model.
It only does this:
- Calls Draw Things gRPC
Echo. - Reads metadata for models/LoRAs/ControlNets already installed or visible in your Draw Things app/server.
- Resolves aliases/default settings for those installed items.
- Calls
GenerateImageusing the selected installed model.
It will not install Hugging Face files, mutate your Draw Things model library, or fill your disk.
- Hermes Agent with plugin support.
- Draw Things with the gRPC server enabled.
- Python dependencies available in the Hermes environment:
grpcioflatbuffersfpzipnumpyPillow
Install missing dependencies into Hermes' venv, for example:
~/.hermes/hermes-agent/venv/bin/python3 -m pip install grpcio flatbuffers fpzip numpy PillowClone/copy this plugin into your Hermes plugins directory:
mkdir -p ~/.hermes/plugins
git clone https://github.com/Wysie/drawthings-grpc-hermes-plugin.git ~/.hermes/plugins/drawthings-grpc
hermes plugins enable drawthings-grpc
hermes gateway restart # if using Telegram/WhatsApp/etc.Then start a new Hermes session so the new toolset is loaded.
drawthings_list: list installed models, LoRAs, ControlNets/IP-Adapters, upscalers, textual inversions from Draw Things gRPCEchometadata.drawthings_generate: text-to-image generation via Draw Things gRPCGenerateImage.
Toolset name:
drawthings
Defaults:
- Host:
localhost - Port:
7859 - TLS: enabled
For a durable setup, put the endpoint in the plugin's user config:
{
"endpoint": {
"host": "drawthings.local",
"port": 7859,
"tls": true,
"tls_name": "localhost"
}
}User config path:
~/.hermes/drawthings-grpc/config.json
This is preferred for Hermes gateway / WhatsApp / Telegram sessions because shell environment variables are not always inherited by long-running gateway tool processes. tls_name is the hostname used for TLS certificate verification; keep it as localhost when connecting to Draw Things by LAN IP because Draw Things' generated certificate is usually issued for localhost.
Environment variables are still supported as overrides, and are useful for one-off CLI runs, tests, or temporary endpoint switching:
DRAWTHINGS_GRPC_HOSTDRAWTHINGS_GRPC_PORTDRAWTHINGS_GRPC_TLSDRAWTHINGS_GRPC_TLS_NAME(defaultlocalhost; useful because Draw Things cert CN is usually localhost)DRAWTHINGS_OUTPUT_DIR(default~/Pictures/Draw Things)
Example temporary override:
export DRAWTHINGS_GRPC_HOST=drawthings.local
export DRAWTHINGS_GRPC_PORT=7859
export DRAWTHINGS_GRPC_TLS=true
export DRAWTHINGS_GRPC_TLS_NAME=localhostIf you do not want to manually enable the Draw Things app gRPC server after every launch, run the standalone gRPCServerCLI-macOS binary as a macOS LaunchAgent.
cd /tmp
curl -L -o gRPCServerCLI-macOS \
https://github.com/drawthingsai/draw-things-community/releases/download/v1.20260418.1/gRPCServerCLI-macOS
chmod +x gRPCServerCLI-macOS
sudo mkdir -p /usr/local/bin
sudo mv gRPCServerCLI-macOS /usr/local/bin/gRPCServerCLI-macOS
sudo xattr -dr com.apple.quarantine /usr/local/bin/gRPCServerCLI-macOSCommon macOS sandbox path:
~/Library/Containers/com.liuliu.draw-things/Data/Documents/Models
If unsure, search for it:
find "$HOME/Library/Containers" "$HOME/Documents" "$HOME/Library/Application Support" \
-type d -name Models 2>/dev/null | grep -i "draw\\|liuliu"Replace the models path if yours is different:
/usr/local/bin/gRPCServerCLI-macOS \
"$HOME/Library/Containers/com.liuliu.draw-things/Data/Documents/Models" \
--name "Draw Things gRPC Server" \
--address 0.0.0.0 \
--port 7859 \
--model-browserNotes:
- TLS is enabled by default. Do not pass
--no-tlsunless you also configure the plugin withDRAWTHINGS_GRPC_TLS=false. --address 0.0.0.0allows other machines on your LAN to connect.--port 7859matches the plugin default.--model-browserenables model/LoRA metadata discovery throughEcho.
From another machine, verify with grpcurl and the Draw Things imageService.proto:
grpcurl -insecure \
-import-path /path/to/draw-things-comfyui/resources \
-proto imageService.proto \
-d '{"name":"test"}' \
drawthings.local:7859 \
ImageGenerationService/EchoIf you use an IP address instead of drawthings.local, replace the host accordingly.
mkdir -p ~/Library/LaunchAgents ~/Library/Logs
cat > ~/Library/LaunchAgents/io.example.drawthings-grpc.plist <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>io.example.drawthings-grpc</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/gRPCServerCLI-macOS</string>
<string>/Users/YOUR_USERNAME/Library/Containers/com.liuliu.draw-things/Data/Documents/Models</string>
<string>--name</string>
<string>Draw Things gRPC Server</string>
<string>--address</string>
<string>0.0.0.0</string>
<string>--port</string>
<string>7859</string>
<string>--model-browser</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/YOUR_USERNAME/Library/Logs/drawthings-grpc.out.log</string>
<key>StandardErrorPath</key>
<string>/Users/YOUR_USERNAME/Library/Logs/drawthings-grpc.err.log</string>
</dict>
</plist>
PLISTEdit the plist and replace YOUR_USERNAME with your macOS username. Then load it:
launchctl unload ~/Library/LaunchAgents/io.example.drawthings-grpc.plist 2>/dev/null || true
launchctl load ~/Library/LaunchAgents/io.example.drawthings-grpc.plist
launchctl start io.example.drawthings-grpcVerify:
launchctl list | grep drawthings
lsof -nP -iTCP:7859 -sTCP:LISTEN
tail -50 ~/Library/Logs/drawthings-grpc.out.log
tail -50 ~/Library/Logs/drawthings-grpc.err.logOnce Echo works, configure this plugin to point at that server using ~/.hermes/drawthings-grpc/config.json:
{
"endpoint": {
"host": "drawthings.local",
"port": 7859,
"tls": true,
"tls_name": "localhost"
}
}Use DRAWTHINGS_GRPC_HOST, DRAWTHINGS_GRPC_PORT, and DRAWTHINGS_GRPC_TLS only when you need a temporary override.
Generate with Qwen Image quality defaults (also the bundled default model if model is omitted):
{
"prompt": "Hammy, a fluffy golden-and-white hamster...",
"model": "qwen-image-2512"
}Generate with Qwen Lightning LoRA:
{
"prompt": "Hammy, a fluffy golden-and-white hamster...",
"model": "qwen-image-2512",
"lora": "qwen-lightning"
}Generate with Z Image Turbo:
{
"prompt": "Hammy, a fluffy golden-and-white hamster...",
"model": "z-image-turbo"
}Generate with ERNIE:
{
"prompt": "Hammy, a fluffy golden-and-white hamster...",
"model": "ernie-image"
}The plugin accepts exact Draw Things filenames, exact display names, generated slugs, and configured aliases. Examples:
ernie-image,ernie-image-base→ernie_image_q8p.ckpternie-image-turbo,ernie-turbo→ernie_image_turbo_q8p.ckptqwen-image-2512,qwen2512,qwen-image→qwen_image_2512_q8p.ckptz-image-turbo,zturbo→z_image_turbo_1.0_q8p.ckptrealvisxl,realvisxl-v4→ RealVisXLjuggernaut-xl,juggernaut-v9→ Juggernaut XL v9qwen-lightning,lightning-4step→ Qwen Lightning LoRA
Draw Things has many models. The plugin should not maintain a giant download catalog. Instead it uses layered defaults:
version_defaults: defaults by Draw Things model family/version, e.g.qwen_image,z_image,ernie_image,sdxl_base_v0.9.model_defaults: overrides for known installed model files.lora_defaults: overrides for known LoRA files.default_model: model alias/name/file used when the caller omitsmodel.default_lora: optional LoRA alias/name/file used when the caller omitslora; callers can pass"lora": "none"to disable it.- user config overrides in
~/.hermes/drawthings-grpc/config.json. - explicit tool arguments always win.
Bundled defaults live in:
~/.hermes/plugins/drawthings-grpc/defaults.json
User overrides live in:
~/.hermes/drawthings-grpc/config.json
The bundled defaults.json and user config file use the same schema. User config is deep-merged over bundled defaults, so you can override just one alias or one field without copying the whole file.
Top-level options:
| Option | Type | Meaning |
|---|---|---|
description |
string | Human-readable note only. The plugin does not use it for behavior. |
endpoint |
object | Durable Draw Things gRPC connection settings. Preferred over environment variables for gateway/WhatsApp/Telegram sessions. |
host |
string | Legacy top-level endpoint host fallback. Usually prefer endpoint.host. |
port |
number/string | Legacy top-level endpoint port fallback. Usually prefer endpoint.port. |
tls |
boolean/string | Legacy top-level TLS fallback. Usually prefer endpoint.tls. |
tls_name |
string | Legacy top-level TLS certificate hostname fallback. Usually prefer endpoint.tls_name. |
default_model |
string | Model alias, display name, or exact file used when drawthings_generate omits model. |
default_lora |
string | Optional LoRA alias, display name, or exact file used when drawthings_generate omits lora. Pass "lora": "none" in a tool call to disable it for that generation. |
aliases |
object | Friendly names mapped to exact Draw Things model/LoRA filenames or display names. Alias keys are slugified, so Qwen Turbo V3 and qwen-turbo-v3 resolve the same way. |
version_defaults |
object | Defaults keyed by Draw Things model version, e.g. qwen_image, z_image, ernie_image. Applied when the selected model has that version. |
model_defaults |
object | Defaults keyed by exact model file, e.g. ernie_image_turbo_q8p.ckpt. Applied after version_defaults; use this when multiple model variants share the same version. |
lora_defaults |
object | Defaults keyed by exact LoRA file. Applied after model defaults when that LoRA is selected. Useful for speed LoRAs that need lower steps/CFG. |
endpoint fields:
| Field | Meaning |
|---|---|
host |
Hostname or IP of the Draw Things gRPC server. Public default is localhost; LAN setups often use a .local hostname or private IP in user config. |
port |
gRPC port. Draw Things and gRPCServerCLI commonly use 7859. |
tls |
Whether to use TLS. Draw Things gRPC uses TLS by default. Set false only if the server was started with --no-tls. |
tls_name |
Hostname used for TLS certificate verification. Draw Things certificates are usually issued for localhost, so keep this as localhost when connecting by LAN IP. |
Generation default fields inside version_defaults, model_defaults, and lora_defaults:
| Field | Meaning |
|---|---|
steps |
Sampling step count. Higher is slower and may improve quality for base models; turbo/lightning LoRAs usually need fewer steps. |
sampler |
Draw Things sampler name. Supported names include Euler A Trailing, Euler A, DPM++ 2M Karras, DPM++ SDE Karras, DPM++ 2M Trailing, DPM++ SDE Trailing, DDIM, DDIM Trailing, UniPC, UniPC Trailing, LCM, and TCD. Unknown names fall back to Euler A Trailing. |
cfg |
Guidance scale / CFG. Higher values follow the prompt more strongly but can overcook images; turbo models often use 1.0. |
lora_weight |
LoRA strength. Only used when a LoRA is selected. 1.0 means full weight; lower values reduce the LoRA effect. |
shift |
Flow scheduler shift value. Model-specific; keep the bundled default unless you know the recommended value. |
shift_terminal |
Optional terminal shift for schedulers/schemas that support it. If the installed Draw Things FlatBuffer schema lacks this field, the plugin reports it under unsupported_settings instead of failing. |
guidance_embed |
Guidance embedding value used by supported flow models. Defaults to 3.5 when not specified. |
resolution_dependent_shift |
Whether Draw Things should adjust shift by image resolution. Useful for some flow models, disabled for several turbo defaults. |
speed_up |
Controls Draw Things' speedUpWithGuidanceEmbed flag. Defaults to true if omitted. |
Resolution, seed, prompt, negative prompt, and output path are tool-call arguments rather than config-file defaults. width/height are rounded down to multiples of 64 and clamped between 64 and 2048.
Precedence for a generation is:
- Built-in fallback defaults in code.
- Bundled
defaults.json. - User config at
~/.hermes/drawthings-grpc/config.json. - Selected model
version_defaults. - Selected exact
model_defaults. - Selected exact
lora_defaults. - Explicit
drawthings_generatetool arguments.
Current bundled examples:
z_image/ Z Image Turbo: 8 steps, Euler A Trailing, CFG 1.0qwen_image/ Qwen Image 2512: 30 steps, Euler A Trailing, CFG 4.0ernie_image_q8p.ckpt/ ERNIE Image Base: 30 steps, Euler A Trailing, CFG 4.0ernie_image_turbo_q8p.ckpt/ ERNIE Image Turbo: 8 steps, Euler A Trailing, CFG 1.0flux1: 4 steps, Euler A Trailing, CFG 1.0sdxl_base_v0.9: 25 steps, DPM++ 2M Karras, CFG 7.0- Qwen Lightning/Turbo 4-step LoRAs: 4 steps, Euler A Trailing, CFG 1.0, LoRA weight 1.0
- Wuli Qwen Turbo 2-step LoRA: 2 steps, Euler A Trailing, CFG 1.0, LoRA weight 1.0
First install/add the model inside Draw Things itself. Once Draw Things can see it, the plugin can see it via drawthings_list.
Then optionally add friendly aliases and defaults:
{
"default_model": "qwen-image-2512",
"default_lora": "qwen-turbo-v3",
"aliases": {
"my-anime-model": "my_anime_model_q8p.ckpt",
"my-style-lora": "my_style_lora_f16.ckpt"
},
"model_defaults": {
"my_anime_model_q8p.ckpt": {
"steps": 28,
"sampler": "Euler A Trailing",
"cfg": 4.5,
"shift": 1.0,
"guidance_embed": 3.5,
"resolution_dependent_shift": true
}
},
"lora_defaults": {
"my_style_lora_f16.ckpt": {
"lora_weight": 0.8
}
}
}Save that as:
~/.hermes/drawthings-grpc/config.json
Then use:
{
"prompt": "...",
"model": "my-anime-model",
"lora": "my-style-lora"
}If an alias is ambiguous, use the exact Draw Things file name from drawthings_list.
Draw Things' HTTP API can be convenient, but gRPC exposes model browsing metadata, LoRA/ControlNet metadata, and deterministic FlatBuffer generation configuration. This makes it better for agent automation.
Implemented:
- model/LoRA listing
- alias resolution
- text-to-image generation
- output decoding/saving
- layered defaults and user overrides
Planned / future work:
- img2img
- inpainting
- ControlNet/IP-Adapter image hints
- FaceID workflows
- batch generation
- richer CLI wrapper
MIT