This is part 2 of the Your First Plugin tutorial. Make sure you’ve completed 1. Plugin Definition first.
V2 vs V1 nodes
There are two kinds of node, and you should almost always write V2:- V2 (recommended, connector-free). A V2 node mirrors the platform’s native
nodes: it has no edge connectors. Instead it is two schemas — a config
schema whose fields are the node’s settings (a field marked
bindable=Truebecomes an input that accepts a literal or a:var[...]reference to an upstream output), and an output schema that declares every output. Everything arrives onself.config;call(ctx)returns a dict keyed by the output field names. - V1 (legacy — edge connectors). Inputs and outputs are
Connectorobjects wired by edges, and inputs arrive as keyword arguments tocall. Only use V1 when you specifically need a node for a V1 flow.
nodes() returns them together and the
SDK splits them into the correct editor automatically.
Define the node
- V2 (recommended)
- V1 (legacy)
Add a new node to A
weather_plugin/:list[X]-typed output field (e.g. tags: list[str]) becomes a list output.
Required-but-unbound inputs fail with a clear error before call runs, so you
don’t need to defensively check them.Register the node in your plugin
Add the node class to your plugin’snodes() method:
Test it locally
Restart the plugin server:/nodes/{node_name}/execute endpoint takes a body
with ctx, inputs, and config:
- V2 (recommended)
- V1 (legacy)
For a V2 node, bindable and plain config values both go in
config; inputs
stays empty:ExecutionResponse:
Key concepts
Available data types
V2 output fields and V1 connectors both use these types (V2 infers them from the Python annotation; V1 declares them viaTypeDefinition):
Image, Audio, and Chat are also available as file-like types.
Node metadata
Next: First Integration →
Define credentials and an integration for an external API.