Executing Tools

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

LLMs on their own can only do generation. Tool calling changes that by letting them interact with external services. Instead of just drafting an email, the model can call GMAIL_SEND_EMAIL to actually send it. The tool’s results feed back to the LLM, closing the loop so it can decide, act, observe, and adapt.

In Composio, every tool is a single API action—fully described with schema, parameters, and return type. Tools live inside toolkits like Gmail, Slack, or GitHub, and Composio handles authentication and user scoping.

User Scoping: All tools are scoped to a specific user - that’s why every example includes a user_id. Each user must authenticate with their respective services (Gmail, Calendar, etc.) before executing tools. Learn more about authentication →

Using Chat Completions

Use the Composio SDK with providers like OpenAI, Anthropic, and Google AI. To learn how to set-up these providers, see Providers.

1from composio import Composio
2from composio_openai import OpenAIProvider
3from openai import OpenAI
4from datetime import datetime
5
6# Use a unique identifier for each user in your application
7user_id = "user-k7334"
8
9# Create composio client
10composio = Composio(provider=OpenAIProvider(), api_key="your_composio_api_key")
11
12# Create openai client
13openai = OpenAI()
14
15# Get calendar tools for this user
16tools = composio.tools.get(
17 user_id=user_id,
18 tools=["GOOGLECALENDAR_EVENTS_LIST"]
19)
20
21# Ask the LLM to check calendar
22result = openai.chat.completions.create(
23 model="gpt-4o-mini",
24 tools=tools,
25 messages=[
26 {"role": "system", "content": "You are a helpful assistant."},
27 {"role": "user", "content": f"What's on my calendar for the next 7 days. Its {datetime.now().strftime("%Y-%m-%d")} today.",}
28 ]
29)
30
31
32# Handle tool calls
33result = composio.provider.handle_tool_calls(user_id=user_id, response=result)
34print(result)

Using Agentic Frameworks

Agentic frameworks automatically handle the tool execution loop. Composio provides support for frameworks like this by making 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
5
6# Use a unique identifier for each user in your application
7user_id = "user-k7334"
8
9# Initialize Composio toolset
10composio = Composio(provider=OpenAIAgentsProvider(), api_key="your_composio_api_key")
11
12# Get all tools for the user
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
25async def main():
26 result = await Runner.run(
27 starting_agent=agent,
28 input=("Do a thorough DEEP research on Golden Gate Bridge"),
29 )
30 print(result.final_output)
31
32# Run the agent
33asyncio.run(main())

Direct Tool execution

In case you just want to call a tool without using any framework or LLM provider, you can use the execute method directly.

Finding tool arguments: In the Auth Configs tab → Select your toolkit → Tools & Triggers → Select the tool to see its required and optional parameters, types, and descriptions.

1from composio import Composio
2
3user_id = "user-k7334"
4composio = Composio(api_key="your_composio_key")
5
6# Find available arguments for any tool in the Composio dashboard
7result = composio.tools.execute(
8 "GITHUB_LIST_STARGAZERS",
9 user_id=user_id,
10 arguments={"owner": "ComposioHQ", "repo": "composio", "page": 1, "per_page": 5}
11)
12print(result)

Proxy Execute — Manually calling toolkit APIs

You can proxy requests to any supported toolkit API and let Composio inject the authentication state. This is useful when you need an API endpoint that isn’t available as a predefined tool.

The endpoint can be a relative path or absolute URL. Composio uses the connected_account_id to determine the toolkit and resolve relative paths against the appropriate base URL.

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

Need an API that isn’t supported by any Composio toolkit, or want to extend an existing one? Learn how to create custom tools.

Automatic File Handling

Composio handles file operations automatically. Pass file paths to tools that need them, and get local file paths back from tools that return files.

File Upload

Pass local file paths, URLs, or File objects to tools that accept files:

1# Upload a local file to Google Drive
2result = composio.tools.execute(
3 slug="GOOGLEDRIVE_UPLOAD_FILE",
4 user_id="user-1235***",
5 arguments={"file_to_upload": os.path.join(os.getcwd(), "document.pdf")}, # Local file path
6)
7
8print(result) # Print Google Drive file details

File Download

When tools return files, Composio downloads them to the local directory and provides file path in the response: When tools return files, Composio downloads them to the local directory and provides the file path in the response:

1composio = Composio(
2 api_key="your_composio_key", file_download_dir="./downloads"
3) # Optional: Specify the directory to download files to
4
5result = composio.tools.execute(
6 "GOOGLEDRIVE_DOWNLOAD_FILE",
7 user_id="user-1235***",
8 arguments={"file_id": "your_file_id"},
9)
10
11# Result includes local file path
12print(result)

Disabling Auto File Handling

You can disable automatic file handling when initializing the TypeScript SDK. When disabled, handle file uploads and downloads manually using files.upload and files.download:

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({
8filePath: path.join(\_\_dirname, 'document.pdf'),
9toolSlug: 'GOOGLEDRIVE_UPLOAD_FILE',
10toolkitSlug: 'googledrive'
11});