TypeScript Custom Provider

Learn how to create custom providers for any AI platform in TypeScript

This guide provides a comprehensive walkthrough of creating custom providers for the Composio TypeScript SDK, enabling integration with different AI frameworks and platforms.

Provider Architecture

The Composio SDK uses a provider architecture to adapt tools for different AI frameworks. The provider handles:

  1. Tool Format Transformation: Converting Composio tools into formats compatible with specific AI platforms
  2. Tool Execution: Managing the flow of tool execution and results
  3. Platform-Specific Integration: Providing helper methods for seamless integration

Types of Providers

There are two types of providers:

  1. Non-Agentic Providers: Transform tools for platforms that don't have their own agency (e.g., OpenAI)
  2. Agentic Providers: Transform tools for platforms that have their own agency (e.g., LangChain, AutoGPT)

Provider Class Hierarchy

BaseProvider (Abstract)
├── BaseNonAgenticProvider (Abstract)
│   └── OpenAIProvider (Concrete)
│   └── [Your Custom Non-Agentic Provider] (Concrete)
└── BaseAgenticProvider (Abstract)
    └── [Your Custom Agentic Provider] (Concrete)

Creating a Non-Agentic Provider

Non-agentic providers implement the BaseNonAgenticProvider abstract class:

import { class BaseNonAgenticProvider<TToolCollection$1, TTool$1, TMcpResponse$1 = McpServerGetResponse>
@publicBase class for all non-agentic providers. This class is not meant to be used directly, but rather to be extended by concrete provider implementations.
BaseNonAgenticProvider
,
type Tool = {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
Tool
} from '@composio/core';
// Define your tool format interface MyAITool { MyAITool.name: stringname: string; MyAITool.description: stringdescription: string;
MyAITool.parameters: {
    type: string;
    properties: Record<string, unknown>;
    required?: string[];
}
parameters
: {
type: stringtype: string; properties: Record<string, unknown>properties: type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type T
Record
<string, unknown>;
required?: string[] | undefinedrequired?: string[]; }; } // Define your tool collection format type type MyAIToolCollection = MyAITool[]MyAIToolCollection = MyAITool[]; // Create your provider export class class MyAIProviderMyAIProvider extends class BaseNonAgenticProvider<TToolCollection$1, TTool$1, TMcpResponse$1 = McpServerGetResponse>
@publicBase class for all non-agentic providers. This class is not meant to be used directly, but rather to be extended by concrete provider implementations.
BaseNonAgenticProvider
<type MyAIToolCollection = MyAITool[]MyAIToolCollection, MyAITool> {
// Required: Unique provider name for telemetry readonly MyAIProvider.name: "my-ai-platform"
@publicThe name of the provider. Used to identify the provider in the telemetry.
name
= 'my-ai-platform';
// Required: Method to transform a single tool override MyAIProvider.wrapTool(tool: Tool): MyAITool
Wrap a tool in the provider specific format.
@paramtool - The tool to wrap.@returnsThe wrapped tool.
wrapTool
(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
:
type Tool = {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
Tool
): MyAITool {
return { MyAITool.name: stringname:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.slug: stringslug,
MyAITool.description: stringdescription:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.description?: string | undefineddescription || '',
MyAITool.parameters: {
    type: string;
    properties: Record<string, unknown>;
    required?: string[];
}
parameters
: {
type: stringtype: 'object', properties: Record<string, unknown>properties:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.
inputParameters?: {
    type: "object";
    properties: Record<string, any>;
    description?: string | undefined;
    anyOf?: any[] | undefined;
    oneOf?: any[] | undefined;
    allOf?: any[] | undefined;
    not?: any;
    required?: string[] | undefined;
    title?: string | undefined;
    default?: any;
    nullable?: boolean | undefined;
    additionalProperties?: boolean | undefined;
} | undefined
inputParameters
?.properties: Record<string, any> | undefinedproperties || {},
required?: string[] | undefinedrequired:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.
inputParameters?: {
    type: "object";
    properties: Record<string, any>;
    description?: string | undefined;
    anyOf?: any[] | undefined;
    oneOf?: any[] | undefined;
    allOf?: any[] | undefined;
    not?: any;
    required?: string[] | undefined;
    title?: string | undefined;
    default?: any;
    nullable?: boolean | undefined;
    additionalProperties?: boolean | undefined;
} | undefined
inputParameters
?.required?: string[] | undefinedrequired || [],
}, }; } // Required: Method to transform a collection of tools override MyAIProvider.wrapTools(tools: Tool[]): MyAIToolCollection
Wrap a list of tools in the provider specific format.
@paramtools - The tools to wrap.@returnsThe wrapped tools.
wrapTools
(
tools: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}[]
tools
:
type Tool = {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
Tool
[]): type MyAIToolCollection = MyAITool[]MyAIToolCollection {
return
tools: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}[]
tools
.
Array<{ slug: string; name: string; description?: string | undefined; inputParameters?: { type: "object"; properties: Record<string, any>; description?: string | undefined; anyOf?: any[] | undefined; oneOf?: any[] | undefined; allOf?: any[] | undefined; not?: any; required?: string[] | undefined; title?: string | undefined; default?: any; nullable?: boolean | undefined; additionalProperties?: boolean | undefined; } | undefined; ... 7 more ...; isNoAuth?: boolean | undefined; }>.map<MyAITool>(callbackfn: (value: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}, index: number, array: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}[]) => MyAITool, thisArg?: any): MyAITool[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
=> this.MyAIProvider.wrapTool(tool: Tool): MyAITool
Wrap a tool in the provider specific format.
@paramtool - The tool to wrap.@returnsThe wrapped tool.
wrapTool
(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
));
} // Optional: Custom helper methods for your AI platform async
MyAIProvider.executeMyAIToolCall(userId: string, toolCall: {
    name: string;
    arguments: Record<string, unknown>;
}): Promise<string>
executeMyAIToolCall
(
userId: stringuserId: string,
toolCall: {
    name: string;
    arguments: Record<string, unknown>;
}
toolCall
: {
name: stringname: string; arguments: Record<string, unknown>arguments: type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type T
Record
<string, unknown>;
} ): interface Promise<T>
Represents the completion of an asynchronous operation
Promise
<string> {
// Use the built-in executeTool method const
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
= await this.BaseProvider<McpServerGetResponse>.executeTool(toolSlug: string, body: ToolExecuteParams, modifers?: ExecuteToolModifiers): Promise<ToolExecuteResponse>
@publicGlobal function to execute a tool. This function is used by providers to implement helper functions to execute tools. This is a 1:1 mapping of the `execute` method in the `Tools` class.@paramtoolSlug - The slug of the tool to execute.@parambody - The body of the tool execution.@parammodifers - The modifiers of the tool execution.@returnsThe result of the tool execution.
executeTool
(
toolCall: {
    name: string;
    arguments: Record<string, unknown>;
}
toolCall
.name: stringname, {
userId?: string | undefineduserId, arguments?: Record<string, unknown> | undefinedarguments:
toolCall: {
    name: string;
    arguments: Record<string, unknown>;
}
toolCall
.arguments: Record<string, unknown>arguments,
}); return var JSON: JSON
An intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.
JSON
.JSON.stringify(value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): string (+1 overload)
Converts a JavaScript value to a JavaScript Object Notation (JSON) string.
@paramvalue A JavaScript value, usually an object or array, to be converted.@paramreplacer A function that transforms the results.@paramspace Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.@throws{TypeError} If a circular reference or a BigInt value is found.
stringify
(
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
.data: Record<string, unknown>data);
} }

Creating an Agentic Provider

Agentic providers implement the BaseAgenticProvider abstract class:

import { class BaseAgenticProvider<TToolCollection$1, TTool$1, TMcpResponse$1>
@publicBase class for all agentic providers. This class is not meant to be used directly, but rather to be extended by concrete provider implementations.
BaseAgenticProvider
,
type Tool = {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
Tool
, type ExecuteToolFn = (toolSlug: string, input: Record<string, unknown>) => Promise<ToolExecuteResponse>
This type is used to infer the wrapped tool type from the provider. It checks if the provider has a method `_wrapTool` and infers the return type.
ExecuteToolFn
} from '@composio/core';
// Define your tool format interface AgentTool { AgentTool.name: stringname: string; AgentTool.description: stringdescription: string; AgentTool.execute: (args: Record<string, unknown>) => Promise<unknown>execute: (args: Record<string, unknown>args: type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type T
Record
<string, unknown>) => interface Promise<T>
Represents the completion of an asynchronous operation
Promise
<unknown>;
AgentTool.schema: Record<string, unknown>schema: type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type T
Record
<string, unknown>;
} // Define your tool collection format interface AgentToolkit { AgentToolkit.tools: AgentTool[]tools: AgentTool[]; AgentToolkit.createAgent: (config: Record<string, unknown>) => unknowncreateAgent: (config: Record<string, unknown>config: type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type T
Record
<string, unknown>) => unknown;
} // Create your provider export class class MyAgentProviderMyAgentProvider extends class BaseAgenticProvider<TToolCollection$1, TTool$1, TMcpResponse$1>
@publicBase class for all agentic providers. This class is not meant to be used directly, but rather to be extended by concrete provider implementations.
BaseAgenticProvider
<AgentToolkit, AgentTool> {
// Required: Unique provider name for telemetry readonly MyAgentProvider.name: "my-agent-platform"name = 'my-agent-platform'; // Required: Method to transform a single tool with execute function override MyAgentProvider.wrapTool(tool: Tool, executeToolFn: ExecuteToolFn): AgentToolwrapTool(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
:
type Tool = {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
Tool
, executeToolFn: ExecuteToolFnexecuteToolFn: type ExecuteToolFn = (toolSlug: string, input: Record<string, unknown>) => Promise<ToolExecuteResponse>
This type is used to infer the wrapped tool type from the provider. It checks if the provider has a method `_wrapTool` and infers the return type.
ExecuteToolFn
): AgentTool {
return { AgentTool.name: stringname:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.slug: stringslug,
AgentTool.description: stringdescription:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.description?: string | undefineddescription || '',
AgentTool.schema: Record<string, unknown>schema:
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.
inputParameters?: {
    type: "object";
    properties: Record<string, any>;
    description?: string | undefined;
    anyOf?: any[] | undefined;
    oneOf?: any[] | undefined;
    allOf?: any[] | undefined;
    not?: any;
    required?: string[] | undefined;
    title?: string | undefined;
    default?: any;
    nullable?: boolean | undefined;
    additionalProperties?: boolean | undefined;
} | undefined
inputParameters
|| {},
AgentTool.execute: (args: Record<string, unknown>) => Promise<unknown>execute: async (args: Record<string, unknown>args: type Record<K extends keyof any, T> = { [P in K]: T; }
Construct a type with a set of properties K of type T
Record
<string, unknown>) => {
const
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
= await executeToolFn: (toolSlug: string, input: Record<string, unknown>) => Promise<ToolExecuteResponse>executeToolFn(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
.slug: stringslug, args: Record<string, unknown>args);
if (!
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
.successful: booleansuccessful) {
throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error
(
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
.error: string | nullerror || 'Tool execution failed');
} return
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
.data: Record<string, unknown>data;
}, }; } // Required: Method to transform a collection of tools with execute function override MyAgentProvider.wrapTools(tools: Tool[], executeToolFn: ExecuteToolFn): AgentToolkitwrapTools(
tools: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}[]
tools
:
type Tool = {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
Tool
[], executeToolFn: ExecuteToolFnexecuteToolFn: type ExecuteToolFn = (toolSlug: string, input: Record<string, unknown>) => Promise<ToolExecuteResponse>
This type is used to infer the wrapped tool type from the provider. It checks if the provider has a method `_wrapTool` and infers the return type.
ExecuteToolFn
): AgentToolkit {
const const agentTools: AgentTool[]agentTools =
tools: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}[]
tools
.
Array<{ slug: string; name: string; description?: string | undefined; inputParameters?: { type: "object"; properties: Record<string, any>; description?: string | undefined; anyOf?: any[] | undefined; oneOf?: any[] | undefined; allOf?: any[] | undefined; not?: any; required?: string[] | undefined; title?: string | undefined; default?: any; nullable?: boolean | undefined; additionalProperties?: boolean | undefined; } | undefined; ... 7 more ...; isNoAuth?: boolean | undefined; }>.map<AgentTool>(callbackfn: (value: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}, index: number, array: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}[]) => AgentTool, thisArg?: any): AgentTool[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
=> this.MyAgentProvider.wrapTool(tool: Tool, executeToolFn: ExecuteToolFn): AgentToolwrapTool(
tool: {
    slug: string;
    name: string;
    description?: string | undefined;
    inputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    outputParameters?: {
        type: "object";
        properties: Record<string, any>;
        description?: string | undefined;
        anyOf?: any[] | undefined;
        oneOf?: any[] | undefined;
        allOf?: any[] | undefined;
        not?: any;
        required?: string[] | undefined;
        title?: string | undefined;
        default?: any;
        nullable?: boolean | undefined;
        additionalProperties?: boolean | undefined;
    } | undefined;
    ... 6 more ...;
    isNoAuth?: boolean | undefined;
}
tool
, executeToolFn: ExecuteToolFnexecuteToolFn));
return { AgentToolkit.tools: AgentTool[]tools: const agentTools: AgentTool[]agentTools, AgentToolkit.createAgent: (config: Record<string, unknown>) => unknowncreateAgent: config: Record<string, unknown>config => { // Create an agent using the tools return { run: (prompt: string) => Promise<void>run: async (prompt: stringprompt: string) => { // Implementation depends on your agent framework var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(`Running agent with prompt: ${prompt: stringprompt}`);
// The agent would use the tools.execute method to run tools }, }; }, }; } // Optional: Custom helper methods for your agent platform async MyAgentProvider.runAgent(agentToolkit: AgentToolkit, prompt: string): Promise<unknown>runAgent(agentToolkit: AgentToolkitagentToolkit: AgentToolkit, prompt: stringprompt: string): interface Promise<T>
Represents the completion of an asynchronous operation
Promise
<unknown> {
const const agent: unknownagent = agentToolkit: AgentToolkitagentToolkit.AgentToolkit.createAgent: (config: Record<string, unknown>) => unknowncreateAgent({}); return await const agent: unknownagent.run(prompt: stringprompt); } }

Using Your Custom Provider

After creating your provider, use it with the Composio SDK:

import { class Composio<TProvider extends BaseComposioProvider<unknown, unknown, unknown> = OpenAIProvider>
This is the core class for Composio. It is used to initialize the Composio SDK and provide a global configuration.
Composio
} from '@composio/core';
import { import MyAIProviderMyAIProvider } from './my-ai-provider'; // Create your provider instance const const myProvider: anymyProvider = new import MyAIProviderMyAIProvider(); // Initialize Composio with your provider const const composio: Composio<any>composio = new new Composio<any>(config?: ComposioConfig<any> | undefined): Composio<any>
Creates a new instance of the Composio SDK. The constructor initializes the SDK with the provided configuration options, sets up the API client, and initializes all core models (tools, toolkits, etc.).
@paramconfig - Configuration options for the Composio SDK@paramconfig.apiKey - The API key for authenticating with the Composio API@paramconfig.baseURL - The base URL for the Composio API (defaults to production URL)@paramconfig.allowTracking - Whether to allow anonymous usage analytics@paramconfig.provider - The provider to use for this Composio instance (defaults to OpenAIProvider)@example```typescript // Initialize with default configuration const composio = new Composio(); // Initialize with custom API key and base URL const composio = new Composio({ apiKey: 'your-api-key', baseURL: 'https://api.composio.dev' }); // Initialize with custom provider const composio = new Composio({ apiKey: 'your-api-key', provider: new CustomProvider() }); ```
Composio
({
apiKey?: string | null | undefined
The API key for the Composio API.
@example'sk-1234567890'
apiKey
: 'your-composio-api-key',
provider?: any
The tool provider to use for this Composio instance.
@examplenew OpenAIProvider()
provider
: const myProvider: anymyProvider,
}); // Get tools - they will be transformed by your provider const const tools: anytools = await const composio: Composio<any>composio.Composio<any>.tools: Tools<unknown, unknown, any>
List, retrieve, and execute tools
tools
.Tools<unknown, unknown, any>.get<any>(userId: string, filters: ToolListParams, options?: any): Promise<any> (+1 overload)
Get a list of tools from Composio based on filters. This method fetches the tools from the Composio API and wraps them using the provider.
@paramuserId - The user id to get the tools for@paramfilters - The filters to apply when fetching tools@paramoptions - Optional provider options including modifiers@returnsThe wrapped tools collection@example```typescript // Get tools from the GitHub toolkit const tools = await composio.tools.get('default', { toolkits: ['github'], limit: 10 }); // Get tools with search const searchTools = await composio.tools.get('default', { search: 'user', limit: 10 }); // Get a specific tool by slug const hackerNewsUserTool = await composio.tools.get('default', 'HACKERNEWS_GET_USER'); // Get a tool with schema modifications const tool = await composio.tools.get('default', 'GITHUB_GET_REPOS', { modifySchema: (toolSlug, toolkitSlug, schema) => { // Customize the tool schema return {...schema, description: 'Custom description'}; } }); ```
get
('default', {
toolkits: [string]toolkits: ['github'], }); // Use the tools with your AI platform var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(const tools: anytools); // These will be in your custom format

Provider State and Context

Your provider can maintain state and context:

export class class StatefulProviderStatefulProvider extends BaseNonAgenticProvider<type ToolCollection = /*unresolved*/ anyToolCollection, type Tool = /*unresolved*/ anyTool> {
  readonly StatefulProvider.name: "stateful-provider"name = 'stateful-provider';

  // Provider state
  private StatefulProvider.requestCount: numberrequestCount = 0;
  private StatefulProvider.toolCache: Map<string, any>toolCache = new 
var Map: MapConstructor
new <string, any>(iterable?: Iterable<readonly [string, any]> | null | undefined) => Map<string, any> (+3 overloads)
Map
<string, any>();
private StatefulProvider.config: ProviderConfigconfig: type ProviderConfig = /*unresolved*/ anyProviderConfig; constructor(config: ProviderConfigconfig: type ProviderConfig = /*unresolved*/ anyProviderConfig) { super(); this.StatefulProvider.config: ProviderConfigconfig = config: ProviderConfigconfig; } override StatefulProvider.wrapTool(tool: Tool): ProviderToolwrapTool(tool: Tooltool: type Tool = /*unresolved*/ anyTool): type ProviderTool = /*unresolved*/ anyProviderTool { this.StatefulProvider.requestCount: numberrequestCount++; // Use the provider state/config const
const enhancedTool: {
    name: any;
    description: any;
    schema: any;
}
enhancedTool
= {
// Transform the tool name: anyname: this.StatefulProvider.config: ProviderConfigconfig.useUpperCase ? tool: Tooltool.slug.toUpperCase() : tool: Tooltool.slug, description: anydescription: tool: Tooltool.description, schema: anyschema: tool: Tooltool.inputParameters, }; // Cache the transformed tool this.StatefulProvider.toolCache: Map<string, any>toolCache.Map<string, any>.set(key: string, value: any): Map<string, any>
Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.
set
(tool: Tooltool.slug,
const enhancedTool: {
    name: any;
    description: any;
    schema: any;
}
enhancedTool
);
return
const enhancedTool: {
    name: any;
    description: any;
    schema: any;
}
enhancedTool
;
} override StatefulProvider.wrapTools(tools: Tool[]): ProviderToolCollectionwrapTools(tools: Tool[]tools: type Tool = /*unresolved*/ anyTool[]): type ProviderToolCollection = /*unresolved*/ anyProviderToolCollection { return tools: Tool[]tools.Array<Tool>.map<ProviderTool>(callbackfn: (value: Tool, index: number, array: Tool[]) => ProviderTool, thisArg?: any): ProviderTool[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
map
(tool: Tooltool => this.StatefulProvider.wrapTool(tool: Tool): ProviderToolwrapTool(tool: Tooltool));
} // Custom methods that use provider state StatefulProvider.getRequestCount(): numbergetRequestCount(): number { return this.StatefulProvider.requestCount: numberrequestCount; } StatefulProvider.getCachedTool(slug: string): ProviderTool | undefinedgetCachedTool(slug: stringslug: string): type ProviderTool = /*unresolved*/ anyProviderTool | undefined { return this.StatefulProvider.toolCache: Map<string, any>toolCache.Map<string, any>.get(key: string): any
Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.
@returnsReturns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.
get
(slug: stringslug);
} }

Advanced: Provider Composition

You can compose functionality by extending existing providers:

import { class OpenAIProviderOpenAIProvider } from '@composio/openai';

// Extend the OpenAI provider with custom functionality
export class class EnhancedOpenAIProviderEnhancedOpenAIProvider extends class OpenAIProviderOpenAIProvider {
  // Add properties
  private 
EnhancedOpenAIProvider.analytics: {
    toolCalls: number;
    errors: number;
}
analytics
= {
toolCalls: numbertoolCalls: 0, errors: numbererrors: 0, }; // Override methods to add functionality override async EnhancedOpenAIProvider.executeToolCall(userId: any, tool: any, options: any, modifiers: any): Promise<string>
Executes a tool call from OpenAI's chat completion. This method processes a tool call from OpenAI's chat completion API, executes the corresponding Composio tool, and returns the result.
@paramuserId - The user ID for authentication and tracking@paramtool - The tool call from OpenAI@paramoptions - Optional execution options@parammodifiers - Optional execution modifiers@returnsThe result of the tool call as a JSON string@example```typescript // Execute a tool call from OpenAI const toolCall = { id: 'call_abc123', type: 'function', function: { name: 'SEARCH_TOOL', arguments: '{"query":"composio documentation"}' } }; const result = await provider.executeToolCall( 'user123', toolCall, { connectedAccountId: 'conn_xyz456' } ); console.log(JSON.parse(result)); ```
executeToolCall
(userId: anyuserId, tool: anytool, options: anyoptions, modifiers: anymodifiers) {
this.
EnhancedOpenAIProvider.analytics: {
    toolCalls: number;
    errors: number;
}
analytics
.toolCalls: numbertoolCalls++;
try { // Call the parent implementation const const result: stringresult = await super.OpenAIProvider.executeToolCall(userId: string, tool: ChatCompletionMessageFunctionToolCall, options?: ExecuteToolFnOptions, modifiers?: ExecuteToolModifiers): Promise<string>
Executes a tool call from OpenAI's chat completion. This method processes a tool call from OpenAI's chat completion API, executes the corresponding Composio tool, and returns the result.
@paramuserId - The user ID for authentication and tracking@paramtool - The tool call from OpenAI@paramoptions - Optional execution options@parammodifiers - Optional execution modifiers@returnsThe result of the tool call as a JSON string@example```typescript // Execute a tool call from OpenAI const toolCall = { id: 'call_abc123', type: 'function', function: { name: 'SEARCH_TOOL', arguments: '{"query":"composio documentation"}' } }; const result = await provider.executeToolCall( 'user123', toolCall, { connectedAccountId: 'conn_xyz456' } ); console.log(JSON.parse(result)); ```
executeToolCall
(userId: anyuserId, tool: anytool, options: anyoptions, modifiers: anymodifiers);
return const result: stringresult; } catch (function (local var) error: unknownerror) { this.
EnhancedOpenAIProvider.analytics: {
    toolCalls: number;
    errors: number;
}
analytics
.errors: numbererrors++;
throw function (local var) error: unknownerror; } } // Add new methods
EnhancedOpenAIProvider.getAnalytics(): {
    toolCalls: number;
    errors: number;
}
getAnalytics
() {
return this.
EnhancedOpenAIProvider.analytics: {
    toolCalls: number;
    errors: number;
}
analytics
;
} async EnhancedOpenAIProvider.executeWithRetry(userId: any, tool: any, options: any, modifiers: any, maxRetries?: number): Promise<string>executeWithRetry(userId: anyuserId, tool: anytool, options: anyoptions, modifiers: anymodifiers, maxRetries: numbermaxRetries = 3) { let let attempts: numberattempts = 0; let let lastError: anylastError; while (let attempts: numberattempts < maxRetries: numbermaxRetries) { try { return await this.EnhancedOpenAIProvider.executeToolCall(userId: any, tool: any, options: any, modifiers: any): Promise<string>
Executes a tool call from OpenAI's chat completion. This method processes a tool call from OpenAI's chat completion API, executes the corresponding Composio tool, and returns the result.
@paramuserId - The user ID for authentication and tracking@paramtool - The tool call from OpenAI@paramoptions - Optional execution options@parammodifiers - Optional execution modifiers@returnsThe result of the tool call as a JSON string@example```typescript // Execute a tool call from OpenAI const toolCall = { id: 'call_abc123', type: 'function', function: { name: 'SEARCH_TOOL', arguments: '{"query":"composio documentation"}' } }; const result = await provider.executeToolCall( 'user123', toolCall, { connectedAccountId: 'conn_xyz456' } ); console.log(JSON.parse(result)); ```
executeToolCall
(userId: anyuserId, tool: anytool, options: anyoptions, modifiers: anymodifiers);
} catch (function (local var) error: unknownerror) { let lastError: anylastError = function (local var) error: unknownerror; let attempts: numberattempts++; await new
var Promise: PromiseConstructor
new <unknown>(executor: (resolve: (value: unknown) => void, reject: (reason?: any) => void) => void) => Promise<unknown>
Creates a new Promise.
@paramexecutor A callback used to initialize the promise. This callback is passed two arguments: a resolve callback used to resolve the promise with a value or the result of another promise, and a reject callback used to reject the promise with a provided reason or error.
Promise
(resolve: (value: unknown) => voidresolve => function setTimeout(callback: (_: void) => void, delay?: number): NodeJS.Timeout (+2 overloads)
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/setTimeout)
setTimeout
(resolve: (value: unknown) => voidresolve, 1000 * let attempts: numberattempts));
} } throw let lastError: unknownlastError; } }

Best Practices

  1. Keep providers focused: Each provider should integrate with one specific platform
  2. Handle errors gracefully: Catch and transform errors from tool execution
  3. Follow platform conventions: Adopt naming and structural conventions of the target platform
  4. Optimize for performance: Cache transformed tools when possible
  5. Add helper methods: Provide convenient methods for common platform-specific operations
  6. Provide clear documentation: Document your provider's unique features and usage
  7. Use telemetry: Set a meaningful provider name for telemetry insights