termal.in

← Blog

How to connect Claude Code to a server over SSH — a hands-on walkthrough

· Termalin team claude-codemcpsshtutorial

Claude Code is comfortable in a repo. The moment the task leaves the repo — check why the service won’t start, free up disk space, fix the nginx config on the actual box — it needs SSH, and most people solve that by pasting a private key somewhere into the agent’s environment. We wrote about why that’s the one move you can’t undo; this post is the practical version. Twenty minutes, one VPS, no key ever leaves your side.

What you need

  • Termalin — the desktop app, free tier is fine. It’s an SSH client with a built-in MCP server; that server is what Claude Code will talk to.
  • Claude Code on the same machine.
  • One host saved in Termalin — pick something low-stakes for the first run. Staging, a toy VPS, the box that only runs your RSS reader.

Step 1 — turn agent access on

Agent access is off by default. In Termalin, open Settings → MCP and enable it, then tick the hosts the agent may reach. Nothing outside that list exists as far as the agent is concerned — a new host is a decision you make in the app, not something the agent can talk its way into.

Two things happen under the hood. Termalin writes a host inventory for the MCP server with agent-only auth entries — no passwords or keys land in that file. And authentication stays with the app’s key custodian: you unlock your keys once, Termalin signs on the agent’s behalf. There is no key file for the agent to read, so there’s nothing for it to leak.

Step 2 — register the server with Claude Code

One command:

claude mcp add termalin -- <path>/termalin-mcp

That’s the whole integration. Restart Claude Code and it picks up the tools: hosts_list, ssh_exec, persistent sessions (session_open, session_exec), SFTP reads and writes, and — if you allow it — tools that drive the live Termalin window itself.

Step 3 — give it a real chore

Don’t start with a demo command; start with a task you’d actually do. For example:

Disk usage on staging-1 keeps creeping up. Find what’s eating the space, clean up anything that’s obviously safe to remove, and tell me what you did.

Watch what happens in Claude Code: it calls hosts_list, sees staging-1, opens a session, and starts working — df -h, then du down the suspicious paths, then a look at whatever it finds (in our runs it’s almost always logs nobody rotated or a Docker image graveyard). It cleans up, verifies with another df -h, and reports back.

The part that makes this comfortable is that none of it is invisible. Every session the agent opens appears in Termalin as a live terminal tab, and the watch grid shows all open sessions side by side with the agent-driven tiles glowing.

The watch grid mirroring live sessions, with agent-driven tiles highlighted You’re not reading a summary after the fact — you’re watching the commands land as they run, and you can step in at any moment.

Where the boundaries are

A few defaults worth knowing before you point it at anything you care about:

  • Your keys never touch disk for the agent — the custodian signs; the agent requests. Revoking access is a toggle in Settings, not a key rotation across your fleet.
  • The agent’s reach is the allowlist you set in Step 1, nothing more.
  • Typing into your session is separate. By default the agent opens its own sessions. Letting it act inside a session you already have open (on Pro) is its own consent toggle — it never rides along silently.
  • Recordings mark agent activity. Session recordings capture output only — never your keystrokes — and every agent command is tagged as the agent’s, with the device and IP it came from in the audit log. At 2 a.m. you can tell “it did this” from “I did this”.

No desktop around? Use the hosted endpoint

If the agent runs where your desktop isn’t — CI, a cloud sandbox — you don’t ship the app with it. Create an API key in the web cabinet and point the agent at the hosted MCP endpoint:

{
  "mcpServers": {
    "termalin": {
      "url": "https://termal.in/api/v1/mcp",
      "headers": { "Authorization": "Bearer tk_live_…" }
    }
  }
}

The hosted endpoint only reaches servers you’ve enrolled with the tunnel agent, and each run authenticates with a short-lived certificate — same custodian idea, no standing credential anywhere. Keys are scoped to specific servers, expire on a schedule you pick (30, 90 or 365 days), and die instantly when revoked. File tools are deliberately modest there: text files up to 512 KB — config-editing territory, not a data channel.

The habit that makes it stick

Treat the first week like onboarding a new teammate who types very fast. Keep the watch grid open. Give it chores with a clear done-state — “make the health check pass”, “get the cert renewed” — and read how it gets there. You’ll learn quickly where it’s careful and where it needs a tighter leash, and you can widen the allowlist one boring host at a time.

The asymmetry is the point: the agent gets real reach, and you keep the one thing that can’t be taken back.


Termalin’s Free tier is the full desktop app, and every new account starts with a 14-day Pro trial — download it, or read the MCP docs first.

Try it on one host.

Termalin is a fast SSH client for you — and your agents.

Free tier · 14-day Pro trial · pricing