# Composio

URL: https://docs.hanzo.ai/docs/guides/migrate/composio

> Composio gives an agent authenticated tools across third-party apps. Here that is /v1/provider for the org's credential, /v1/connection for a user's own, and /v1/tool for the actions they reach.

Composio holds OAuth credentials for third-party apps and hands an agent the
actions those credentials reach. Two capabilities answer it: `/v1/provider`
(56 operations) holds the credential an **org** connects,
`/v1/connection` (8) holds the one a **user** connects, and every
action either one reaches shows up in `/v1/tool`.

## Start here

A fresh key already reaches the platform's own tools, so you can dispatch one
before connecting any provider.

```bash
# 1. mint a key — sk- belongs on a server, pk- is safe in a browser
curl -sS -X POST https://api.hanzo.ai/v1/account/keys \
  -H "Authorization: Bearer $HANZO_SESSION" \
  -H 'Content-Type: application/json' \
  -d '{"type":"secret"}'

# 2. what this key can already call, before any provider is connected.
#    Each row carries a name, an inputSchema and its source.
curl -sS "https://api.hanzo.ai/v1/tools?activated=true" \
  -H "Authorization: Bearer $HANZO_API_KEY"

# 3. dispatch one, by the exact name step 2 printed
curl -sS -X POST https://api.hanzo.ai/v1/tool/call \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"NAME_FROM_STEP_2","arguments":{}}'
```

Three calls and no OAuth. The key carried the org, the project and the user, so
step 2 answered with the set this caller can actually dispatch and step 3 would
have refused anything outside it with a 403 — which is why Composio's `userId`
argument has no counterpart here.

### Core capabilities

| Capability       | What it does                                                                        | Operations |
| ---------------- | ----------------------------------------------------------------------------------- | ---------- |
| `/v1/provider`   | The credential an **org** connects to a provider, and the callbacks that acquire it | 56         |
| `/v1/connection` | The same credential held per **user** — device flow, refresh, token read            | 8          |
| `/v1/tool`       | One flat set of callable actions across every source, plus dispatch and activation  | 19         |

## Nouns

| Composio                                             | Hanzo                                                                                          |
| ---------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| Toolkit — an app such as GitHub or Slack             | Provider — `GET /v1/provider/{provider}` returns one with this org's connection status         |
| Auth config — the OAuth app you register per toolkit | The deployment's own provider configuration. A connect against a provider it lacks answers 503 |
| Connected account, shared by a team                  | Connection — `POST /v1/provider/{provider}/connect`                                            |
| Connected account, one per end user                  | Connector — `GET /v1/connection`, rows keyed by (org, user)                                    |
| `userId` passed on every call                        | The validated principal in the key                                                             |
| Tool                                                 | Tool — `GET /v1/tool`, one flat set across every source, each with an `inputSchema`            |
| Executing a tool                                     | `POST /v1/tool/call`                                                                           |
| A session's hosted MCP endpoint                      | `POST /v1/mcp`                                                                                 |
| Disconnecting an account                             | `POST /v1/provider/{provider}/disconnect`, which deletes the custodied secret and the row      |

Two scopes, not one. Composio scopes a connected account by the `userId` you
pass; here the scope is structural. A `/v1/provider` connection belongs to
the org and every member reaches it. A `/v1/connection` row belongs
to one person and is invisible to everyone else, including their own org's
admins. Pick by who owns the account, not by a field.

## The call

Composio, connecting a user and handing their tools to an agent:

```typescript
import { Composio } from '@composio/core'
import { OpenAIAgentsProvider } from '@composio/openai-agents'

const composio = new Composio({ provider: new OpenAIAgentsProvider() })

const session = await composio.create('user_123')
const tools = await session.tools()
```

Hanzo — connect, discover, dispatch:

```bash
# 1. Acquire the org's GitHub credential. With no `token` in the body this
#    begins OAuth and answers an `authorizeUrl` to send the person to.
curl -X POST https://api.hanzo.ai/v1/provider/github/connect \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{}'

# 2. What the org can now call. Each row carries a name, an inputSchema,
#    its source, and whether it is switched on.
curl "https://api.hanzo.ai/v1/tools?activated=true" \
  -H "Authorization: Bearer $HANZO_API_KEY"

# 3. Dispatch one, by the name step 2 printed.
curl -X POST https://api.hanzo.ai/v1/tool/call \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"name":"NAME_FROM_STEP_2","arguments":{}}'
```

If the credential is a personal access token you already hold, put it in the
body as `token` and the connect seals it directly instead of starting OAuth.

An agent framework that speaks MCP does not need steps 2 and 3: point it at
`https://api.hanzo.ai/v1/mcp` with the same key.

## What does not carry

**The catalogue is a different shape.** Composio's is its product: pre-built
toolkits across a large set of apps, the same for every customer.
`GET /v1/tool` returns what _this_ org can reach — the platform's own
operations, the actions of its connected providers, its authored skills, its
agents and functions, and the tools of every external MCP server it
registered. Check `GET /v1/provider` for the
providers this deployment carries before you plan a cutover. A provider that is
not there is added by registering its MCP server with
`POST /v1/tool/mcp/servers`, not by waiting for a catalog entry.

**Triggers have no equivalent.** Composio subscribes you to events inside the
third-party app — a new Gmail message, a closed GitHub issue. `/v1/webhook`
delivers Hanzo's own events, not the provider's. Inbound app events you keep
yourself: register the webhook with the provider and take the delivery.

**Tool names differ.** Composio slugs are stable identifiers you can hardcode.
Here a tool's existence, its price and its activation are rows, not code, so the
callable set is only knowable once the caller is. Read `GET /v1/tool` at
startup rather than compiling a list in.

**Custom tools go in differently.** Composio lets you register your own tool
against its execution plane. Here you publish it as an MCP server and register
that server on the org; the tool then appears in the same listing, from the
source `mcp`.
