Creating a custom LangChain Toolkit by grouping multiple Tools together

I’m working on a TypeScript project and need to group several LangChain Tools into one custom Toolkit. I tried creating a class that extends the base Toolkit, but I’m getting TypeScript errors when trying to use it with an Agent.

Here’s my attempt at building the custom toolkit:

import { Toolkit } from 'langchain/agents';
import { DynamicTool, Tool } from 'langchain/tools';

export class MyCustomToolkit extends Toolkit {
  tools: Tool[];

  constructor() {
    super();
    this.tools = [
      new DynamicTool({
        name: 'GET_DATA',
        description: 'retrieves data value when called with empty input',
        func: async () => 'result_data'
      }),
      new DynamicTool({
        name: 'FETCH_INFO', 
        description: 'fetches information when provided with empty string input',
        func: async () => 'info_value'
      })
    ];
  }
}

The error message I get says: Type 'MyCustomToolkit' is missing the following properties from type 'Tool': schema, call, lc_namespace, _call, and 11 more.ts(2740)

What’s the proper way to bundle these tools into a working toolkit that the Agent can use without throwing TypeScript errors?

Been wrestling with LangChain toolkits too until I figured something out. Manual approaches work for small projects, but they’re a nightmare when you’re juggling multiple toolkits across different services.

You need proper automation. Stop fighting TypeScript and managing tool configs by hand - set up an automated workflow that handles toolkit creation and deployment.

I built something where external triggers automatically generate and update toolkits based on API changes or new requirements. The workflow pulls tool definitions from a database, validates them, generates TypeScript code, and deploys everything without me touching it.

This kills the type errors because code generation follows exact patterns that work with LangChain. You also get versioning, rollbacks, and consistent structure across all toolkits.

Your current code structure would work perfectly as a template in an automated system. Just needs the right orchestration to generate and maintain it.

Had the same problem building a database toolkit. TypeScript gets confused because it’s trying to match your toolkit against the Tool interface instead of seeing it as a collection of tools. What fixed it for me: ditch the constructor approach and use a static factory method instead. javascript export class MyCustomToolkit { static create(): Tool[] { return [ new DynamicTool({ name: 'GET_DATA', description: 'retrieves data value when called with empty input', func: async () => 'result_data' }), new DynamicTool({ name: 'FETCH_INFO', description: 'fetches information when provided with empty string input', func: async () => 'info_value' }) ]; } } Then just call MyCustomToolkit.create() when passing to your agent. Works because you’re returning the actual Tool array the agent wants, not wrapping it in another object.

LangChain’s TypeScript version is picky about toolkit structure. Hit this exact issue building a monitoring toolkit for production.

You’re mixing up concepts here. Toolkits aren’t classes you extend - they’re just ways to organize related tools. The agent doesn’t even care about your toolkit wrapper.

Here’s what actually works:

const createCustomToolkit = () => {
  return [
    new DynamicTool({
      name: 'GET_DATA',
      description: 'retrieves data value when called with empty input',
      func: async () => 'result_data'
    }),
    new DynamicTool({
      name: 'FETCH_INFO', 
      description: 'fetches information when provided with empty string input',
      func: async () => 'info_value'
    })
  ];
};

Just use createCustomToolkit() directly with your agent. No classes, no inheritance, no TypeScript fights.

Saved me hours of debugging type errors. Agent setup becomes dead simple and you can still organize tools however you want.

Drop the extends part - langchain wants a plain object with a tools property, not inheritance. Try this: class MyCustomToolkit { get tools() { return [your tools here]; } } The getter works better for TypeScript inference and won’t make the agent complain about missing methods.

You’re extending the wrong base class. In LangChain TypeScript, you don’t extend a Toolkit class - just create a regular class with a tools property that returns an array of Tool instances. I hit this same issue last month building a custom toolkit for API operations. The fix is way simpler: import { DynamicTool, Tool } from 'langchain/tools'; export class MyCustomToolkit { tools: Tool[]; constructor() { this.tools = [ new DynamicTool({ name: 'GET_DATA', description: 'retrieves data value when called with empty input', func: async () => 'result_data' }), new DynamicTool({ name: 'FETCH_INFO', description: 'fetches information when provided with empty string input', func: async () => 'info_value' }) ]; } } When you initialize your agent, pass new MyCustomToolkit().tools instead of the toolkit instance. The Agent wants an array of tools, not a toolkit wrapper. This kills the TypeScript errors completely.

TypeScript’s trying to read your class as a Tool instead of a tool container. Hit this same issue building internal toolkits at work - cleanest fix is a simple interface pattern. typescript interface CustomToolkit { tools: Tool[]; } export const myCustomToolkit: CustomToolkit = { tools: [ new DynamicTool({ name: 'GET_DATA', description: 'retrieves data value when called with empty input', func: async () => 'result_data' }), new DynamicTool({ name: 'FETCH_INFO', description: 'fetches information when provided with empty string input', func: async () => 'info_value' }) ] }; You get proper type safety and keep the organization you’re after. Just pass myCustomToolkit.tools to your agent. TypeScript gets the structure without throwing inheritance errors, and it’s consistent across LangChain versions.