AnythingLLM
Retrieval Augmented Generation (RAG) with LLM and Vector DB that can be local for full data privacy or cloud-based for greater functionality. Prompts and responses can be scanned for security issues using Prisma Airs. APIs are documented at: <Anything LLM URL> /api/docs Product documentation: https://docs.useanything.com/
Utilities · Anything LLM
Details
| ID | AnythingLLM |
|---|---|
| Provider | Mintplex Labs Inc |
| Category | Utilities |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.8319994 |
| Supported Modules | Agentix XSIAM |
README
Retrieval Augmented Generation (RAG) with LLM and Vector DB that can be local for full data privacy or cloud-based for greater functionality
Configure AnythingLLM in Cortex
| Parameter | Description | Required |
|---|---|---|
| AnythingLLM URL (e.g., http://<url to local AnythingLLM>:3001) or https://<Anything LLM cloud url> | True | |
| AnythingLLM API Key | True | |
| Cloudflare Access Client Id | False | |
| Cloudflare Access Client Secret | False | |
| AIRS API URL | Leave blank if AIRS is not being used | False |
| AIRS API Key | Leave blank if AIRS is not being used | False |
| Sync Scan LLM Prompts with AIRS | Have AIRS scan all LLM prompts and throw exeception if BLOCK is returned | False |
| Sync Scan LLM Response with AIRS | Have AIRS scan all LLM responses and throw exeception if BLOCK is returned | False |
| AIRS Profile Name for Scan Requests | The profile must be created in the AIRS console | False |
| AIRS Application Name for Scan Requests | Provide an application name to identify XSOAR scan requests in AIRS | False |
| AIR User for Scan Requests | Provide a user name to include in XSOAR scan requests in AIRS | False |
| Anything LLM Model in use | Provide the LLM model being used for scan requests in AIRS | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
anyllm-document-upload-file
Uploads an XSOAR file entry to the custom-documents folder.
Base Command
anyllm-document-upload-file
Input
| Argument Name | Description | Required |
|---|---|---|
| fileentry | XSOAR file entry to upload - example: 181@24789. | Required |
Context Output
There is no context output for this command.
anyllm-document-upload-link
Uploads a web link to the custom-documents folder
Base Command
anyllm-document-upload-link
Input
| Argument Name | Description | Required |
|---|---|---|
| link | Web link to upload - example: https://unit42.paloaltonetworks.com/darkgate-malware-uses-excel-files”. | Required |
| title | No description provided. | Required |
| description | No description provided. | Required |
| author | No description provided. | Required |
| source | No description provided. | Required |
Context Output
There is no context output for this command.
anyllm-document-upload-text
Upload text content as a document to the custom-documents folder
Base Command
anyllm-document-upload-text
Input
| Argument Name | Description | Required |
|---|---|---|
| text | Raw text content that is the document. | Required |
| title | Document title to use when uploading. | Required |
| description | Description of the document. | Optional |
| author | Author of the document. | Optional |
| source | Source of the document. | Optional |
Context Output
There is no context output for this command.
anyllm-workspace-new
Creates a new workspace in AnythingLLM
Base Command
anyllm-workspace-new
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace to create. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-delete
Deletes an AnythingLLM workspace
Base Command
anyllm-workspace-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace to delete. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-list
List all the workspaces in AnythingLLM
Base Command
anyllm-workspace-list
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
anyllm-workspace-get
Get a specific workspace details
Base Command
anyllm-workspace-get
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-settings
Update workspace settings
Base Command
anyllm-workspace-settings
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| settings | JSON object for the settings. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-add-embedding
Add a document to a workspace and create its vector embedding in the workspace
Base Command
anyllm-workspace-add-embedding
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| folder | Folder name containing the document. | Required |
| document | Document name to add as an embedding. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-delete-embedding
Delete a document embedding from the workspace
Base Command
anyllm-workspace-delete-embedding
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| folder | Folder the document originated from. | Required |
| document | Name of the document to have its embedding deleted. | Required |
Context Output
There is no context output for this command.
anyllm-document-createfolder
Create a new document folder
Base Command
anyllm-document-createfolder
Input
| Argument Name | Description | Required |
|---|---|---|
| folder | Name of the folder to create. | Required |
Context Output
There is no context output for this command.
anyllm-document-move
Move a document from a source folder to a destination folder
Base Command
anyllm-document-move
Input
| Argument Name | Description | Required |
|---|---|---|
| srcfolder | Name of the source folder. | Required |
| dstfolder | Name of the destination folder. | Optional |
| document | Document name to move. | Optional |
Context Output
There is no context output for this command.
anyllm-document-delete
Delete a document
Base Command
anyllm-document-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| folder | Name of the folder. | Required |
| document | Name of the document to delete. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-chat
Send a chat message to a workspace (default thread). Query mode is based on embedded documents in chat, whereas chat mode is more general.
Base Command
anyllm-workspace-chat
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| message | Message to send. | Required |
| mode | Mode to chat, query or chat. Possible values are: query, chat. | Required |
| format | No description provided. Possible values are: markdown, dictionary. Default is dictionary. | Optional |
Context Output
There is no context output for this command.
anyllm-workspace-stream-chat
Send a stream chat message to a workspace (default thread). Query mode is based on embedded documents in chat, whereas chat mode is more general
Base Command
anyllm-workspace-stream-chat
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| message | Message to send. | Required |
| mode | Chat mode, query or chat. Possible values are: query, chat. | Optional |
Context Output
There is no context output for this command.
anyllm-document-list
List all document details
Base Command
anyllm-document-list
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
There is no context output for this command.
anyllm-document-get
Get a specific document details
Base Command
anyllm-document-get
Input
| Argument Name | Description | Required |
|---|---|---|
| folder | Folder containing the document. | Required |
| document | Document name. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-pin
Set the pinned status of a document embedding
Base Command
anyllm-workspace-pin
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Workspace name. | Required |
| folder | Folder the document originated from. | Required |
| document | Document name. | Required |
| status | Set pin status to true or false. Possible values are: true, false. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-thread-chats
Get the conversation for a workspace thread
Base Command
anyllm-workspace-thread-chats
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | No description provided. | Required |
| thread | No description provided. | Optional |
Context Output
There is no context output for this command.
anyllm-workspace-thread-chat
Send a chat a message to a conversation thread
Base Command
anyllm-workspace-thread-chat
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| thread | Name of the conversation thread. | Required |
| message | Message to send. | Required |
| mode | Mode to chat, query or chat. Possible values are: query, chat. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-thread-new
Create a new conversation thread
Base Command
anyllm-workspace-thread-new
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Required |
| thread | Name of the new conversation thread. | Required |
Context Output
There is no context output for this command.
anyllm-workspace-thread-delete
Delete a thread in a workspace
Base Command
anyllm-workspace-thread-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| workspace | Name of the workspace. | Optional |
| thread | Name of the thread. | Optional |
Context Output
There is no context output for this command.
anyllm-scan-request
Perform an AI security scan of a request with AIRS
Base Command
anyllm-scan-request
Input
| Argument Name | Description | Required |
|---|---|---|
| profile_name | AIRS profile name to use in scanning. | Required |
| app_name | AIRS application name - metadata. | Optional |
| app_user | AIRS application user name - metadata. | Optional |
| ai_model | LLM model in use - metadata. | Optional |
| user_ip | User IP - metadata. | Optional |
| prompt | LLM prompt to scan. | Optional |
| response | LLM response to scan. | Optional |
| code_prompt | LLM prompt with code to scan. | Optional |
| code_response | LLM response with code to scan. | Optional |
| context | LLM context for grounding. | Optional |
Context Output
The context data returned from a scan request is:
| Key | Value |
|---|---|
| action | block or allow |
| category | malicious etc |
| profile_id | ID of the AIRS profile used |
| profile_name | Name of the AIRS profile used |
| prompt_detected | Details of a prompt detection - dictionary |
| response_detected | Details of a response detection - dictionary |
| scan_id | Scan ID |
| tr_id | TR ID |
Configuration parameters
url— AnythingLLM URL (e.g., http://<url to local AnythingLLM>:3001) or https://<Anything LLM cloud url> (required)apikey— AnythingLLM API Key (required)cf_auth— Cloudflare Access Client Idairs_url— AIRS API URLairs_apikey—airs_scan_prompt— Sync Scan LLM Prompts with AIRSairs_scan_response— Sync Scan LLM Response with AIRSairs_profile— AIRS Profile Name for Scan Requestsairs_app— AIRS Application Name for Scan Requestsairs_user— AIR User for Scan Requestsairs_model— Anything LLM Model in use
Commands (23)
-
anyllm-document-createfolderCreate a new document folder.
-
anyllm-document-deleteDelete a document.
-
anyllm-document-getGet a specific document details.
-
anyllm-document-listList all document details.
-
anyllm-document-moveMove a document from a source folder to a destination folder.
-
anyllm-document-upload-fileUploads an XSOAR file entry to the custom-documents folder.
-
anyllm-document-upload-linkUploads a web link to the custom-documents folder.
-
anyllm-document-upload-textUpload text content as a document to the custom-documents folder.
-
anyllm-scan-requestPerform an AI security scan of a request with AIRS.
-
anyllm-workspace-add-embeddingAdd a document to a workspace and create its vector embedding in the workspace.
-
anyllm-workspace-chatSend a chat message to a workspace (default thread). Query mode is based on embedded documents in chat, whereas chat mode is more general.
-
anyllm-workspace-deleteDeletes an AnythingLLM workspace.
-
anyllm-workspace-delete-embeddingDelete a document embedding from the workspace.
-
anyllm-workspace-getGet a specific workspace details.
-
anyllm-workspace-listList all the workspaces in AnythingLLM.
-
anyllm-workspace-newCreates a new workspace in AnythingLLM.
-
anyllm-workspace-pinSet the pinned status of a document embedding.
-
anyllm-workspace-settingsUpdate workspace settings. Anything LLM APIs are documented at: <URL>/api/docs.
-
anyllm-workspace-stream-chatSend a stream chat message to a workspace (default thread). Query mode is based on embedded documents in chat, whereas chat mode is more general.
-
anyllm-workspace-thread-chatSend a chat a message to a conversation thread.
-
anyllm-workspace-thread-chatsGet the conversation for a workspace thread.
-
anyllm-workspace-thread-deleteDelete a thread in a workspace.
-
anyllm-workspace-thread-newCreate a new conversation thread.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import pytest @pytest.fixture(autouse=True) def mock_demisto(mocker): mocker.patch.object( demisto, "params", return_value={ "url": "https://example.com", "apikey": {"password": "test-api-key"}, }, ) TRAVERSAL_FILENAMES = [ ("/var/lib/demisto/malicious", "malicious"), ("/etc/passwd", "passwd"), ("../../../etc/shadow", "shadow"), ("....//....//etc/hosts", "hosts"), ("subdir/nested/file.txt", "file.txt"), ("normal_file.txt", "normal_file.txt"), ] @pytest.mark.parametrize("malicious_name, expected_basename", TRAVERSAL_FILENAMES) def test_document_upload_file_sanitizes_filename(malicious_name: str, expected_basename: str, mocker): """ Given: A file entry whose getFilePath()["name"] contains directory components. When: document_upload_file() is called. Then: The file_name used for shutil.copy() and open() is the basename only. """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", return_value={ "path": "/tmp/server_file_path", "name": malicious_name, }, ) mock_copy = mocker.patch("AnythingLLM.shutil.copy") mock_remove = mocker.patch("AnythingLLM.os.remove") client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) mocker.patch.object(client, "document_list", return_value={"localFiles": {"items": []}}) mocker.patch.object(client, "_http_request", return_value={"success": True}) mock_open = mocker.patch("builtins.open", mocker.mock_open(read_data=b"file content")) client.document_upload_file("entry123") mock_copy.assert_called_once_with("/tmp/server_file_path", expected_basename) mock_open.assert_called_once_with(expected_basename, "rb") mock_remove.assert_called_once_with(expected_basename) def test_document_upload_file_cleanup_handles_missing_file(mocker): """ Given: A file entry where the copied file does not exist at cleanup time. When: document_upload_file() completes and os.remove raises FileNotFoundError. Then: The exception is suppressed and the function completes without error. """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", return_value={ "path": "/tmp/server_file_path", "name": "test_file.txt", }, ) mocker.patch("AnythingLLM.shutil.copy") mock_remove = mocker.patch("AnythingLLM.os.remove", side_effect=FileNotFoundError) client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) mocker.patch.object(client, "document_list", return_value={"localFiles": {"items": []}}) mocker.patch.object(client, "_http_request", return_value={"success": True}) mocker.patch("builtins.open", mocker.mock_open(read_data=b"file content")) client.document_upload_file("entry123") mock_remove.assert_called_once_with("test_file.txt") def test_document_upload_file_absolute_path_write_prevented(mocker): """ Given: A filename with an absolute path. When: document_upload_file() is called. Then: shutil.copy target is the basename only, not the full absolute path. """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", return_value={ "path": "/tmp/server_file_path", "name": "/var/lib/demisto/evil", }, ) mock_copy = mocker.patch("AnythingLLM.shutil.copy") mocker.patch("AnythingLLM.os.remove") client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) mocker.patch.object(client, "document_list", return_value={"localFiles": {"items": []}}) mocker.patch.object(client, "_http_request", return_value={"success": True}) mocker.patch("builtins.open", mocker.mock_open(read_data=b"file content")) client.document_upload_file("entry123") copy_dest = mock_copy.call_args[0][1] assert copy_dest == "evil" assert "/" not in copy_dest def test_document_upload_file_relative_traversal_prevented(mocker): """ Given: A filename with relative path traversal components. When: document_upload_file() is called. Then: shutil.copy target is the basename only, with no directory traversal. """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", return_value={ "path": "/tmp/server_file_path", "name": "../../../etc/shadow", }, ) mock_copy = mocker.patch("AnythingLLM.shutil.copy") mocker.patch("AnythingLLM.os.remove") client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) mocker.patch.object(client, "document_list", return_value={"localFiles": {"items": []}}) mocker.patch.object(client, "_http_request", return_value={"success": True}) mocker.patch("builtins.open", mocker.mock_open(read_data=b"file content")) client.document_upload_file("entry123") copy_dest = mock_copy.call_args[0][1] assert copy_dest == "shadow" assert ".." not in copy_dest def test_document_upload_file_already_exists_uses_sanitized_name(mocker): """ Given: A file entry with a traversal-laden name where the document already exists in AnythingLLM. When: document_upload_file() is called and document_name() succeeds (no exception). Then: The function raises with the SANITIZED basename in the error message, confirms the upload is skipped (no shutil.copy / _http_request), and the security improvement is reflected at the user-facing error level. """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", return_value={ "path": "/tmp/server_file_path", "name": "../../../etc/shadow", }, ) # document_name returning a value (no exception) means the document already exists. mocker.patch("AnythingLLM.document_name", return_value="existing-doc-id") mock_copy = mocker.patch("AnythingLLM.shutil.copy") mocker.patch("AnythingLLM.os.remove") client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) mocker.patch.object(client, "document_list", return_value={"localFiles": {"items": []}}) mock_http = mocker.patch.object(client, "_http_request", return_value={"success": True}) with pytest.raises(Exception) as exc_info: client.document_upload_file("entry123") # Sanitized basename must appear; original traversal must NOT appear. assert "shadow" in str(exc_info.value) assert "../../../etc/shadow" not in str(exc_info.value) assert "document already exists" in str(exc_info.value) # Upload path must be skipped entirely when document already exists. mock_copy.assert_not_called() mock_http.assert_not_called() def test_document_upload_file_empty_basename_skips_copy(mocker): """ Given: A file entry whose name results in an empty basename (e.g., "evil/"). When: document_upload_file() is called. Then: The function fails gracefully without calling shutil.copy("...", "") and the cleanup os.remove is NOT invoked on an empty filename. """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", return_value={ "path": "/tmp/server_file_path", "name": "evil/", }, ) mock_copy = mocker.patch("AnythingLLM.shutil.copy", side_effect=IsADirectoryError("empty filename")) mock_remove = mocker.patch("AnythingLLM.os.remove") client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) mocker.patch.object(client, "document_list", return_value={"localFiles": {"items": []}}) mocker.patch.object(client, "_http_request", return_value={"success": True}) mocker.patch("builtins.open", mocker.mock_open(read_data=b"file content")) with pytest.raises(Exception) as exc_info: client.document_upload_file("entry123") # Empty basename guard: cleanup must not attempt to remove an empty path. mock_remove.assert_not_called() # Either the function never reaches copy, or it copies to "" — both are acceptable # as long as cleanup is guarded; the user receives a wrapped error either way. if mock_copy.called: copy_dest = mock_copy.call_args[0][1] assert copy_dest == "" assert "exception uploading a file entry" in str(exc_info.value) def test_document_upload_file_get_file_path_failure_wraps_exception(mocker): """ Given: An invalid entry_id where demisto.getFilePath() raises an exception. When: document_upload_file() is called. Then: The exception is wrapped with the standard "AnythingLLM: document_upload_file: exception uploading a file entry [<id>]" format, demisto.debug is invoked, and cleanup does not crash on the uninitialised file_name (empty string). """ from AnythingLLM import Client mocker.patch.object( demisto, "getFilePath", side_effect=Exception("entry not found"), ) mock_debug = mocker.patch.object(demisto, "debug") mock_remove = mocker.patch("AnythingLLM.os.remove") client = Client(base_url="https://example.com/api", verify=False, headers={"Content-Type": "application/json"}) with pytest.raises(Exception) as exc_info: client.document_upload_file("bad_entry_id") err = str(exc_info.value) assert "AnythingLLM: document_upload_file:" in err assert "exception uploading a file entry [bad_entry_id]" in err assert "entry not found" in err mock_debug.assert_called_once() # file_name was never assigned (stayed ""), so cleanup must not invoke os.remove. mock_remove.assert_not_called()