> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inworld.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Nodes

Inworld offers a number of different Built-in Nodes that can be used to build a Graph. In addition to provided Built-in Nodes, you can also create your own node using Custom Nodes.

## Nodes

To use a node in a graph:

1. **Create the node**: Instantiate the node with configuration options.
2. **Add node to graph**: Add the node to the graph.

<CodeGroup>
  ```javascript Node theme={"system"}
  import { GraphBuilder, RemoteLLMChatNode } from '@inworld/runtime/graph';

  // Create an LLM node
  const llmNode = new RemoteLLMChatNode({
    id: 'llm_node',
    provider: 'openai',
    modelName: 'gpt-4o-mini',
    stream: true,
  });

  // Build graph
  const graph = new GraphBuilder({
    id: 'my-graph',
    apiKey: process.env.INWORLD_API_KEY,
    enableRemoteConfig: false,
  })
    .addNode(llmNode)
    .setStartNode(llmNode)
    .setEndNode(llmNode)
    .build();
  ```
</CodeGroup>

### Node configurations

Nodes are created with various configuration options that control their behavior. Different nodes types will have different node-specific configurations, but all nodes will include the following optional configurations:

* `id`: Unique identifier for the node (auto-generated if not provided)
* `reportToClient`: Defaults to false, which means the node's result will be passed to the next nodes in the graph, but will not be available to the client. If true, the node's result will be sent to the client immediately when available AND propagated to the next nodes. This is useful if you want to access the intermediate node result (e.g., to display in the UI).

Below is an example of configuring an LLM node, where provider and modelName are LLM node specific parameters:

```javascript Node theme={"system"}
const llmNode = new RemoteLLMChatNode({
  id: 'my_llm_node',
  reportToClient: true,
  provider: 'openai',
  modelName: 'gpt-4o-mini',
});
```

See the [Node.js Agent Runtime Reference](/node/runtime-reference/overview#nodes) for the configurations available for each node.

<Note> Additional error handling configurations coming soon! </Note>

## Built-in Nodes

Built-in nodes are pre-built nodes provided by Inworld that cover common use cases. Below is an overview of available Built-in Nodes.

| **Node**                                                                                                             | **Description**                                                              | **Input Type(s)**                                                                                                      | **Output Type(s)**                                                                                                           |
| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| [KeywordMatcherNode](/node/runtime-reference/classes/graph_dsl_nodes_keyword_matcher_node.KeywordMatcherNode)        | Matches keywords in text input                                               | String                                                                                                                 | [GraphTypes.​​MatchedKeywords](/node/runtime-reference/classes/common_data_types_api_matched_keywords.MatchedKeywords)       |
| [KnowledgeNode](/node/runtime-reference/classes/graph_dsl_nodes_knowledge_node.KnowledgeNode)                        | Retrieves relevant knowledge based on input text                             | String                                                                                                                 | [GraphTypes.​KnowledgeRecords](/node/runtime-reference/classes/common_data_types_api_knowledge_records.KnowledgeRecords)     |
| [LLMPromptBuilderNode](/node/runtime-reference/classes/graph_dsl_nodes_llm_prompt_builder_node.LLMPromptBuilderNode) | Generates formatted prompts using prompt templates populated with JSON input | Object                                                                                                                 | String                                                                                                                       |
| [MCPCallToolNode](/node/runtime-reference/classes/graph_dsl_nodes_mcp_call_tool_node.MCPCallToolNode)                | Calls multiple tools on an MCP server in parallel                            | [GraphTypes.​ToolCallRequest](/node/runtime-reference/classes/common_data_types_api_tool_call_request.ToolCallRequest) | [GraphTypes.​ToolCallResponse](/node/runtime-reference/classes/common_data_types_api_tool_call_response.ToolCallResponse)    |
| [MCPListToolsNode](/node/runtime-reference/classes/graph_dsl_nodes_mcp_list_tools_node.MCPListToolsNode)             | Lists available tools from an MCP server                                     | any                                                                                                                    | [GraphTypes.​ListToolsResponse](/node/runtime-reference/classes/common_data_types_api_list_tools_response.ListToolsResponse) |
| [ProxyNode](/node/runtime-reference/classes/graph_dsl_nodes_proxy_node.ProxyNode)                                    | Simple data passing node for forwarding input to output                      | any                                                                                                                    | any                                                                                                                          |
| [RandomCannedTextNode](/node/runtime-reference/classes/graph_dsl_nodes_random_canned_text_node.RandomCannedTextNode) | Selects a random text from a list of predefined phrases                      | any                                                                                                                    | String                                                                                                                       |
| [RemoteLLMChatNode](/node/runtime-reference/classes/graph_dsl_nodes_remote_llm_chat_node.RemoteLLMChatNode)          | Generates a response using a large language model                            | [GraphTypes.​LLMChatRequest](/node/runtime-reference/classes/common_data_types_api_llm_chat_request.LLMChatRequest)    | GraphTypes.​LLMChatResponse                                                                                                  |

\| [RemoteSTTNode](/node/runtime-reference/classes/graph_dsl_nodes_remote_stt_node.RemoteSTTNode) | Converts speech audio to text using a speech-to-text (STT) model | [GraphTypes.​Audio](/node/runtime-reference/classes/common_data_types_api_audio.Audio) | String |
\| [RemoteTTSNode](/node/runtime-reference/classes/graph_dsl_nodes_remote_tts_node.RemoteTTSNode) | Converts text-to-speech audio using a text-to-speech (TTS) model | String <br /> GraphTypes.​TextStream <br /> [GraphTypes.​TTSRequest](/node/runtime-reference/classes/common_data_types_api_tts_request.TTSRequest) | GraphTypes.​TTSOutputStream |
\| [SubgraphNode](/node/runtime-reference/classes/graph_dsl_nodes_subgraph_node.SubgraphNode) | Executes a compiled subgraph as a node | any | any |
\| [TextAggregatorNode](/node/runtime-reference/classes/graph_dsl_nodes_text_aggregator_node.TextAggregatorNode) | Combines text streams (chunks) into a single string | String <br /> GraphTypes.​TextStream <br /> GraphTypes.​LLMChatResponse | String |
\| [TextChunkingNode](/node/runtime-reference/classes/graph_dsl_nodes_text_chunking_node.TextChunkingNode) | Splits text into smaller chunks | GraphTypes.​TextStream <br /> GraphTypes.​ContentStream | GraphTypes.​TextStream |
\| [TextClassifierNode](/node/runtime-reference/classes/graph_dsl_nodes_text_classifier_node.TextClassifierNode) | Analyzes text and classifies it into predefined categories using ML models | String | [GraphTypes.​ClassificationResult](/node/runtime-reference/classes/common_data_types_api_classification_result.ClassificationResult) |

### Subgraphs

<Tip> Use subgraphs to simplify maintenance, improve readability, and promote reusability</Tip>

The `SubgraphNode` is a special type of node that executes a compiled **Subgraph**.

A **Subgraph** is a reusable graph component that encapsulate a set of nodes and edges into a single logical unit. To use a subgraph in your main graph, you need to:

1. **Build the subgraph** using `SubgraphBuilder`, which follows a very similar syntax as `GraphBuilder`. This includes adding nodes, adding edges, and setting the start and end node. A Subgraph must have exactly one start node and one end node.
2. **Create a SubgraphNode** that references the subgraph by its ID
3. **Register the subgraph** with your main graph using `.addSubgraph()`
4. **Add the SubgraphNode** to your main graph like any other node

In the example below, the text processing subgraph handles chunking and aggregating text, while the main graph orchestrates the overall flow using proxy nodes for input and output handling.

<CodeGroup>
  ```javascript Node theme={"system"}
  import { 
    GraphBuilder, 
    SubgraphBuilder, 
    SubgraphNode,
    TextChunkingNode,
    TextAggregatorNode,
    ProxyNode 
  } from '@inworld/runtime/graph';

  const textChunkingNode = new TextChunkingNode({ reportToClient: true });
  const textAggregatorNode = new TextAggregatorNode();

  // Create a reusable text processing subgraph
  const textProcessingSubgraph = new SubgraphBuilder('text_processing_subgraph')
    .addNode(textChunkingNode)
    .addNode(textAggregatorNode)
    .addEdge(textChunkingNode, textAggregatorNode)
    .setStartNode(textChunkingNode)
    .setEndNode(textAggregatorNode);

  // Create a SubgraphNode
  const subgraphNode = new SubgraphNode({
    subgraphId: 'text_processing_subgraph',
  });

  const inputProxy = new ProxyNode();
  const outputProxy = new ProxyNode();

  const graph = new GraphBuilder({
    id: 'main_graph',
    enableRemoteConfig: false,
  })
    .addSubgraph(textProcessingSubgraph) // Register the subgraph
    .addNode(inputProxy)
    .addNode(subgraphNode)               // Add the SubgraphNode
    .addNode(outputProxy)
    .addEdge(inputProxy, subgraphNode)
    .addEdge(subgraphNode, outputProxy)
    .setStartNode(inputProxy)
    .setEndNode(outputProxy)
    .build();
  ```
</CodeGroup>

## Custom Nodes

Custom Nodes can be created to implement any custom logic in your graph by extending the [CustomNode](/node/runtime-reference/classes/graph_dsl_nodes_custom_node.CustomNode) class.

To use a custom node:

1. **Create a custom node class**: Extend `CustomNode` and implement the `process` method with your custom logic.
2. **Instantiate the custom node**: Create an instance of your custom node class.
3. **Add custom node to graph**: Use `addNode` to add the custom node to the graph.

The below example creates a custom node that reverses a string.

<CodeGroup>
  ```javascript Node theme={"system"}
  import { CustomNode, GraphBuilder, ProcessContext } from '@inworld/runtime/graph';

  // Create a custom node class
  class ReverseTextNode extends CustomNode {
    process(context: ProcessContext, input: string): string {
      return input.split('').reverse().join('');
    }
  }

  // Create the custom node instance
  const customNode = new ReverseTextNode();

  // Add it to the graph, same as a built-in node
  const graph = new GraphBuilder({
    id: 'custom-graph',
    apiKey: process.env.INWORLD_API_KEY,
    enableRemoteConfig: false,
  })
    .addNode(customNode)
    .setStartNode(customNode)
    .setEndNode(customNode)
    .build();
  ```
</CodeGroup>

Custom nodes can also be useful for processing inputs from multiple nodes, as shown in this [guide](/node/templates/multi-input).
