Skip to main content

Overview

Tool execution is the core operation in Composio, allowing you to run actions from integrated services. This guide covers executing tools manually, handling authentication, managing versions, and customizing behavior with modifiers.

Basic Tool Execution

1
Step 1: Initialize Composio
2
First, create a Composio instance with your API key:
3
TypeScript
import { Composio } from 'composio-core';

const composio = new Composio({
  apiKey: process.env.COMPOSIO_API_KEY
});
Python
from composio import Composio

composio = Composio(api_key=os.environ["COMPOSIO_API_KEY"])
4
Step 2: Execute a tool
5
Execute a tool with the required parameters:
6
TypeScript
const result = await composio.tools.execute('GITHUB_GET_REPOS', {
  userId: 'default',
  version: '20250909_00',
  arguments: {
    owner: 'composio'
  }
});

if (result.successful) {
  console.log('Repositories:', result.data);
} else {
  console.error('Error:', result.error);
}
Python
result = composio.tools.execute(
    'GITHUB_GET_REPOS',
    user_id='default',
    version='20250909_00',
    arguments={'owner': 'composio'}
)

if result.successful:
    print('Repositories:', result.data)
else:
    print('Error:', result.error)
7
Step 3: Handle the response
8
The execution response contains:
9
  • successful: Boolean indicating success/failure
  • data: The result data (when successful)
  • error: Error details (when failed)
  • logId: Log identifier for debugging
  • sessionInfo: Session metadata (for stateful tools)
  • Version Control

    By default, manual tool execution requires a specific toolkit version. If the version resolves to “latest”, execution will throw a ComposioToolVersionRequiredError unless dangerouslySkipVersionCheck is set to true.

    Why Version Control Matters

    Using “latest” version in manual execution can lead to unexpected behavior when new toolkit versions are released, potentially breaking your application. For production use, it’s recommended to pin specific toolkit versions.

    Setting Versions

    There are multiple ways to control toolkit versions:
    // Pass version directly in execute call (highest priority)
    const result = await composio.tools.execute('GITHUB_GET_REPOS', {
      userId: 'default',
      version: '20250909_00',
      arguments: { owner: 'composio' }
    });
    

    Authenticated Tool Execution

    Using Connected Accounts

    Most tools require authentication. Use a connected account to execute authenticated tools:
    // Execute with connected account ID
    const result = await composio.tools.execute('GITHUB_CREATE_ISSUE', {
      userId: 'user123',
      connectedAccountId: 'conn_abc123',
      version: '20250909_00',
      arguments: {
        owner: 'myorg',
        repo: 'myrepo',
        title: 'Bug Report',
        body: 'Description of the issue'
      }
    });
    
    If you don’t specify connectedAccountId, Composio uses the first active connected account for the user and toolkit.

    Custom Authentication

    For one-off requests, you can provide custom authentication parameters:
    const result = await composio.tools.execute('GITHUB_GET_REPOS', {
      userId: 'default',
      version: '20250909_00',
      customAuthParams: {
        access_token: 'ghp_yourpersonalaccesstoken',
        token_type: 'Bearer'
      },
      arguments: {
        owner: 'composio'
      }
    });
    
    Custom authentication bypasses Composio’s token refresh and security features. Use connected accounts for production applications.

    No-Auth Tools

    Some tools don’t require authentication:
    // Execute HackerNews API (no authentication needed)
    const result = await composio.tools.execute('HACKERNEWS_GET_USER', {
      userId: 'default',
      version: '20250909_00',
      arguments: {
        userId: 'pg'
      }
    });
    

    Execution with Modifiers

    Modifiers allow you to customize tool behavior before and after execution. See the Modifiers Guide for detailed information.
    const result = await composio.tools.execute('GITHUB_GET_REPOS', {
      userId: 'default',
      version: '20250909_00',
      arguments: { owner: 'composio' }
    }, {
      beforeExecute: async ({ toolSlug, params }) => {
        console.log(`Executing ${toolSlug}`);
        return params;
      },
      afterExecute: async ({ result }) => {
        console.log(`Execution complete`);
        return result;
      }
    });
    

    Custom Tools Execution

    Custom tools you’ve created can be executed the same way:
    // Execute a custom tool
    const result = await composio.tools.execute('MY_CUSTOM_TOOL', {
      userId: 'default',
      arguments: {
        query: 'search term',
        limit: 10
      }
    });
    
    Custom tools with a toolkit slug automatically use the connected account for that toolkit. See Custom Tools Guide for more details.

    Error Handling

    Properly handle execution errors:
    try {
      const result = await composio.tools.execute('GITHUB_GET_REPOS', {
        userId: 'default',
        version: '20250909_00',
        arguments: { owner: 'composio' }
      });
      
      if (!result.successful) {
        // Handle tool-level errors
        console.error('Tool execution failed:', result.error);
        return;
      }
      
      // Process successful result
      console.log('Data:', result.data);
      
    } catch (error) {
      // Handle SDK-level errors
      if (error instanceof ComposioToolNotFoundError) {
        console.error('Tool not found:', error.message);
      } else if (error instanceof ComposioConnectedAccountNotFoundError) {
        console.error('No connected account:', error.message);
      } else if (error instanceof ComposioToolVersionRequiredError) {
        console.error('Version required:', error.message);
      } else {
        console.error('Unexpected error:', error);
      }
    }
    
    See the Error Handling Guide for comprehensive error management strategies.

    Best Practices

    Pin Versions

    Always specify toolkit versions for production applications to avoid breaking changes.

    Use Connected Accounts

    Prefer connected accounts over custom auth params for better security and token management.

    Handle Errors

    Check both result.successful and catch SDK exceptions for robust error handling.

    Enable Tracing

    Set allowTracing: true in execution params for debugging and monitoring.

    Advanced Options

    Execution Tracing

    Enable tracing to monitor tool execution:
    const result = await composio.tools.execute('GITHUB_GET_REPOS', {
      userId: 'default',
      version: '20250909_00',
      allowTracing: true,
      arguments: { owner: 'composio' }
    });
    
    // Access trace data via logId
    console.log('Trace Log ID:', result.logId);
    

    Text-based Execution

    Some tools support natural language input:
    const result = await composio.tools.execute('GITHUB_CREATE_ISSUE', {
      userId: 'default',
      version: '20250909_00',
      text: 'Create a bug report titled "Login fails" with description "Users cannot log in with OAuth"'
    });
    

    Next Steps

    Authentication Flows

    Learn how to set up and manage user authentication

    Modifiers

    Customize tool behavior with before and after execution hooks

    Error Handling

    Implement robust error handling strategies

    File Handling

    Work with file uploads and downloads in tools

    Build docs developers (and LLMs) love