OpenRouter Simple (Text Output)
Frontier LLM answers inside your graph, without a key widget floating in your workflow JSON
- image
- image_2
- image_3
- video
- video_2
- video_3
- audio
- audio_2
- audio_3
- text
- info
- credits
If you've tried a local 8B in a prompt-enhancer node and watched it garble your instructions, this is the answer to that specific frustration. ComfyUI-OpenRouter-Simple is a single node - LLM → OpenRouter → OpenRouter Simple (Text Output) - that sends your prompt, plus up to three images, three videos, and three audio clips, to whatever frontier model you pick on OpenRouter, and hands back plain text. No local VRAM, no GGUF juggling, no Llama.cpp server to babysit. One key, one node, frontier-chat quality wired straight into a diffusion workflow.
Why you'd reach for it
The KB's read on the local-vs-API split is the read you'll hit in practice: a local abliterated model wins when you want uncensored and free, but small local models are exactly where people report instruction-following pain - that's the recurring complaint in the r/comfyui threads that end with someone asking for OpenRouter. This node is the API path: you're calling a hosted model that filters (so don't route your NSFW stuff through it) and costs per call, but follows directions. It slots in wherever you'd drop an LLM node - prompt enhancement, image captioning, describing a video frame before an image-to-video step - and the one thing it does differently is swallow multimodal context.
How it works
The node fetches OpenRouter's live model list, keeps only text-output models, and caches the snapshot. It then computes which models actually accept the media you've connected: required = text + every connected kind among image/video/audio, and only models whose input_modalities cover that set appear in the dropdown. If you plug an image cable in and the current model can't see it, it goes back to choose a compatible OpenRouter model rather than silently billing you for a model that ignores your attachment.
Before it sends anything, media gets compressed locally against hard byte caps - 1 MB WebP images, 10 MB MP4 video, 1 MB MP3 audio - so you're not paying to upload a 200 MB clip, and the request hardcodes modalities: ["text"]. Timeout is a real deadline, not a polite suggestion: ComfyUI Stop cancels the HTTP call and kills ffmpeg children instead of leaving a phantom background request burning credits. There's no seed, no tools, no streaming, no JSON Schema - deliberately.
The inputs that actually matter
You'll set a handful of these and leave the rest alone:
model- live OpenRouter models, filtered by what's connected.system_promptanduser_prompt- the instruction and the message.reasoning_effort-autothroughmax; if a model doesn't support what you pick, it fails before submission, not after billing you.max_tokens- one total budget shared by hidden reasoning and visible output; maps tomax_completion_tokenswhere available.response_format-textorjson_object, useful if you're feeding an LLM into a structured prompt step.timeout_seconds- defaults to 120.
The three outputs are text (wire it into whatever expects a string), info (compact JSON with model and routing details), and credits (remaining balance - key-limited unless you also set an OPENROUTER_MANAGEMENT_KEY).
Install
ComfyUI Manager: search ComfyUI-OpenRouter-Simple. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/Hearmeman24/ComfyUI-OpenRouter-Simple.git
python -m pip install -r ComfyUI-OpenRouter-Simple/requirements.txt
Then restart ComfyUI. You need ComfyUI v0.32.0+ and Python 3.10+; if you want the video or audio sockets to do anything, install ffmpeg/ffprobe too. There's deliberately no key widget - the generation key goes in your environment:
export OPENROUTER_API_KEY="your-generation-key"
Where people trip up
The first thing you'll hunt for is the key field, because every other API node has one. This one doesn't - no key saved into workflow JSON, which is a feature when you share a workflow and don't want your key in it. Second: the regenerate toggle is on by default (fresh request every queue); flip it off to reuse ComfyUI's output cache while inputs are unchanged. And if the model dropdown ever looks empty or stuck on "choose a compatible model," it's the modality filter doing its job - check what's plugged into those nine sockets. Also, the whole thing is arbitrary Python that phones home with a credential, the same shape as the category that shipped malware once, so only install it from the official repo/registry and read it before you trust it with a real key.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | Loading OpenRouter models… | 1 options: Loading OpenRouter models… |
| reasoning_effort | COMBO | auto | 8 options: auto, none, minimal, low, medium, high, +2 |
| timeout_seconds | INT | 1201–3600 | — |
| temperature | FLOAT | 1.000–2 | — |
| max_tokens | INT | 40961–1000000 | — |
| response_format | COMBO | text | 2 options: text, json_object |
| zdr | BOOLEAN | false | — |
| regenerate | BOOLEAN | true | — |
| system_prompt | STRING | You are a helpful assistant. | — |
| user_prompt | STRING | Describe the supplied context. | — |
| imageopt | IMAGE | — | |
| image_2opt | IMAGE | — | |
| image_3opt | IMAGE | — | |
| videoopt | VIDEO | — | |
| video_2opt | VIDEO | — | |
| video_3opt | VIDEO | — | |
| audioopt | AUDIO | — | |
| audio_2opt | AUDIO | — | |
| audio_3opt | AUDIO | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| info | STRING | — |
| credits | STRING | — |