Connectors SDK
gaia.connectors is GAIA’s external-integration layer. It manages two
kinds of connectors:
- OAuth (type
oauth_pkce) — user-authorized flows (Google, etc.). Stores refresh tokens in the OS keyring. - MCP server (type
mcp_server) — API-key-based connections to third-party MCP servers (GitHub, Brave Search, etc.). Stores keys in the OS keyring as$keyringreferences.
gaia connectors …), and
Agent UI (Settings → Connectors page).
Catalog
The catalog is populated at import time bygaia.connectors.catalog.
Every connector is a ConnectorSpec:
core, productivity,
dev, and search tiers.
SDK use — OAuth
get_access_token raises AuthRequiredError on four failure modes:
Forwarded connections (no re-auth)
When a host app has already authenticated the user (its own OAuth flow), it can FORWARD that connection to GAIA instead of triggering a second consent screen. GAIA persists the forwarded grant and refreshes as the host app’s client — credential forwarding, not a GAIA-run OAuth flow. The host app forwards three things: the OAuth client it was issued under (client_id + client_secret) and the user’s long-lived refresh_token.
REST: POST /v1/connections/{provider}
The same ingestion is exposed over REST by the Agent UI server (which binds
localhost by default and gates remote/tunnel access behind a token).
Mutating routes require the X-Gaia-UI: 1 header.
After a successful POST the agent resolves the connection ambiently — the
triage request carries no credentials;
get_access_token reads the
persisted grant and refreshes transparently.
GAIA refuses to persist tokens to an insecure keyring backend (plaintext /
weak file-backed stores). On such a backend the import fails loudly with an
actionable error pointing at the system credential-store setup. Forwarded
secrets are never written to
~/.gaia/ and never echoed in any response.SDK use — MCP server
MCP server connectors are configured once and then provide their API keys via theget_credential dispatcher:
CLI use
Agent-author guide
Declare the connectors your agent needs asREQUIRED_CONNECTORS:
reason in plain language. After
the user grants the scopes, subsequent get_access_token_sync calls
return fresh tokens transparently.
If instead your agent loads MCP servers dynamically at runtime (from
~/.gaia/mcp_servers.json) rather than declaring specific connectors, set
CONSUMES_MCP_SERVERS = True so the Settings → Connectors “Active for”
panel lists it for every mcp_server connector:
Per-agent activation (MCP servers only)
Activations are the second axis of the per-agent authorization model (issue #1005) and apply tomcp_server connectors only:
- Grant (
grants.json) — agent X is allowed to use connector Y’s credentials with scopes S. Gates credential access (get_access_token). Applies to every connector type. - Activation (
activations.json) — agent X currently has MCP connector Y’s tools surfaced in its toolset. Gates MCP tool visibility (MCPClientManager.tools_for_agent).
true/false entries; an unknown pair returns
is_agent_active == False.
One-click activation: activating an agent with no prior grant
auto-creates a grant using the agent’s declared REQUIRED_CONNECTORS
scopes. This is the path Settings → Connectors → “Active for” takes when
the user ticks an agent that has never been granted access:
Which agents appear in the “Active for” panel
For anmcp_server connector the panel lists agents from two sources:
- Agents that declare the connector in
REQUIRED_CONNECTORS(static). - Agents that set
CONSUMES_MCP_SERVERS = True— they load MCP servers dynamically at runtime (from~/.gaia/mcp_servers.json) and gate the tools through this same activation ledger, so they can use any MCP connector once activated.builtin:chatis the canonical example.
use scope. The registry surfaces the flag on
each agent as consumes_mcp_servers. OAuth connectors have no activatable
agents — the panel is hidden for them entirely.
The HTTP router exposes:
mcp_server connectors with 400 Bad Request (after the standard X-Gaia-UI CSRF check).
Every activation change emits the SSE event connector.activation.changed
({connector_id, agent_id, active}) so an open Agent UI Settings tab
refreshes the “Active for” state without a manual reload. The emit is
centralized in api.activate / api.deactivate, so HTTP, SDK, and CLI
callers all notify through one path. Because the CLI runs in a separate
process from the UI server, the server also runs a background watcher on
activations.json that emits the same event (within ~1 s) when an
out-of-process writer changes the ledger.
Disconnecting a connector wipes both grants and activations for that
connector — re-adding the same connector_id must not silently inherit
the previous user’s tool-visibility decisions.
Where things live
Adding a new OAuth provider
- Create
src/gaia/connectors/providers/<name>.pysatisfying theOAuthProviderprotocol (auth/token URLs, client env vars, etc.). - Register in
src/gaia/connectors/providers/__init__.py:get. - Add a
ConnectorSpecentry insrc/gaia/connectors/catalog.py. - Add unit tests under
tests/unit/connectors/test_providers.py.
Adding a new MCP server connector
Add one entry to the_MCP_CATALOG list in
src/gaia/connectors/catalog.py:
MY_SERVICE_API_KEY from the keyring as an
environment variable when launching the server process.