# AI assistant and tools

TanStack AI streams a private conversation through one authorized tool catalog.

<Diagram name="approvals" alt="The assistant and MCP share a catalog; an exact write waits for user approval before the transaction commits its change, audit and replay result." />

## Enable and configure [#enable-and-configure]

Set `AI_PROVIDER` and its matching secret, then enable `ai.assistant`. Both gates are required. `AI_MODEL` can override the provider default. Secrets remain server-side. The existing MCP server works without a configured AI provider.

The default request limits are five model/tool steps, 2,048 output tokens per model call, a 60-second abort deadline and ten requests per minute per User. Input and history are separately bounded. These per-request limits do not replace provider account spending controls.

## One catalog [#one-catalog]

`catalog.schema.ts` defines Zod tool contracts; `catalog.ts` binds authorized implementations. The assistant and MCP adapt those same operations. Each call checks current Organization membership. The assistant uses the Session's Active Organization and rejects a change during a turn.

The catalog has 15 tools. Read operations include `todo_list`, `todo_detail`, `files_list`, `whoami`, `search`, `fetch`, `document_read` and `organization_info`. Approved writes are `todo_create`, `todo_complete`, `import_start`, `create_todo_draft`, `draft_task_plan` and `propose_review`; `ask_for_input` pauses for a User choice.

`files_list` exposes confirmed file IDs and conversion status. `document_read` returns two chunks by default, at most four of 8 KiB each, and `nextCursor` for another page. Search ranks converted text alongside Todos and filenames. Original file bytes never enter tool results. An `awaitingBrowser` result means the User must finish preparation in Files. Reading Document Text sends the selected chunks to the configured model provider and stores the results in the Thread. Treat source text as untrusted data and disclose partial reads. See [documents](/docs/features/documents).

Every write needs approval bound to its User, Organization, tool name and parsed arguments. Assistant approvals also bind the Thread and call ID. The execution transaction checks current membership and expiry, applies the change, records its audit and stores the result. A replay returns that result rather than repeating the mutation.

## Streaming and persistence [#streaming-and-persistence]

TanStack AI owns the native Promise/SSE lifecycle. The HTTP boundary owns input limits, auth, cancellation, the Thread lease and its bounded pool. Persistence snapshots at most once per second and saves the finished transcript. Stop, timeout or disconnect aborts the turn; reopening recovers the last saved state and pending interrupts.

There is no disconnected background run or resumable transport. Text after the last snapshot can be lost. Deleting a Thread deletes its messages and linked approvals but does not undo completed domain changes.

## Extend [#extend]

Add a catalog contract and authorized operation once, then adapt through the existing assistant/MCP consumers. Preserve exact-argument approval and replay protection. Tests use the deterministic adapter only in an `ai-test` build plus `AI_TEST_PROVIDER=true`; never publish that build. Read [ADR-0007](/docs/adr/0007-ai-assistant-and-tool-catalog) before changing transport, approvals or persistence.


## Key files [#key-files]

- [`packages/api/src/ai/catalog.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/ai/catalog.ts)
- [`packages/api/src/ai/catalog.schema.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/ai/catalog.schema.ts)
- [`packages/api/src/ai/http.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/ai/http.ts)
- [`packages/api/src/ai/approvals.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/ai/approvals.ts)
- [`packages/api/src/ai/threads.ts`](https://github.com/CarlosZiegler/doro/blob/main/packages/api/src/ai/threads.ts)
- [`scripts/test-local-ai.mjs`](https://github.com/CarlosZiegler/doro/blob/main/scripts/test-local-ai.mjs)

