Creating Custom Tools

View as markdown

Custom tools allow you to create your own tools that can be used with Composio.

  1. Standalone tools - Simple tools that don't require any authentication
  2. Toolkit-based tools - Tools that require authentication and can use toolkit credentials

Creating a Custom Tool

Standalone Tool

A standalone tool is the simplest form of custom tool. It only requires input parameters and an execute function:

from pydantic import BaseModel, Field

from composio import Composio
from composio.types import ExecuteRequestFn

composio = Composio()


class AddTwoNumbersInput(BaseModel):
    a: int = Field(
        ...,
        description="The first number to add",
    )
    b: int = Field(
        ...,
        description="The second number to add",
    )

# function name will be used as slug
@composio.tools.custom_tool
def add_two_numbers(request: AddTwoNumbersInput) -> int:
    """Add two numbers."""
    return request.a + request.b
const 
const 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
= await const composio: Composio<OpenAIProvider>composio.Composio<OpenAIProvider>.tools: Tools<unknown, unknown, OpenAIProvider>
List, retrieve, and execute tools
tools
.
Tools<unknown, unknown, OpenAIProvider>.createCustomTool<z.ZodObject<{
    number: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    number: number;
}, {
    number: number;
}>>(body: CustomToolOptions<z.ZodObject<{
    number: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    number: number;
}, {
    number: number;
}>>): Promise<Tool>
Creates a custom tool that can be used within the Composio SDK. Custom tools allow you to extend the functionality of Composio with your own implementations while keeping a consistent interface for both built-in and custom tools.
@parambody - The configuration for the custom tool@returnsThe created custom tool@example```typescript // creating a custom tool with a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', userId: 'default', connectedAccountId: '123', toolkitSlug: 'github', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input, connectionConfig, executeToolRequest) => { // Custom logic here return { data: { result: 'Success!' } }; } }); ```@example```typescript // creating a custom tool without a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input) => { // Custom logic here return { data: { result: 'Success!' } }; } });
createCustomTool
({
slug: stringslug: 'CALCULATE_SQUARE', name: stringname: 'Calculate Square', description?: string | undefineddescription: 'Calculates the square of a number',
inputParams: z.ZodObject<{
    number: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    number: number;
}, {
    number: number;
}>
inputParams
: import zz.
object<{
    number: z.ZodNumber;
}>(shape: {
    number: z.ZodNumber;
}, params?: z.RawCreateParams): z.ZodObject<{
    number: z.ZodNumber;
}, "strip", z.ZodTypeAny, {
    number: number;
}, {
    number: number;
}>
export object
object
({
number: z.ZodNumbernumber: import zz.
function number(params?: z.RawCreateParams & {
    coerce?: boolean;
}): z.ZodNumber
export number
number
().ZodType<number, ZodNumberDef, number>.describe(description: string): z.ZodNumberdescribe('The number to calculate the square of'),
}),
execute: (input: {
    number: number;
}) => Promise<{
    data: {
        result: number;
    };
    error: null;
    successful: true;
}>
execute
: async
input: {
    number: number;
}
input
=> {
const { const number: numbernumber } =
input: {
    number: number;
}
input
;
return {
ToolExecuteResponse.data: {
    [key: string]: unknown;
}
Tool execution output data that varies based on the specific tool
data
: { result: numberresult: const number: numbernumber * const number: numbernumber },
ToolExecuteResponse.error: string | null
Error message if the tool execution was not successful (null if successful)
error
: null,
ToolExecuteResponse.successful: boolean
Indicates if the tool execution was successful
successful
: true,
}; }, });

Toolkit-based Tool

A toolkit-based tool has access to two ways of making authenticated requests:

1. Using executeToolRequest - The recommended way to make authenticated requests to the toolkit's API endpoints. Composio automatically handles credential injection and baseURL resolution:

class GetIssueInfoInput(BaseModel):
    issue_number: int = Field(
        ...,
        description="The number of the issue to get information about",
    )

# function name will be used as slug
@composio.tools.custom_tool(toolkit="github")
def get_issue_info(
    request: GetIssueInfoInput,
    execute_request: ExecuteRequestFn,
    auth_credentials: dict,
) -> dict:
    """Get information about a GitHub issue."""
    response = execute_request(
        endpoint=f"/repos/composiohq/composio/issues/{request.issue_number}",
        method="GET",
        parameters=[
            {
                "name": "Accept",
                "value": "application/vnd.github.v3+json",
                "type": "header",
            },
            {
                "name": "Authorization",
                "value": f"Bearer {auth_credentials['access_token']}",
                "type": "header",
            },
        ],
    )
    return {"data": response.data}
const 
const 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
= await const composio: Composio<OpenAIProvider>composio.Composio<OpenAIProvider>.tools: Tools<unknown, unknown, OpenAIProvider>
List, retrieve, and execute tools
tools
.
Tools<unknown, unknown, OpenAIProvider>.createCustomTool<z.ZodObject<{
    repository: z.ZodString;
    page: z.ZodOptional<z.ZodNumber>;
    customHeader: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}>>(body: CustomToolOptions<z.ZodObject<{
    repository: z.ZodString;
    page: z.ZodOptional<z.ZodNumber>;
    customHeader: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}>>): Promise<Tool>
Creates a custom tool that can be used within the Composio SDK. Custom tools allow you to extend the functionality of Composio with your own implementations while keeping a consistent interface for both built-in and custom tools.
@parambody - The configuration for the custom tool@returnsThe created custom tool@example```typescript // creating a custom tool with a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', userId: 'default', connectedAccountId: '123', toolkitSlug: 'github', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input, connectionConfig, executeToolRequest) => { // Custom logic here return { data: { result: 'Success!' } }; } }); ```@example```typescript // creating a custom tool without a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input) => { // Custom logic here return { data: { result: 'Success!' } }; } });
createCustomTool
({
slug: stringslug: 'GITHUB_STAR_COMPOSIOHQ_REPOSITORY', name: stringname: 'Github star composio repositories', toolkitSlug: stringtoolkitSlug: 'github', description?: string | undefineddescription: 'Star any specified repo of `composiohq` user',
inputParams: z.ZodObject<{
    repository: z.ZodString;
    page: z.ZodOptional<z.ZodNumber>;
    customHeader: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}>
inputParams
: import zz.
object<{
    repository: z.ZodString;
    page: z.ZodOptional<z.ZodNumber>;
    customHeader: z.ZodOptional<z.ZodString>;
}>(shape: {
    repository: z.ZodString;
    page: z.ZodOptional<z.ZodNumber>;
    customHeader: z.ZodOptional<z.ZodString>;
}, params?: z.RawCreateParams): z.ZodObject<{
    repository: z.ZodString;
    page: z.ZodOptional<z.ZodNumber>;
    customHeader: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}, {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}>
export object
object
({
repository: z.ZodStringrepository: import zz.
function string(params?: z.RawCreateParams & {
    coerce?: true;
}): z.ZodString
export string
string
().ZodType<string, ZodStringDef, string>.describe(description: string): z.ZodStringdescribe('The repository to star'),
page: z.ZodOptional<z.ZodNumber>page: import zz.
function number(params?: z.RawCreateParams & {
    coerce?: boolean;
}): z.ZodNumber
export number
number
().ZodType<number, ZodNumberDef, number>.optional(): z.ZodOptional<z.ZodNumber>optional().ZodType<number | undefined, ZodOptionalDef<ZodNumber>, number | undefined>.describe(description: string): z.ZodOptional<z.ZodNumber>describe('Pagination page number'),
customHeader: z.ZodOptional<z.ZodString>customHeader: import zz.
function string(params?: z.RawCreateParams & {
    coerce?: true;
}): z.ZodString
export string
string
().ZodType<string, ZodStringDef, string>.optional(): z.ZodOptional<z.ZodString>optional().ZodType<string | undefined, ZodOptionalDef<ZodString>, string | undefined>.describe(description: string): z.ZodOptional<z.ZodString>describe('Custom header'),
}),
execute: (input: {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}, connectionConfig: ConnectionData | null, executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>) => Promise<ToolExecuteResponse>
execute
: async (
input: {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}
input
,
connectionConfig: {
    authScheme: "OAUTH1";
    val: z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIALIZING">;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIATED">;
        authUri: z.ZodString;
        oauth_token: z.ZodString;
        oauth_token_secret: z.ZodString;
        redirectUrl: z.ZodString;
        callbackUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional ...
connectionConfig
, executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>executeToolRequest) => {
// This method makes authenticated requests to the relevant API // You can use relative paths! // Composio will automatically inject the baseURL const const result: ToolExecuteResponseresult = await executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>executeToolRequest({ endpoint: stringendpoint: `/user/starred/composiohq/${
input: {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}
input
.repository: stringrepository}`,
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"method: 'PUT', body?: unknownbody: {}, // Add custom headers or query parameters
parameters?: {
    name: string;
    value: string | number;
    in: "query" | "header";
}[] | undefined
parameters
: [
// Add query parameters { name: stringname: 'page', value: string | numbervalue:
input: {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}
input
.page?: number | undefinedpage?.Number.toString(radix?: number): string
Returns a string representation of an object.
@paramradix Specifies a radix for converting numeric values to strings. This value is only used for numbers.
toString
() || '1',
in: "query" | "header"in: 'query', }, // Add custom headers { name: stringname: 'x-custom-header', value: string | numbervalue:
input: {
    repository: string;
    page?: number | undefined;
    customHeader?: string | undefined;
}
input
.customHeader?: string | undefinedcustomHeader || 'default-value',
in: "query" | "header"in: 'header', }, ], }); return const result: ToolExecuteResponseresult; }, });

2. Using connectionConfig - For making direct API calls when needed:

import requests

@composio.tools.custom_tool(toolkit="github")
def get_issue_info_direct(
    request: GetIssueInfoInput,
    execute_request: ExecuteRequestFn,
    auth_credentials: dict,
) -> dict:
    """Get information about a GitHub issue."""
    response = requests.get(
        f"https://api.github.com/repos/composiohq/composio/issues/{request.issue_number}",
        headers={
            "Accept": "application/vnd.github.v3+json",
            "Authorization": f"Bearer {auth_credentials['access_token']}",
        },
    )
    return {"data": response.json()}
const 
const 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
= await const composio: Composio<OpenAIProvider>composio.Composio<OpenAIProvider>.tools: Tools<unknown, unknown, OpenAIProvider>
List, retrieve, and execute tools
tools
.
Tools<unknown, unknown, OpenAIProvider>.createCustomTool<z.ZodObject<{
    repo: z.ZodString;
}, "strip", z.ZodTypeAny, {
    repo: string;
}, {
    repo: string;
}>>(body: CustomToolOptions<z.ZodObject<{
    repo: z.ZodString;
}, "strip", z.ZodTypeAny, {
    repo: string;
}, {
    repo: string;
}>>): Promise<Tool>
Creates a custom tool that can be used within the Composio SDK. Custom tools allow you to extend the functionality of Composio with your own implementations while keeping a consistent interface for both built-in and custom tools.
@parambody - The configuration for the custom tool@returnsThe created custom tool@example```typescript // creating a custom tool with a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', userId: 'default', connectedAccountId: '123', toolkitSlug: 'github', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input, connectionConfig, executeToolRequest) => { // Custom logic here return { data: { result: 'Success!' } }; } }); ```@example```typescript // creating a custom tool without a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input) => { // Custom logic here return { data: { result: 'Success!' } }; } });
createCustomTool
({
slug: stringslug: 'GITHUB_DIRECT_API', name: stringname: 'Direct GitHub API Call', description?: string | undefineddescription: 'Makes direct calls to GitHub API', toolkitSlug: stringtoolkitSlug: 'github',
inputParams: z.ZodObject<{
    repo: z.ZodString;
}, "strip", z.ZodTypeAny, {
    repo: string;
}, {
    repo: string;
}>
inputParams
: import zz.
object<{
    repo: z.ZodString;
}>(shape: {
    repo: z.ZodString;
}, params?: z.RawCreateParams): z.ZodObject<{
    repo: z.ZodString;
}, "strip", z.ZodTypeAny, {
    repo: string;
}, {
    repo: string;
}>
export object
object
({
repo: z.ZodStringrepo: import zz.
function string(params?: z.RawCreateParams & {
    coerce?: true;
}): z.ZodString
export string
string
().ZodType<string, ZodStringDef, string>.describe(description: string): z.ZodStringdescribe('Repository name'),
}),
execute: (input: {
    repo: string;
}, connectionConfig: ConnectionData | null, executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>) => Promise<ToolExecuteResponse>
execute
: async (
input: {
    repo: string;
}
input
,
connectionConfig: {
    authScheme: "OAUTH1";
    val: z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIALIZING">;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIATED">;
        authUri: z.ZodString;
        oauth_token: z.ZodString;
        oauth_token_secret: z.ZodString;
        redirectUrl: z.ZodString;
        callbackUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional ...
connectionConfig
, executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>executeToolRequest) => {
// Use connectionConfig for direct API calls if (!
connectionConfig: {
    authScheme: "OAUTH1";
    val: z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIALIZING">;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIATED">;
        authUri: z.ZodString;
        oauth_token: z.ZodString;
        oauth_token_secret: z.ZodString;
        redirectUrl: z.ZodString;
        callbackUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional ...
connectionConfig
||
connectionConfig: {
    authScheme: "OAUTH1";
    val: z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIALIZING">;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIATED">;
        authUri: z.ZodString;
        oauth_token: z.ZodString;
        oauth_token_secret: z.ZodString;
        redirectUrl: z.ZodString;
        callbackUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional ...
connectionConfig
.authScheme: "OAUTH1" | "OAUTH2" | "API_KEY" | "BASIC" | "BEARER_TOKEN" | "GOOGLE_SERVICE_ACCOUNT" | "NO_AUTH" | "CALCOM_AUTH" | "BILLCOM_AUTH" | "BASIC_WITH_JWT" | "SERVICE_ACCOUNT" | "SAML" | "DCR_OAUTH"authScheme !== 'OAUTH2') {
throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error
('OAuth2 connection required');
} const const result: Responseresult = await function fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> (+1 overload)
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/fetch)
fetch
(`https://api.github.com/repos/${
input: {
    repo: string;
}
input
.repo: stringrepo}`, {
RequestInit.headers?: HeadersInit | undefined
A Headers object, an object literal, or an array of two-item arrays to set request's headers.
headers
: {
type Authorization: stringAuthorization: `Bearer ${
connectionConfig: {
    authScheme: "OAUTH2";
    val: z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIALIZING">;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIATED">;
        code_verifier: z.ZodOptional<z.ZodString>;
        redirectUrl: z.ZodString;
        callback_url: z.ZodOptional<z.ZodString>;
        finalRedirectUri: z.ZodOptional<z.ZodString>;
        webhook_signature: z.ZodOptional<z.ZodString>;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional< ...
connectionConfig
.
val: z.objectOutputType<{
    subdomain: z.ZodOptional<z.ZodString>;
    "your-domain": z.ZodOptional<z.ZodString>;
    region: z.ZodOptional<z.ZodString>;
    shop: z.ZodOptional<z.ZodString>;
    account_url: z.ZodOptional<z.ZodString>;
    COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
    extension: z.ZodOptional<z.ZodString>;
    ... 23 more ...;
    composio_link_redirect_url: z.ZodOptional<z.ZodString>;
} & {
    ...;
}, z.ZodUnknown, "strip"> | ... 4 more ... | z.objectOutputType<...>
val
.access_token: unknownaccess_token}`,
}, }); return {
ToolExecuteResponse.data: {
    [key: string]: unknown;
}
Tool execution output data that varies based on the specific tool
data
: await const result: Responseresult.Body.json(): Promise<any>
[MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/json)
json
(),
ToolExecuteResponse.error: string | null
Error message if the tool execution was not successful (null if successful)
error
: null,
ToolExecuteResponse.successful: boolean
Indicates if the tool execution was successful
successful
: true,
}; }, });

Using Custom Headers and Query Parameters

You can add custom headers and query parameters to your toolkit-based tools using the parameters option in executeToolRequest:

@composio.tools.custom_tool(toolkit="github")
def get_issue_info(
    request: GetIssueInfoInput,
    execute_request: ExecuteRequestFn,
    auth_credentials: dict,
) -> dict:
    """Get information about a GitHub issue."""
    response = execute_request(
        endpoint=f"/repos/composiohq/composio/issues/{request.issue_number}",
        method="GET",
        parameters=[
            {
                "name": "Accept",
                "value": "application/vnd.github.v3+json",
                "type": "header",
            },
            {
                "name": "Authorization",
                "value": f"Bearer {auth_credentials['access_token']}",
                "type": "header",
            },
            {
                "name": 'X-Custom-Header',
                "value": 'custom-value',
                "type": 'header',
            },
        ],
    )
    return {"data": response.data}
const 
const 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
= await const composio: Composio<OpenAIProvider>composio.Composio<OpenAIProvider>.tools: Tools<unknown, unknown, OpenAIProvider>
List, retrieve, and execute tools
tools
.
Tools<unknown, unknown, OpenAIProvider>.createCustomTool<z.ZodObject<{
    query: z.ZodString;
    perPage: z.ZodOptional<z.ZodNumber>;
    acceptType: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}>>(body: CustomToolOptions<z.ZodObject<{
    query: z.ZodString;
    perPage: z.ZodOptional<z.ZodNumber>;
    acceptType: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}>>): Promise<Tool>
Creates a custom tool that can be used within the Composio SDK. Custom tools allow you to extend the functionality of Composio with your own implementations while keeping a consistent interface for both built-in and custom tools.
@parambody - The configuration for the custom tool@returnsThe created custom tool@example```typescript // creating a custom tool with a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', userId: 'default', connectedAccountId: '123', toolkitSlug: 'github', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input, connectionConfig, executeToolRequest) => { // Custom logic here return { data: { result: 'Success!' } }; } }); ```@example```typescript // creating a custom tool without a toolkit await composio.tools.createCustomTool({ name: 'My Custom Tool', description: 'A custom tool that does something specific', slug: 'MY_CUSTOM_TOOL', inputParameters: z.object({ param1: z.string().describe('First parameter'), }), execute: async (input) => { // Custom logic here return { data: { result: 'Success!' } }; } });
createCustomTool
({
slug: stringslug: 'GITHUB_SEARCH_REPOSITORIES', name: stringname: 'Search GitHub Repositories', description?: string | undefineddescription: 'Search for repositories with custom parameters', toolkitSlug: stringtoolkitSlug: 'github',
inputParams: z.ZodObject<{
    query: z.ZodString;
    perPage: z.ZodOptional<z.ZodNumber>;
    acceptType: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}>
inputParams
: import zz.
object<{
    query: z.ZodString;
    perPage: z.ZodOptional<z.ZodNumber>;
    acceptType: z.ZodOptional<z.ZodString>;
}>(shape: {
    query: z.ZodString;
    perPage: z.ZodOptional<z.ZodNumber>;
    acceptType: z.ZodOptional<z.ZodString>;
}, params?: z.RawCreateParams): z.ZodObject<{
    query: z.ZodString;
    perPage: z.ZodOptional<z.ZodNumber>;
    acceptType: z.ZodOptional<z.ZodString>;
}, "strip", z.ZodTypeAny, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}, {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}>
export object
object
({
query: z.ZodStringquery: import zz.
function string(params?: z.RawCreateParams & {
    coerce?: true;
}): z.ZodString
export string
string
().ZodType<string, ZodStringDef, string>.describe(description: string): z.ZodStringdescribe('Search query'),
perPage: z.ZodOptional<z.ZodNumber>perPage: import zz.
function number(params?: z.RawCreateParams & {
    coerce?: boolean;
}): z.ZodNumber
export number
number
().ZodType<number, ZodNumberDef, number>.optional(): z.ZodOptional<z.ZodNumber>optional().ZodType<number | undefined, ZodOptionalDef<ZodNumber>, number | undefined>.describe(description: string): z.ZodOptional<z.ZodNumber>describe('Results per page'),
acceptType: z.ZodOptional<z.ZodString>acceptType: import zz.
function string(params?: z.RawCreateParams & {
    coerce?: true;
}): z.ZodString
export string
string
().ZodType<string, ZodStringDef, string>.optional(): z.ZodOptional<z.ZodString>optional().ZodType<string | undefined, ZodOptionalDef<ZodString>, string | undefined>.describe(description: string): z.ZodOptional<z.ZodString>describe('Custom accept header'),
}),
execute: (input: {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}, connectionConfig: ConnectionData | null, executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>) => Promise<ToolExecuteResponse>
execute
: async (
input: {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}
input
,
connectionConfig: {
    authScheme: "OAUTH1";
    val: z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIALIZING">;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional<z.ZodString>;
        registration_client_uri: z.ZodOptional<z.ZodString>;
        composio_link_redirect_url: z.ZodOptional<z.ZodString>;
    } & {
        status: z.ZodLiteral<"INITIATED">;
        authUri: z.ZodString;
        oauth_token: z.ZodString;
        oauth_token_secret: z.ZodString;
        redirectUrl: z.ZodString;
        callbackUrl: z.ZodOptional<z.ZodString>;
    }, z.ZodUnknown, "strip"> | z.objectOutputType<{
        subdomain: z.ZodOptional<z.ZodString>;
        "your-domain": z.ZodOptional<z.ZodString>;
        region: z.ZodOptional<z.ZodString>;
        shop: z.ZodOptional<z.ZodString>;
        account_url: z.ZodOptional<z.ZodString>;
        COMPANYDOMAIN: z.ZodOptional<z.ZodString>;
        extension: z.ZodOptional<z.ZodString>;
        form_api_base_url: z.ZodOptional<z.ZodString>;
        instanceEndpoint: z.ZodOptional<z.ZodString>;
        api_url: z.ZodOptional<z.ZodString>;
        borneo_dashboard_url: z.ZodOptional<z.ZodString>;
        proxy_username: z.ZodOptional<z.ZodString>;
        proxy_password: z.ZodOptional<z.ZodString>;
        domain: z.ZodOptional<z.ZodString>;
        version: z.ZodOptional<z.ZodString>;
        dc: z.ZodOptional<z.ZodString>;
        site_name: z.ZodOptional<z.ZodString>;
        instanceName: z.ZodOptional<z.ZodString>;
        account_id: z.ZodOptional<z.ZodString>;
        your_server: z.ZodOptional<z.ZodString>;
        server_location: z.ZodOptional<z.ZodString>;
        base_url: z.ZodOptional<z.ZodString>;
        api_key: z.ZodOptional<z.ZodString>;
        generic_api_key: z.ZodOptional<z.ZodString>;
        bearer_token: z.ZodOptional<z.ZodString>;
        basic_encoded: z.ZodOptional<z.ZodString>;
        long_redirect_url: z.ZodOptional<z.ZodBoolean>;
        state_prefix: z.ZodOptional<z.ZodString>;
        registration_access_token: z.ZodOptional ...
connectionConfig
, executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>executeToolRequest) => {
const const result: ToolExecuteResponseresult = await executeToolRequest: (data: ToolProxyParams) => Promise<ToolExecuteResponse>executeToolRequest({ endpoint: stringendpoint: '/search/repositories', method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"method: 'GET',
parameters?: {
    name: string;
    value: string | number;
    in: "query" | "header";
}[] | undefined
parameters
: [
// Add query parameters for pagination { name: stringname: 'q', value: string | numbervalue:
input: {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}
input
.query: stringquery,
in: "query" | "header"in: 'query', }, { name: stringname: 'per_page', value: string | numbervalue: (
input: {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}
input
.perPage?: number | undefinedperPage || 30).Number.toString(radix?: number): string
Returns a string representation of an object.
@paramradix Specifies a radix for converting numeric values to strings. This value is only used for numbers.
toString
(),
in: "query" | "header"in: 'query', }, // Add custom headers { name: stringname: 'Accept', value: string | numbervalue:
input: {
    query: string;
    perPage?: number | undefined;
    acceptType?: string | undefined;
}
input
.acceptType?: string | undefinedacceptType || 'application/vnd.github.v3+json',
in: "query" | "header"in: 'header', }, { name: stringname: 'X-Custom-Header', value: string | numbervalue: 'custom-value', in: "query" | "header"in: 'header', }, ], }); return const result: ToolExecuteResponseresult; }, });

Executing Custom Tools

You can execute custom tools just like any other tool:

response = composio.tools.execute(
    user_id="default",
    slug="TOOL_SLUG", # For the tool above you can use `get_issue_info.slug`
    arguments={"issue_number": 1},
)
const 
const result: {
    error: string | null;
    data: Record<string, unknown>;
    successful: boolean;
    logId?: string | undefined;
    sessionInfo?: unknown;
}
result
= await const composio: Composio<OpenAIProvider>composio.Composio<OpenAIProvider>.tools: Tools<unknown, unknown, OpenAIProvider>
List, retrieve, and execute tools
tools
.Tools<unknown, unknown, OpenAIProvider>.execute(slug: string, body: ToolExecuteParams, modifiers?: ExecuteToolModifiers): Promise<ToolExecuteResponse>
Executes a given tool with the provided parameters. This method calls the Composio API or a custom tool handler to execute the tool and returns the response. It automatically determines whether to use a custom tool or a Composio API tool based on the slug. **Version Control:** By default, manual tool execution requires a specific toolkit version. If the version resolves to "latest", the execution will throw a `ComposioToolVersionRequiredError` unless `dangerouslySkipVersionCheck` is set to `true`. This helps prevent unexpected behavior when new toolkit versions are released.
@paramslug - The slug/ID of the tool to be executed@parambody - The parameters to be passed to the tool@parambody.version - The specific version of the tool to execute (e.g., "20250909_00")@parambody.dangerouslySkipVersionCheck - Skip version validation for "latest" version (use with caution)@parambody.userId - The user ID to execute the tool for@parambody.connectedAccountId - The connected account ID to use for authenticated tools@parambody.arguments - The arguments to pass to the tool@parammodifiers - Optional modifiers to transform the request or response@returns- The response from the tool execution@throws{ComposioCustomToolsNotInitializedError} If the CustomTools instance is not initialized@throws{ComposioConnectedAccountNotFoundError} If the connected account is not found@throws{ComposioToolNotFoundError} If the tool with the given slug is not found@throws{ComposioToolVersionRequiredError} If version resolves to "latest" and dangerouslySkipVersionCheck is not true@throws{ComposioToolExecutionError} If there is an error during tool execution@exampleExecute with a specific version (recommended for production) ```typescript const result = await composio.tools.execute('GITHUB_GET_REPOS', { userId: 'default', version: '20250909_00', arguments: { owner: 'composio' } }); ```@exampleExecute with dangerouslySkipVersionCheck (not recommended for production) ```typescript const result = await composio.tools.execute('HACKERNEWS_GET_USER', { userId: 'default', arguments: { userId: 'pg' }, dangerouslySkipVersionCheck: true // Allows execution with "latest" version }); ```@exampleExecute with SDK-level toolkit versions configuration ```typescript // If toolkitVersions are set during Composio initialization, no need to pass version const composio = new Composio({ toolkitVersions: { github: '20250909_00' } }); const result = await composio.tools.execute('GITHUB_GET_REPOS', { userId: 'default', arguments: { owner: 'composio' } }); ```@exampleExecute with modifiers ```typescript const result = await composio.tools.execute('GITHUB_GET_ISSUES', { userId: 'default', version: '20250909_00', arguments: { owner: 'composio', repo: 'sdk' } }, { beforeExecute: ({ toolSlug, toolkitSlug, params }) => { console.log(`Executing ${toolSlug} from ${toolkitSlug}`); return params; }, afterExecute: ({ toolSlug, toolkitSlug, result }) => { console.log(`Completed ${toolSlug}`); return result; } }); ```
execute
('TOOL_SLUG', {
arguments?: Record<string, unknown> | undefinedarguments: { // Tool input parameters }, userId?: string | undefineduserId: 'user-id', connectedAccountId?: string | undefinedconnectedAccountId: 'optional-account-id', // Required for toolkit-based tools });

Best Practices

  1. Use descriptive names and slugs for your tools
  2. Always provide descriptions for input parameters using describe()
  3. Handle errors gracefully in your execute function
  4. For toolkit-based tools:
    • Prefer executeToolRequest over direct API calls when possible
    • Use relative paths with executeToolRequest - Composio will automatically inject the correct baseURL
    • Use the parameters option to add custom headers or query parameters:
      parameters: [
        { name: stringname: 'page', value: stringvalue: '1', in: stringin: 'query' }, // Adds ?page=1 to URL
        { name: stringname: 'x-custom', value: stringvalue: 'value', in: stringin: 'header' }, // Adds header
      ];
    • Remember that executeToolRequest can only call tools from the same toolkit
    • Use executeToolRequest to leverage Composio's automatic credential handling
    • Only use connectionConfig when you need to make direct API calls or interact with different services
  5. Chain multiple toolkit operations using executeToolRequest for better maintainability

Limitations

  1. Custom tools are stored in memory and are not persisted
  2. They need to be recreated when the application restarts
  3. Toolkit-based tools require a valid connected account with the specified toolkit
  4. executeToolRequest can only execute tools from the same toolkit that the custom tool belongs to
  5. Each toolkit-based tool can only use one connected account at a time