OpenRouter Chat
One API key, fifty free LLMs inside your workflow — OpenRouter Chat
- image_input
- response
- status
- help
You do not need a second GPU to put a smart language model in your ComfyUI workflow. That's the whole pitch of the OpenRouter Chat node: one API key from openrouter.ai, one node, and the entire catalog of models OpenRouter fronts - dozens of them free. It is a chat-completion client wearing a ComfyUI jacket, and it's the node people actually mean when they say "put an LLM in ComfyUI without running Ollama."
Why would you want an LLM in the graph at all? The modern answer: prompt generation has become an in-workflow step, not a browser tab. The KB's own reading of the landscape is that LLM-assisted prompting is now the norm - on LLM-encoded models like Anima or Klein, the encoder is itself an LLM reading an instruction, so having another LLM write that instruction is translation between two things that speak the same language. In practice that means: feed a rough idea in, get a structured, camera-and-lighting-savvy prompt out, wire the response straight into your text encoder. It's also the obvious tool for batch captioning, JSON metadata, or "why is this prompt giving me fingers" debugging.
How it works
Under the hood it's a plain HTTP call to OpenRouter's OpenAI-compatible endpoint (https://openrouter.ai/api/v1/chat/completions). The node builds a message array - your system_prompt first, then your user_prompt - and POSTs it with a bearer token. Vision is handled by base64-encoding the image into the message content, the standard trick that makes the same endpoint speak to Llama-4, Qwen-VL, and the rest.
The model dropdown is the clever bit: instead of a hardcoded list that rots, the node fetches OpenRouter's public model catalog on load and caches it for five minutes. New models appear without a pack update - hit Refresh on the node to re-pull. If OpenRouter is unreachable, you still get "Manual Input" so nothing bricks.
The inputs that actually matter
The node exposes a lot of sliders; you'll touch maybe five.
api_key- your OpenRouter key. Required, and the tooltip is blunt about it: the key is visible in workflows. Redact before you share anything.model- dropdown of currently-free models, or "Manual Input" with a customprovider/model:free(or paid) id inmanual_model.user_prompt- the thing you're asking. Required. This is the field you'd wire a node's text output into if you're chaining.system_prompt- sets behavior. The default ("You are a helpful AI assistant…") is fine to overwrite when you want tag-style output or a strict JSON contract.response_format-textorjson_object. Pick JSON and the model will actually return parseable JSON, but tell it what fields you want in the prompt or you'll get a shrug.temperature- 0.7 default; drop toward 0.2 for consistent structured output.
The ones to leave alone until you're chasing something: top_k, the three penalties, seed_mode/seed_value, max_retries. Outputs are response (the text/JSON - wire this into a Show Text node or a prompt writer), status (which model answered and the token counts), and help (a static usage cheat sheet).
Installing it
ComfyUI Manager is the easy road: search ComfyUI-EACloudNodes and install. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/EnragedAntelope/ComfyUI-EACloudNodes
cd ComfyUI-EACloudNodes
pip install -r requirements.txt
Then restart ComfyUI. Good news: requirements.txt is just Pillow, requests, torch, and torchvision - you already have all four, and there are no model files to download. The whole pack is three source files.
Where people get burned
- Sharing a workflow leaks your key. It's stored as a plain string input. Strip it or use an env-style loader before posting a workflow.
- Free models are a moving target. OpenRouter retires free endpoints with little notice; the "default" model you see is whatever the fetch returned, so it can drift between runs. If a dropdown entry 404s, that's why - pick a current one or type it manually.
- Image too big. Vision inputs cap at 2048×2048, and the node tells you to resize rather than guessing.
- Trust, but verify. Custom nodes run arbitrary Python with full OS access - the ecosystem has a documented history of exactly this being abused (the LLMVISION incident), and this is a third-party pack. Small install surface and readable source, but check the repo before you paste a key into it.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | ⚠️ Your OpenRouter API key from https://openrouter.ai/keys (Note: key will be visible - take care when sharing workflows) | |
| model | COMBO | cohere/north-mini-code:free | Select a free OpenRouter model or choose 'Manual Input' for custom models. Models with 'vision' or 'vl' support image inputs. Use ComfyUI's Refresh to update this list from OpenRouter's API. |
| manual_model | STRING | Enter a custom model identifier (only used when 'Manual Input' is selected). Format: provider/model-name[:free]. Leave empty if using dropdown. | |
| base_url | STRING | https://openrouter.ai/api/v1/chat/completions | OpenRouter API endpoint URL. Leave as default unless using a proxy or alternate endpoint. |
| system_prompt | STRING | You are a helpful AI assistant. Please provide clear, accurate, and ethical responses. | Optional system prompt to set the AI's behavior and context. Defines the assistant's role, personality, and guidelines. |
| user_prompt | STRING | Main prompt or question for the model. For vision models, describe what you want to know about the image. Required field. | |
| send_system | COMBO | yes | Toggle system prompt sending. Set to 'no' if the model doesn't support system prompts or you want to skip it. |
| temperature | FLOAT | 0.700–2 | Controls response randomness and creativity. Lower values (0.0-0.3) = more focused and deterministic. Higher values (0.7-2.0) = more creative and varied. |
| top_p | FLOAT | 0.700–1 | Nucleus sampling threshold. Controls diversity of word choices. Lower values (0.0-0.3) = more focused vocabulary. Higher values (0.7-1.0) = more diverse word selection. |
| top_k | INT | 501–1000 | Limits vocabulary to top K most likely tokens. Lower values = more focused. Higher values = more diverse. 50 is a balanced default. Range: 1-1000. |
| max_tokens | INT | 10001–32768 | Maximum number of tokens to generate in the response. Note: actual limit varies by model. Higher values allow longer responses. Range: 1-32,768. |
| frequency_penalty | FLOAT | 0.00-2–2 | Penalizes tokens based on their frequency in the output. Positive values reduce word repetition. Range: -2.0 to 2.0. 0.0 = no penalty. |
| presence_penalty | FLOAT | 0.00-2–2 | Penalizes tokens that have already appeared in the output. Positive values encourage topic diversity. Range: -2.0 to 2.0. 0.0 = no penalty. |
| repetition_penalty | FLOAT | 1.101–2 | OpenRouter-specific repetition penalty. Values > 1.0 reduce repetition. 1.0 = off. Higher values = stronger penalty. Range: 1.0-2.0. |
| response_format | COMBO | text | Response format: 'text' for natural language, 'json_object' for structured JSON output. When using JSON, instruct the model in your prompt to output JSON. |
| seed_mode | COMBO | random | Seed behavior control: 'fixed' uses the seed_value below, 'random' generates new seed each time, 'increment' increases by 1, 'decrement' decreases by 1. |
| seed_value | INT | 00–9007199254740991 | Seed value for reproducibility when seed_mode is 'fixed'. Use same seed + parameters for similar outputs. Valid range: 0-9007199254740991 (JavaScript safe integer limit). |
| max_retries | INT | 30–5 | Maximum number of automatic retry attempts for recoverable errors (rate limits, temporary server issues). 0 disables retries. Range: 0-5. |
| debug_mode | COMBO | off | Enable detailed error messages and request debugging information. Useful for troubleshooting API issues or parameter problems. |
| image_inputopt | IMAGE | Optional image input for vision-capable models. Supported: llama-4-maverick/scout, nemotron-nano-12b-v2-vl, qwen2.5-vl-32b. Maximum size: 2048x2048. | |
| additional_paramsopt | STRING | Additional OpenRouter API parameters in JSON format. Example: {"min_p": 0.1, "top_a": 0.5}. Use for advanced model-specific parameters not exposed in the UI. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| response | STRING | — |
| status | STRING | — |
| help | STRING | — |