> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lupin.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Connections

> Configure supported apps and authorize an account through hosted Composio authentication.

# Connections

The console and `/v0/capabilities` expose only operator-configured apps. Browser
sessions are a separate provider capability; see [Browsers](https://docs.lupin.sh/build/browsers.md).
The app catalog is searchable and paginated; it can hold all provider toolkits
without fitting their configuration IDs into a Worker environment variable.
Connections require an organization key; inbox/project-scoped keys cannot manage
a shared workspace account. Read, create/reconnect and disconnect use
`api_key_read`, `api_key_create` and `api_key_delete` permissions respectively.

## Operator setup

Apply the API migrations, including `0020_product_records.sql`, and bind D1.
Configure these API Worker values through the normal deployment secret/variable path:

| Name | Value |
| - | - |
| `COMPOSIO_API_KEY` | Secret project API key from Composio |
| `COMPOSIO_AUTH_CONFIGS` | JSON mapping toolkit slug to an auth-config ID, for example `{"github":"ac_YOUR_CONFIG","slack":"ac_OTHER_CONFIG"}` |
| `CONSOLE_URL` | HTTPS console origin used for the `/connections` return URL |

Create the corresponding Composio auth configs, including the OAuth application's
required permissions and provider setup. Lupin's catalog reads this allowlist;
arbitrary app names cannot start authorization. Auth-config IDs are server-side
configuration and are not returned by capabilities.

For the complete toolkit inventory, apply `0024_provider_catalog.sql` and use the
operator provisioner `infra/provision-composio-catalog.mjs`. It paginates provider
toolkits/auth configs, reuses enabled configs, creates managed OAuth blueprints
where supported, and tries empty app credentials for non-OAuth schemes. User
API keys and login credentials are collected later by Composio's hosted connect
flow; they are never invented or stored in Lupin's catalog. Custom OAuth apps
that require client credentials remain explicitly unavailable. No-auth toolkits
are labeled separately because they do not require an account connection.

The provisioner requires explicit `LUPIN_COMPOSIO_PROVISION=1` for writes and a
`LUPIN_COMPOSIO_CATALOG_PATH` output path. Its adjacent checkpoint is written
before each creation. Preserve that checkpoint when resuming an interrupted
run; uncertain creations are recovered from inventory, never blindly repeated.
The activation workflow validates the safe catalog metadata and stores it in D1;
only the Composio project API key becomes a Worker secret. Existing small
`COMPOSIO_AUTH_CONFIGS` maps remain a fallback for slugs absent from D1, while
explicit disabled D1 entries take precedence.

`GET /v0/connections/catalog?search=github&limit=50` searches configured apps.
Use `include_unavailable=true` to inspect no-auth and setup-required entries,
and pass `next_cursor` as `cursor` to fetch another page. Public catalog responses
include app names/status only, never auth-config IDs or customer accounts.
Capabilities include only the first 100 configured apps plus total/next-cursor
metadata; clients should use the catalog endpoint to search the complete list.

## Connect and inspect

```bash theme={null}
lupin capabilities
lupin connections create --app github --idempotency-key SAVED_CREATE_KEY
# Open authorize_url from the response and complete hosted authorization.
lupin connections list
lupin connections reconnect --connection-id CONNECTION_ID --idempotency-key SAVED_RECONNECT_KEY
lupin connections disconnect --connection-id CONNECTION_ID
```

The backend uses [Composio's v3.1 hosted link API](https://docs.composio.dev/reference/api-reference/connected-accounts/postConnectedAccountsLink),
with workspace organization ID as `user_id`. The provider owns OAuth credentials;
Lupin stores account IDs in D1 and returns a sanitized account/status/scopes view.
The return URL is navigation only. Query parameters such as `status=ACTIVE` cannot
activate a connection. Each list checks the saved account's provider-reported
`user_id` and status before displaying it.

Reconnect keeps the old account registered while replacement authorization is
pending. After the provider confirms the replacement is active, a subsequent
list retires the old account. Finish the pending authorization or disconnect
before starting a second reconnect. Disconnect validates ownership, performs
[upstream revocation](https://docs.composio.dev/reference/api-reference/connected-accounts/postConnectedAccountsByNanoidRevoke)
for authorized accounts, then deletes the provider account and durable registry.
If revocation fails or the toolkit cannot revoke programmatically, Lupin preserves
the record and reports failure so an operator can reconcile access. Already
revoked accounts and absent accounts support retry cleanup.

Creation and reconnect require a preserved `Idempotency-Key`. The console keeps
the attempt identity across retries and page reloads. A durable journal records
the provider outcome before publishing the local connection; recovery replays
only local persistence. HTTP 409 `reconciliation_required` includes an operation
ID when the outcome is uncertain. Keep the same key and contact support before
starting another attempt. Reconnect's resource lock remains held through the
durable replacement, so concurrent deletion cannot remove an unfinished account.

## Discover and execute app tools

After authorization is active, discover the app's available tools and their real
input schemas with `GET /v0/connections/:connection_id/tools?search=issues` or:

```bash theme={null}
lupin connections tools --connection-id CONNECTION_ID --search issues
lupin connections execute --connection-id CONNECTION_ID \
  --connection-revision REVISION_FROM_DISCOVERY \
  --tool-slug DISCOVERED_TOOL --version CONCRETE_VERSION \
  --arguments '{"owner":"example","repo":"example","title":"Approved issue"}' \
  --idempotency-key YOUR_SAVED_OPERATION_KEY
```

Only tools belonging to the connection's configured toolkit can execute. The API
verifies the durable connection, provider account ownership and active status,
then pins the discovered tool version and account revision. Reconnecting or
switching the account invalidates old approvals. The provider's [v3.1 tool execution API](https://docs.composio.dev/reference/api-reference/tools/postToolsExecuteByToolSlug)
receives only the server-derived organization/account IDs and approved tool
arguments. Custom auth parameters, credential overrides and arbitrary proxy
requests are not accepted. Discovery uses `api_key_read`; execution uses
`api_key_create`, both with an organization key.

The consumer agent requires an exact human approval for every app tool execution,
including apparent reads, because toolkit operations can have side effects.
MCP clients receive write annotations and must obtain authorization themselves.
The durable operation journal prevents concurrent execution and retry duplication.
Provider timeouts retain an uncertain operation and its usage reservation; contact
support before issuing a different operation key. App execution is treated as an
unbounded paid effect and is blocked when a matching spending limit is active.

## Recovery

`connections_not_configured` means the provider/D1/catalog setup is incomplete.
`unsupported_app` means the app is outside the enabled catalog. A provider error
never proves successful authorization or disconnect; retry after checking provider
status. Persistent lifecycle operations use a durable compare-and-set to reject
concurrent changes. If a Worker terminates while holding an operation marker,
an operator must reconcile the recorded account(s) in Composio before clearing
the marker in D1; do not delete the registry merely to hide an error. If provider
cleanup and durable storage both fail during link creation, inspect the Composio
project for the unfinished account before retrying. The local test suite mocks
provider responses; a sandbox OAuth walkthrough is required before activation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.