"Local-first" is true, and it has an asterisk: the moment you talk to the copilot, some of your machine's reality has to reach a model. This page is the exact list — including the parts we'd rather not advertise.
When you send the copilot a message, that conversation leaves your Mac. It goes to our gateway at cloud.tryssh.com, which forwards it to Anthropic, streams the reply straight back, and charges you a credit. The conversation includes your prompt, the commands the agent proposed or ran during the turn, and excerpts of what those commands printed.
Everything else stays put. Your keys, your host list, your terminal session, your saved history — none of it is part of that request, and none of it is stored on our side.
If you run a command whose output contains a secret, that secret is in a model request. We scrub the obvious shapes (see below) but we cannot catch everything. Treat the copilot the way you'd treat a colleague looking over your shoulder: extremely useful, and not the right audience for cat /etc/shadow.
One row per kind of data, and where it actually ends up.
| Data | Sent to the model? | Stored by us? | Notes |
|---|---|---|---|
| Your chat message | Yes Yes | No No | It's the prompt. Kept locally in ~/.tryssh/tryssh.db. |
| Commands the agent proposes or runs | Yes Yes | No No | The agent writes them, so they're in the transcript by construction. |
| Output of those commands | Yes Excerpts | No No | Redacted, then capped at roughly the first 8,000 and last 4,000 characters before the model sees it. The full output is shown to you locally. |
| Hostnames, usernames, paths you mention | Yes If in the conversation | No No | Your host list is never uploaded; the host you're talking about is obviously in context. |
| Files the agent reads or edits over SFTP | Yes If the agent opens them | No No | Same redaction and cap as command output. Files you browse yourself are not sent. |
| SSH private keys and passphrases | No Never | No Never | macOS Keychain only, read by the local SSH engine at connect time. |
| Your interactive terminal session | No Never | No Never | A separate SSH channel the agent has no access to. What you type there is yours. |
The ~/.tryssh databases |
No Never | No Never | Hosts, chat history, audit log, agent memory, metrics. Files on your disk; no sync. |
| Account email, name, avatar | No No | Yes Yes | From Google or GitHub SSO. Needed to have an account at all. |
| Credit ledger row per turn | No No | Yes Yes | A turn id, a number, a timestamp, a reason. No content — the turn id is a random UUID minted per message. |
| Payment card details | No Never | No Never | Stripe handles checkout. We receive a subscription state, not a card. |
The Tryssh backend runs on your machine and speaks the Anthropic Messages API. In hosted mode it points that API at our gateway instead of at Anthropic directly. Each request carries two things: the bearer token minted when you signed in, and an x-turn-id header — a random UUID for the turn you're in.
The gateway then:
chat-extended.api.anthropic.com using our Anthropic credential, which lives on the server and only on the server.There is no step in that sequence that writes your prompt or the model's reply anywhere.
The gateway emits one JSON line per request. It contains a request id, your user id, the turn id, the model, the HTTP status, token counts, and a stop reason. When Anthropic returns an error we also log the first 500 characters of Anthropic's error envelope — their message about what went wrong.
It does not contain your prompt, the model's reply, command text, or command output. That exclusion is written into the code as a rule at the logging function itself, precisely because the alternative would be parking customers' shell output in a log tail forever.
An honest gap: we have not published a retention window for those logs. They live in our hosting provider's log stream and are subject to its default retention; neither our code nor our privacy policy currently states a number. We would rather flag that than invent "30 days" on a marketing page. If you need a committed retention period in writing, ask us — and expect a real answer rather than a comfortable one.
We do not use your conversations to train models. That is stated in the privacy policy and there is nowhere for training data to come from anyway: the gateway is a pass-through and our database has no table that could hold a conversation.
Anthropic is our model provider and processes the request in order to generate the reply. What they retain is governed by their API terms, not by us. If your threat model requires you to reason about that directly, use direct mode below and cut us out of the path entirely.
Three things happen to host output on its way out of the SSH channel, in this order.
The value side of credential-shaped assignments is replaced — DB_PASSWORD=…, "api_key": "…", x-api-key: …, client_secret=… — along with recognisable vendor tokens: AWS access key ids, GitHub, Slack, Stripe, Google, Anthropic and OpenAI-style keys, and JWTs. Only the value changes; the rest of the line survives so the error text still makes sense. This happens before the output is shown to you, before it is written to the local database, and before it reaches the model.
Long output is cut to about the first 8,000 and last 4,000 characters, with a marker in between. You still see the whole thing in the app; the model gets the head and tail, because the useful line is almost always at one end and the middle is what makes turns expensive.
Once a turn's transcript grows past a threshold, the oldest command outputs are dropped from the context before the model reads it — the newest few are kept, and anything the agent asked you directly is never cleared. So the longer a turn runs, the less of your early output remains in play.
The backend picks its LLM path at startup. If it finds an Anthropic credential in its environment — ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN — it builds a provider pointed straight at Anthropic and never constructs the gateway client at all. In that mode there is no bearer token, no x-turn-id, no credit check, no account requirement, and no request to any Tryssh server. Your conversation goes from your Mac to Anthropic on your own key.
This is a genuine escape hatch, not a marketing line: it is the same switch we use to develop the app. Be clear about what it is today, though — it is set on the backend process's environment, which makes it a self-hosting and power-user path rather than a text field in the app's Settings screen.
~/.tryssh. Hosts, chats, audit log, agent memory and metrics go with it. That's the whole story — there is no shadow copy.ai.definable.tryssh entries in Keychain Access, or delete the host in the app before you delete the folder.If you use hosted agent chat, your commands and your servers' output are in a request to a third-party model provider. No amount of local-first architecture changes that — it is what asking an AI about your server means. What we can honestly claim is narrower and, we think, more useful: your keys never move, your terminal is never watched, we store none of the content, we train on none of it, and if that's still too much, direct mode removes us from the path.
Knowing what the model sees is half of it. The other half is what it's allowed to do.