Termalin

Termalin

@termal.in

Fast SSH client for you and your AI agents. Tabbed terminal, SFTP, E2E-encrypted sync, built-in MCP server. Windows · macOS · Linux — termal.in · TG: t.me/termalin

19 followers13 following143 posts

Termalin 0.1.49 is out. Internal sites: open Home Assistant, Grafana or anything on localhost in any browser. The Connector dials out, so no port is forwarded and there's no public link. Also: Windows and macOS backups, per-server alert settings. termal.in/internal-sites

Before an AI agent touches prod, it should take a backup. Claude is asked to upgrade Postgres 15 to 16. It checks last night's backup, takes a fresh encrypted one with a note saying why, and only then upgrades. It can start a backup. It can never open one.

Termalin 0.1.48 is out. - Remote desktops: RDP and VNC in the app or the browser, through a Connector with no inbound port - The Connector now installs on Windows and macOS, with monitoring there too - Encrypted server backups that only your key opens termal.in/changelog

Coming soon: Termalin for Chrome. A command in a chat answer or a Q&A thread gets a Run button. You confirm, it runs on your server through your Connector, and the result goes into the chat box only when you click. No SSH key in the browser. Every command in your activity log.

Sneak peek at the next Termalin app update: - Keys saved under SSH Keys show up in Agent Keys on desktop, ready to tick for your AI agents - A dropped SSH connection just reconnects, no "Connection lost" error - Copy on Windows retries when another app holds the clipboard No date yet.

nginx down at 2 AM, the site on a 502. Termalin's alert names the failed service; ask Claude or ChatGPT why, and it finds one } too many on line 42, runs nginx -t, then starts nginx. Short blips get one message. An outage of 15+ minutes also gets "back to normal".

Docker's default json-file log driver keeps every line forever, so a chatty container can fill the disk by itself. Cap it in /etc/docker/daemon.json (max-size 10m, max-file 3), restart Docker, then recreate the containers. Old ones keep the old settings until you do.

Saturday question for people who run servers: what is the first command you type when a box feels off? Mine: uptime, then df -h, then journalctl -p err -b | tail.

Ask claude.ai or ChatGPT "Are all my servers online?" It checks them, finds / at 91% on web-01, trims the journal when you say yes, and reports back. No SSH key in the chat, no open port, and every command lands in your activity log. termal.in/claude-ssh

SSH from a chat window, no terminal open. Add Termalin as a connector in claude.ai or ChatGPT, sign in once, and the chat can list your servers, run commands, tail logs and edit files, in the browser or on your phone. No SSH key pasted anywhere, and every command is audited. termal.in/claude-ssh

An API key refused with a bare "invalid" sends you guessing. Termalin's keys now say why: expired, revoked, or cut off when it was pasted, and the cabinet shows the last refused attempt. Also new: ready-to-paste setup for Claude Code, Cursor and VS Code, plus a Test button.

Let's Encrypt renews itself every 60 days. Until the certbot timer gets disabled in a migration and nobody notices. One line worth running on every server: systemctl is-enabled certbot.timer How it looks when an alert catches it 3 days out:

The usual suspect when a server's disk fills up at 3 AM: the systemd journal. journalctl --disk-usage sudo journalctl --vacuum-size=2G SystemMaxUse=2G in journald.conf so it stays that way 40 seconds, from the alert to the fix in chat:

Termalin's inactivity lock hides the screen but keeps your SSH sessions running, and by default your AI agents keep working behind it too. One switch in Settings, "Pause AI agents while locked", makes them get a clear "locked" answer until you unlock.

No Termalin plan limits hosts, keys or devices. Your vault is one end-to-end encrypted blob our server can't open, so it can't count them; the old "100 hosts" line is gone. Plans bound what costs us to run: recording space, log retention, AI requests. termal.in/pricing

termal.inTermalin Pricing — Free SSH Client, Pro $8/mo, Team $15Start free. No plan limits hosts, keys or devices; paid plans add encrypted sync, the web cabinet, Connectors, cloud recordings and the AI assistant.

"Host key changed" is the SSH warning worth stopping for. Termalin's web terminal pins each server's key on first connect and refuses a different one. Now it says why and offers to trust the new key, but leaves the call to you: only you know if the server was reinstalled.

New in Termalin's AI tools: background jobs. Claude or ChatGPT starts the install or backup, then checks status, exit code and log tail later, instead of being cut off at ~90 s. Jobs live on your server in ~/.termalin/jobs. Plus: one command on up to 10 servers.

New, opt-in: keep what your AI agent's commands printed, next to what it ran. Your browser makes the key; the private half is wrapped by your master password. Our server sees the output once while it runs, then stores it sealed to you. Off by default; turning it off erases it.

New: an AI access switch on every Termalin Connector. Off means the server is gone from Claude, ChatGPT, Codex and API keys, and their commands, file ops and DB queries are refused on the next call. Your own app and web sessions keep working; the tunnel isn't touched.

Why can't Claude see a server I saved? Its password or key is encrypted on your side, so our backend can't use it; AI apps only reach servers running a Termalin Connector. New: the web terminal offers "Make it available". It shows the install command, then runs it in that session on your click.

New: the Termalin web terminal and file browser reach IPv6-only servers. IPv6 goes through a small relay on the host (IPv4 stays direct and preferred), and the relay only ever gets an address that already passed the public-IP check, never a hostname.

Revoke should stop an agent on its next call, not undo what already ran. Through a Termalin Connector every command re-checks that the agent and key aren't revoked, then gets its own 3-minute certificate. A command already running finishes, capped at 5 min.

New: sign in to Termalin with Google, GitHub or Apple, one click, including straight from the ChatGPT app directory. What it doesn't do is unlock your synced vault: keys and passwords stay end-to-end encrypted behind your master password, which is never sent to us.

Termalin in 60 seconds: a fast SSH client with an MCP server built in. Your agent works on your servers, Termalin keeps the keys, and you watch every move live. Free on Windows, macOS, Linux & iOS → termal.in

The host file an agent reads should be boring. Ours holds hostname, port, user, auth: {type: "agent"} and the public key to offer. No password, no private key; the app signs. Pinning the key also means one auth attempt per host, not every key in the agent tripping MaxAuthTries.

Allowlisting agent commands by prefix is a trap: "git" matches "gitleaks", and "git status; rm -rf /" starts with git too. Ours matches the first token only, rejects the whole command on ; & | $ ` < > ( ) or a newline, and an allowlisted key can't write files at all.

MCP tip, learned the hard way: never return an empty array. An agent that gets [] from hosts_list doesn't stop, it guesses. Ours now returns hosts: [] plus a note on how to enroll the first server, so the assistant walks a new user through step one instead of inventing it. Empty states are results.

When an agent opens an SSH session, something still has to answer “is this really your server?” Skip that and a rebuilt or spoofed host quietly gets the session. Termalin pins the host key on first connect, per account, and every later connection has to match it.

The strongest form of "the agent never holds your key" is that there is no key to hold. Termalin mints a fresh Ed25519 pair per connection, signs a certificate valid for 180 seconds, and throws the pair away. Exfiltrate it and you have three minutes.

A session recorder that captures keystrokes is a keylogger with better branding. Termalin records what the terminal printed, never what you typed. Even the command labels come from what the screen echoed — so a password at a hidden prompt was never in the file to begin with.

Termalin is on the App Store — iPhone, iPad and Apple Watch. A real terminal (tabs, an Esc/Ctrl/F-key row, so htop and vim behave), SFTP with an editor, live CPU and memory above the session. With a Connector, no key ever lands on the phone. Free: apps.apple.com/app/id6802817714

When a call times out, the agent can't tell whether it ran. Its only move is to try again. For a read that's free; for anything that writes, the same intent can land twice — two restarts, two rows, two emails. The fix isn't a more careful prompt, it's making the second attempt a no-op.

Revoke is not undo. Cutting an agent's access stops the next command, not the one already running — and that one can be the migration. So the real question isn't how fast you can revoke, it's what state you're left in when you do, and whether you can resume from there.

The safest state for an agent integration is not "configured and idle". It is off, until someone turns it on for a reason they can name. What ships is usually the opposite: enabled at install, used twice, reachable all year. Off by default costs one toggle on the day you need it.

Most agent integrations start with write access, because that is what the credential already had. Nobody chose it, it arrived with the key. Flip the default: read first, and anything more granted on purpose. SELECT before INSERT, describe before apply, a listing before a delete.

Rotating a key is the only way to un-share it. Handing an agent your credentials has no undo, only cleanup. Keep the key with the client and give the agent a capability instead: scoped to a host, narrowed to a command, switched off in a second. Revocation should be a toggle, not an incident.

You wouldn't give a new hire root on day one. You'd start them with read access and widen it as trust builds. An AI agent is a new hire that never sleeps and reads everything it's pointed at. Onboard it the same way: least privilege first, widen on purpose, not "here's the keys, good luck."

If an agent has access to your servers, you should be able to watch it work. Not a summary afterward, the actual session live, with a replay you can scrub later. "The logs say it ran X" isn't the same as watching it happen. Oversight you can't observe isn't oversight.

Keeping the credential out of the agent's hands is half the job. The other half is the capability you hand it. "Run any shell command" gives it your full authority without ever touching the key. Scope the operation, not just the secret: allowlist commands, read-only by default. Two walls, not one.

An agent running commands on your servers is a new kind of user. Give it its own identity, scoped permissions, and make every action attributable. Later, "was that me or the agent?" should be one grep away, not a shrug. An audit trail isn't about blame, it's answering that fast.

An agent with your prod SSH key can do anything you can. The fix isn't a smarter prompt — it's not handing it the key. A client holds the credential; the agent gets a scoped, revocable capability. Off by default, read-only by default. Custody beats trust.

Letting an agent touch your database: writing the SQL was never the risk — the connection string is. It can DROP as easily as SELECT, and you can't un-share it once it's in the model's context. So the client should hold it, and the agent only gets to ask. Read-only by default.