--- title: "Use Arcade tools with LangGraph" description: "Integrate Arcade tools into your LangGraph applications" --- import { Steps, Tabs, Callout } from "nextra/components"; ## Use LangGraph with Arcade In this guide, let's explore how to integrate Arcade tools into your LangGraph application. Follow the step-by-step instructions below. For complete working examples, see our [Python](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain/langgraph_arcade_minimal.py) and [JavaScript](https://github.com/ArcadeAI/arcade-ai/blob/main/examples/langchain-ts/langgraph-arcade-minimal.ts) examples. ### Prerequisites - [Obtain an Arcade API key](/get-started/setup/api-keys) ### Set up your environment Install the required packages, and ensure your environment variables are set with your Arcade and OpenAI API keys: ```bash pip install langchain-arcade langchain-openai langgraph ``` ```bash npm install @arcadeai/arcadejs @langchain/openai @langchain/core @langchain/langgraph ``` ### Configure API keys Provide your Arcade and OpenAI API keys. You can store them in environment variables or directly in your code: > Need an Arcade API key? Visit the [Get an API key](/get-started/setup/api-keys) page to create one. ```python import os arcade_api_key = os.environ.get("ARCADE_API_KEY", "YOUR_ARCADE_API_KEY") openai_api_key = os.environ.get("OPENAI_API_KEY", "YOUR_OPENAI_API_KEY") ``` ```bash ARCADE_API_KEY= OPENAI_API_KEY= ``` ### Create and manage Arcade tools Use the ArcadeToolManager to retrieve specific tools or entire MCP Servers: ```python from langchain_arcade import ArcadeToolManager manager = ArcadeToolManager(api_key=arcade_api_key) # Fetch the "ScrapeUrl" tool from the "Firecrawl" MCP Server tools = manager.get_tools(tools=["Firecrawl.ScrapeUrl"]) print(manager.tools) # Get all tools from the "Gmail" MCP Server tools = manager.get_tools(toolkits=["Gmail"]) print(manager.tools) ``` Arcade offers methods to convert tools into Zod schemas, which is essential since LangGraph defines tools using Zod. The `toZod` method is particularly useful, as it simplifies this integration and makes it easier to use Arcade's tools with LangGraph. Learn more about Arcade's Zod integration options [here](/guides/tool-calling/custom-apps/get-tool-definitions#get-zod-tool-definitions). ```javascript import { Arcade } from "@arcadeai/arcadejs"; import { executeOrAuthorizeZodTool, toZod } from "@arcadeai/arcadejs/lib"; import { tool } from "@langchain/core/tools"; // Initialize the Arcade client const arcade = new Arcade(); // Get the Arcade tools, you can customize the MCP Server (e.g. "github", "notion", "gmail", etc.) const googleToolkit = await arcade.tools.list({ toolkit: "gmail", limit: 30 }); const arcadeTools = toZod({ tools: googleToolkit.items, client: arcade, userId: "", // Replace this with your application's user ID (e.g. email address, UUID, etc.) }); // Convert Arcade tools to LangGraph tools const tools = arcadeTools.map(({ name, description, execute, parameters }) => tool(execute, { name, description, schema: parameters, }), ); console.log(tools); ``` ### Set up the language model and memory Create an AI model and bind your tools. Use MemorySaver for checkpointing: ```python from langchain_openai import ChatOpenAI from langgraph.checkpoint.memory import MemorySaver model = ChatOpenAI(model="gpt-4o", api_key=openai_api_key) bound_model = model.bind_tools(tools) memory = MemorySaver() ``` ```javascript import { ChatOpenAI } from "@langchain/openai"; import { MemorySaver } from "@langchain/langgraph"; const model = new ChatOpenAI({ model: "gpt-4o", apiKey: process.env.OPENAI_API_KEY }); const boundModel = model.bindTools(tools); const memory = new MemorySaver(); ``` ### Create a ReAct-style agent Use the prebuilt ReAct agent from LangGraph to handle your Arcade tools: ```python from langgraph.prebuilt import create_react_agent graph = create_react_agent(model=bound_model, tools=tools, checkpointer=memory) ``` ```javascript import { createReactAgent } from "@langchain/langgraph/prebuilt"; const graph = createReactAgent({ llm: boundModel, tools, checkpointer: memory }); ``` ### Provide configuration and user query Supply a basic config dictionary and a user query. Notice that user_id is required for tool authorization: ```python config = { "configurable": { "thread_id": "1", "user_id": "{arcade_user_id}" } } user_input = { "messages": [ ("user", "List any new and important emails in my inbox.") ] } ``` ```javascript const config = { configurable: { thread_id: "1", user_id: "{arcade_user_id}", }, streamMode: "values" as const, }; const user_input = { messages: [ { role: "user", content: "List any new and important emails in my inbox.", }, ], }; ``` ### Stream the response Stream the assistant's output. If the tool requires authorization, the agent will ask the user to authorize the tool. ```python from langgraph.errors import NodeInterrupt try: for chunk in graph.stream(user_input, config, stream_mode="values"): chunk["messages"][-1].pretty_print() except NodeInterrupt as exc: print(f"\nNodeInterrupt occurred: {exc}") print("Please authorize the tool or update the request, then re-run.") ``` ```javascript try { const stream = await graph.stream(user_input, config); for await (const chunk of stream) { console.log(chunk.messages[chunk.messages.length - 1]); } } catch (error) { console.error("Error streaming response:", error); } ``` ## Tips for selecting tools - **Relevance**: Pick only the tools you need. Avoid using all tools at once. - **Avoid conflicts**: Be mindful of duplicate or overlapping functionality. ## Next steps Now that you have integrated Arcade tools into your LangGraph agent, you can: - Experiment with different MCP Servers, such as "Math" or "Search." - Customize the agent's prompts for specific tasks. - Try out other language models and compare their performance. Enjoy exploring Arcade and building powerful AI-enabled Python applications!