Executing Tools

Learn how to execute Composio's tools with different providers and frameworks

Tool calling is a feature of all frontier LLMs to allow them to interact with the outside world. Earlier you might be able to ask an LLM to write you a nice email, but you would have to manually send it. With tool calling, you can now provide an LLM a valid tool, for example, GMAIL_SEND_EMAIL to go and accomplish the task autonomously.

Using Chat Completions

For non-agent providers—such as OpenAI, Anthropic, and Google AI—you can process tool calls using the tool call handlers provided by the Composio SDK. This approach works consistently across all supported non-agent providers.

To learn how to setup these providers, see Providers.

1from composio import Composio
2from composio_gemini import GeminiProvider
3from google import genai
4from google.genai import types
5
6user_id = "0000-1111-2222"
7
8# Create composio client
9composio = Composio(provider=GeminiProvider())
10
11# Create google client
12client = genai.Client()
13
14# Create genai client config
15config = types.GenerateContentConfig(
16 tools=composio.tools.get(
17 user_id=user_id,
18 tools=[
19 "COMPOSIO_SEARCH_DUCK_DUCK_GO_SEARCH",
20 ],
21 )
22)
23
24# Use the chat interface.
25chat = client.chats.create(model="gemini-2.0-flash", config=config)
26response = chat.send_message("What's new happening with Cluely?")
27print(response.text)

Using Agentic Frameworks

Composio also has first-party support for agentic frameworks which execute tools, feed the result to the LLM and continue the conversation.

Here, the tool execution is handled by the agentic framework. Composio makes sure the tools are formatted into the correct objects for the agentic framework to execute.

1import asyncio
2from agents import Agent, Runner
3from composio import Composio
4from composio_openai_agents import OpenAIAgentsProvider
5from uuid import uuid4
6
7user_id = uuid4()
8
9# Initialize Composio toolset
10composio = Composio(provider=OpenAIAgentsProvider())
11
12# Get all the tools
13tools = composio.tools.get(
14 user_id=user_id,
15 toolkits=["COMPOSIO_SEARCH"],
16)
17
18# Create an agent with the tools
19agent = Agent(
20 name="Deep Researcher",
21 instructions="You are an investigative journalist.",
22 tools=tools,
23)
24
25
26# Run the agent
27async def main():
28 result = await Runner.run(
29 starting_agent=agent,
30 input=("Do a thorough DEEP research on Ilya Sutskever"),
31 )
32 print(result.final_output)
33
34
35asyncio.run(main())

Tools are scoped to a user

Each tool and tool action is scoped to a user. Hence, a user_id is required to fetch and execute tools.

The authentication state is checked and used while fetching and executing a tool.

You need to authorize the user to execute tools. For more information on authentication, see Authenticating Tools.

For Humans (deterministic tool calling)

In case you just want to call a tool manually — not using any framework or LLM provider, you can do so using the execute method.

1user_id = "user@example.com"
2composio = Composio()
3
4result = composio.tools.execute(
5 "HACKERNEWS_GET_USER",
6 user_id=user_id,
7 arguments={"username": "pg"}
8)
9print(result)

Proxy Execute — Manually calling toolkit APIs

You can also proxy requests to an API of any supported toolkit. This is useful when you want to manually call an API of a toolkit and inject the authentication state from Composio.

1response = composio.tools.proxy(
2 endpoint="/repos/composiohq/composio/issues/1",
3 method="GET",
4 connected_account_id="ac_1234", # use connected account for github
5 parameters=[
6 {
7 "name": "Accept",
8 "value": "application/vnd.github.v3+json",
9 "type": "header",
10 },
11 ],
12)

If you’re interested in extending toolkits and creating custom tools, see Custom tools.

Automatic File Handling

Composio SDK includes automatic file handling for tools that work with files. When enabled (default), the SDK automatically handles file uploads and downloads during tool execution.

File Upload

When a tool accepts file inputs (marked with file_uploadable: true), you can pass local file paths or URLs or a File object. Here’s an example using Google Drive upload:

1import os
2
3from composio import Composio
4
5composio = Composio()
6
7# Upload a local file to Google Drive
8result = composio.tools.execute(
9 "GOOGLEDRIVE_UPLOAD_FILE",
10 user_id="default",
11 arguments={
12 "file_to_upload": os.path.join(os.getcwd(), "document.pdf") # Local file path
13 }
14)
15
16print(result.data) # Contains Google Drive file details

The SDK automatically:

  1. Reads the file content
  2. Uploads it to secure storage
  3. Passes the file metadata to the tool

File Download

When a tool returns file outputs, the SDK automatically:

  1. Downloads the file to a local temporary directory
  2. Provides the local file path in the response
1# Download a file from Google Drive
2result = composio.tools.execute(
3 "GOOGLEDRIVE_DOWNLOAD_FILE",
4 user_id="default",
5 arguments={
6 "file_id": "your_file_id"
7 }
8)
9
10# Result includes local file path
11print(result.data["file"]) # "/path/to/downloaded/file.pdf"

Disabling Auto File Handling

You can disable automatic file handling when initializing the Typescript SDK:

TypeScript
1const composio = new Composio({
2 apiKey: process.env.COMPOSIO_API_KEY,
3 autoUploadDownloadFiles: false
4});
5
6// Now you need to handle files manually using composio.files API
7const fileData = await composio.files.upload({
8 filePath: path.join(__dirname, 'document.pdf'),
9 toolSlug: 'GOOGLEDRIVE_UPLOAD_FILE',
10 toolkitSlug: 'googledrive'
11});

For more details on file handling, see Auto Upload and Download Files.