# How to Customize the System Prompt and Prompt Variables in AnythingLLM

> Customize AnythingLLM system prompts globally or per workspace. Learn how to use dynamic prompt variables like {user.name} for personalized AI interactions and unlock the full potential of your LLM.

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

---

**You can customize AnythingLLM's system prompt globally via the `/system/default-system-prompt` REST endpoint or per-workspace through the `openAiPrompt` field, while dynamic variables like `{user.name}` and `{date}` are automatically expanded at runtime through the `SystemPromptVariables` model.**

AnythingLLM is an open-source document management and LLM interaction platform that allows deep customization of AI behavior through system prompts. Understanding how to customize the system prompt and prompt variables in AnythingLLM enables you to tailor responses based on user context, workspace purpose, and temporal information without modifying the core codebase.

## Understanding the System Prompt Architecture

### Global Default System Prompt

AnythingLLM stores the **global** default system prompt in the `SystemSettings` model within [`server/models/systemSettings.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/systemSettings.js). Administrators retrieve and modify this value through the `default_system_prompt` setting. When no custom prompt is specified, the system falls back to a hard-coded sane default.

The REST endpoints in [`server/endpoints/system.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/endpoints/system.js) expose this functionality:

- **GET** `/system/default-system-prompt` returns the current default and fallback prompts
- **POST** `/system/default-system-prompt` allows administrators to update the global default

### Per-Workspace Prompt Overrides

Individual workspaces can override the global default through the `openAiPrompt` field in the `Workspace` model ([`server/models/workspace.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/workspace.js)). During workspace creation (lines 96-102), if a global default exists, it is copied into `openAiPrompt`; otherwise, the workspace receives the hard-coded `defaultPrompt`.

This design ensures that modifying the global default only affects new workspaces, preserving existing workspace configurations unless explicitly updated through the workspace settings UI or API.

## How Prompt Variables Work

### Built-in Variables

The `SystemPromptVariables` model in [`server/models/systemPromptVariables.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/systemPromptVariables.js) defines built-in variables under `DEFAULT_VARIABLES`. These include:

- `{time}` - Current time in LTS format
- `{date}` - Current date in LL format
- `{datetime}` - Full date-time in LLLL format
- `{user.id}` - ID of the current user (multi-user mode)
- `{user.name}` - Username of the current user
- `{workspace.id}` - Workspace identifier
- `{workspace.name}` - Human-readable workspace name

### Custom Variable Creation

Administrators can create custom variables through the System Prompt Variables UI or API. These are stored in the `system_prompt_variables` database table. Each variable has a `key`, `value`, `description`, and `type` (static or dynamic).

### The Variable Expansion Engine

The expansion logic resides in `SystemPromptVariables.expandSystemPromptVariables()`. The algorithm:

1. Identifies all `{variable}` patterns using regex `/\{([^}]+)\}/g`
2. Looks up each key in the combined built-in and custom variables
3. Resolves values by calling appropriate functions (system vars return static values, user/workspace vars fetch from database using provided IDs)
4. Replaces placeholders with resolved values

This expansion occurs in `chatPrompt()` within [`server/utils/chats/index.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/chats/index.js) immediately before sending the request to the LLM provider.

## Implementation Details and Code Flow

### The chatPrompt Function

Located in [`server/utils/chats/index.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/chats/index.js), the `chatPrompt()` function orchestrates prompt assembly:

```javascript
// server/utils/chats/index.js
async function chatPrompt(workspace, user = null) {
  const { SystemSettings } = require("../../models/systemSettings");
  const basePrompt =
    workspace?.openAiPrompt ?? SystemSettings.saneDefaultSystemPrompt;
  return await SystemPromptVariables.expandSystemPromptVariables(
    basePrompt,
    user?.id,
    workspace?.id
  );
}

```

This function retrieves the base prompt from either the workspace's `openAiPrompt` or the global `SystemSettings.saneDefaultSystemPrompt`, then calls `SystemPromptVariables.expandSystemPromptVariables()` to substitute all `{variable}` placeholders with actual values.

### REST API Endpoints

The backend exposes several endpoints for prompt management:

**System-level endpoints** ([`server/endpoints/system.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/endpoints/system.js)):
- `GET /system/default-system-prompt` - Retrieves current and default prompts
- `POST /system/default-system-prompt` - Updates global default (admin only)

**Workspace endpoints**:
- `PATCH /api/workspaces/:id` - Updates workspace-specific `openAiPrompt`

**Variable management endpoints**:
- `GET /api/system-prompt-variables` - Lists all variables
- `POST /api/system-prompt-variables` - Creates custom variables
- `DELETE /api/system-prompt-variables/:key` - Removes custom variables

### Frontend Integration

The React frontend accesses these capabilities through [`frontend/src/models/system.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/frontend/src/models/system.js):

```javascript
import System from '@/models/system';

// Load the current global prompt when the settings page mounts
useEffect(() => {
  System.fetchDefaultSystemPrompt().then(({ defaultSystemPrompt }) => {
    setPromptText(defaultSystemPrompt);
  });
}, []);

// Save the edited prompt
const savePrompt = async () => {
  const { success, message } = await System.updateDefaultSystemPrompt(promptText);
  if (success) toast.success('Prompt updated');
  else toast.error(message);
};

```

This model provides `fetchDefaultSystemPrompt()` to wrap the GET endpoint and `updateDefaultSystemPrompt(prompt)` to wrap the POST endpoint.

## Practical Examples

### Updating the Global System Prompt via API

To set a new default prompt for all future workspaces:

```bash
curl -X POST https://your-anything-llm.com/api/system/default-system-prompt \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer <ADMIN_TOKEN>" \
     -d '{"defaultSystemPrompt":"You are a helpful assistant. Today is {date}. Use the user name {user.name} when addressing them."}'

```

### Setting a Workspace-Specific Prompt

To override the global default for a specific workspace:

```bash
curl -X PATCH https://your-anything-llm.com/api/workspaces/42 \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer <ADMIN_OR_MANAGER_TOKEN>" \
     -d '{"openAiPrompt":"You are a finance analyst for {workspace.name}. Answer queries concisely."}'

```

Now workspace **#42** always uses that prompt, regardless of the global default.

### Creating Custom Variables

To add a static company name variable:

```bash
curl -X POST https://your-anything-llm.com/api/system-prompt-variables \
     -H "Content-Type: application/json" \
     -H "Authorization: Bearer <ADMIN_TOKEN>" \
     -d '{
           "key":"company.name",
           "value":"Acme Corp",
           "description":"Static company name used in prompts",
           "type":"static"
         }'

```

You can then reference it in any prompt as `{company.name}` and it will be replaced with **Acme Corp**.

### Frontend Usage in React

Integrating prompt management into a React component:

```javascript
import System from '@/models/system';

// Load the current global prompt when the settings page mounts
useEffect(() => {
  System.fetchDefaultSystemPrompt().then(({ defaultSystemPrompt }) => {
    setPromptText(defaultSystemPrompt);
  });
}, []);

// Save the edited prompt
const savePrompt = async () => {
  const { success, message } = await System.updateDefaultSystemPrompt(promptText);
  if (success) toast.success('Prompt updated');
  else toast.error(message);
};

```

This mirrors the code in [`frontend/src/models/system.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/frontend/src/models/system.js) (see lines 91-123).

## Summary

- **Global defaults** are stored in `SystemSettings` (`default_system_prompt`) and affect all new workspaces via the `/system/default-system-prompt` endpoint.
- **Workspace overrides** use the `openAiPrompt` field in the `Workspace` model, allowing specific contexts to deviate from the global default.
- **Variable expansion** is handled by `SystemPromptVariables.expandSystemPromptVariables()` in [`server/models/systemPromptVariables.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/systemPromptVariables.js), supporting built-in variables like `{date}`, `{user.name}`, and `{workspace.name}`.
- **Custom variables** can be created via the API or UI and stored in the `system_prompt_variables` table for static or dynamic values.
- **Frontend integration** uses the `System` model in [`frontend/src/models/system.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/frontend/src/models/system.js) to fetch and update prompts via REST endpoints.

## Frequently Asked Questions

### What is the difference between the global system prompt and a workspace system prompt?

The global system prompt is stored in `SystemSettings` and serves as the default for all newly created workspaces. A workspace system prompt, stored in the `openAiPrompt` field of the `Workspace` model, overrides the global default for that specific workspace only. Existing workspaces retain their prompts even if the global default changes later, ensuring stability for active projects.

### Which built-in prompt variables are available in AnythingLLM?

AnythingLLM provides several built-in variables defined in [`server/models/systemPromptVariables.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/models/systemPromptVariables.js): `{time}` for current time in LTS format, `{date}` for current date in LL format, `{datetime}` for full date-time in LLLL format, `{user.id}` and `{user.name}` for user context in multi-user mode, and `{workspace.id}` and `{workspace.name}` for workspace context. These are automatically expanded at runtime before sending to the LLM.

### How do I create a custom prompt variable?

Custom variables can be created via the System Prompt Variables UI or by posting to the `/api/system-prompt-variables` endpoint with a JSON payload containing `key`, `value`, `description`, and `type` (static or dynamic). Once created, reference the variable in any prompt using curly braces, such as `{company.name}`, and it will be replaced with the stored value during the expansion phase handled by `SystemPromptVariables.expandSystemPromptVariables()`.

### Where in the codebase is the system prompt assembled before sending to the LLM?

The final prompt assembly occurs in [`server/utils/chats/index.js`](https://github.com/Mintplex-Labs/anything-llm/blob/main/server/utils/chats/index.js) within the `chatPrompt()` function. This function retrieves the base prompt from either the workspace's `openAiPrompt` or the global `SystemSettings.saneDefaultSystemPrompt`, then calls `SystemPromptVariables.expandSystemPromptVariables()` to substitute all `{variable}` placeholders with actual values before passing the completed prompt to the LLM provider.