Metadata-Version: 2.5
Name: kache-ssh
Version: 0.1.0
Summary: Kache: one terminal to command all your devices over SSH, with a gatekeeper agent on every device.
Author: Simon Malm
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,fleet,mcp,orchestration,remote,ssh,tailscale,terminal,tui
Classifier: Environment :: Console
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.10
Requires-Dist: asyncssh>=2.14
Requires-Dist: platformdirs>=4.0
Requires-Dist: psutil>=5.9
Requires-Dist: textual>=8.0
Provides-Extra: dev
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Provides-Extra: gpu
Requires-Dist: nvidia-ml-py>=12; extra == 'gpu'
Description-Content-Type: text/markdown

# Kache

One terminal to command all your devices.

Kache is a hub that runs in your terminal. Pair your computers once, then
type a command and it runs on the device you picked, or on all of them at
once, exactly as if you were sitting at that machine. Every device runs a
small **gatekeeper** that only obeys devices you paired, refuses orders that
cannot work there, and sends back an evidence report when something fails.
Every order anyone sends (you, a script, or an AI agent working for you)
shows up in the live feed with the exact command.

```
pip install kache-ssh
kache
```

## What you get

- **A real remote terminal.** What you type is what runs on the other device,
  in its own shell (PowerShell on Windows, your shell on Linux and macOS).
  `cd` sticks between commands, output streams live, Ctrl+C stops an order.
- **One device or all of them.** Pick a device, or press F6 and send the same
  order to every device in parallel; output is labelled per device.
- **Device health at a glance.** Online/offline, CPU and RAM use, GPU load,
  temperature and memory (NVIDIA), and CPU temperature where the OS exposes it.
- **Pairing with a yes/no question.** Ask another device to pair; its Kache
  terminal asks *"laptop wants to send orders to this device. Code 482 913.
  Accept?"* Both screens show the same code, so nobody can sit in between.
- **Works at home and away.** Kache remembers every address of a device (LAN,
  Tailscale IP, Tailscale name) and uses whichever answers. Pair once at
  home; it keeps working over [Tailscale](https://tailscale.com) anywhere.
- **A gatekeeper on every device.** Unknown devices can only say hello or ask
  to pair. Paired devices are pinned by key. Orders for commands that do not
  exist on that device are refused up front (Linux/macOS) or explained
  afterwards (Windows).
- **Evidence when things break.** A failing order comes back with a report:
  exit code, last lines of output, labelled hints (command not found,
  permission, disk full, missing Python module, network, out of memory...)
  and the machine's state at that moment.
- **A live feed of every order.** Who sent what to which device, when, and
  how it ended, including orders from scripts and AI agents, which are
  labelled with the agent's name.
- **Built for AI agents too.** Every command has `--json`, there is an MCP
  server (`kache mcp`), and `kache guide` explains everything an agent needs.

## Quick start

On every device:

```
pip install kache-ssh
kache service install     # keep the gatekeeper running at logon (recommended)
kache                     # open the Kache terminal
```

In the Kache terminal on the device you want to command *from*, press **F2**
and enter the other device's address: its LAN IP, Tailscale IP or Tailscale
machine name (devices on your tailnet are listed for you). Accept on the
other device when the codes match. It appears in your device list, and
anything you type now runs there.

On Windows, the first time the gatekeeper starts, Windows may ask whether
Python may accept connections. Allow it on private networks.

### Keys

| Key        | Action                                        |
|------------|-----------------------------------------------|
| Enter      | send what you typed to the selected device(s) |
| ↑ / ↓      | previous / next command                       |
| Ctrl+↑ / ↓ | select the previous / next device             |
| F6         | switch between one device and all devices     |
| Ctrl+C     | stop the running order(s)                     |
| F2         | pair a new device                             |
| F3         | rename the selected device                    |
| F4         | remove the selected device                    |
| F5         | show the last failure's evidence              |
| Ctrl+Q     | quit                                          |

## Away from home: Tailscale

Kache connects devices directly, so a device must be reachable from the one
commanding it. At home that is your LAN. Away from home, install
[Tailscale](https://tailscale.com) (free for personal use) on both devices
and sign in with the same account. Then:

- `kache discover` lists the devices on your tailnet and which run Kache;
- pairing by Tailscale name works: `kache pair my-desktop`;
- devices paired over LAN switch to Tailscale automatically when the LAN
  address stops answering;
- `kache listen tailscale` makes a gatekeeper answer on your tailnet only,
  ignoring the local network.

## For scripts and AI agents

Everything the terminal does is also a command with `--json` output, and
every order still appears in the feed:

```
kache devices --json                              # status and health of every device
kache run desktop --json --timeout 60 -- nvidia-smi
kache run all --as nightly-job -- git pull         # labelled in every feed
kache feed -d all -f --json                       # live JSON-lines feed from all devices
kache evidence E-3f2a9c -d desktop                # a failure report
kache doctor desktop --json                       # why a device cannot be reached
```

For MCP clients (Claude Code, Claude Desktop, Cursor and others):

```
claude mcp add kache -- kache mcp
```

Agents get the tools `kache_devices`, `kache_run`, `kache_feed`,
`kache_evidence`, `kache_doctor`, `kache_discover`, `kache_pending` and
`kache_pair`. Accepting pair requests and revoking devices stays with
people. `kache guide` prints the full guide: JSON shapes, feed event kinds,
exit codes and rules for agents.

## How it works

Each device has one ed25519 key, created on first run. The gatekeeper is an
SSH server (built on asyncssh, port 7722) that accepts any key but only lets
unknown keys say hello or ask to pair; paired keys may send orders. The
Kache terminal is an SSH client that pins each paired device's key. Nothing
goes through a server in between.

State lives in one folder per device (`kache whoami` shows where; override
with `KACHE_HOME`): the device key, its name, the devices it commands, the
devices trusted to command it, the feed and the evidence reports.

If something does not connect, `kache doctor` checks every step (gatekeeper,
Tailscale, each address, the device's key, the pairing) and says what to fix.

## Status

Version 0.1: pairing, orders, sessions, evidence, live feed, health,
Tailscale, JSON output and MCP work on Windows, Linux and macOS.

Planned:
- full interactive sessions (`kache attach` for programs like vim or htop);
- confirmation popups for dangerous orders;
- pairing both directions in one step;
- a relay for devices that cannot reach each other directly.

MIT licensed.
