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

# ADE SDK

> Embed ADE chat in your own app. A sidecar runtime, durable named threads, and optional React UI — published as @ade-dev/sdk and @ade-dev/chat-ui.

The ADE SDK is how a **third-party app** embeds ADE chat. Your process owns a slim ADE runtime as a child, talks to it over JSON-RPC, and presents chat as durable named threads. The runtime is a guest: isolated home, sync off, no machine-brain authority. It dies with your process.

This is not ADE desktop or personal chats in the ADE app. Those stay first-party. Use the SDK when *your* product needs an agent chat sidecar.

> [card] [Install](https://ade-app.dev/docs/sdk/install.md)
>
> `npm install @ade-dev/sdk` — Node 22, then a 10-line client.

> [card] [Quickstart](https://ade-app.dev/docs/sdk/quickstart.md)
>
> Open a thread, send a message, resume by key after a restart.

> [card] [MCP servers](https://ade-app.dev/docs/sdk/mcp.md)
>
> Inject your tools. Strict mode is enforced only on Claude — read the honesty table.

> [card] [Chat UI](https://ade-app.dev/docs/sdk/chat-ui.md)
>
> React components that render the conversation for *your* users.

> [card] [API reference](https://ade-app.dev/docs/sdk/api.md)
>
> Every export with its exact signature, generated from the declarations.

## Packages

| Package | What it is |
| - | - |
| [`@ade-dev/sdk`](https://www.npmjs.com/package/@ade-dev/sdk) | Node / Electron-main client. Spawns and owns the sidecar. Zero runtime dependencies. |
| [`@ade-dev/chat-ui`](https://www.npmjs.com/package/@ade-dev/chat-ui) | React components. React is a peer; the SDK is an optional peer used for types. No lanes, projects, or worktrees in any prop. |

Both packages are MIT. The runtime binary and ADE itself are AGPL-3.0-only, and an embedding exception lets a proprietary app ship an unmodified runtime binary. See [License](https://ade-app.dev/docs/sdk/license.md) for the per-artifact table and the exact conditions.

## How it fits

```mermaid theme={null}
flowchart TB
  Host["Your app"]
  Sdk["@ade-dev/sdk"]
  Ui["@ade-dev/chat-ui"]
  Runtime["ade runtime --profile embedded"]

  Host --> Sdk
  Host --> Ui
  Ui -->|"adaptSdkClient"| Sdk
  Sdk -->|"NDJSON JSON-RPC"| Runtime
```

The client downloads (or you pin) an `ade` binary, spawns `ade runtime run --socket <path> --profile embedded`, and exposes `threads.open(key)`. Reopening the same key after a restart continues the conversation. [`doctor()`](https://ade-app.dev/docs/sdk/reference#doctor) reports the SDK version, the runtime version, the socket, and provider auth.

SDK 0.7 uses isolated provider logins by default; set `useMachineLogin: true`
to reuse the host machine's Claude or Codex login. `doctor()` reports the active
login mode. See [Accounts](https://ade-app.dev/docs/sdk/accounts.md).

## What's new in 0.7

SDK 0.7 keeps the runtime range at `>=1.2.82 <2.0.0`; new runtime actions are
feature-detected. It adds provider accounts and sign-in, secret-safe API
credentials and endpoint presets, provider capability reports, per-thread
account/credential/preset selection, usage-limit handling, and queue/recovery
controls.

* **BREAKING: login isolation is the default.** Machine logins are no longer reused implicitly. Set `useMachineLogin: true` to preserve SDK 0.6 behavior, or sign the user in under the app's isolated runtime.
* **Host-owned secrets.** `resolveSecret(provider, credentialId)` sends a vault value only to the live runtime session; it is not written to the SDK thread store.
* **Usage limits.** Pick `wait`, `failover` or `ask` and listen for `usageLimit` when the host needs to show a decision.

## What's new in 0.6

SDK 0.6.0 supported runtime `>=1.2.82 <2.0.0`, the same range as 0.5. On an older runtime, tool filters are refused before they are sent (they need `capabilities.personalChats.mcpToolFilters`), and a mid-turn `updateMcpServers` is refused with `turn_in_flight` instead of queued. The header refresh needs nothing new.

* **Tokens that expire during a chat.** `mcpHeaders` may be async, and it runs before every `send`, `retry` and `editLast`: a changed token is pushed before the turn, and `thread.refreshMcpHeaders()` pushes one on demand. See [Tokens that expire during a chat](https://ade-app.dev/docs/sdk/mcp.md#tokens-that-expire-during-a-chat).
* **Per-server tool filters.** `allowedTools` / `disallowedTools` on an MCP server choose which of its tools reach the model. A filter the provider cannot enforce is refused, never dropped. See [Filtering a server's tools](https://ade-app.dev/docs/sdk/mcp.md#filtering-a-servers-tools).
* **`updateMcpServers` during a turn.** The runtime queues the servers for the turn's end instead of refusing, and the session summary reports `mcpServersPending: true` until the swap.

## What's new in 0.5

SDK 0.5.1 supports runtime `>=1.2.82 <2.0.0`. The lower bound did **not** move across 0.5: nothing in that line needs a new wire, so a host on runtime 1.2.82 keeps working. Patch 0.5.1 carries one tidy that landed on main after 0.5.0 published: the buffered-event category list no longer names `cto_voice`, a category an `agent`-role sidecar never receives. See [Version compatibility](https://ade-app.dev/docs/sdk/runtime.md#version-compatibility).

* **Attachment roots that fail the whole open.** `checkAttachmentRoot(path, home)` and `filterAttachmentRoots(list, home)` test a root before you send it, so one bad entry no longer locks every chat. An identical list is not sent again. See [Where a path may point](https://ade-app.dev/docs/sdk/threads.md#where-a-path-may-point).
* **A host hook for removals.** `registerAdeIpc({ onThreadRemoved })` fires for every delete and archive the served client reports, whoever made it, so your chat list stays exact. It follows a client swapped per account as soon as the bridge serves a call. See [Electron](https://ade-app.dev/docs/sdk/electron.md#hosts-with-many-threads).
* **A cost preference for new chats.** `models.defaultModel({ prefer })` and `pickDefaultModel(models, { prefer })` rank a provider's models yourself, so a host can start on Sonnet instead of the provider's most expensive default. See [`pickDefaultModel`](https://ade-app.dev/docs/sdk/reference#pickdefaultmodel).
* **Less noise from an embedded runtime.** Four lines an embedded runtime printed on every start — the role-ceiling sentence, its `brain.role_ceiling_below_cto` warning, and the two "could not bound runtime log" lines — are gone from runtime 1.2.83. An older runtime still prints them.
* **Docs.** `ModelCatalogEntry.provider` now points at `isSupportedProvider`; the retry and edit docs say the rollback does not cover the disk and how to find the files yourself; the activity-label docs now state that a bare MCP key is compared with the tool's own name, with an example.

## What's new in 0.4

`@ade-dev/sdk` 0.4.0, `@ade-dev/chat-ui` 0.4.0 and runtime 1.2.82 are available together. SDK 0.4.0 supports runtime `>=1.2.82 <2.0.0`. An older runtime still connects, and the features below that need 1.2.82 throw `unsupported` or do nothing. See [Version compatibility](https://ade-app.dev/docs/sdk/runtime.md#version-compatibility).

* **Retry and edit.** `thread.retry()` and `thread.editLast(text)` run the last user message again, and the transcript shows it once. Claude and Codex. See [Retry and edit](https://ade-app.dev/docs/sdk/threads.md#retry-and-edit).
* **Links.** `onLinkClick` on `<AdeChat>`, `<Transcript>`, `<ProviderCard>` and `<ProviderCards>`, so a host decides what opens and where. In Electron, pass it. See [Links](https://ade-app.dev/docs/sdk/chat-ui.md#links).
* **Attachment roots.** `attachmentRoots` lets a thread attach files from folders outside its `cwd` without a copy. The attachments guide now says how paths compare. See [Where a path may point](https://ade-app.dev/docs/sdk/threads.md#where-a-path-may-point).
* **Bridge.** `openOptions` gets `{ exists, summary }`, so a host can tell a resume from a create. `allowThreadKey` and `allowModel` can be async. `thread.send` options are filtered. `threads.get`, `forget(key)`, and `checkAdeBridge` for a hand-copied preload. See [Electron](https://ade-app.dev/docs/sdk/electron.md).
* **Client.** `threads.get(key)`, `models.onChange`, `models.defaultModel`, `pickDefaultModel`, the `threadLifecycle` event, and `final` on `restart`. See [Reference](https://ade-app.dev/docs/sdk/reference.md).
* **Chat UI.** Controlled draft, `onSend`, a render prop and `threadRef` on `<AdeChat>`; `ThreadState.update`, `retry` and `editLast`; a reload after a runtime restart or a retry. See [Chat UI](https://ade-app.dev/docs/sdk/chat-ui.md#host-control-of-the-composer).
* **Runtime.** Codex no longer shows a `computer_use` tool call that never ends, and the Computer Use server is not started for a thread whose policy does not allow it. `update({ title: null })` clears the title. `--version` reports the runtime's own version. No `canUseTool` warning on every Claude turn. The `doctor().runtime.version` probe of the SDK also works on a 1.2.81 binary started from inside ADE.

### Breaking changes

* Refusals caused by a running turn (`setModel`, a reasoning `update`) now throw `turn_in_flight`, not `invalid_option`. Branch on `turn_in_flight`.
* `window.ade` from `@ade-dev/sdk/electron/global` is optional. `createAdeIpcClient(window.ade)` still compiles; code that reads `window.ade.invoke` directly needs a check.
* The `restart` event payload has a new `final` field, and `ADE_CLIENT_EVENTS` has `threadLifecycle`. A listener table typed on the old list must add it.

## What's new in 0.3

`@ade-dev/sdk` 0.3.0 and `@ade-dev/chat-ui` 0.3.0 release together. SDK 0.3.0 supports runtime `>=1.2.81 <2.0.0`. See [Version compatibility](https://ade-app.dev/docs/sdk/runtime.md#version-compatibility).

* **Thread lifecycle.** `threads.delete`, `threads.archive`, `threads.unarchive`, and `thread.update()` for a rename, reasoning effort or fast mode. `ThreadSummary` and the thread carry `title`, the resolved model with its display name, and `updatedAt`. See [Threads](https://ade-app.dev/docs/sdk/threads.md#list-rename-archive-delete).
* **Attachments.** `type` (`"file"` or `"image"`, inferred when absent), so images reach the model as images. `hydrate: false` sends the path only. `steer()` takes attachments. See [Attachments](https://ade-app.dev/docs/sdk/threads.md#attachments).
* **Paged history.** `thread.historyPage()`. See [History](https://ade-app.dev/docs/sdk/threads.md#history).
* **Credentials that change.** MCP header values are no longer stored. `refresh.mcpServers`, `thread.updateMcpServers()` and the `mcpHeaders` callback supply current tokens. See [MCP servers](https://ade-app.dev/docs/sdk/mcp.md#credentials-that-change).
* **Codex MCP approvals.** The permission policy now judges Codex MCP tool calls, and `approve()` answers them. `approvalTimeoutMs` lets the SDK decline an approval that nobody answers. See [Permissions](https://ade-app.dev/docs/sdk/permissions.md#codex-mcp-tool-calls).
* **Runtime exits.** `client.on("exit" | "transport" | "restart")`, a synthetic error status on each live thread, and opt-in `autoRestart`. See [Runtime](https://ade-app.dev/docs/sdk/runtime.md#when-the-runtime-exits).
* **Electron bridge.** The renderer no longer configures threads: an `openOptions` hook in main decides, or only four fields cross. `allowModel`, `threads.list` and the lifecycle calls over IPC, a client getter, `@ade-dev/sdk/electron/global`, and a copy-paste sandboxed preload. See [Electron](https://ade-app.dev/docs/sdk/electron.md).
* **Packaging.** `resolvePackagedRuntime()` and `doctor().runtime.source: "packaged"`. See [Bundling](https://ade-app.dev/docs/sdk/bundling.md#inside-a-packaged-app).
* **Chat UI.** Composer rail slots and controlled attachments on `<AdeChat>`, a windowed transcript, tool identity and tool-result slots. See [Chat UI](https://ade-app.dev/docs/sdk/chat-ui.md).

### Breaking changes

* The Electron bridge drops every renderer `threads.open` option except `provider`, `model`, `title` and `reasoningEffort`, unless you set `openOptions`. See [What a renderer may send](https://ade-app.dev/docs/sdk/electron.md#what-a-renderer-may-send-to-threadsopen).
* When the runtime lost a session, the recreate uses the stored record first, not the call's options. See [Threads](https://ade-app.dev/docs/sdk/threads.md#when-the-runtime-lost-the-session).
* `setModel()` returns `displayName` and `capabilities` beside `modelId`, `provider` and `model`. A test that compares the whole result with `toEqual` must change.

`thread.retry()` and `thread.editLast()` are not in 0.3. They are in 0.4.

## What this is not

* Not a hosted ADE cloud API. The sidecar runs on the same machine as your app.
* Not ADE desktop IPC. The SDK speaks the machine JSON-RPC surface.
* Not a way to drive lanes, PRs, or the Work tab from a third-party renderer.

## Next

> [card] [Install](https://ade-app.dev/docs/sdk/install.md)
>
> Node 22, npm, Electron main, pinning a binary.

> [card] [Threads](https://ade-app.dev/docs/sdk/threads.md)
>
> Send, steer, interrupt, switch models, export.


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