What Opsty does with your data
The short version: Opsty makes one network request of its own, the update check, and you can turn it off. It has no account, no telemetry and no AI inside it. What it keeps, it keeps on your Mac, and this page lists every file.
lsof is also asked which program file it runs, to tell an app’s own helper from a server you started. A program that renamed itself is shown by its new name only, because macOS’s ps prints such a program’s environment after it. The update check reads the lowest macOS a version needs from the same file it always fetched. Opsty also answers Claude Code when it asks whether the terminal can read its status: the reply goes to the program in your tab and nowhere else, and Claude then reports in words what it is doing, which Opsty reads as it reads its title. Nothing new is kept, and nothing new is sent. See what it reads.
2026-10-15, for 0.6.0: the picture of the page a server serves is no longer taken when you hover over it. It is taken when you select that server in the Running list, a moment after, and only while it stays selected, so moving down the list loads nothing on the way. It is still a request from your Mac to your Mac. The menu bar’s Start againlist reads which commands you usually start in each folder from
history.db, on this Mac. Nothing new is kept, and nothing new is sent.
2026-10-14, for 0.5.0: workspace.json began to keep where each window was on your screens, and the tabs you close are kept in memory, with their folder and a copy of their scrollback, for Reopen closed tab, until Opsty quits. 2026-10-12: two sentences were corrected; nothing Opsty does changed. The programs it starts on its own also include the ones an update runs, and
lsof sees the programs your account runs, not every program on the Mac. This website also stopped keeping anything in your browser.
For 0.4.0, on 2026-10-11, Opsty began making one network request of its own: about once a day it asks dl.opsty.dev whether there is a new version, downloads it in the background, and installs it only when you say so or when you quit. It sends no account and no per-install number, and you can turn it off. Hovering over a port on the Running list began showing a picture of the page it serves, which Opsty fetches from that port on your own Mac, a request that never leaves it. It also began reading more on your Mac, and says where: every listening TCP port of the programs your account runs, so the list can name servers no tab owns; the names of files that change in a folder while something runs there; the names and dates of Claude Code’s conversation files for a tab’s folder; and, only when you click, Terminal’s and iTerm2’s preferences. See what it reads, what it writes and 0.4.0 in the changelog.
Earlier: 2026-10-10, nothing Opsty did changed; this page began showing how to check it yourself, and named support@lonelyduck.io. 2026-10-05, for 0.3.0: Opsty began starting lsof as well as ps, to learn which ports each tab’s programs listen on; began writing running.json; and began showing macOS notifications. 2026-09-26: the font menu began reading the names of the fonts on this Mac when you open it. 2026-09-25, for 0.2.0: Opsty made no network request at all, and Help ▸ Check for Updates… opened the changelog in your browser instead; history stopped keeping what a command printed; passwords, tokens and keys began to be actually removed before a line is written; two sentences nothing made true were withdrawn; and this website stopped loading fonts from Google. 2026-09-21, twice: the update check began to be logged, and the app began reading folder listings and manual pages for command cards.
1. One network request: the update check
The update check
About a minute after Opsty opens, then about once a day, and when your Mac wakes if the last check was a day or more ago, Opsty makes one HTTPS request to dl.opsty.dev for a small file, releases/latest-mac.yml, with a number from the clock added to the address so that no cache answers instead. It also asks whenever you choose Check for Updates…
: in the Help menu, in the launcher, or with Check now
in Settings ▸ Advanced.
The request carries no account, and neither your version of Opsty nor your version of macOS nor your Mac’s model: its user agent is the generic electron-builder. The update library Opsty uses makes a random installation number for each copy and would send it with every check; Opsty sends the same all-zero value from every copy instead, and the server deletes that header before it writes its log. It is made in a network session of its own, kept in memory, that shares nothing with Opsty’s windows. Like every connection, it comes from your IP address.
When there is a new version that your macOS can run, Opsty downloads it in the background, with no notification and nothing over your work. The download names what it fetches: opsty-0.4.1-arm64.zip, for example. The first update after installing from the disk image fetches that whole file. Later ones first fetch small index files (.blockmap) of the new version and, when Opsty has not kept one, of the version you have, so the server’s log can show which version you had. Then it fetches only the parts that changed. To install it, the update framework built into Opsty (Squirrel) takes the download from Opsty itself, over a connection to 127.0.0.1 that never leaves your Mac, and checks that it is signed the way Opsty is.
Nothing restarts by itself: a restart would stop your dev servers, drop your ssh sessions and interrupt your agents. When an update is ready, a small 0.4.1 ready
button appears in the title bar. It lists what a restart would stop, and offers Restart and bring it back
, Install when I quit
and Later
.
To turn it off: Settings ▸ Privacy ▸ Check for updates
, or updates = "off" in ~/.config/opsty/config.toml. Off, Opsty asks nothing by itself; Check for Updates…
still asks, because you did. If a firewall blocks the check, nothing pops up; Settings ▸ Advanced says it couldn’t reach dl.opsty.dev.
Port previews, on your own Mac
When you select a server in the Running list, its detail shows a small picture of the page that port serves, a moment after you select it and only while it stays selected: walking down the list with the arrow keys loads nothing on the way. To take it, a hidden window loads http://localhost:<port>/ in a sandboxed session of its own, which keeps nothing on disk and shares nothing with Opsty’s windows. The page’s own scripts run there, as they would in your browser, but every request it makes to anything other than this Mac, like a web font or an analytics script, is cancelled, and it may not leave that port, open windows, download files or use any permission. So these connections are from your Mac to your Mac. The hidden window closes half a minute after the last picture. To turn it off: Settings ▸ Privacy, or peekPorts = false.
Notifications
Notifications are macOS’s own, shown on this Mac. Opsty shows one when a tab needs you while you are looking elsewhere. When an agent asks you something, the notification quotes its question, and can carry the agent’s own first answer as a button or, when it is simply your turn, a reply field. Clicking the button sends the key for that answer to the agent only if the same question is still on its screen; a reply is typed at its prompt only if it is still waiting at the same turn; otherwise the click just opens the tab. Settings ▸ General ▸ When a tab needs me
turns notifications off; notifyActions = false keeps them but takes away the button and the reply field.
Nothing else: no analytics, no crash reports. The spell-check dictionary download that Electron apps make by default is switched off, and the crash reporter is never started. Help ▸ Documentation, Help ▸ Privacy and What’s new beside an update open pages of opsty.dev in your browser; those requests are your browser’s, not Opsty’s. What you run in a terminal can of course use the network (ssh, curl, git push, an agent talking to its own service), but those are programs you started.
Check it yourself
Opsty’s source isn’t public, so this promise can’t be read in its code. You can watch it instead, with tools your Mac already has. Open Opsty, use it as you normally do, then run these in Terminal, or in Opsty itself.
-
What it has open now. This lists every internet connection held by Opsty and its helper processes, whose names all begin with “Opsty”.
lsof -nP -i -a -p "$(pgrep -i -d, '^opsty')"Expected, with the update check and port previews switched off in Settings ▸ Privacy: nothing at all, or at most connections to this Mac itself (
127.0.0.1or[::1]), as in the window above.With them on, you may also see a brief connection to port 443 at the address
dig +short dl.opsty.devprints, while Opsty checks for or downloads an update; a connection to127.0.0.1within Opsty itself while an update installs; and connections tolocalhostwhile a server is selected in the Running list, and for up to half a minute after. Nothing else. -
What it does over time.
nettopshows connections live, refreshed every second, for the two processes a connection of Opsty’s would come from: the app, and the helper that makes its network requests. Leave it open while you work. Press q to quit.nettop -p Opsty -p "Opsty Helper"Expected: the only connection to another computer that ever appears is to dl.opsty.dev, and only with the update check on.
-
Without a command. In Activity Monitor ▸ Network, search for Opsty: with the update check on, a check adds a few kilobytes about once a day, and an update adds its size when it downloads. Or use a firewall that asks before any program connects out, such as LuLu (free) or Little Snitch.
Expected: with the update check on, it asks about Opsty connecting to dl.opsty.dev, and never about any other computer. Blocking it is fine: Opsty says nothing, and Settings ▸ Advanced says it couldn’t reach dl.opsty.dev.
ssh, git, npm, an agent) is its own program with its own name, so its connections are its own and don’t show up under Opsty. Opsty isn’t sandboxed: a terminal can’t be, because it runs the programs you ask for. So macOS can’t vouch for it the way it can for an app its sandbox keeps offline, and watching it is the check. If you ever see Opsty itself connect anywhere but dl.opsty.dev and your own Mac, please write to support@lonelyduck.io.2. No account, no telemetry, no bundled AI
There is nothing to sign up for or sign in to. Nothing about how you use Opsty is counted or sent anywhere. There is no AI model inside Opsty and it talks to none: the explanations in command and failure cards were written in advance and ship inside the app, and each names where its words came from. When you run an AI agent in Opsty, Opsty reads what that agent shows any terminal (the window title it sets; the status it reports, which Codex sends to every terminal and Claude Code sends once Opsty answers its question; and, when it asks you something, the question on its screen) and installs nothing into it. To bring each Claude Code tab back to its own conversation the next morning, it reads the names and dates of Claude Code’s conversation files for that tab’s folder, never what is in them.
3. What it reads, on this Mac only
~/.ssh/config, to list your servers in the launcher and the port forwards you set up there.~/.config/opsty/hosts.toml, which records the servers you marked as production.- A folder’s listing (names, sizes and dates, never what is in the files) when you open a folder picker in a command card.
- The manual pages installed on this Mac: for a command whose card is open, to check that every option the card offers exists here, and for a word you ask about with What is this?.
- A project’s manifest files (
package.jsonand similar), to offer its scripts. - The names of the fonts installed on this Mac, when you open the font menu in Settings.
- Every program your account runs that is listening on a TCP port, and, for one no tab started, the program file it runs and the folder it was started in, so the Running list can say which tab each server belongs to, whether none does, and whether it is part of an app. A server you started is listed under
No tab
; an app’s ports are folded under2 other apps
at the end of the list; macOS’s own are not listed. A command line is shown without its environment, with passwords and tokens removed. To turn this off and ask only about each tab’s own programs: Settings ▸ Privacy, orallServers = false. - The names of files created, changed or deleted in a folder while a command or an agent runs there, from macOS’s file events, so a command can say which files it changed. Never what is in them, and never in Documents, Desktop, Downloads or iCloud Drive, on another disk, in your home folder itself or in a top-level system folder. Not over ssh. To turn it off: Settings ▸ Privacy, or
watchChanges = false. - The names and modification dates of Claude Code’s conversation files in
~/.claude/projects/, for the folder of a tab where Claude Code ran, after one of its turns ends. The files are never opened. - Three short files in
/etc/pam.dthat any user can read, the first timesudoasks you for a password, to see whether Touch ID forsudois already on. To stop it asking:touchIdOffer = false. - Only when you click Import… in Settings ▸ Appearance: Terminal’s and iTerm2’s preferences files, for their color profiles, or a theme file you pick. Never at launch, never in the background, and the originals are never changed.
It never runs a program on your behalf. Anything it suggests is placed on your line, and nothing runs until you press Enter, or click a button that shows exactly what it will send, such as Run the command above again
on the Running list, Stop
on a server no tab owns, which prints the kill it sends, or an agent’s own answer in a notification. A command you tell the Running list to keep up is the same: you arm it, for that command, and Opsty stops trying after five stops in two minutes.
The only programs Opsty starts on its own are macOS’s ps and lsof: ps to see what is running and in which tab, lsof to see which programs are listening on which ports and, for one no tab started, which program file it runs, both with name lookups off. When it downloads an update it also runs sysctl and uname once, to check it is on Apple silicon, and installing the update runs macOS’s ditto and Squirrel’s ShipIt installer. ps is asked for each process’s number, parent, terminal and name, and for a listening server its memory, age and command line, of which a program that renamed itself keeps only its new name, because macOS’s ps prints such a program’s environment after it; lsof is asked about every two seconds. Neither touches the network. Opsty installs nothing on your servers.
4. What it writes, and where
What Opsty keeps is in ~/.config/opsty:
config.toml: your settings.hosts.toml: the servers you marked as production.workspace.json: the windows, tabs and splits to reopen, and where each window was on your screens, if you turn that on.history.db: the commands you ran, for History.running.json: the commands that were running when Opsty closed, with their folder, port and, for an agent, which one, the task it named and, for Claude Code, which conversation, so the next launch can offer to start them again. Never a production host’s, and with passwords, tokens and keys removed by the same rules as history. Turning off Settings ▸ General ▸Offer to start what was running
deletes it at once.themes/: the themes you imported, one file each.shim/: small startup files that let your shell tell Opsty where each command begins and ends. Your own dotfiles are never edited.
History keeps the command line, the folder, the host, the exit code and how long it took, never the output. Before a line is written, anything that looks like a password, token or key is removed: KEY=… assignments, --password …, Authorization: … headers, and tokens in common formats such as sk-… and ghp_…. The same rules remove secrets from a command’s output when you choose Copy for an AI chat
. Commands run on a host marked as production are never recorded. Settings ▸ Privacy lists these files; Command history
turns history off, and Erase everything
deletes it.
For updates, outside that folder:
~/Library/Caches/opsty-updater: the last update’s download, kept so the next update can fetch only what changed.~/Library/Caches/dev.opsty.opsty.ShipIt: Squirrel’s working folder while it installs an update.- In
~/Library/Application Support/opsty, beside Electron’s own working files (caches and window state):.updaterId, the random number the update library makes for each copy, which Opsty never sends;last-version.json, the version the last launch ran, so Opsty can say once that it was updated;update-install.json, for a moment during an update restart, the version it is installing; andupdate-failed.json, a version that did not install, so it is not tried again until you ask. None of your commands, output or history is there.
Only when you click it, in Settings ▸ Advanced: installing the Finder Quick Action copies one file into ~/Library/Services; and making Opsty the app that opens ssh:// and x-man-page:// links changes that macOS setting, and the same switch changes it back. A link opens a tab with its command placed and read back; it never runs anything. Putting the opsty command on your PATH is a line Opsty places for you to run; it never runs it.
Kept in memory only, never written to disk: the names of changed files, what each tab did while you were away, the screen snapshots behind Rewind
(gone when the tab’s shell ends: at once when you close it, or after the few seconds a closed tab with something running is kept), the tabs you closed, with their folder and a copy of their scrollback, for Reopen closed tab
(gone when Opsty quits), the list of servers on the Mac, and port previews.
5. The websites
opsty.dev, dl.opsty.dev (where the downloads and the update check go), opsty.sh, which serves the install script, and docs.opsty.dev, which now only forwards to opsty.dev/docs/, keep a standard web-server access log: the time, your IP address, the address you asked for, the response status, and the headers your browser or Opsty sent with the request, such as its user agent, the page you came from and your language. The installation-number header described above is deleted before a line is written. It is kept for about a week: the log is cut into 10 MB files, at most five old files are kept, and none is kept longer than seven days. It is read only to keep the server working and to spot attacks on it; update checks are not counted; and it is not shared or sold.
These pages load nothing from any other company: no fonts, no scripts, no analytics. Their typeface, JetBrains Mono, is served from opsty.dev itself. They set no cookies and keep nothing in your browser. The one script on opsty.dev works only inside the page: it fits and plays the pictures of Opsty, makes the page’s buttons work, and says when a browser reports a computer Opsty can’t run on, and it sends nothing anywhere. The front page also carries a block of data for search engines (JSON-LD: the app’s name, version and requirements, and LonelyDuck as its publisher); browsers never run it.
If this page is wrong
If something here stops being true, that is a bug in Opsty, not a change of policy, and this page changes in the same release as the code.
Questions, or something on this page you found to be untrue: write to support@lonelyduck.io. Opsty is a LonelyDuck app, and that mailbox is where its mail is read; opsty.dev has none.