Authentication

Understand how Tool Router handles user authentication to toolkits

Tool Router handles authentication through Connect Links, hosted pages where users complete OAuth or enter credentials.

In-chat authentication

By default, when a tool requires authentication, the agent prompts the user with a Connect Link. The user authenticates and confirms in chat. The agent handles OAuth flows, token refresh, and credential management automatically.

Here's what this looks like in a conversation:

You: Star the composio repo on GitHub

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

You: Done

Agent: Done! I've starred ComposioHQ/composio.

This flow works well for chat applications where users interact directly with the agent. See Using in-chat authentication.

Manual authentication

For apps that manage auth outside of chat, use session.authorize() to generate Connect Links programmatically:

connection_request = session.authorize("github")
print(connection_request.redirect_url)
# https://connect.composio.dev/link/ln_abc123
const const connectionRequest: ConnectionRequestconnectionRequest = await const session: ToolRouterSession<unknown, unknown, OpenAIProvider>session.
ToolRouterSession<unknown, unknown, OpenAIProvider>.authorize: (toolkit: string, options?: {
    callbackUrl?: string;
}) => Promise<ConnectionRequest>
Initiate an authorization flow for a toolkit. Returns a ConnectionRequest with a redirect URL for the user.
authorize
("github");
var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v24.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v24.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v24.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v24.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(const connectionRequest: ConnectionRequestconnectionRequest.ConnectionRequestState.redirectUrl?: string | null | undefinedredirectUrl);
// https://connect.composio.dev/link/ln_abc123

Use this when you want users to connect accounts during onboarding, or when building a custom connections page. See Manually authenticating users for a detailed guide.

How Tool Router manages auth configs

When executing a tool, Tool Router needs an auth config to find or create a connected account. It handles this automatically:

  1. Uses your authConfigs override if provided
  2. Otherwise, reuses an auth config it previously created for this toolkit
  3. If none exists, creates one using Composio managed auth

You don't need to create auth configs manually for most toolkits.

Supported auth methods

Tool Router supports Composio managed OAuth (GitHub, Gmail, Slack, and most toolkits) and API key auth (users enter their own keys via Connect Link).

Toolkits without Composio managed auth require a custom auth config. See Using custom auth configs.

White-labeling

Show your own branding on OAuth consent screens by creating your own OAuth app. See White-labeling authentication.