CLI-Anything Software-Specific Backends: Blender, OBS-WebSocket, Python, and QGIS
CLI-Anything supports four software-specific backends—Blender (bpy), OBS-WebSocket (obs-websocket), generic Python (py), and QGIS—that translate uniform CLI commands into native API calls for each target application.
CLI-Anything, developed by HKUDS, is an open-source framework that exposes complex desktop and server applications through a standardized command-line interface. The project achieves this abstraction through software-specific backends, which are Python modules that handle process spawning, IPC channel management, and API translation. Each backend implements a consistent protocol in the HKUDS/CLI-Anything repository, allowing AI agents and users to interact with diverse software without learning individual native APIs.
Overview of Supported Software-Specific Backends
CLI-Anything currently ships with four dedicated backends, each targeting a specific software ecosystem. The following table summarizes how each backend connects to its target application and where the implementation resides in the source tree.
| Backend | Target Application | Implementation File | Selection Method |
|---|---|---|---|
| Blender (bpy) | Blender's embedded Python interpreter | cli_anything/blender/utils/blender_backend.py |
--backend bpy or auto-detection |
| OBS-WebSocket | OBS Studio via obs-websocket plugin (v5) | cli_anything/obs_studio/utils/obs_backend.py |
--backend obs-websocket |
| Python (py) | Arbitrary Python scripts and libraries | cli_anything/python/utils/python_backend.py |
--backend py (default) |
| QGIS | QGIS Python API (qgis.core, qgis.gui) | cli_anything/qgis/utils/qgis_backend.py |
--backend qgis |
Each backend module is responsible for locating its target software, establishing the necessary communication channel (whether it is Blender's bpy module, a WebSocket connection, or a headless QGIS process), and mapping generic CLI verbs to native API operations.
How Backend Selection Works
Backend discovery and selection are centralized in cli_anything/common/runtime.py through the RuntimeContext class. When you invoke a CLI-Anything command, the system follows this resolution flow:
- Explicit selection: The
--backendflag acceptsauto,bpy,obs-websocket,py, orqgis - Auto-detection: If set to
auto,RuntimeContext.detect_backend()iterates through known backends and calls each module'sis_available()method - First match wins: The first backend returning
True(indicating the target software is installed and reachable) becomes the active backend
The entry point in cli_anything/<software>/<software>_cli.py (e.g., blender_cli.py) exposes this flag:
@click.command()
@click.option(
"--backend",
type=click.Choice(["auto", "bpy", "obs-websocket", "py", "qgis"]),
default="auto",
)
def cli(backend, ...):
if backend == "auto":
backend = RuntimeContext.detect_backend()
ctx = RuntimeContext(backend=backend, ...)
Every backend implements a uniform protocol consisting of is_available(), run_command(), and cleanup() methods, allowing the generic harness to treat them interchangeably.
Blender (bpy) Backend
The Blender backend provides direct access to Blender's scene graph, objects, materials, and rendering capabilities through the embedded bpy Python module. When selected, cli_anything/blender/utils/blender_backend.py launches a headless Blender process and exposes operations like render, object list, and material create.
Key implementation details:
- Discovery: Checks for Blender installation in standard system paths
- IPC: Direct Python module import within the Blender interpreter
- File:
cli_anything/blender/utils/blender_backend.py
Usage example:
# Render a scene using the bpy backend
cli-anything ./blender --backend bpy render --output scene.png
What happens: The backend starts a headless Blender interpreter and executes bpy.ops.render.render(write_still=True, filepath="scene.png").
OBS-WebSocket Backend
The OBS-WebSocket backend controls OBS Studio remotely via the obs-websocket plugin (WebSocket v5 protocol). Implemented in cli_anything/obs_studio/utils/obs_backend.py, this backend manages scene switching, source manipulation, and streaming state by sending JSON requests to ws://localhost:4455.
Key implementation details:
- Discovery: Probes
ws://localhost:4455to verify the obs-websocket plugin is listening - IPC: WebSocket connection over port 4455
- File:
cli_anything/obs_studio/utils/obs_backend.py
Usage example:
# Switch to the "Gameplay" scene
cli-anything ./obs-studio --backend obs-websocket scene switch --name Gameplay
What happens: The backend opens a WebSocket connection and sends the JSON request { "request-type": "SetCurrentScene", "scene-name": "Gameplay" }.
Python (py) Backend
The Python backend serves as the generic fallback when no dedicated backend exists for a target application. Located in cli_anything/python/utils/python_backend.py, this backend loads user-provided Python modules and introspects public functions, generating thin wrapper commands that forward CLI arguments to Python function calls.
Key implementation details:
- Discovery: Always available (requires Python only)
- IPC: Direct function invocation within the same process
- File:
cli_anything/python/utils/python_backend.py
Usage example:
# Execute a function from a custom module
cli-anything ./my-tool --backend py --module ./my_tool.py add --a 5 --b 7
What happens: The backend imports my_tool.py, discovers the add function, and invokes add(a=5, b=7).
QGIS Backend
The QGIS backend enables scripting of geographic information systems through the QGIS Python API (qgis.core and qgis.gui). Implemented in cli_anything/qgis/utils/qgis_backend.py, it searches for QGIS installations via the QGIS_PREFIX_PATH environment variable or standard install locations, then spawns a headless QGIS process to handle layer management, processing algorithms, and map exports.
Key implementation details:
- Discovery: Checks
QGIS_PREFIX_PATHenvironment variable or standard installation directories - IPC: Headless QGIS process with Python API access
- File:
cli_anything/qgis/utils/qgis_backend.py
Usage example:
# Export the current project to PDF
cli-anything ./qgis --backend qgis project export --format pdf --output map.pdf
What happens: The backend spawns a headless QGIS instance, loads the active project, and executes QgsProject.instance().write() with the appropriate PDF driver.
Backend Architecture and Protocol
All software-specific backends in CLI-Anything conform to a lightweight protocol defined in the runtime system. This standardization ensures that the CLI harness in cli_anything/common/runtime.py can initialize and invoke any backend without software-specific logic.
The three required methods:
is_available(): ReturnsTrueif the target software is installed and ready for communicationrun_command(command, **kwargs): Executes the native API call and returns standardized resultscleanup(): Releases resources, closes sockets, and terminates spawned processes
This architecture allows CLI-Anything to treat Blender's bpy module, OBS Studio's WebSocket API, and QGIS's processing algorithms as interchangeable command targets, abstracting implementation differences behind a uniform command-line surface.
Summary
- CLI-Anything provides software-specific backends for Blender, OBS-WebSocket, Python, and QGIS, located in
cli_anything/<software>/utils/<software>_backend.py. - Backend selection uses the
--backendflag orRuntimeContext.detect_backend()auto-detection logic incli_anything/common/runtime.py. - Each backend implements
is_available(),run_command(), andcleanup()to provide uniform interaction with native APIs. - Blender (bpy) offers direct scene manipulation via the embedded Python interpreter.
- OBS-WebSocket controls streaming software via WebSocket v5 protocol on port 4455.
- Python (py) serves as the generic backend for arbitrary Python modules and functions.
- QGIS enables geospatial scripting through headless QGIS processes with full access to
qgis.core.
Frequently Asked Questions
How does CLI-Anything automatically detect which backend to use?
When you run a command without specifying --backend, CLI-Anything invokes RuntimeContext.detect_backend() from cli_anything/common/runtime.py. This method iterates through the list of known backends (bpy, obs-websocket, py, qgis), imports each module, and calls its is_available() method. The first backend returning True is selected automatically, making the tool work out-of-the-box when target software is installed.
Can I use the Python backend to wrap any arbitrary Python library?
Yes. The Python backend (cli_anything/python/utils/python_backend.py) is designed as a generic fallback. Use --module <path> to specify your Python file, and CLI-Anything introspects all public functions, creating CLI commands that map directly to function signatures. This allows you to expose any Python API—whether standard library, third-party package, or custom code—through a uniform command-line interface without writing a dedicated backend.
What is required for the OBS-WebSocket backend to function?
The OBS-WebSocket backend requires OBS Studio with the obs-websocket plugin (version 5) installed and enabled. The backend attempts to connect to ws://localhost:4455 to verify availability. If OBS Studio is running and the WebSocket server is active on that port, the backend can switch scenes, control sources, and manage streaming state remotely.
How does the QGIS backend locate the QGIS installation?
The QGIS backend (cli_anything/qgis/utils/qgis_backend.py) checks the QGIS_PREFIX_PATH environment variable first. If not set, it probes standard installation locations for QGIS binaries and Python libraries. Once located, it launches a headless QGIS process that imports qgis.core and qgis.gui, enabling CLI commands to manipulate layers, run processing algorithms, and export maps without opening the QGIS GUI.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →