Commands
Commands ask Santa to do something on a host right now and report the result back to Workshop. Workshop pushes each command out as soon as you queue it, so an online host acts within seconds.
Open Hosts → Commands to see every command and its progress. To start one, click Run command and pick a type. To target a single host, use the actions menu on that host's page.
| Command | What it does | Where the results go |
|---|---|---|
| Kill | Ends matching processes | The command's host results |
| App inventory | Walks paths you choose and uploads every app bundle it finds | Apps → Bundles |
| Package inventory | Scans for installed packages, extensions, MCP servers and skills | The packages table in Telemetry |
| Binary upload | Copies one binary from a host into your storage bucket | Your bucket. See Binary Upload |
Running a command
Every command targets a tag. Each host whose tags include it receives the command. Commands started from a host's page use that host's own tag, so they reach only that host.
The TTL sets how long an offline host has to come back online and still run the command. After the TTL passes, hosts that never picked the command up skip it, and you can't retry it. Queue a new command to reach those hosts.
Workshop sends a push notification so hosts check in for the command right away.
A host without push notifications picks it up at its next sync.
If you restrict Santa's commands with the AllowedSantaCommands key, allow each command you plan to run.
Tracking progress
The command's page lists one row per host. A retry adds a new row instead of replacing the old one. To see every attempt for a host, choose View attempt history from the row's menu.
| Host status | Meaning |
|---|---|
| Queued | Waiting for the host to pick up the command |
| Delivered | The host received the command and is running it |
| Complete | The host ran the command and reported back |
| Rejected | The host refused the command, for example because it is not allowed |
| Failed | The host could not run the command |
| Expired | The TTL passed before the host reported back |
Complete means the host finished, not that it succeeded. Check the result columns too. For example, a package inventory can complete with Upload failed, which means no rows reached Telemetry.
To try again before the TTL passes, use Retry on a host's row or Retry all failed at the top of the page.
App inventory results
App inventory uploads the bundles it finds to Workshop, the same way Santa does when it blocks a binary inside a bundle.
Each path can be a glob like /Applications/*, a bundle, or a single binary.
For a binary, Santa walks up to the bundle that contains it.
The bundles appear in Apps → Bundles, and their binaries appear in Apps → Binaries. On the command's page, click View Bundles to go there.
The bundles list shows apps from every host, not just the hosts this command reached. To find a specific app, filter by name, bundle ID or team ID.
Package inventory results
Package inventory requires Telemetry.
Each host runs a read-only scan and uploads one row per package to the packages telemetry table.
Workshop doesn't keep a separate copy, so Telemetry is the only place to see the results.
To open the results:
- Every host in the command: on the command's page, click Query Packages.
- One host: in that host's row, open the menu and choose Query packages. This appears only for a host whose scan completed and uploaded without an error.
Both links open the results in the telemetry query editor.
Rows appear after Workshop processes the upload, which can lag behind the host's Complete status. If the query reports no data, wait and run it again.
Querying packages yourself
The packages table follows the usual table naming.
Add a date for a single day, month or year, and add a host ID to read only that host's data.
Every row from one scan shares a RunID, so filter on it to look at a single scan.
-- Every package found on one host this year
SELECT Ecosystem, PackageName, Version, ProjectPath
FROM packages_2026_a1b2c3d4_e5f6_a7b8_c9d0_e1f2a3b4c5d6
ORDER BY Ecosystem, NormalizedName;
-- Which hosts have a given npm package, and which versions
SELECT Hostname, Version, ProjectPath
FROM packages_2026
WHERE Ecosystem = 'npm' AND NormalizedName = 'left-pad'
ORDER BY Hostname;
-- Packages that run scripts on install, a common supply-chain risk
SELECT Hostname, Ecosystem, PackageName, Version, LifecycleScripts
FROM packages_2026
WHERE HasLifecycleScripts
LIMIT 100;
-- The most recent scan on each host
SELECT *
FROM packages_2026
QUALIFY RunID = arg_max(RunID, EventTime) OVER (PARTITION BY MachineID);
The Schema page describes every column.
Scan profiles
| Profile | What it scans |
|---|---|
| Baseline | A curated set of package and tool roots. Use this for routine fleet scans |
| Project | A curated set of developer and project roots |
| Deep | Only the roots you list, which may include home directories. Use this for incident response, as it costs more |
Leave Roots empty to use the profile's defaults. Deep scans require at least one root. Leave every ecosystem unchecked to scan all of them. The Scan budget caps how long one scan can run, up to 60 minutes.