Docs menu
Reference

Command line

Every command and option of tangle-core, tangle and tangle-sim, the environment variables they read, and where they keep their files.

Tangle has three command-line programs: tangle-core runs projects and manages tokens, licenses and the boot service; tangle installs device modules and edits the devices of a project file; tangle-sim runs virtual devices for testing. Each one prints its help with --help and its version with --version.

tangle-core

tangle-core <command> [options]
CommandWhat it does
runRun a project: start its device modules and serve clients.
checkCheck a project file and exit.
modulesList the device modules found.
tokenCreate, list and revoke API tokens.
licenseActivate, check or move the license of this computer.
serviceInstall or remove the boot service.
clusterThe cluster this computer joined by pairing.
communityThe community driver repository.
projectsThe project library: the projects kept on this computer.
mcpMCP over stdio for desktop assistants, connected to a running tangle-core.

On error, every command prints error: <message> and exits with code 1.

tangle-core run

tangle-core run [--project show.yaml] [options]

Loads the project (without --project: the project open last, from the library, or a new one), starts the modules of its devices, and serves the WebSocket, REST API, MCP endpoint, designer and dashboards on one port. It stops cleanly on Ctrl+C (and SIGTERM on macOS and Linux): modules get a shutdown request and core exits within about 5 seconds.

OptionDefaultDescription
-p, --project <file>the libraryProject file (.json, .yaml or .yml), edited in place: changes made through the API are saved back to it. Without it, core runs the project open last from its library, or a new one.
-m, --modules <folder>Extra folder of modules (one sub-folder per module). Repeatable. The installed modules folder is always searched first; later folders win on the same module id.
--listen <addr:port>127.0.0.1:7340Address to serve clients on.
--allow-remoteoffAllow listening on a network address, so other machines can connect.
--insecure-httpoffAccept unencrypted remote connections. Required with a network address until TLS is available: trusted networks only.
--node-id <id>core-1Name of this node, shown to clients. With --peer, required and unique per node.
--catalog <folder>modules next to the programFolder of modules offered for install in the designer (one sub-folder per module), such as the modules bundled with the installer. Repeatable. Also read from TANGLE_MODULE_CATALOG.
--device-creator <folder>device-creator next to the programThe device creator's builder. Also read from TANGLE_DEVICE_CREATOR.
--dwg-converter <program>ODA File Converter, ODAFileConverter or dwg2dxfConverts DWG map plans to DXF. Also read from TANGLE_DWG_CONVERTER.
--ui <folder>ui next to the programFolder of the built web apps (dashboards, and the designer in its designer/ sub-folder). Also read from TANGLE_UI.
--demooffWithout a license, run in demo mode (every feature, up to 10 devices, sessions of one hour) instead of the free designer (this computer only, pauses every hour).
--log-jsonoffWrite console logs as JSON lines.
--log-dir <folder>platform log folderWhere log files go.

Redundancy options (all need --peer):

OptionDefaultDescription
--peer <host:port>Another node's redundancy address. Repeat it, or separate addresses with commas, for each other node. Turns redundancy on.
--role primary|backupprimaryprimary: this node goes first when choosing a primary. Others follow by node id.
--cluster-listen <addr:port>0.0.0.0:7341Address for heartbeats (UDP) and state mirroring (TCP).
--cluster-key <secret>TANGLE_CLUSTER_KEYShared secret, identical on every node, at least 16 characters.
--cluster-key-file <file>File holding the shared secret (what installed services use). Cannot be combined with --cluster-key.
--no-project-syncoffDo not copy the primary's project to the backups (update them by hand).

--no-discovery (no --peer needed) stops this core from announcing itself on the local network and from listing discovered cores. A core that was paired from the designer rejoins its cluster from the saved cluster.json without any of these options. See Redundancy.

Examples:

# This machine only
tangle-core run -p show.yaml

# Accept other machines on a trusted network
tangle-core run -p show.yaml --listen 0.0.0.0:7340 --allow-remote --insecure-http

# Extra module folder
tangle-core run -p show.yaml -m ./my-modules

# Redundant pair (run the matching command on 10.0.0.2 with --role backup)
export TANGLE_CLUSTER_KEY=<same secret on every node>
tangle-core run -p show.yaml --node-id core-a --peer 10.0.0.2:7341

Notes:

  • Core refuses to listen on a network address without --allow-remote, and without --insecure-http (no TLS yet).
  • The license is checked once, at start. If the project has more devices, DMX universes or timelines than the edition allows, run stops with a message naming the limit. In the free designer mode, remote access is turned off. See Licensing.
  • If a tangle.lock file sits next to the project, the locked module versions are made active at start (see tangle module lock).
  • Logs go to the console (stderr) and to a daily JSON log file tangle-core.<date>.log in the log folder; 14 files are kept. Set TANGLE_LOG to change the level.
  • See Redundancy for how the cluster chooses its primary.

tangle-core check

tangle-core check --project show.yaml

Validates the file against the contract schema and its cross-references (a scene pointing at a missing device, a device in a missing room...). On success it prints a summary and exits with 0:

show.yaml: valid (2 rooms, 8 devices, 3 scenes, 1 timelines)

On failure it lists each problem and exits with 1.

OptionDescription
-p, --project <file>Project file (required).

tangle-core modules

tangle-core modules [-m <folder>]...

Lists the modules found in the installed modules folder and in the extra folders: id, version and folder. Folders that are not valid modules are reported as skipped: ... on stderr.

OptionDescription
-m, --modules <folder>Extra folder of modules. Repeatable.

tangle-core token

API tokens authenticate REST, MCP and WebSocket clients from other machines. See REST API.

tangle-core token create --name stage-ipad --scopes read,control
tangle-core token list
tangle-core token revoke stage-ipad
CommandOptionsDescription
token create--name <name> (required), --scopes <list> (default read,control)Create a token and print its secret once. Scopes, comma-separated: read, control, configure, admin, live. Names must be unique among active tokens.
token listId, name, scopes and state (active or revoked) of every token. Secrets are never shown.
token revoke <name-or-id>Revoke a token. It stops working at once, even on a running core.

Tokens are stored hashed in tokens.json in the data folder. A core installed as a boot service uses the machine-wide data folder: manage its tokens with sudo tangle-core token ... on macOS and Linux.

tangle-core license

tangle-core license <command>
CommandOptionsDescription
activate <key>--name <name>Activate this computer. The first host creates the installation; the next ones join it as redundant hosts. --name defaults to this computer's name.
status--jsonShow the license, edition, limits and what the next start will run as. --json prints { status, nextStart }.
refreshFetch a fresh license file now (renewals, new limits).
deactivateRemove this computer from its installation. It runs as the free designer (or --demo) from its next start.
move <key>--name <name>Move a floating license to this computer (once every 7 days).
fingerprintPrint this computer's id, for offline activation.
issue <key>--fingerprint <id> (required), --name <name>, -o, --out <file> (required)Offline activation, step 1, on a computer with internet: write the license file for the offline computer whose fingerprint is given.
import <file>Offline activation, step 2, on the offline computer: install the license file. Also installs the answer to a license request.
sign-in <email>--license <id>, --name <name>Sign in with the license owner's email and activate their license. The password comes from TANGLE_LICENSE_PASSWORD or is typed on standard input. With several licenses and no --license, their ids are listed.
request--key <key> or --email <email>, --name <name>, -o, --out <file> (required)Write a license request for this computer, to email to licensing@tangle.systems. The answer is a license file for import.

A license change applies at the next start of tangle-core. See Licensing.

tangle-core service

Runs tangle-core at boot, restarts it after a crash, and stops it cleanly.

sudo tangle-core service install -- --project /shows/main.yaml --node-id core-a   # macOS, Linux
tangle-core service install -- --project C:\Shows\main.yaml                      # Windows, administrator terminal
sudo tangle-core service uninstall
CommandOptionsDescription
service install [--user] -- <run options>--userInstall and start the service. Everything after -- is passed to run. With --user (macOS, Linux) it runs at login for the current user instead of at boot.
service uninstall [--user]--userStop and remove the service.

What install does:

  • Checks the run options and loads the project first, so mistakes show now and not at boot.
  • Makes paths absolute (--project, --modules, --log-dir, --cluster-key-file, --ui).
  • Keeps PATH, TANGLE_HOME, TANGLE_PYTHON, TANGLE_NODE and TANGLE_LOG from your shell, so node and python3 are found.
  • With --peer, writes the cluster key (from TANGLE_CLUSTER_KEY or --cluster-key) to cluster.key in the data folder, readable only by the service, and passes --cluster-key-file. The key never appears in the service definition.
macOSWindowsLinux
Servicelaunchd daemon /Library/LaunchDaemons/tangle-core.plist (--user: ~/Library/LaunchAgents)Windows Service tangle-core ("Tangle core"), automatic startsystemd unit /etc/systemd/system/tangle-core.service (--user: ~/.config/systemd/user)
Needssudo (not with --user)Administrator terminal; --user is not availablesudo (not with --user)

See Operations.

tangle-core cluster

tangle-core cluster show    # this machine's saved cluster: id, node id, members
tangle-core cluster leave

leave forgets this machine's saved cluster membership and key (cluster.json in the data folder), so the next start runs standalone. Stop core first. The other members are not changed. Run it with sudo for a core installed as a boot service.

tangle-core projects

tangle-core projects list               # the open project is marked *
tangle-core projects import show.tangle # or a project .json / .yaml

The library keeps each project in projects/<id>/project.json in the core data folder, with its dashboards and plans. The designer's project menu creates, opens, duplicates, exports and deletes them.

tangle-core community

tangle-core community status            # which server, who is signed in
tangle-core community search [words] [--mine]

Signing in and publishing are done in the designer (Settings > Community, Publish to community). TANGLE_COMMUNITY_URL points core at another community server. See Device creator.

tangle-core mcp

tangle-core mcp [--url <url>] [--token <token>]

Bridges MCP over stdio to a running tangle-core, for desktop assistants.

OptionDefaultDescription
--url <url>http://127.0.0.1:7340Address of the running tangle-core.
--token <token>TANGLE_TOKENAPI token.

See MCP.

tangle

tangle <command> [options]

tangle manages device modules and devices on this machine. Device commands edit a project file. While tangle-core runs that project they refuse, because the running core would not see the change: use its REST API, MCP or the designer then.

CommandWhat it does
moduleInstall, update, roll back and lock device modules.
deviceAdd, test and bulk-edit the devices of a project file.
discoverScan the local network for devices and suggest modules.

tangle module

CommandOptionsDescription
module add <folder>-y, --yesInstall (or update) a module from its folder. Asks before granting the permissions it requests; --yes grants them without asking (needed when not run in a terminal). Reinstalling a version that a running project uses is refused.
module list--jsonInstalled modules: id, version, channel. --json adds source, previous version and folder.
module remove <id>Remove a module and all its versions. Refused while a running project uses it.
module rollback <id>Make the previously active version active again.
module lock-p, --project <file> (required)Write tangle.lock next to the project with the module versions it uses.
module sync-p, --project <file> (required)Make the versions in the project's tangle.lock active. Reports modules that are not installed or whose files differ, and exits with 1 if any.

Each module keeps its active and previous versions. Module ids look like misc.pjlink.projector. See Devices and Module SDK.

tangle module add ./misc.pjlink.projector --yes
tangle module lock -p show.yaml          # on the programming machine
tangle module sync -p show.yaml          # on the show machine

tangle device

All device commands take -p, --project <file> (required), except secret.

CommandOptionsDescription
device listId, name, module and room of each device.
device add <id>-m, --module <id> (required), --name <name> (default: the id), --room <room>, --set KEY=VALUE (repeatable)Add one device. Settings are typed from the module's settings schema (numbers, booleans, objects and arrays as JSON). Secret settings go to the credential store. The whole project is validated before saving.
device remove <id>Remove a device.
device test <id>Start the device's module on its own and check that the device answers (10 s at most). Prints its state on success, or the status and detail on failure (exit code 1).
device import <file>--skip-invalid, --dry-runAdd devices from a .csv or .json file. Nothing is added if a row is invalid, unless --skip-invalid. --dry-run checks only.
device export--format csv|json (default csv), -o, --output <file>Write the devices as CSV or JSON, to stdout without --output.
device secret <device> <setting>--deleteStore a secret setting (a password) for a device on this machine. The value is read without echo, or from stdin when piped. --delete removes it.

CSV columns: id, name, moduleId, room, tags (separated by ;), and one config.<setting> column per setting. Cells are typed from the module's settings schema; errors give the line number.

tangle device add -p show.yaml pj-1 -m misc.pjlink.projector --room hall --set host=10.0.0.5 --set password=admin
tangle device import -p show.yaml displays.csv
tangle device export -p show.yaml --format csv -o displays.csv
tangle device test -p show.yaml pj-1
echo "s3cret" | tangle device secret pj-1 password

Secrets are stored in the OS credential store (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux) under service tangle. Where no store answers, they go to secrets.json in the data folder, readable by its owner only.

tangle discover

tangle discover [--seconds 5] [--json]

Scans the local network with mDNS, SSDP and the module searches (vendor broadcasts) at the same time, and suggests installed modules for each device found.

OptionDefaultDescription
--seconds <n>5How long to listen (1 to 30).
--jsonoffPrint the results as JSON.

Refused while tangle-core runs a project on this machine: scan through the core then (POST /api/v1/discovery), which refuses only while a timeline plays.

tangle-sim

tangle-sim <command> [options]

tangle-sim runs virtual devices that speak their real protocols on real ports, so Tangle's modules connect to them as to the real devices. It needs Node.js 20 or newer (Node 22.6 or newer when run from source). See Simulator.

Run devices

CommandDescription
tangle-sim run [config.json]Start the devices. Default config tangle-sim.json; without one, it starts with no devices and creates the file when you add the first device in the web UI. run is the default command.
tangle-sim init [file]Write an example config (default tangle-sim.json): two PJLink projectors, a video matrix (ASCII over TCP), a DMX receiver and three scenarios. Refuses to overwrite a file.
tangle-sim typesList the device types and their options.

run options:

OptionDefaultDescription
--ui-host <ip>127.0.0.1Address of the control API and web UI.
--ui-port <n>4380Port of the control API and web UI.
--no-mdnsDo not advertise devices over mDNS.
--no-ssdpDo not advertise devices over SSDP.
-q, --quietDo not print protocol lines.

Device types: pjlink (PJLink projector, TCP 4352), ascii (any line-based device over TCP or UDP, port 5000, behaviour from rules) and dmx (Art-Net receiver on UDP 6454 and sACN on UDP 5568).

Control a running simulator

These commands talk to a running simulator at --url (default http://127.0.0.1:4380, or TANGLE_SIM_URL).

CommandDescription
tangle-sim statusDevices, ports, status and faults.
tangle-sim show <device>Full state, faults and the last 20 log lines.
tangle-sim set <device> key=value...Change state, for example set pj-1 lampHours=1990 power=on. Values are JSON when they parse, text otherwise.
tangle-sim fault <device> key=value...Set faults: offline, silent, fail, rejectAuth (on or off; a bare name means on), latency=<ms>.
tangle-sim clear <device>Remove every fault.
tangle-sim drop <device>Cut its connections.
tangle-sim reboot <device> [seconds]Take it offline for N seconds (default 5); it comes back with its initial state.
tangle-sim add <type> <id> [key=value...]Add a device, for example add pjlink pj-3 name="Lobby PJ". Saved to the config file.
tangle-sim remove <device>Remove a device. Saved to the config file.
tangle-sim scenario [name] [stop]List scenarios, or start or stop one.
tangle-sim init
tangle-sim run
tangle-sim fault pj-1 offline
tangle-sim clear pj-1

Environment variables

VariableRead byDescription
TANGLE_HOMEtangle-core, tanglePuts every Tangle folder (modules, data, tokens, logs in logs/) in this one folder. Handy for portable installs.
TANGLE_LOGtangle-coreLog filter, for example debug or warn. Default info.
TANGLE_PYTHONtangle-core, tanglePython interpreter for Python modules, for example a virtualenv's python. Default python3 (python on Windows). A module with its own virtual environment uses that one.
TANGLE_NODEtangle-core, tangleNode.js executable for JavaScript modules. Default node.
TANGLE_NATIVE_DIRtangle-core, tangleExtra folders where native module executables are looked for (path list).
TANGLE_SECRETStangle-core, tanglefile keeps device secrets in secrets.json in the data folder instead of the OS credential store.
TANGLE_TOKENtangle-core mcpAPI token for the MCP bridge (instead of --token).
TANGLE_CLUSTER_KEYtangle-core run, tangle-core service installRedundancy shared secret (instead of --cluster-key), at least 16 characters, the same on every node.
TANGLE_UItangle-core runFolder of the built web apps (instead of --ui).
TANGLE_MODULE_CATALOGtangle-core runFolder of modules offered for install (instead of --catalog).
TANGLE_DEVICE_CREATORtangle-core runFolder of the device creator's builder (instead of --device-creator).
TANGLE_DWG_CONVERTERtangle-core runProgram that converts DWG plans to DXF (instead of --dwg-converter).
TANGLE_COMMUNITY_URLtangle-coreAddress of another community driver server.
TANGLE_LICENSE_PASSWORDtangle-core license sign-inThe license owner's password, instead of typing it.
TANGLE_SIM_URLtangle-simAddress of the running simulator for control commands (instead of --url).

Files and folders

macOSWindowsLinux
Data folder~/Library/Application Support/Tangle%ProgramData%\Tangle~/.local/share/tangle
Log folder~/Library/Logs/Tangle%ProgramData%\Tangle\logs~/.local/state/tangle/logs
Data folder, as root (boot service)/Library/Application Support/Tanglesame as above/var/lib/tangle
Log folder, as root (boot service)/Library/Logs/Tanglesame as above/var/log/tangle

TANGLE_HOME replaces all of them: data in that folder, logs in its logs sub-folder.

In the data folderWhat it holds
modules/Installed modules, one folder per module id with its active and previous versions.
module-data/Writable data of each module.
tokens.jsonAPI tokens (hashes only).
secrets.jsonDevice and channel secrets, when no OS credential store answers.
license/The license of this computer.
cluster.keyRedundancy key written by service install.
cluster.jsonCluster membership and key saved at pairing (mode 600).
dashboards/<project>/Dashboard drafts and published versions.
sentinel/<project>/Monitoring alert history (history.jsonl).
In the log folderWhat it holds
tangle-core.<date>.logDaily JSON log, 14 days kept.
audit.logOne JSON line per configuration change or control action: time, surface (rest, mcp, ws, cli), caller, action, target, outcome.