Files
composio-skills-reference/composio-sdk/rules/app-execute-tools.md
sohamganatra b8b711dff6 Add Composio SDK skill with rules and agent config
Adds composio-sdk/ with SKILL.md, AGENTS.md, and 18 rule files
covering Tool Router, direct execution, triggers, and auth patterns.

Source: composiohq/skills

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-05 22:54:21 -08:00

212 lines
5.8 KiB
Markdown

---
title: Direct Tool Execution for Applications
impact: HIGH
description: Core patterns for manually executing Composio tools in traditional applications without agent frameworks
tags: [tools, execute, execution, apps, manual]
---
# Direct Tool Execution for Applications
When building traditional applications without agent frameworks, use `composio.tools.execute()` to manually execute tools.
## Basic Execution
```typescript
// Execute with a specific version (REQUIRED)
const result = await composio.tools.execute('GITHUB_GET_ISSUES', {
userId: 'default',
arguments: { owner: 'composio', repo: 'sdk' },
version: '12082025_00', // Specific version required
});
```
## Version Management
**CRITICAL**: When manually executing tools (especially in workflows), a **specific version is required**. Using `'latest'` will throw an error.
**Why version pinning is required:**
- Tool argument schemas can change between versions
- Using `'latest'` in workflows can cause runtime errors when tools are updated
- Pinned versions ensure workflow stability and predictability
- Version validation prevents production issues from schema mismatches
See [Tool Version Management](app-tool-versions.md) for detailed version strategies.
## Parameters
### ExecuteParams Object
```typescript
{
userId: string, // User ID for connected account lookup
arguments: object, // Tool-specific input parameters
version?: string, // Toolkit version (required for manual execution)
dangerouslySkipVersionCheck?: boolean // Bypass version validation (NOT recommended)
}
```
### Execution Modifiers
Transform requests and responses with modifiers:
```typescript
const result = await composio.tools.execute(
'GITHUB_GET_ISSUES',
{
userId: 'default',
arguments: { owner: 'composio', repo: 'sdk' },
version: '12082025_00',
},
{
beforeExecute: ({ toolSlug, toolkitSlug, params }) => {
// Modify params before execution
console.log('Executing:', toolSlug);
return {
...params,
arguments: {
...params.arguments,
per_page: 100 // Add default parameter
}
};
},
afterExecute: ({ toolSlug, toolkitSlug, result }) => {
// Transform result after execution
console.log('Completed:', toolSlug);
return {
...result,
timestamp: new Date().toISOString()
};
},
}
);
```
## Response Format
```typescript
interface ToolExecuteResponse {
data: any; // Tool-specific response data
error: string | null; // Error message if execution failed
successful: boolean; // Whether execution succeeded
}
```
## Error Handling
```typescript
try {
const result = await composio.tools.execute('GITHUB_GET_ISSUES', {
userId: 'user_123',
arguments: { owner: 'composio', repo: 'sdk' },
version: '12082025_00',
});
if (!result.successful) {
console.error('Tool execution failed:', result.error);
// Handle error case
return;
}
// Process successful result
console.log('Issues:', result.data);
} catch (error) {
if (error.name === 'ComposioToolNotFoundError') {
console.error('Tool not found');
} else if (error.name === 'ComposioToolExecutionError') {
console.error('Execution error:', error.message);
} else {
console.error('Unexpected error:', error);
}
}
```
## Common Error Types
- `ComposioCustomToolsNotInitializedError`: Custom tools instance not initialized
- `ComposioToolNotFoundError`: Tool with the given slug not found
- `ComposioToolExecutionError`: Error during tool execution
- Version validation errors: Thrown when version is missing or `'latest'` is used
## Best Practices
1. **Always specify versions**: Use explicit versions or configure at initialization
2. **Handle errors gracefully**: Check `successful` flag and handle `error` field
3. **Validate arguments**: Ensure all required parameters are provided
4. **Use modifiers sparingly**: Only add modifiers when necessary for transformation
5. **Log execution details**: Track which tools are executed for debugging
6. **Test with real data**: Validate execution with actual connected accounts
7. **Handle authentication errors**: User may not have connected account for toolkit
## Common Patterns
### Execute with retry logic
```typescript
async function executeWithRetry(slug, params, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const result = await composio.tools.execute(slug, params);
if (result.successful) return result;
console.log(`Retry ${i + 1}/${maxRetries}`);
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
} catch (error) {
if (i === maxRetries - 1) throw error;
}
}
}
```
### Execute multiple tools in sequence
```typescript
async function executeWorkflow(userId) {
// Step 1: Get repository
const repo = await composio.tools.execute('GITHUB_GET_REPO', {
userId,
arguments: { owner: 'composio', repo: 'sdk' },
version: '12082025_00',
});
if (!repo.successful) {
throw new Error(`Failed to get repo: ${repo.error}`);
}
// Step 2: Create issue using data from step 1
const issue = await composio.tools.execute('GITHUB_CREATE_ISSUE', {
userId,
arguments: {
owner: 'composio',
repo: 'sdk',
title: `Update for ${repo.data.name}`,
body: 'Automated issue creation'
},
version: '12082025_00',
});
return { repo: repo.data, issue: issue.data };
}
```
### Execute with parameter validation
```typescript
async function sendSlackMessage(userId, channel, text) {
// Validate inputs
if (!channel.startsWith('#')) {
throw new Error('Channel must start with #');
}
if (text.length > 4000) {
throw new Error('Message too long');
}
const result = await composio.tools.execute('SLACK_SEND_MESSAGE', {
userId,
arguments: { channel, text },
version: '10082025_01',
});
return result;
}
```