Extend the workspace.
TypeScript-first, async Node.js under the hood, the same open-source codebase that ships Studio and Cloud. Write a custom node, drive the canvas from a CLI, generate workflows in code — and put the result in front of your team without rewriting it for a different runtime.
Drive the workspace from code
The same workflows you build on the canvas, callable from a TypeScript SDK and CLI. The @nodetool-ai packages aren't published to npm yet — these examples run from a source checkout today.
TypeScript SDK
Build and run workflows from code. Strict types, async streaming, and a fluent graph builder.
import { WorkflowRunner } from "@nodetool-ai/kernel";
const runner = new WorkflowRunner();
const result = await runner.run(graph, {
prompt: "A sunset over mountains",
});Graph DSL
Declare workflows in code. Type-checked node inputs and outputs, no YAML, no JSON-by-hand.
import { workflow, constant, text } from "@nodetool-ai/dsl";
const a = constant.string({ value: "Hello, " });
const b = constant.string({ value: "NodeTool!" });
const out = text.concat({ a: a.output, b: b.output });
const wf = workflow(out);Custom nodes
Add your own nodes to the workspace. Decorate fields, implement process(), ship it.
import { BaseNode, prop } from "@nodetool-ai/node-sdk";
export class MyNode extends BaseNode {
static readonly nodeType = "my.pkg.MyNode";
static readonly metadataOutputTypes = { output: "str" };
@prop({ type: "str", default: "" })
declare prompt: string;
async process() {
return { output: await myLogic(this.prompt) };
}
}Open source, end to end
Workflows run on an async Node.js runtime. Embed NodeTool as a library, drive it from the CLI, or run the same code that powers Studio and Cloud on your own boxes.
Node-based DSL
Declare graphs in code. Strict types, vendor-neutral.
Agents as nodes
Planner, browser, search, and tool-calling baked in.
Every major provider
FAL, KIE, OpenAI, Anthropic, Gemini, Replicate, Ollama, and more — your keys.
RAG & vector stores
Built-in SQLite-vec, plus adapters for ChromaDB and friends.
Actor-based execution
One actor per node, streaming-first architecture.
Custom nodes
Add your own nodes to the workspace with the SDK.
Installation
npm package:
npm install @nodetool-ai/kernelcoming soonFrom source (today):
git clone https://github.com/nodetool-ai/nodetool
cd nodetool
nvm use # Node 22.22.1 (.nvmrc)
npm install
npm run build:packagesDSL Example
API previewimport { workflow, constant, text, agent } from "@nodetool-ai/dsl";
// Define an input
const question = constant.string({ value: "What is NodeTool?" });
// Create an agent that processes the question
const reply = agent.run({
provider: "ollama",
model: "llama3.2:3b",
prompt: question.output,
});
// Wrap it in a workflow
const wf = workflow(reply);
// Run it:
// import { WorkflowRunner } from "@nodetool-ai/kernel";
// const result = await new WorkflowRunner().run(wf);The @nodetool-ai packages aren't on npm yet — these imports work from a source checkout today and will work via npm install once published.
Why the DSL?
What declaring a graph buys you over imperative code
Declarative, Not Imperative
Define what to compute, not how. The DSL builds a graph the engine schedules and streams.
Automatic Data Flow
Connect nodes by referencing outputs (e.g., agent.out.text). The engine handles data passing and dependencies.
Built for Composition
Each node's output feeds the next node's input — big workflows are small nodes wired together.
Visual + Code Sync
The same graph runs in the UI or from code. Export visual workflows, edit, import them back.
Build, run, and extend from code
Declare graphs, write custom nodes, and run workflows from code. The CLI ships them, the runner streams them. Until the @nodetool-ai packages land on npm, these examples run from a source checkout.
Complete DSL Workflow
A complete chat workflow defined in code
// simple_chat_workflow.ts
// A complete chat workflow in code
import { workflow, input, agent, output } from "@nodetool-ai/dsl";
// Accept chat message input
const userMessage = input.message({
name: "user_message",
description: "Incoming message from user",
});
// Process with an agent
const reply = agent.run({
provider: "ollama",
model: "llama3.2:3b",
system: "You are a helpful assistant.",
prompt: userMessage.text,
});
// Return response
const response = output.string({
name: "assistant_response",
value: reply.text,
});
const wf = workflow(response);
console.log(JSON.stringify(wf));nodetool run simple_chat_workflow.tsCLI Commands
Run Workflows
Execute DSL workflows directly
nodetool run examples/concat_text.tsStart the Server
HTTP + WebSocket API on port 7777
nodetool serveAgent Chat
Interactive agent CLI with planning + tools
nodetool-chat --agent --provider anthropicCustom Node
Extend BaseNode, decorate fields, implement process()
// my-nodes/src/SentimentNode.ts
import { BaseNode, prop } from "@nodetool-ai/node-sdk";
export class SentimentNode extends BaseNode {
static readonly nodeType = "my.text.Sentiment";
static readonly title = "Sentiment";
static readonly description = "Score text sentiment from -1 to 1.";
static readonly metadataOutputTypes = { score: "float" };
@prop({ type: "str", default: "" })
declare text: string;
async process(): Promise<{ score: number }> {
const score = await analyze(this.text);
return { score };
}
}Run Programmatically
Build a graph and stream events with WorkflowRunner
import { WorkflowRunner } from "@nodetool-ai/kernel";
import { workflow, constant, text } from "@nodetool-ai/dsl";
const a = constant.string({ value: "Hello, " });
const b = constant.string({ value: "NodeTool!" });
const out = text.concat({ a: a.output, b: b.output });
const wf = workflow(out);
const runner = new WorkflowRunner();
runner.on("node_progress", (m) => console.log(m.progress));
runner.on("node_update", (m) => console.log(m.status));
const result = await runner.run(wf);
console.log(result);Build your first workflow
The docs take you from install to a running workflow, with examples and API references.
Every model. Your keys.
340+ built-in nodes covering every major provider and media type. Bring your own keys across the board.
Language Models
- OpenAI GPT-5.5
- Claude Opus 4.8
- Gemini 3 Pro
- Ollama
- Llama
- Mistral
- Qwen
Image Generation
- FLUX
- gpt-image-2.0
- Qwen Image
- Ideogram
- Stable Diffusion
Video & Audio
- Veo 3.1
- Kling 3
- Seedance 3
- Wan 2.5
- Runway
- ElevenLabs
- Suno
- Whisper
Data & Search
- ChromaDB
- Pinecone
- Weaviate
- Elasticsearch
- PostgreSQL
100% open source
NodeTool is AGPL-3.0. Fork it, audit it, self-host it. No lock-in, no usage limits — bring your own keys to every provider and pay providers directly.
Made with working creatives
NodeTool is AGPL-3.0 open source. Star the repo, jump into Discord, and trade workflows with other artists, motion designers, and studios using it for real work.
Get in
touch
Questions, bug reports, feature requests — we answer.