Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ComposioHQ/composio/llms.txt

Use this file to discover all available pages before exploring further.

Composio provides two authentication flows for connecting users to third-party apps. In-chat authentication lets the agent handle OAuth prompts automatically — no extra setup required. Manual authentication lets your app initiate connections during onboarding or from a settings page, giving you full control over when and where users authenticate.

In-chat authentication

By default, every session includes the COMPOSIO_MANAGE_CONNECTIONS meta-tool. When a user asks the agent to do something that requires an account the agent hasn’t connected yet, the agent calls this meta-tool and returns a Connect Link URL directly in chat. The user clicks the link, completes OAuth, confirms in the conversation, and the agent retries the original task. No extra setup is required. Just create a session:
import { Composio } from "@composio/core";

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const session = await composio.create("user_123");
const tools = await session.tools();
When the user triggers a tool that requires authentication, the agent response looks like this:
You: Summarize my emails from today

Agent: I need you to connect your Gmail account first. Please click here to authorize:
       https://connect.composio.dev/link/ln_abc123

You: Done

Agent: Here's a summary of your emails from today...
You can redirect users back to your chat page after they authenticate by passing a callbackUrl:
const session = await composio.create("user_123", {
  manageConnections: {
    callbackUrl: "https://yourapp.com/chat",
  },
});

Manual authentication with session.authorize()

Use manual authentication when you want users connected before they ever start chatting — for example, during onboarding, from a settings page, or as a pre-flight check before running an automated task.
1
Create a session and disable in-chat auth promptsPass manageConnections: false to prevent the agent from prompting users to authenticate in chat. You’ll handle auth entirely in your UI.
const session = await composio.create("user_123", {
  manageConnections: false,
});
2
Generate a Connect Link with session.authorize()Call session.authorize() with the toolkit slug to get a redirectUrl (also called redirect_url in Python). Redirect the user to this URL to start the OAuth flow.
const connectionRequest = await session.authorize("gmail");

console.log(connectionRequest.redirectUrl);
// https://connect.composio.dev/link/ln_abc123

// Redirect the user to this URL in your UI
3
Wait for the user to complete OAuthPoll for completion using waitForConnection() / wait_for_connection(). The method resolves with the connected account once the user finishes authentication.
const connectedAccount = await connectionRequest.waitForConnection(60000);
console.log(`Connected: ${connectedAccount.id}`);
If the user closes the Connect Link without completing auth, the connection stays in INITIATED status until it expires. waitForConnection() will timeout after the specified milliseconds.

Callback URL

Pass a callbackUrl to control where users land after they finish authenticating. You can embed query parameters to carry context through the OAuth flow:
const connectionRequest = await session.authorize("gmail", {
  callbackUrl: "https://your-app.com/callback?user_id=user_123&source=onboarding",
});

console.log(connectionRequest.redirectUrl);
After authentication, Composio redirects the user to your callback URL with these parameters appended:
ParameterDescription
statussuccess or failed
connected_account_idThe ID of the newly created connected account
https://your-app.com/callback?user_id=user_123&source=onboarding&status=success&connected_account_id=ca_abc123

Checking connection status

Use session.toolkits() to inspect which toolkits are connected for the current session user:
const toolkits = await session.toolkits();

toolkits.items.forEach((toolkit) => {
  const accountId = toolkit.connection?.connectedAccount?.id ?? "Not connected";
  console.log(`${toolkit.name}: ${accountId}`);
});

Putting it all together

A common pattern is to verify all required connections before starting the agent loop:
import { Composio } from "@composio/core";

const composio = new Composio({ apiKey: process.env.COMPOSIO_API_KEY });
const requiredToolkits = ["gmail", "github"];

const session = await composio.create("user_123", {
  manageConnections: false,
});

const toolkits = await session.toolkits();

const connected = toolkits.items
  .filter((t) => t.connection?.connectedAccount)
  .map((t) => t.slug);

const pending = requiredToolkits.filter((slug) => !connected.includes(slug));

console.log("Connected:", connected);
console.log("Pending:", pending);

for (const slug of pending) {
  const connectionRequest = await session.authorize(slug);
  console.log(`Connect ${slug}: ${connectionRequest.redirectUrl}`);
  await connectionRequest.waitForConnection();
}

console.log(`All toolkits connected! MCP URL: ${session.mcp.url}`);

Sessions

Understand how sessions work and what options are available

Connected Accounts

Manage multiple connected accounts per user and toolkit

MCP

Use the session MCP URL with Claude Desktop, Cursor, and other MCP clients

Tool Router

Semantically select tools at runtime to keep LLM context focused

Build docs developers (and LLMs) love