Install
$ agentstack add skill-jtydhr88-comfyui-custom-node-skills-comfyui-node-basics ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
ComfyUI Custom Node Basics (V3 API)
ComfyUI uses Python classes to define nodes. The V3 API is the current recommended approach. Nodes inherit from io.ComfyNode and define a schema + execute method.
Quick Start
from comfy_api.latest import ComfyExtension, io
class MyNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MyNode",
display_name="My Custom Node",
category="my_category",
inputs=[
io.Image.Input("image"),
io.Float.Input("strength", default=1.0, min=0.0, max=1.0, step=0.01),
],
outputs=[
io.Image.Output("IMAGE"),
],
)
@classmethod
def execute(cls, image, strength):
result = image * strength
return io.NodeOutput(result)
V3 Node Class Structure
Every V3 node requires:
- Inherit from
io.ComfyNode define_schema(cls)- classmethod returningio.Schemaexecute(cls, ...)- classmethod performing the computation
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
class ImageBrighten(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="ImageBrighten", # unique identifier
display_name="Brighten Image", # shown in UI
category="image/adjust", # menu path
description="Adjusts image brightness",
inputs=[
io.Image.Input("image"),
io.Float.Input("factor", default=1.2, min=0.0, max=3.0, step=0.1),
],
outputs=[
io.Image.Output("IMAGE"),
],
)
@classmethod
def execute(cls, image, factor):
result = torch.clamp(image * factor, 0.0, 1.0)
return io.NodeOutput(result)
io.Schema Fields
io.Schema(
node_id="UniqueNodeID", # required: unique string ID
display_name="Display Name", # optional: shown in UI menus
category="category/subcategory", # menu hierarchy (default "sd")
description="Node description", # optional: tooltip text
inputs=[...], # list of Input objects
outputs=[...], # list of Output objects
hidden=[...], # list of Hidden enum values
is_output_node=False, # True for nodes with side effects (save, preview)
is_experimental=False, # marks as experimental
is_deprecated=False, # marks as deprecated
is_dev_only=False, # hidden unless dev mode enabled
is_api_node=False, # marks as API-only node
is_input_list=False, # receive full lists instead of individual items
not_idempotent=False, # prevents caching
accept_all_inputs=False, # accept arbitrary inputs via **kwargs
enable_expand=False, # allow node expansion (subgraphs)
search_aliases=["alias1", "alias2"],# alternative search terms
essentials_category="Basic", # optional: Essentials tab category
price_badge=None, # optional: PriceBadge for API nodes
has_intermediate_output=False, # True for nodes with interactive UI that produce intermediate outputs
)
V3 Node Registration
V3 nodes are registered via ComfyExtension and comfy_entrypoint():
from typing_extensions import override
from comfy_api.latest import ComfyExtension, io
class MyNode(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="MyNode",
display_name="My Node",
category="my_nodes",
inputs=[io.String.Input("text", multiline=True)],
outputs=[io.String.Output()],
)
@classmethod
def execute(cls, text):
return io.NodeOutput(text.upper())
class MyExtension(ComfyExtension):
@override
async def get_node_list(self) -> list[type[io.ComfyNode]]:
return [MyNode]
async def comfy_entrypoint() -> MyExtension:
return MyExtension()
The comfy_entrypoint() function must be defined at the module level (in the file directly imported by ComfyUI).
V1 Node Structure (Legacy Reference)
V1 nodes use class attributes and NODE_CLASS_MAPPINGS:
class MyNodeV1:
CATEGORY = "my_category"
FUNCTION = "execute"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE",),
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0}),
}
}
def execute(self, image, strength):
return (image * strength,)
NODE_CLASS_MAPPINGS = {"MyNodeV1": MyNodeV1}
NODE_DISPLAY_NAME_MAPPINGS = {"MyNodeV1": "My Node V1"}
Key Differences: V3 vs V1
| Aspect | V3 | V1 | |---|---|---| | Base class | io.ComfyNode | Plain class | | Execute method | execute classmethod (fixed name) | Instance method (custom name via FUNCTION) | | Inputs | io.Schema(inputs=[...]) | INPUT_TYPES() dict | | Outputs | io.Schema(outputs=[...]) | RETURN_TYPES tuple | | Return value | io.NodeOutput(...) | Plain tuple | | Registration | ComfyExtension + comfy_entrypoint() | NODE_CLASS_MAPPINGS dict | | State | No instance state (classmethods) | Instance state allowed | | Hidden inputs | cls.hidden.prompt, etc. | kwargs from "hidden" dict |
Important Rules
node_idmust be globally unique across all nodesexecute()parameters must match input IDs exactly- All methods are
@classmethodin V3 (no instance state) - Return
io.NodeOutput(val1, val2, ...)matching output count - Category uses
/separator for hierarchy:"image/transform" - Prefix category with
_to hide from menus:"_for_testing"
See Also
comfyui-node-datatypes- Data types (IMAGE, LATENT, MASK, etc.)comfyui-node-inputs- Input configuration detailscomfyui-node-outputs- Output types and UI outputscomfyui-node-packaging- Project structure and packagingcomfyui-node-lifecycle- Execution lifecycle and caching
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: jtydhr88
- Source: jtydhr88/comfyui-custom-node-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.