Questions
6 of 24
1What is a Tool in LangChain and how does it differ from a plain function or API call?
2What is the difference between the tool() helper, DynamicTool, and StructuredTool class?
3How does an LLM decide which tool to call — what role does the tool description play?
4What is the role of Zod schema in tool definitions and how does it map to OpenAI's function calling spec?
5What is a ToolNode in LangGraph and how does it differ from calling a tool manually inside a graph node?
6How do you wrap a REST API call with auth headers inside a Tool in TypeScript?
7How do you handle async errors and retries inside a Tool without crashing the agent loop?
8How do you pass runtime context (userId, authToken, DB connection) into a Tool using RunnableConfig?
9How do you build a Toolkit (grouped set of related tools) using BaseToolkit?
10How do you validate and sanitize tool output before it is passed back to the LLM?
11How do you stream tool call results back to the client in real time?
12How do you implement tool-level authorization — allowing certain tools only for certain users?
13How do you build stateful tools that read/write to a database across multiple agent turns?
14How do you prevent tool abuse or infinite loops where an agent keeps calling the same tool repeatedly?
15How do you implement parallel tool calling — when the LLM decides to call multiple tools simultaneously?
16How do you create a human-in-the-loop tool that pauses the agent and waits for user approval before executing?
17How do you unit test and mock tools in isolation without invoking the LLM?
18How do you implement tool call caching to avoid redundant API calls for identical inputs?
19How do you design a multi-agent system where one agent's tool is actually another agent (agent-as-tool pattern)?
20How does LangGraph's ToolNode handle tool call errors and surface them back into the message state?
21What is the difference between tool_choice: "auto", "required", and "none" when binding tools to an LLM?
22How do you implement dynamic tool loading — where the set of available tools changes based on user role or session state?
23How do you trace and observe tool call latency in production using LangSmith?
24What are the token cost implications of registering too many tools and how do you mitigate it?
06 / 24

How do you wrap a REST API call with auth headers inside a Tool in TypeScript?

You wrap a REST API call with auth headers in TypeScript by using the tool() helper from @langchain/core/tools, defining a Zod schema for the tool's input, and implementing the func to make an authenticated fetch request that includes the required Authorization header.

To create a secure, reusable LangChain tool that interacts with a protected REST API, you should use the tool() factory function. This function creates a StructuredTool that accepts a Zod schema for input validation and an asynchronous function containing the fetch logic. The key to authentication is manually adding an Authorization header (or any required custom headers) to the fetch request inside the tool's func. This approach gives you full control over the request, including error handling and response parsing, which is more flexible than trying to configure headers on pre-built request tools .

TypeScript Example: Creating an Authenticated API Tool

This method provides complete control over the request, making it robust for production. The API token is securely injected from environment variables at runtime, preventing hardcoding. The tool also includes structured error handling, which is critical for agents to function reliably when external services fail. This pattern is universally applicable, whether you're using a bearer token, API key, or any other authentication scheme. Simply modify the headers object in the fetch call to match your API's requirements.

Alternative Approach: Using a Pre-built Tool with Configuration
  1. 1

    Context: As an alternative, you could use a pre-built tool like the RequestsGetTool and try to configure its internal request wrapper. However, this approach is generally less flexible and reliable than building a custom tool.

  2. 2

    Example: Based on a community discussion, you might attempt to access a tool's internal request wrapper to update its headers . While this can work for simple cases, it is less discoverable and can break if the internal structure of the tool changes in future library versions.

  3. 3

    Code Snippet (Less Recommended):

    // This is a less robust, exploratory pattern.
    import { RequestsGetTool } from "langchain/tools";
    
    const tools = [new RequestsGetTool()];
    const requestTool = tools[0];
    
    // Attempt to modify the internal wrapper's headers (structure is not guaranteed).
    if (requestTool.requests_wrapper) {
      requestTool.requests_wrapper.headers['Authorization'] = `Bearer ${process.env.API_KEY}`;
    }
    

In summary, for wrapping a REST API call with authentication in TypeScript, the custom tool() approach is the most robust, type-safe, and maintainable method. It provides full control over the request and response lifecycle, which is essential for integrating with any protected external service in a LangChain agent.