RemRun Add Remote Node Definitions
Use Your Second Machine's Nodes Like They're Installed Locally
So you've got the second box set up - the one with the big GPU - and you're offloading work to it with comfy_remote_run. Great. Now you hit the actual annoyance: all the good nodes and models live over there, and your local graph doesn't know they exist. Installing every custom node on both machines so your menus match is a slow way to burn an afternoon.
This node is the shortcut. It asks the remote ComfyUI for its complete node list, then registers stub definitions locally. Instantly, every node the remote machine can run shows up in your local node menu, in their own [RemoteNd]/ category, ready to wire in.
How it works
The mechanism is simple but a little wild. The node does an HTTP GET on <remote_url>/object_info - that's the same endpoint ComfyUI's own frontend uses to build its menus - then takes the JSON response and dynamically creates new node classes with Python's type(), injecting them straight into ComfyUI's nodes.NODE_CLASS_MAPPINGS and NODE_DISPLAY_NAME_MAPPINGS at runtime.
In other words: no files copied, no pack installed locally. The definitions are just stubs - the class signature so the graph editor knows what sockets exist. When the workflow actually runs, the work still happens on the remote, which is exactly what you want: the remote is where the models are.
The inputs that matter
You mostly set two things and hit run:
remote_url- the remote instance URL, defaulthttp://127.0.0.1:8189/(that default assumes a second instance on the same box; for another machine it'shttp://<ip>:8188).dry_run- report what would be registered in the console without registering anything. Do this first. It costs nothing and tells you whether your regexes did what you thought.
Then the naming controls. display_name_prefix defaults to [RemoteNd] and category_name_prefix to [RemoteNd]/, which keeps the remote nodes visually separated from your local ones. overwrite_existing is off by default, meaning any class that already exists locally is skipped - flip it on if you actually want the remote definition to win.
The rest is filtering. There are five slots each of include/ignore regexes for class type, display name, and category. All are case-insensitive. If you leave them empty, everything comes in; if you only want the VAE and upscaler nodes, drop a .*VAE.* in a class_type_include_regex slot and ignore the rest.
It has no outputs - it's an output node whose whole effect is registering stuff. You'll see the new nodes appear in your menu and the summary in the ComfyUI console: added: N, overwrote: N, skipped: N.
Install
Same as the rest of the pack - on both machines:
cd ComfyUI/custom_nodes
git clone https://github.com/LatentRat/comfy_remote_run
then restart ComfyUI. Or use ComfyUI Manager and search "comfy_remote_run". Dependencies are just websockets and requests, which Manager installs automatically. No model downloads.
Where people get burned
The stubs are only as real as the remote. If the remote's node comes from a custom pack that isn't actually loaded over there, the definition is useless - you've registered a ghost. Also, a class that already exists locally gets silently skipped unless overwrite_existing is true, which reads as "my new node isn't showing up" to a lot of people. Check the console log for the skip reason. And since the whole thing happens at runtime, it's per-session: restart ComfyUI and the remote nodes vanish from your menu until you run this node again.
One honest caveat: this is a niche convenience in an already-niche pack. If you only offload one or two things, installing the matching custom nodes locally is simpler and more predictable. This node earns its keep when the remote runs a genuinely different toolset and you want your local graph to feel like the whole farm is one machine.
Inputs (39)
| Name | Type | Default | Description |
|---|---|---|---|
| remote_url | STRING | http://127.0.0.1:8189/ | ComfyUI instance URL |
| request_timeout | FLOAT | 15.00.1–86400 | Request timeout in seconds |
| dry_run | BOOLEAN | false | — |
| display_name_prefix | STRING | [RemoteNd] | — |
| display_name_suffix | STRING | — | |
| category_name_prefix | STRING | [RemoteNd]/ | — |
| category_name_suffix | STRING | — | |
| overwrite_existing | BOOLEAN | false | — |
| is_changed | BOOLEAN | false | — |
| class_type_include_regex_0opt | STRING | — | |
| class_type_include_regex_1opt | STRING | — | |
| class_type_include_regex_2opt | STRING | — | |
| class_type_include_regex_3opt | STRING | — | |
| class_type_include_regex_4opt | STRING | — | |
| display_name_include_regex_0opt | STRING | — | |
| display_name_include_regex_1opt | STRING | — | |
| display_name_include_regex_2opt | STRING | — | |
| display_name_include_regex_3opt | STRING | — | |
| display_name_include_regex_4opt | STRING | — | |
| class_type_ignore_regex_0opt | STRING | — | |
| class_type_ignore_regex_1opt | STRING | — | |
| class_type_ignore_regex_2opt | STRING | — | |
| class_type_ignore_regex_3opt | STRING | — | |
| class_type_ignore_regex_4opt | STRING | — | |
| display_name_ignore_regex_0opt | STRING | — | |
| display_name_ignore_regex_1opt | STRING | — | |
| display_name_ignore_regex_2opt | STRING | — | |
| display_name_ignore_regex_3opt | STRING | — | |
| display_name_ignore_regex_4opt | STRING | — | |
| category_name_regex_0opt | STRING | — | |
| category_name_regex_1opt | STRING | — | |
| category_name_regex_2opt | STRING | — | |
| category_name_regex_3opt | STRING | — | |
| category_name_regex_4opt | STRING | — | |
| category_name_ignore_regex_0opt | STRING | — | |
| category_name_ignore_regex_1opt | STRING | — | |
| category_name_ignore_regex_2opt | STRING | — | |
| category_name_ignore_regex_3opt | STRING | — | |
| category_name_ignore_regex_4opt | STRING | — |
Outputs (0)
No outputs