---
title: "Providers"
type: concept
tags: [providers, architecture, foundational, well-established]
created: 2026-08-06
updated: 2026-08-06
sources: ["raw/github_doc-docs-internals-providers-md.md", "raw/github_doc-docs-user-providers-claude-md.md", "raw/github_doc-docs-user-providers-codex-md.md", "raw/github_doc-readme-md.md"]
confidence: high
t3code_version: "0.0.32-nightly (2026-08-05)"
---

## Definition

A **provider** is the agent runtime that does the actual work behind a T3 Code thread — Codex,
Claude Code, Cursor, Grok Build, or OpenCode. T3 Code's orchestration layer is deliberately
provider-agnostic: it does not know or care which provider is behind a given thread. Each provider
is wired into T3 Code through a **driver** plus an **adapter** that translate that provider's
native CLI protocol into T3 Code's internal command/event model.

## How It Works

`builtInDrivers.ts` exports `BUILT_IN_DRIVERS` with five entries:

| Driver kind   | Driver source           |
| ------------- | ------------------------ |
| `codex`       | `Drivers/CodexDriver.ts` |
| `claudeAgent` | `Drivers/ClaudeDriver.ts` |
| `cursor`      | `Drivers/CursorDriver.ts` |
| `grok`        | `Drivers/GrokDriver.ts`  |
| `opencode`    | `Drivers/OpenCodeDriver.ts` |

Each driver declares a `driverKind`, a `configSchema`, and a `create` function that builds an
adapter in a child scope. Adapter implementations (`CodexAdapter.ts`, `ClaudeAdapter.ts`, etc.)
live beside their drivers and conform to a shared `ProviderAdapter` interface.

Two registries separate configuration from live processes: `ProviderInstanceRegistry` keys
configured instances by `ProviderInstanceId` (looking up the driver by `driverKind`, decoding the
instance's config with that driver's schema, and calling `driver.create` in a child scope), while
`ProviderAdapterRegistry` resolves an instance ID to its live adapter. `ProviderService` sits on
top of both, routing session and turn operations by thread rather than by agent — so callers name
a thread, and the provider behind it is an implementation detail. Adding a new driver only means
writing the driver plus its adapter and registering it in `BUILT_IN_DRIVERS`; no orchestration,
contract, or client change is required for the common case.

Clients never call a provider directly. They dispatch orchestration commands over the RPC method
`orchestration.dispatchCommand` — the client-facing provider commands are `thread.turn.start`,
`thread.turn.interrupt`, `thread.approval.respond`, `thread.user-input.respond`,
`thread.checkpoint.revert`, `thread.session.stop`, and the mode setters
`thread.runtime-mode.set` / `thread.interaction-mode.set` (the runtime-mode setter underlies
[[concepts/permission-modes]]). The server persists an event for the command, and a server-side
reactor performs the actual provider call; provider output comes back as internal commands
(`thread.message.assistant.delta`, `thread.session.set`, etc.) that clients observe via
`orchestration.subscribeThread`.

Provider work flows through three queue-backed workers, each built with `makeDrainableWorker` and
exposing `drain` for deterministic test synchronization: `ProviderRuntimeIngestion` (consumes
provider runtime streams and emits orchestration commands), `ProviderCommandReactor` (reacts to
orchestration intent events and dispatches provider calls), and `CheckpointReactor` (captures
workspace checkpoints on turn start/completion and performs reverts). A thread in `buffered`
assistant delivery mode accumulates assistant text instead of streaming every delta; the buffer
spills as one delta if it would exceed `MAX_BUFFERED_ASSISTANT_CHARS` (24,000 characters), and also
flushes at interaction boundaries (an approval opening, or user input being requested).

### Per-provider setup

Install-and-login basics for each provider (see [[concepts/install-and-getting-started]] for the
full table): Codex CLI + `codex login`; Claude Code + `claude auth login`; Cursor CLI (binary
`cursor-agent`) + `agent login`; Grok Build CLI + `grok login`; OpenCode + `opencode auth login`.
Each provider CLI must be on the T3 Code server's `PATH`, or have an explicit binary path
configured in Settings.

Claude and Codex both support **multi-account setups** in T3 Code:

- **Claude** ([[entities/provider-claude-code]]): a single account uses the default provider with
  an empty `CLAUDE_CONFIG_DIR path`. Multiple accounts (e.g. work and personal) each get a
  dedicated `CLAUDE_CONFIG_DIR` — set via `CLAUDE_CONFIG_DIR=~/.claude_personal_home claude auth
  login` at login time, then a matching `CLAUDE_CONFIG_DIR path` on the provider instance in T3
  Code Settings. T3 Code only offers Claude providers that share the same config directory for
  continuing an existing thread, since Claude Code keeps account and local state across multiple
  files under that directory. External/compatible setups (OpenRouter, Claude Code Router) are
  configured the same way: a dedicated `CLAUDE_CONFIG_DIR` plus provider-instance Environment
  variables (e.g. `ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN` marked sensitive).
- **Codex** ([[entities/provider-codex]]): a single account uses `CODEX_HOME path: ~/.codex` with
  an empty Shadow home path. Multiple accounts use one shared `CODEX_HOME` plus a second account's
  auth in a separate **Shadow home path** (e.g. `~/.codex_p`), so both accounts can see the same
  T3/Codex sessions and either can continue an existing thread. A third Codex provider with a
  completely different `CODEX_HOME path` is instead treated as a separate workspace, not offered
  for existing threads.

Sensitive values placed in a provider's Environment variables (API keys, tokens) are stored as
server secrets and are not sent back to the client app after saving.

## Key Parameters

- **Five built-in driver kinds**: `codex`, `claudeAgent`, `cursor`, `grok`, `opencode`.
- **Driver contract**: `driverKind`, `configSchema`, `create`.
- **Provider-facing commands**: `thread.turn.start`, `thread.turn.interrupt`,
  `thread.approval.respond`, `thread.user-input.respond`, `thread.checkpoint.revert`,
  `thread.session.stop`, `thread.runtime-mode.set`, `thread.interaction-mode.set`.
- **Buffered delivery threshold**: `MAX_BUFFERED_ASSISTANT_CHARS` = 24,000 characters.
- **Multi-account keys**: Claude uses `CLAUDE_CONFIG_DIR`; Codex uses `CODEX_HOME` plus an
  optional Shadow home path.

## When To Use

Consult this page when deciding which coding-agent CLI to run under T3 Code, when a provider shows
as "not authenticated," when setting up more than one account for Claude or Codex, or when
diagnosing why a thread does or does not offer a particular provider for continuation.

## Risks & Pitfalls

- A provider CLI installed but not on the server's `PATH` (and without an explicit binary path
  configured) will not be detected.
- Cursor authentication is a common trap: installing Cursor CLI gives you `cursor-agent`, but you
  must run `agent login`, not `cursor-agent login`.
- Setting `HOME` instead of `CLAUDE_CONFIG_DIR` when logging in to a second Claude account writes
  credentials to the wrong location (`~/.claude_personal_home/.claude` instead of where T3 Code
  looks).
- Mixing up which Codex provider has the Shadow home path set, or copying `~/.codex` wholesale
  into a shadow directory (rather than just `auth.json`), can make two providers appear to use the
  same account.
- Environment variable assignments belong in a provider's Environment variables section, not in
  Launch arguments.

## Related Concepts

- [[concepts/t3code-overview]]
- [[concepts/install-and-getting-started]]
- [[concepts/permission-modes]]
- [[entities/provider-claude-code]]
- [[entities/provider-codex]]
- [[entities/provider-cursor]]
- [[entities/provider-grok-build]]
- [[entities/provider-opencode]]

## Sources

- raw/github_doc-docs-internals-providers-md.md
- raw/github_doc-docs-user-providers-claude-md.md
- raw/github_doc-docs-user-providers-codex-md.md
- raw/github_doc-readme-md.md
