# How to Set Up Workspace Thread Management and Chat History in AnythingLLM

> Master AnythingLLM workspace thread management and chat history. Learn how to organize conversations effectively using its three-tier hierarchy for seamless retrieval and CRUD operations.

- Repository: [Mintplex Labs/anything-llm](https://github.com/Mintplex-Labs/anything-llm)
- Tags: how-to-guide
- Published: 2026-03-07

---

**AnythingLLM uses a three-tier hierarchy of workspace → thread → chat to organize conversations, with dedicated middleware, Prisma models, and REST endpoints handling validation, CRUD operations, and history retrieval.**

Setting up workspace thread management and chat history in AnythingLLM requires understanding how the Mintplex-Labs/anything-llm repository structures conversation data. The platform isolates discussions into workspaces (top-level containers), threads (sub-conversations), and individual chat messages, with each layer protected by specific middleware and database models.

## Understanding the Workspace-Thread-Chat Hierarchy

AnythingLLM organizes conversations hierarchically to support multi-project deployments and isolated user sessions.

- **Workspace** – A top-level container defined in the `Workspace` Prisma model, accessed via `/workspace/:slug/...` endpoints.
- **Thread** – A sub-conversation within a workspace, stored in the `workspace_threads` table and managed through the `WorkspaceThread` model helper.
- **Chat** – Individual message-response pairs persisted in the `workspace_chats` table, linked to both workspace and thread IDs.

## Core Architecture and Key Files

### Middleware Validation

Request validation happens in [`server/utils/middleware/validWorkspace.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/middleware/validWorkspace.js). Two primary middleware functions protect thread-related routes:

- **`validWorkspaceSlug`** – Validates the workspace slug, loads the workspace into `res.locals.workspace`, and handles multi-user isolation.
- **`validWorkspaceAndThreadSlug`** – Extends workspace validation to also load the thread into `res.locals.thread` using the `WorkspaceThread` helper.

### Thread Management Models

The [`server/models/workspaceThread.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspaceThread.js) file provides the `WorkspaceThread` class, which wraps Prisma operations for the `workspace_threads` table. It exposes methods for creation, updates, deletion, and automatic renaming based on message content via `autoRenameThread`.

### Chat Storage and Retrieval

Chat persistence relies on two files:

- **[`server/models/workspaceChats.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspaceChats.js)** – Contains the `WorkspaceChats` helper with `new()` for inserting messages and `where()` for filtered retrieval by workspace, user, and thread IDs.
- **[`server/utils/helpers/chat/responses.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/helpers/chat/responses.js)** – Provides `convertToChatHistory`, which transforms raw database rows into UI-ready chat history objects.

## Setting Up Thread Management

### Creating New Threads

To programmatically create a thread, send a POST request to the thread creation endpoint. The server uses `validWorkspaceSlug` middleware to validate access, then invokes `WorkspaceThread.new` to insert a record into `workspace_threads`.

```bash
curl -X POST "https://your-instance.com/workspace/my-workspace/thread/new" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-session-token>" \
  -d '{}'

```

The endpoint returns a JSON object containing the created `thread` and a success `message`.

### Listing and Updating Threads

Retrieve all threads for a specific workspace using the list endpoint, which queries `WorkspaceThread` methods filtered by workspace and user ID in multi-user mode.

```javascript
async function listThreads(workspaceSlug) {
  const res = await fetch(
    `https://your-instance.com/workspace/${workspaceSlug}/threads`,
    {
      method: "GET",
      headers: { Authorization: `Bearer ${token}` },
    }
  );
  const data = await res.json(); // { threads: [...] }
  return data.threads;
}

```

Update thread metadata (currently limited to the `name` field as defined in `WorkspaceThread.writable`) via the update endpoint:

```bash
curl -X POST "https://your-instance.com/workspace/my-workspace/thread/old-slug/update" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  -d '{"name":"New Thread Title"}'

```

### Deleting Threads

Remove individual threads or perform bulk deletions using `WorkspaceThread.delete`. The DELETE endpoint requires both workspace and thread slugs, validated by `validWorkspaceAndThreadSlug` middleware.

## Managing Chat History

### Storing Chat Messages

When users send messages through `POST /workspace/:slug/thread/:threadSlug/stream-chat`, the `streamChatWithWorkspace` function streams the LLM response while simultaneously persisting the conversation via `WorkspaceChats.new`. This method stores the raw prompt, JSON-stringified LLM response, optional attachments, and the associated `thread_id` in the `workspace_chats` table.

### Retrieving Thread History

Fetch historical messages for a specific thread using the chat history endpoint. The server executes `WorkspaceChats.where` filtered by `workspaceId`, `user_id`, and `thread_id`, then passes results through `convertToChatHistory` in [`server/utils/helpers/chat/responses.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/helpers/chat/responses.js) to format them for the UI.

```javascript
async function getChatHistory(workspaceSlug, threadSlug) {
  const res = await fetch(
    `https://your-instance.com/workspace/${workspaceSlug}/thread/${threadSlug}/chats`,
    {
      method: "GET",
      headers: { Authorization: `Bearer ${token}` },
    }
  );
  const { history } = await res.json(); // array of formatted chat objects
  return history;
}

```

### Disabling Chat History Access

For privacy compliance or administrative control, set the environment variable `DISABLE_VIEW_CHAT_HISTORY` to any value in your server configuration or Docker environment. This activates the `chatHistoryViewable` middleware in [`server/utils/middleware/chatHistoryViewable.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/middleware/chatHistoryViewable.js), which rejects all history retrieval requests with HTTP **422** and the message *"This feature has been disabled by the administrator."*

```text
DISABLE_VIEW_CHAT_HISTORY=true

```

## Summary

- **Workspace thread management and chat history** in AnythingLLM rely on a strict hierarchy: workspaces contain threads, which contain individual chat messages.
- **Validation middleware** (`validWorkspaceSlug`, `validWorkspaceAndThreadSlug`) protects all thread-related routes by loading objects into `res.locals`.
- **CRUD operations** use the `WorkspaceThread` helper ([`server/models/workspaceThread.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspaceThread.js)) for thread lifecycle management and `WorkspaceChats` ([`server/models/workspaceChats.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspaceChats.js)) for message persistence.
- **History retrieval** flows through `convertToChatHistory` in [`server/utils/helpers/chat/responses.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/helpers/chat/responses.js) to format database records for the UI.
- **Privacy controls** allow administrators to disable history viewing entirely via the `DISABLE_VIEW_CHAT_HISTORY` environment variable and `chatHistoryViewable` middleware.

## Frequently Asked Questions

### What is the difference between a workspace and a thread in AnythingLLM?

A **workspace** is the top-level container that groups related conversations and configurations, while a **thread** is a sub-conversation within that workspace representing a specific topic or project. The `Workspace` model handles workspace-level settings, whereas the `WorkspaceThread` model in [`server/models/workspaceThread.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspaceThread.js) manages individual discussion threads linked to a workspace ID.

### How does AnythingLLM handle chat history storage?

Chat history is stored in the `workspace_chats` table via the `WorkspaceChats` helper in [`server/models/workspaceChats.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspaceChats.js). When a user sends a message, the `streamChatWithWorkspace` function calls `WorkspaceChats.new` to persist the raw prompt, JSON-stringified LLM response, optional attachments, and the associated `thread_id` while streaming the response to the client.

### Can I disable chat history viewing for privacy compliance?

Yes, set the `DISABLE_VIEW_CHAT_HISTORY` environment variable to any value in your server configuration or Docker environment. This activates the `chatHistoryViewable` middleware in [`server/utils/middleware/chatHistoryViewable.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/middleware/chatHistoryViewable.js), which blocks all history retrieval requests with HTTP 422 and returns the message *"This feature has been disabled by the administrator."*

### How do I programmatically create threads via the API?

Send a POST request to `/workspace/:slug/thread/new` with proper authorization headers. The endpoint uses the `validWorkspaceSlug` middleware to validate access, then invokes `WorkspaceThread.new` to insert a record into the `workspace_threads` table. The endpoint returns the created thread object and a success message, automatically handling multi-user isolation if enabled.