Skip to main content
A connector is an OAuth connection to an outside app. It binds a running server to a third party — Google, Atlassian, and others — and manages the token exchange and storage so a tool can call an authenticated API without ever handling raw credentials.

The provider-agnostic engine

The connector engine is provider-agnostic. The domain and wire models and the provider ABCs live in the contract; the skeleton owns the runtime — the OAuth flow, the token store, the resolver, and the stdio glue. A provider is one descriptor — a ProviderDescriptor — declaring the provider’s id, its OAuth or no-auth mode, the env var names that hold its client credentials, its sub-services and their scopes and MCP endpoints, and an icon_url brand mark. The icon_url must be an https:// URL (the same rule the plugin descriptor’s icon follows), so the catalog serves it verbatim with no bundled asset to host. See the ProviderDescriptor reference for the full schema. Providers come from the server manifest’s connectors list. A marketplace install of a connector patches one descriptor into that list; you can also add one by hand. The server registers each listed descriptor at boot and on every reload — there is no import side-effect and no code to install, so a whole OAuth integration is just a manifest entry.

Tokens resolved at call time

A managed connection is referenced from the manifest by its provider and sub-service; the actual credential is resolved at call time, per outbound request. The resolver serves a healthy, still-fresh token on the hot path without locking, and only takes a lock to refresh a stale one — so replicas racing an expired token converge on one refresh. The resolved credential is injected on the right channel for the transport: an Authorization: Bearer header for HTTP, or the _meta token field for a stdio MCP server. A connection can also be no-auth-with-config, in which case configured values are injected as headers or environment instead of a token.

Where tokens live

The token store keeps tokens in Redis as a cache and Postgres as the source of truth. It comes up only when its database is configured — the named database the core skeleton component binds to, on with a non-empty TAI_DATABASE_<NAME>_PG_PASSWORD — the same presence gate every other database-backed feature uses. That gate is what turns connectors on for a deployment; absent it, connectors are off and startup never opens Postgres for them. With the database configured and none reachable, startup fails loudly. The provider catalog is not loaded from the database. The server registers each descriptor in the manifest’s connectors list through its register_connector seam at boot and on every reload, so listing and resolving providers reads the in-memory registry and never touches Postgres. Only the token store, above, uses the database.

Connection health

A connection carries a health state, so a token that has stopped refreshing or a connection that needs re-authorising surfaces as a clear, typed condition rather than a silent failure at call time. Reconnect-required and refresh-failing states raise their own errors.

Engine settings

The engine’s own settings apply to every connector, not to any one provider. A provider adds only its own client credentials (the CONNECTORS_<PROVIDER>_* env var names its descriptor declares); these CONNECTORS_* keys are shared: The CONNECTORS_KEK and CONNECTORS_STATE_HMAC_KEY are key material: they are kept out of logs and are refused inside a settings profile. The origin a provider registers with must appear in CONNECTORS_REDIRECT_URI_ALLOWLIST, and it must be https for anything but a local host.

Managing connections

Drive the OAuth lifecycle from the CLI:
The platform documents connectors at the platform level. A specific provider’s setup — its scopes, redirect URIs, and environment — lives in that connector’s own repository, reachable from the Plugins section.
See the connect-an-OAuth-provider guide for the end-to-end flow and the HTTP API reference for the connector routes.