# ToolNode

> **Class** in `@langchain/langgraph`

📖 [View in docs](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode)

A node that runs the tools requested in the last AIMessage. It can be used
either in StateGraph with a "messages" key or in MessageGraph. If multiple
tool calls are requested, they will be run in parallel. The output will be
a list of ToolMessages, one for each tool call.

## Signature

```javascript
class ToolNode
```

## Extends

- `RunnableCallable<T, T>`

## Constructors

- [`constructor()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/constructor)

## Properties

- `config`
- `func`
- `handleToolErrors`
- `lc_kwargs`
- `lc_namespace`
- `lc_runnable`
- `lc_serializable`
- `name`
- `recurse`
- `tags`
- `tools`
- `trace`
- `lc_aliases`
- `lc_attributes`
- `lc_id`
- `lc_secrets`
- `lc_serializable_keys`

## Methods

- [`_batchWithConfig()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_batchWithConfig)
- [`_callWithConfig()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_callWithConfig)
- [`_getOptionsList()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_getOptionsList)
- [`_separateRunnableConfigFromCallOptions()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_separateRunnableConfigFromCallOptions)
- [`_streamIterator()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_streamIterator)
- [`_streamLog()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_streamLog)
- [`_tracedInvoke()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_tracedInvoke)
- [`_transformStreamWithConfig()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/_transformStreamWithConfig)
- [`assign()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/assign)
- [`asTool()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/asTool)
- [`batch()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/batch)
- [`getGraph()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/getGraph)
- [`getName()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/getName)
- [`invoke()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/invoke)
- [`pick()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/pick)
- [`pipe()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/pipe)
- [`run()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/run)
- [`runTool()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/runTool)
- [`stream()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/stream)
- [`streamEvents()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/streamEvents)
- [`streamLog()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/streamLog)
- [`toJSON()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/toJSON)
- [`toJSONNotImplemented()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/toJSONNotImplemented)
- [`transform()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/transform)
- [`withConfig()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/withConfig)
- [`withFallbacks()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/withFallbacks)
- [`withListeners()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/withListeners)
- [`withRetry()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/withRetry)
- [`isRunnable()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/isRunnable)
- [`lc_name()`](https://reference.langchain.com/javascript/langchain-langgraph/prebuilt/ToolNode/lc_name)

## Examples

### Example 1

```ts
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { AIMessage } from "@langchain/core/messages";

const getWeather = tool((input) => {
  if (["sf", "san francisco"].includes(input.location.toLowerCase())) {
    return "It's 60 degrees and foggy.";
  } else {
    return "It's 90 degrees and sunny.";
  }
}, {
  name: "get_weather",
  description: "Call to get the current weather.",
  schema: z.object({
    location: z.string().describe("Location to get the weather for."),
  }),
});

const tools = [getWeather];
const toolNode = new ToolNode(tools);

const messageWithSingleToolCall = new AIMessage({
  content: "",
  tool_calls: [
    {
      name: "get_weather",
      args: { location: "sf" },
      id: "tool_call_id",
      type: "tool_call",
    }
  ]
})

await toolNode.invoke({ messages: [messageWithSingleToolCall] });
// Returns tool invocation responses as:
// { messages: ToolMessage[] }
```

### Example 2

```ts
import {
  StateGraph,
  MessagesAnnotation,
} from "@langchain/langgraph";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { ChatAnthropic } from "@langchain/anthropic";

const getWeather = tool((input) => {
  if (["sf", "san francisco"].includes(input.location.toLowerCase())) {
    return "It's 60 degrees and foggy.";
  } else {
    return "It's 90 degrees and sunny.";
  }
}, {
  name: "get_weather",
  description: "Call to get the current weather.",
  schema: z.object({
    location: z.string().describe("Location to get the weather for."),
  }),
});

const tools = [getWeather];
const modelWithTools = new ChatAnthropic({
  model: "claude-3-haiku-20240307",
  temperature: 0
}).bindTools(tools);

const toolNodeForGraph = new ToolNode(tools)

const shouldContinue = (state: typeof MessagesAnnotation.State) => {
  const { messages } = state;
  const lastMessage = messages[messages.length - 1];
  if ("tool_calls" in lastMessage && Array.isArray(lastMessage.tool_calls) && lastMessage.tool_calls?.length) {
    return "tools";
  }
  return "__end__";
}

const callModel = async (state: typeof MessagesAnnotation.State) => {
  const { messages } = state;
  const response = await modelWithTools.invoke(messages);
  return { messages: response };
}

const graph = new StateGraph(MessagesAnnotation)
  .addNode("agent", callModel)
  .addNode("tools", toolNodeForGraph)
  .addEdge("__start__", "agent")
  .addConditionalEdges("agent", shouldContinue)
  .addEdge("tools", "agent")
  .compile();

const inputs = {
  messages: [{ role: "user", content: "what is the weather in SF?" }],
};

const stream = await graph.stream(inputs, {
  streamMode: "values",
});

for await (const { messages } of stream) {
  console.log(messages);
}
// Returns the messages in the state at each step of execution
```

---

[View source on GitHub](https://github.com/langchain-ai/langgraphjs/blob/5e9f3cb532bd006012ec0eab2bb5b005b22c2ebb/libs/langgraph-core/src/prebuilt/tool_node.ts#L154)