Skip to main content

Command overview

beacon endpoint install configures the local endpoint agent, writes the OpenTelemetry Collector configuration, installs the collector service, configures selected agent harnesses, and optionally adds Splunk HEC or Falcon LogScale HEC collector destinations. The service is a launchd job on macOS and a systemd unit on Linux. Where neither is available, Beacon runs a supervised collector instead and says so. See macOS or Linux for the platform setup, including the Linux packages and the --service flag.
Command syntax
By default, Beacon discovers the runtimes installed for the invoking user and configures every integration it can safely install. This includes OTLP settings and supported hooks, plugins, or extensions; VS Code receives both its OTLP and hook configuration. An explicit --harness list disables automatic selection and configures only the runtimes it names: a hook-only list such as --harness omp leaves Claude Code’s and Codex’s settings untouched, and --harness "" installs the collector alone. If discovery finds no automatically installable runtime, Beacon installs the collector without changing any runtime configuration. Discovery can also find runtimes whose collection path cannot be enabled safely by a machine-wide default. Beacon reports these without treating them as install failures: GitHub Copilot CLI needs launch-environment settings, Claude Cowork needs admin configuration, poll-only fx needs beacon endpoint fx sync, and OpenHands CLI/GUI coverage requires project-level hooks installed from inside each repository. Factory Droid’s hooks are installed automatically when Droid is detected, while its separate OTLP endpoint remains launch-environment managed. The claude harness writes both Claude Code’s OpenTelemetry settings and its user-level hooks, because the OTLP export alone carries no session start or end, file activity, or subagent lifecycle; beacon endpoint hooks uninstall --harness claude removes the hooks again, and beacon endpoint hooks install --harness claude --level project adds project-level ones. A hook that cannot be written, for example into a settings file whose hooks key is not an object, is reported as a warning with the retry command; the endpoint itself is installed and endpoint install still exits 0. Codex uses OTLP logs plus one selective turn trace for tokens, and its required SessionStart hook adds local OS-user context. Beacon applies redaction, sanitization, truncation, and event-size limits before writing supported content fields.

Flags

Session backfill

After a successful install, user or system mode, Beacon reads the last 30 days of agent sessions from each runtime’s own session store into the runtime log, so the local dashboard has your recent sessions before any agent runs again. It is the same sweep each runtime’s sync command runs (beacon endpoint claude sync, codex sync, cursor sync, opencode sync, copilot sync, cline sync, factory sync, pi sync, prime sync, hermes sync, devin sync, dsh sync, fx sync, grok sync, harness2 sync, and integrations openclaw sessions sync), and its events carry harness.collection_method=poll like theirs. It is local only and never touches the network. The backfill is bounded so a machine with a lot of history cannot crowd live telemetry out of the runtime log’s rotation window:
  • Only sessions modified in the last 30 days are read, newest first.
  • It writes at most 24 MiB in total, and no single runtime takes more than 12 MiB of that.
Nothing past a limit is lost. The collector cursors move only past what was written, and sessions left out are not touched, so the runtime’s sync command reads the rest; install names the command for each runtime that hit the limit. A runtime also stops early, and is reported the same way, if writing more would rotate its own backfill out of the log, which takes heavy live activity during the backfill. A runtime whose store cannot be read is reported as a warning and never fails the install. Re-running install reads only what changed since the last sweep. A system, package or MDM install runs as root, whose home holds no agent sessions, so it reads the session stores of the active console user instead: the same person system hook repair and the scheduled inventory resolve (SUDO_USER or the logind seat on Linux, the console owner on macOS, the active session on Windows). Its collector cursors stay under the system base directory. Because root is reading a home that user controls, the read is confined to that home: a link that leads out of it, a file the user does not own (including a hard link to someone else’s), and a FIFO, socket or device are skipped rather than read, and install lists what it skipped. SQLite stores are read from a private copy under the system base directory, retaken if the runtime rewrites its write-ahead log mid-copy; a database larger than 512 MiB with its log is not copied, and install names the runtime’s sync command to run as the user instead. A manual beacon endpoint <runtime> sync run as the user is not confined. When nobody is logged in, install says the backfill was skipped and the next connect or manual sync reads the sessions. --dry-run installs skip it, and --no-backfill or BEACON_BACKFILL=0 turn it off. If this install also connects to Beacon Cloud, the same history is uploaded by the connect.

Scheduled session sync

The session backfill runs once, at install. To keep reading the runtimes’ session stores after that, turn on the scheduled session sync:
sessions enable and disable change only this setting and the job. install and repair take --session-sync and --no-session-sync too, but repair rebuilds the endpoint from its flags: run without the ones the endpoint was set up with, it resets the harnesses and OTLP ports and drops a Splunk or Falcon HEC destination. For a package or MDM rollout, set BEACON_SESSION_SYNC=1 in the environment of the package’s install script (/opt/beacon/scripts/install-endpoint.sh), or run /opt/beacon/bin/beacon endpoint sessions enable --system on Macs that already have Beacon. BEACON_SESSION_SYNC=0 turns it off, and leaving it unset keeps what the endpoint already has, so a package upgrade never changes it. It is off by default. Hooks and OTLP already capture sessions live, and the session stores add what only they record, such as Claude Code’s per-request token usage and complete assistant text from its transcripts. Turning it on writes those records as poll events (harness.collection_method=poll) alongside the live ones, which matters when the runtime log is forwarded elsewhere. Token reports keep live usage authoritative over poll usage for the same session.

How it runs

  • The job runs beacon endpoint sessions sync every 15 minutes: com.beacon.endpoint.session-sync (a LaunchDaemon in system mode, a LaunchAgent in user mode) or beacon-session-sync.timer on systemd. The first run is 15 minutes after the job is loaded by the install, a repair, a reboot or a package upgrade, never at load.
  • Each run is the same sweep as the backfill above, with the same 30-day window, size budget and, in system mode, the same confined read of the console user’s stores. Each runtime’s cursor makes a run read only what is new. With nobody logged in, a system run reads nothing.
  • In system mode a SQLite store (Cursor, OpenCode, Devin CLI, Hermes Agent) is read from a private copy, as the backfill does. A copy can approach 512 MiB and those runtimes are captured live by their hooks or plugins, so the scheduled job copies each one at most once an hour. A store over 512 MiB is skipped and named in the job’s output; run that runtime’s sync command as the user to read it.
  • Only one sync runs at a time. An install, connect, beacon endpoint sessions sync or beacon endpoint <runtime> sync waits for a sync already in progress and then reads only what it left. A scheduled run or a --watch sweep skips its turn while another sync is running, and --print dry runs never wait.
  • When the install or a later connect skipped the backfill (--no-backfill or BEACON_BACKFILL=0), each runtime no sync had read yet is limited to sessions active since that skip, not the last 30 days. A session that continues past the skip is read from its start, a runtime that was already synced reads on from where it was, and a later backfill lifts the limit.
  • A user-mode job keeps the store locations the install saw (CLAUDE_CONFIG_DIR, CODEX_HOME, COPILOT_HOME, XDG_DATA_HOME, OPENCODE_DB and the rest), because the scheduler does not pass a shell’s environment.

What to expect when you turn it on

The first runs catch up. When the backfill stopped at its size limit, the rest of the last 30 days is left for the job, and each run writes up to another 12 MiB per runtime (24 MiB in all) until it has read everything. After that, a run writes only what the agents recorded since the previous one. On a machine with a lot of agent history the catch-up takes a few runs, and because the runtime log rotates at 10 MiB and keeps five archives, it pushes older local events out of the log sooner than live telemetry alone would. A connected endpoint forwards the catch-up like any other new events.

Settings and status

The setting is session_sync.enabled in config.json. Repair and package upgrades keep it, and beacon endpoint sessions disable or --no-session-sync turns it off and removes the job. A scheduled run also checks the setting, so a job left behind after the config was set to off reads nothing. beacon endpoint status shows Session sync: every 15m0s; job loaded=true, and beacon endpoint sessions sync runs the same sweep by hand. A host without launchd or systemd cannot run the job; run beacon endpoint sessions sync from your own scheduler there.

Interactive onboarding wizard

On a first interactive install the onboarding wizard signs in through beacon.sh, then asks where this machine’s telemetry should go: --connect presets Beacon Cloud and skips the destination question. Whether connect was chosen in the wizard or by the flag, a failed enrollment leaves the completed local install exiting successfully and prints beacon endpoint connect as the retry command. Automation should verify .managed_ingest.connected with beacon endpoint status --json. BEACON_MANAGED_INGEST=0 hides the managed answer. The wizard is never shown for system/root, package, MDM, CI, dry-run, or redirected-input installs. Customer-managed destinations remain available through the log forwarding packs after choosing Local.

Examples

Install with the default per-user paths:
Install with the default per-user paths
Install without starting the collector service:
Install without starting the collector service
Configure only one harness:
Configure only one harness
Override discovery with an exact harness list:
Configure an exact harness list
Force every installable integration without checking whether its runtime is present:
Configure all supported integrations
Configure VS Code Copilot telemetry:
Configure VS Code Copilot telemetry
Configure Devin CLI and Devin Desktop hooks alongside the default OTLP harnesses:
Configure Devin CLI and Devin Desktop hooks alongside the default OTLP harnesses
Include low-level runtime OTLP metrics that are filtered from JSONL by default:
Include low-level runtime OTLP metrics that are filtered from JSONL by default
Include raw Codex spans for troubleshooting:
Include raw Codex spans for troubleshooting
Install with system paths for a root-managed package or MDM deployment:
Install with system paths for a root-managed package or MDM deployment
Install and forward to CrowdStrike Falcon LogScale HEC:
Install and forward to CrowdStrike Falcon LogScale HEC
Configure Factory Droid’s OTLP endpoint through MDM or another customer-owned launch policy:
Configure Factory Droid's OTLP endpoint through MDM or another customer-owned launch policy
Configure GitHub Copilot CLI’s OTLP endpoint through MDM or another customer-owned launch policy:
Configure GitHub Copilot CLI's OTLP endpoint through MDM or another customer-owned launch policy
For richer hook telemetry, install runtime hooks after the endpoint configuration exists:
Install runtime hooks
Claude Code hooks are already installed at the user level by endpoint install. Add project-level hooks, or re-add user-level ones after removing them:
Add Claude Code hooks to a project
Install Grok Build hooks at the user level:
Install Grok Build hooks at the user level
Install Hermes Agent hooks at the user level:
Install Hermes Agent hooks at the user level
Hermes hooks write config.yaml in the Hermes home directory, which follows HERMES_HOME and the active profile (default ~/.hermes/config.yaml; see Hermes home and profiles), and support user-level installs only. Install Qwen Code hooks at the user level:
Install Qwen Code hooks at the user level
Qwen Code hooks merge into ~/.qwen/settings.json. Qwen Code has no OpenTelemetry export to configure, so qwen is a hook harness on this command too: beacon endpoint install --harness qwen installs the same hooks and writes ~/.qwen/settings.json. Project-level Grok Build hooks write ./.grok/hooks/beacon-endpoint.json and require /hooks-trust in Grok before they execute:
Install project-level Grok Build hooks
System-mode install (--system) is supported on macOS and on Linux distributions that use systemd. Omit --system for the default non-root local install. GitHub Copilot CLI and Factory Droid OTLP use launch-environment settings rather tha Beacon-managed shell-profile edits.

Restricted log access

A system-mode endpoint keeps one runtime log, /var/log/beacon-agent/runtime.jsonl, for every user on the machine. By default the log is shared: hooks run as each logged-in user and append to it directly, so the file is 0666. That also means any local account can truncate or rewrite the log, and read every other user’s prompts, command output and diffs. --log-access restricted makes the collector the only writer:
Install with restricted log access
  • Hooks send their events to the collector over a local Unix socket, /var/run/beacon-agent/ingest.sock, instead of writing the file. Nothing leaves the machine.
  • The collector records each event under the account the operating system says sent it, not the account the event claims.
  • The log directory becomes root:beacon-log mode 2750, the log and its archives 0640, and its lock 0600. Only the collector writes the log; only root and members of the beacon-log group read it. Switching an existing log to restricted replaces its files with fresh copies, so a handle another account opened while the log was shared stops reaching it.
  • If the collector is stopped or restarting, hooks keep their events in a private spool in each user’s home (~/.beacon/endpoint/spool, 0600) and send them with the next event once the collector is back. The agent is never held up.
Install creates the beacon-log group when it is missing and adds nobody to it. Add each account that should read the log, such as a log shipper’s service account, then restart that shipper:
Let a log shipper read a restricted log
The log format and every event field stay the same, so a SIEM or forwarder that parses the log needs no change. Shippers that run as root, and the Beacon Cloud forwarder, keep working without one. The mode is recorded in config.json as log_access, and in a root-owned .beacon-log-access marker beside the log. beacon endpoint repair, package upgrades, the Jamf repair-hooks.sh policy, and a reinstall after uninstall --keep-logs keep it. To go back, run sudo beacon endpoint repair --system --log-access shared; the log is writable by every account again at once. For package installs, set BEACON_LOG_ACCESS=restricted in the environment of the package’s install script. What this does and does not change:
  • Local accounts can no longer alter or delete events already in the log, or read other users’ sessions.
  • Every event that arrives over the socket records the account that sent it, as the operating system reports it. A user still controls their own agent, so they can still send events of their own choosing, including ones that name another session’s id, but always under their own account.
  • The collector’s OTLP ports on 127.0.0.1 still accept telemetry from any local process, as they do in the shared mode. Agents that export over OTLP, such as Claude Code and Codex, use them. Events that arrive that way are not attributed by the operating system.
While the endpoint is restricted, commands that read the system log as the person running them (beacon endpoint dashboard, beacon scan, beacon traces, and the session lookups in beacon share, beacon handoff and beacon git commit linking) see it only when run as root or by a beacon-log member. beacon endpoint doctor connects to the socket and reports a collector that is not answering on it, including one that was killed and left its socket behind, and any events waiting in the caller’s spool. On Windows the mode works the same way with Windows mechanisms: hooks send to the named pipe \\.\pipe\beacon-agent-ingest, the log directory’s ACL gives SYSTEM and Administrators full control, the beacon-log local group read and nobody else anything, events record the sender’s SID and account name, and the commands run from an elevated shell (see On Windows). For how the mode fits with log shippers such as Microsoft Sentinel, and what it does and does not protect, see Restricted log access.

Running user and system mode together

A user-mode collector can run beside a system-mode one on the same machine when the two use different ports. Give the user install its own OTLP ports; its health-check port moves with them:
Install a user-mode endpoint beside the system one
That collector listens on 127.0.0.1:4327, 127.0.0.1:4328, and health check 127.0.0.1:13143. Pass --health-port to choose the health-check port yourself. The port is recorded as collector.health_port in config.json, and beacon endpoint status checks the recorded port. A config written before the field existed has no health_port and keeps using 13133. If a port the collector needs is already taken, the install stops before it writes anything and names that port. If the collector starts but exits before it is ready, the install error quotes the collector’s last error line and gives the path of its log, then rolls back.

Endpoint status

Inspect collector health, runtime log state, harnesses, diagnostics, and forwarding readiness.

Runtime hooks

Install hook-based telemetry after the endpoint collector is configured.