auxly-memory-cli
README.md
<div align="center">
<img src="assets/brand/auxly-banner.png" alt="Auxly" width="380" />
### One memory. Every AI agent. On your machine.
**Auxly is a local-first, file-based memory layer that every AI agent you use โ Claude, Codex, Gemini, Copilot, Cursor, Antigravity, and any CLI agent โ reads from and writes to as a single shared source of truth.**
No cloud. No database. No vendor lock-in. Just Markdown files you own, with an audit trail you can read and a review queue you control.
[](https://github.com/Tzamun-Arabia-IT-Co/auxly-memory-cli/releases)
[](https://github.com/Tzamun-Arabia-IT-Co/auxly-memory-cli/releases)
[](https://github.com/Tzamun-Arabia-IT-Co/auxly-memory-cli/stargazers)
[](LICENSE)
[](go.mod)

<br />
<img src="screenshots/Dashboard-new.png" alt="The Auxly dashboard โ connected agents, memory stats, live activity, and remote connections in one terminal view" width="860" />
<sub>One local dashboard for every agent you use โ connected brands, memory by category, recent writes, and live remote connections.</sub>
</div>
---
## ๐ What's New in Version 1.5.0
- **๐งน Orphan Sweep (`auxly organize --sweep` + TUI "Sweep orphans" + `auxly doctor`).** Vault roots accumulate stray files no organize mode could ever see โ hand-dropped notes, stale exports, loose project files. The sweep detects them, re-files their bullets into the right taxonomy files through the same review-gated pending queue (`auxly approve --agent organize-sweep`), and applies the split-projects two-phase safety contract: additions queue first, and an orphan's deletions are only ever queued for bullets provably present in a target โ rejecting an addition can never lose a fact. Drained husk files are cleaned up, encrypted files are never decrypted, and non-memory files (`.bak`, `.txt`) are reported, never touched. `auxly doctor` now flags orphan files and points at the sweep.
- **๐ง Smarter Headless LLM Resolution.** Organize-family features with no model configured now share one resolver (`detect.ResolveHeadlessLLM`): Direct LLM when reachable, otherwise the first installed CLI agent with a *verified* one-shot invocation โ no more dying on an unreachable `localhost:11434`, and no more falling back to agents whose headless flags were never verified.
- **๐ฎ Removed the dead `--force` flag on `auxly organize`.** Registered in v1.4.6 but never read โ on-demand organize always evaluates every file; the flag lied.
Looking for past release details? See the [CHANGELOG](CHANGELOG.md) for the full history.
---
## Contents
- [Why Auxly](#why-auxly)
- [How it works](#how-it-works)
- [Install](#install)
- [Uninstall](#uninstall)
- [Quick start](#quick-start)
- [The memory vault](#the-memory-vault)
- [Memory insights & review](#memory-insights--review)
- [Trust & access control](#trust--access-control)
- [Skills (slash commands)](#skills-slash-commands)
- [Supported agents](#supported-agents)
- [Setup guide](#setup-guide)
- [The dashboard](#the-dashboard)
- [Remote memory over SSH](#remote-memory-over-ssh)
- [Live Usage](#live-usage)
- [Statusline (Claude Code ยท Cursor ยท Antigravity)](#statusline-claude-code--cursor--antigravity)
- [Git sync](#git-sync)
- [Connect any MCP agent](#connect-any-mcp-capable-agent-manual-setup)
- [Command reference](#command-reference)
- [Configuration](#configuration)
- [Security & privacy](#security--privacy)
- [Contributing](#contributing)
- [License](#license)
---
## Why Auxly
### The problem
Every AI agent keeps its own memory in its own walled garden. Tell Claude your stack, then open Codex โ it knows nothing. Switch to Gemini โ start over. Your context is fragmented across a dozen tools, none of them talk to each other, and none let you see or correct what they "remember" about you.
### What Auxly does
Auxly gives all of your agents **one** memory โ a folder of Markdown files on your own machine โ and wires every agent to it through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io). Teach one agent something once; every other agent knows it instantly. Because the memory is plain Markdown under your control, you can read it, edit it, diff it, and version it in Git like any other file.
### The benefits
| | Benefit |
|---|---|
| ๐ง **Shared context** | Say it once to any agent โ all your other agents inherit it. No more re-explaining your stack, preferences, or projects per tool. |
| ๐ **You own the data** | Memory is Markdown in `~/.auxly/memory/`. Open it in any editor, grep it, commit it. Nothing is locked inside a vendor's cloud. |
| ๐ **Local-first & private** | No server, no telemetry, no embeddings, no Docker. Memory never leaves your machine unless *you* push it to a Git remote. |
| ๐ **You stay in control** | Per-agent trust levels decide whether a write lands instantly, queues for your approval, or is denied. |
| ๐งพ **Fully auditable** | Every read and write is logged append-only with who, what, when, and why โ surfaced in a live dashboard. |
| ๐ **Works across machines** | Share one memory host with NAT'd servers and laptops over plain SSH โ no daemon, no open port, no token. |
| ๐ฑ๏ธ **TUI + CLI, same power** | An interactive dashboard you drive with **mouse or keyboard**, plus a fully scriptable **CLI** โ every action works both ways. |
| ๐ **Free & open** | MIT-licensed Go binary. Single static file, zero runtime dependencies. |
---
## How it works
Auxly is a single static Go binary that plays three roles at once:
```mermaid
flowchart LR
agents["Claude · Codex · Gemini<br/>Copilot · Cursor · any CLI agent"]:::agents
mcp["MCP server<br/>stdio: read · write · search · sync"]:::core
gate{"Trust gate<br/>auto · approve · read-only"}:::gate
vault[("~/.auxly/memory/*.md")]:::store
audit["Audit log<br/>JSONL + SQLite index"]:::audit
git["git push (optional)"]:::ghost
agents -->|MCP over stdio| mcp
mcp --> gate
gate -->|accepted write| vault
vault --> audit
vault -.-> git
classDef agents fill:#917FD1,stroke:#B7A8F0,color:#ffffff,stroke-width:1px;
classDef core fill:#73CBAD,stroke:#A7E6D2,color:#08231B,stroke-width:1px;
classDef gate fill:#D97757,stroke:#F0A988,color:#ffffff,stroke-width:1px;
classDef store fill:#84DCFB,stroke:#BDEEFD,color:#08231B,stroke-width:1px;
classDef audit fill:#775099,stroke:#A88FCB,color:#ffffff,stroke-width:1px;
classDef ghost fill:#2A2540,stroke:#917FD1,color:#D7D0F2,stroke-width:1px,stroke-dasharray:4 3;
linkStyle default stroke:#8E7BD0,stroke-width:1.5px;
```
1. **MCP server** โ `auxly mcp-server` exposes tools (read, write, search, sync, โฆ) to any MCP-capable agent over stdio. Agents call them like any other tool.
2. **Trust gate** โ every write is checked against the writing provider's trust level: write directly, queue for human approval, or reject.
3. **Memory vault** โ accepted writes land as Markdown in `~/.auxly/memory/`, optionally auto-committed to Git.
4. **Audit** โ every access is recorded to an append-only JSON Lines log and indexed in SQLite for instant querying in the dashboard.
The only persistent files are Markdown in `~/.auxly/memory/` and two local SQLite indexes โ the audit log and (optionally) the semantic index. There are **no background daemons** and **no mandatory network calls** โ semantic recall uses a local embedding model by default and cloud is opt-in.
---
## Install
### macOS & Linux
```bash
curl -fsSL https://auxly.io/cli | sh
```
Install **and** wire up your local agents in one go:
```bash
curl -fsSL https://auxly.io/cli | sh -s -- --setup
```
### Windows (PowerShell)
```powershell
irm https://auxly.io/cli.ps1 | iex
```
### Homebrew
```bash
brew install Tzamun-Arabia-IT-Co/homebrew-tap/auxly
```
### npm
```bash
npm install -g auxly-cli
```
The npm package is a thin wrapper: on install it downloads the matching prebuilt
binary for your platform and **verifies it against the signed checksum manifest**
before vendoring it. Set `AUXLY_ALLOW_UNSIGNED=1` only if you knowingly install a
release that predates signing.
### pip
```bash
pip install auxly-cli
```
Same model as the npm package โ the wheel fetches and **signature-verifies** the
platform binary on first run, then caches it. `AUXLY_ALLOW_UNSIGNED=1` opts out of
the strict check.
### Go
```bash
go install github.com/Tzamun-Arabia-IT-Co/auxly-memory-cli@latest
```
### From source
```bash
git clone https://github.com/Tzamun-Arabia-IT-Co/auxly-memory-cli.git
cd auxly-memory-cli
make build # produces ./auxly
# Apple Silicon dev builds: codesign --force --sign - ./auxly
```
Prebuilt binaries, `.deb`, and `.rpm` packages are on the [Releases page](https://github.com/Tzamun-Arabia-IT-Co/auxly-memory-cli/releases). Binaries are CGO-free single files โ nothing to extract, no shared libraries to install.
---
## Uninstall
Auxly is a single static binary plus a `~/.auxly` data directory โ no system services to scrub unless you ran `auxly host setup` (which installs a per-user keep-alive). The steps below remove the binary, the keep-alive (if any), and your local data.
> โ ๏ธ **`~/.auxly` holds your memory vault** (`~/.auxly/memory`) on your **main** machine. Only delete it on a *consumer* box (one that just uses another machine's memory over SSH), or **after exporting** your vault. On a consumer box `~/.auxly` only holds connection config โ safe to delete. Export first with `auxly export` if unsure.
If the machine is wired to an agent, un-wire it first (removes the MCP launcher + `/auxly-*` skills) while the binary still exists:
```bash
auxly connect disconnect <name> --purge # <name> = the saved profile, see `auxly connect list`
```
### macOS & Linux
```bash
# Remove the keep-alive service if you were a memory HOST (no-op otherwise)
auxly host down 2>/dev/null || true
# macOS launchd leftover:
rm -f ~/Library/LaunchAgents/io.auxly.host.plist
# Linux systemd-user leftover:
systemctl --user disable --now auxly-host.service 2>/dev/null || true
rm -f ~/.config/systemd/user/auxly-host.service
# Remove the binary (whichever path it installed to)
sudo rm -f /usr/local/bin/auxly
rm -f ~/.local/bin/auxly
# Remove local data/config (see vault warning above)
rm -rf ~/.auxly
```
### Windows (PowerShell)
```powershell
# Un-wire agent + skills, then remove host keep-alive task (no-op on a consumer box)
auxly connect disconnect <name> --purge 2>$null
schtasks /End /TN "Auxly-Host" 2>$null; schtasks /Delete /TN "Auxly-Host" /F 2>$null
# Delete the binary + per-user install dir
$dir = Join-Path $env:LOCALAPPDATA 'Programs\auxly'
Remove-Item -Recurse -Force $dir -ErrorAction SilentlyContinue
# Strip it from your per-user PATH
$p = [Environment]::GetEnvironmentVariable('Path','User')
[Environment]::SetEnvironmentVariable('Path', (($p -split ';' | Where-Object { $_ -and $_ -ne $dir }) -join ';'), 'User')
# Delete local data/config (see vault warning above)
Remove-Item -Recurse -Force "$env:USERPROFILE\.auxly" -ErrorAction SilentlyContinue
```
### Homebrew
```bash
brew uninstall auxly
rm -rf ~/.auxly # data is not removed by brew (see vault warning above)
```
After uninstalling, **restart your terminal and any AI agent** so the dropped MCP launcher and PATH change take effect.
---
## Quick start
Auxly is built around **one command** โ just run `auxly`:
```bash
auxly
```
- **First run** walks you through a short setup wizard and creates your memory vault.
- **Every run after that** opens the full-screen **dashboard**.
That's the whole entry point โ there's no separate "init" or "ui" step to remember (those exist as explicit aliases, but you never need them).
Next, connect your AI agents to the shared memory:
```bash
auxly setup
```
This detects every AI agent installed on your machine (Claude, Codex, Gemini, Cursor, Antigravity, โฆ) and wires each one to Auxly via MCP โ plus installs the `/auxly-*` slash commands. No manual config editing.
Now, inside any connected agent's chat, start teaching it:
```
/auxly-init # scans the conversation and seeds your memory
/auxly-sync I prefer pnpm and deploy on Vercel
/auxly-memory # shows the profile every agent now shares
```
From here on, save one thing with `/auxly-sync <topic>` or harvest a whole session with `/auxly-max` โ and every other agent picks it up automatically. Agents save the odd fact on their own now and then, but to keep your usage light they're **not** aggressive about it โ so run these yourself whenever you want to be sure (see [Keeping your memory in sync](#keeping-your-memory-in-sync--run-these-yourself)).
---
## The memory vault
Your memory lives in `~/.auxly/memory/` as human-readable Markdown, organized by topic. Smart sync files each new fact under the right category โ the agent picks the best-fit category from the taxonomy, with a keyword router as fallback when it's unsure:
```
~/.auxly/memory/
โโโ identity.md # who you are, role, expertise
โโโ personal.md # private life facts (family, health, finances) โ never shared to a remote unless you grant it
โโโ preferences.md # how you like your agents to work
โโโ infra.md # machines, networks, environments
โโโ products.md # products & services you build
โโโ projects.md # active work, goals, constraints
โโโ business.md # business / organizational context
โโโ daily.md # recent, time-bound notes
โโโ agents.md # registry of connected agents
โโโ CLAUDE.md ยท CODEX.md ยท GEMINI.md ยท โฆ # per-agent instruction files
โโโ trust.yaml # per-provider access control
โโโ git.yaml # Git sync configuration
โโโ .audit.log # append-only audit trail (JSON Lines)
โโโ audit.db # SQLite index of the audit log
โโโ .pending/ # writes awaiting your approval
```
Edit any of these by hand at any time โ Auxly treats the files as the source of truth.
---
## Memory insights & review
Auxly makes memory visible and self-maintaining โ the vault tracks which facts agents actually use (hashes only, never query text), ages out stale facts through a human-approved review queue, and flags cross-file contradictions.
### `auxly stats --recall`
```bash
auxly stats --recall
```
- **Per-file hit tables** โ recall counts over the last 7/30/90 days, broken down file by file.
- **Dead files** โ files with zero recall hits, the first candidates for pruning.
- **Hot facts** โ the individual facts pulled into context most often.
- **Fallback rate** โ how often recall falls back to keyword search instead of embeddings, a quick read on embeddings health.
Only fact **hashes** are stored in `audit.db` โ never the query text โ so a recalled secret can never leak into analytics.
### `auxly review`
`auxly review` surfaces facts that are both old and unrecalled โ untouched for 90 days by default, tunable with `AUXLY_REVIEW_AGE_DAYS`.
```bash
auxly review # walk the queue interactively, fact by fact
auxly review --keep-all # re-stamp every flagged fact and move on
auxly review --archive-all # archive every flagged fact
```
- **Keep** re-stamps the fact's date via a first-seen ledger (consolidation rewrites do not reset fact age), so it won't come up for review again until it's stale once more.
- **Archive** moves the fact into `.archive/` โ never deleted, still plain text, still greppable.
- `personal.md` is excluded by default; pass `--include-personal` to include it too.
- Same queue lives in the dashboard's **Review** tab (`-`) โ `K` keeps, `a` archives. All actions are audit-logged.
### `auxly organize --contradictions`
`auxly organize --contradictions` embeds your facts and pairs up suspiciously-similar ones across files, then has an LLM judge each pair as a contradiction, duplicate, or distinct. Resolutions land in the normal pending queue tagged with the model's reason โ **review them first with `auxly pending`, then `auxly approve <name>` to see each diff**. Bulk `auxly approve --agent organize-contradictions` applies every queued resolution **without a preview**, so only run it after you've reviewed. The pass needs an embeddings provider configured to run. When contradicted, facts are superseded with a dated trace and never erased.
### Memory Browser (`=`)
The full vault can be browsed and edited directly inside the TUI's Memory tab by pressing `=`. Every edit or deletion flows through the pending queue for verification, and duplicate-content deletions are rejected.
### Recall Playground (`?`)
Press `?` in the TUI's Memory tab to launch the recall playground. Run any query through the real recall pipeline with visual score bars, floor cuts, and press `Tab` to cycle through client provider ACL lenses to see exactly what each connected client is permitted to view. Experimental queries in the playground never pollute analytics.
### Trust Auto-Tuning (`auxly trust suggest`)
Approve/reject decisions accumulate as evidence. The `auxly trust suggest` command (also surfaced in `auxly doctor` and TUI settings) proposes promoting agents to `auto` (when at least 50 writes have been decided and at least 95% approved) or demoting them to `read_only` (when 30% or more are rejected). You can opt out via setting `tuning: off` in config.
Everything above is read-only until a human approves it โ analytics never mutate the vault.
---
## Trust & access control
You decide what each provider is allowed to do. Trust levels live in `trust.yaml`:
| Level | Behavior |
|-------|----------|
| `auto` | Writes land in memory immediately |
| `require_approval` | Writes queue in `.pending/` for you to review and approve/reject |
| `read_only` | Provider can read but never write |
```bash
auxly trust list # show current levels
auxly trust set claude auto # trust Claude to write directly
auxly trust set codex require_approval # review Codex's writes first
auxly trust set copilot read_only # let Copilot read but not write
```
Pending writes show up as reviewable diffs in the dashboard's **Approvals** tab โ approve or reject with a keystroke.
---
## Skills (slash commands)
`auxly setup` installs **10 slash commands** into every agent it configures. They work natively inside the agent's chat:
| Skill | What it does |
|-------|--------------|
| `/auxly-init` | Onboards you โ runs the training, scans the current conversation/context, and seeds your memory with what's already known. |
| `/auxly-sync` `<fact>` | Saves a new fact, preference, or detail with a smart delta-merge โ the agent files it under the best-fit category (with a keyword router as fallback). |
| `/auxly-memory` | Prints the consolidated profile (identity + preferences + infrastructure) every agent currently shares. |
| `/auxly-learn` `[folder] [topic]` | Reads the memory vault โ optionally a single folder, optionally focused on a topic โ and grounds the agent in it for the session. No args = learn everything. |
| `/auxly-max` | Exhaustive self-harvest โ scans the whole session and writes every fact up into the vault, one category at a time (private facts go to `personal.md`). Push-only. |
| `/auxly-forget` `[query]` | Searches memory and cleanly prunes obsolete or outdated lines. |
| `/auxly-pending` `[list]` | Lists the approval queue. Approving/rejecting is **human-only** โ use the dashboard's **Approvals** tab or run `auxly approve <id>` / `auxly reject <id>` in your terminal (an agent can't approve its own writes). |
| `/auxly-status` | Shows whether the agent is connected and the MCP link is live, plus diagnostics. |
| `/auxly-bootstrap` | Generates a copyable onboarding block to paste into a tool that doesn't have Auxly installed (e.g. ChatGPT). |
| `/auxly-remote-connect` | Detects and connects this machine to a remote Auxly memory host (or reports the active link). |
Under the hood these map to MCP tools (`auxly_skill_sync`, `auxly_memory_read`, `auxly_memory_write`, `auxly_memory_search`, `auxly_memory_recall`, `auxly_pending_list`, โฆ) that any MCP client can call directly. `auxly_memory_recall` is the semantic search tool โ call it directly from any MCP client for meaning-based lookup without running a skill.
### Keeping your memory in sync โ run these yourself
By design, Auxly's agents are **lightly** nudged to keep memory updated โ never aggressively. An agent may save something on its own **from time to time** when it notices a clearly important fact, but it deliberately won't mine every message in the background, because constant background syncing would steadily **consume your tokens**. Since that occasional auto-sync is **best-effort, not guaranteed**, the reliable way to capture what matters is to run one of these yourself whenever you want to be sure:
- **`/auxly-max`** โ whenever you feel a session produced something worth keeping, run this to harvest the **entire session** into the vault (one category at a time; private facts go to `personal.md`). Best at the end of a working session or before you switch context.
- **`/auxly-sync <topic>`** โ to push **one specific thing** right now โ a decision, a preference, a config value, a fact โ without harvesting everything. The agent files it under the best-fit category automatically.
> **Rule of thumb:** `/auxly-max` = "save the whole session," `/auxly-sync <topic>` = "save just this." Both are push-only and safe to run as often as you like.
A more thorough, **guaranteed** token-aware auto-capture that works across **every** connected agent โ not just Claude โ is on the roadmap. Until then, the occasional self-sync stays light to protect your usage, and these two commands are the reliable way to keep your memory current.
---
## Supported agents
`auxly setup` auto-detects what you have installed and writes the MCP configuration for each โ no manual JSON editing:
| Agent | Integration |
|-------|-------------|
| **Claude Desktop** | MCP server entry (+ importable skills โ see [Setup guide](#setup-guide)) |
| **Claude Code** (CLI) | `claude mcp add` + skills |
| **Codex** (IDE & CLI) | MCP + `codex mcp add` |
| **Cursor** (IDE & Agent CLI) | MCP + auto-approved tool allowlist |
| **Gemini CLI** | MCP server entry + skills |
| **Antigravity** (CLI / Agent / IDE) | MCP server entries |
| **GitHub Copilot** | shared memory via MCP/skills |
| **Warp** (terminal) | MCP โ `~/.warp/.mcp.json` |
| **Void** (editor) | MCP โ `~/.void-editor/mcp.json` |
| **Windsurf**, **Kimi Code**, **Trae** | MCP + workspace rules |
| **Android Studio** | MCP via the Gemini Agent or JetBrains AI Assistant โ [manual setup](#connect-any-mcp-capable-agent-manual-setup) |
| **Any MCP client / CLI agent** | paste an MCP entry ([manual setup](#connect-any-mcp-capable-agent-manual-setup)) or call `auxly read/write/search` |
For each agent, Auxly also drops a workspace rules file (`.clauderules`, `.cursorrules`, `.geminirules`, โฆ) so the agent knows to keep your memory in sync.
---
## Setup guide
### Automatic setup (recommended)
```bash
auxly setup
```
This detects every supported agent on your machine, writes each one's MCP configuration, installs the `/auxly-*` slash commands, and drops a workspace rules file so the agent keeps your memory in sync. Re-run it any time you install a new agent โ it's idempotent and only updates what's needed.
**Verify a connection** from inside the agent's chat:
```
/auxly-status
```
โฆor just open the dashboard (`auxly`): every connected agent appears on the grid, and its reads/writes show live in the **Activity** tab.
### Claude Desktop skills (one manual step)
Claude Desktop is the **only** agent that needs a manual touch. `auxly setup` wires its **MCP connection** automatically, but Claude Desktop doesn't load skills from disk โ so the `/auxly-*` slash commands have to be **imported once**:
1. **Run `auxly setup`.** It exports the skills to `~/Downloads/auxly-skills-v<version>/` as ready-to-import `.zip` files โ one per skill.
2. Open **Claude Desktop โ Settings โ Capabilities โ Skills** (older builds: **Settings โ Skills**).
3. **Add each `.zip`** from that folder (use *Upload skill* / drag-and-drop). You only do this once.
4. **Restart Claude Desktop** if the new skills don't show up right away.
The export folder is version-stamped (`โฆ-v<version>/`), so when a release updates the skills you'll know to re-import the new set. *(Every other agent โ Claude Code, Codex, Gemini, Cursor, โฆ โ picks up skills automatically; this import step is Claude-Desktop-only.)*
### Connect any other MCP agent
`auxly setup` covers the agents listed above. **Any** other tool that speaks MCP โ Android Studio, Perplexity, a homegrown client โ can share the exact same memory with a one-time copy-paste config. The full walkthrough with the ready-to-paste JSON is at the end of this README:
โ **[Connect any MCP-capable agent (manual setup)](#connect-any-mcp-capable-agent-manual-setup)**
---
## The dashboard
`auxly` opens a **fully interactive terminal UI**. Drive it with the **mouse** โ click tabs, agent cards, files, and buttons, and scroll lists โ *or* the keyboard, whichever you prefer. And everything Auxly does is available **two ways**: as a scriptable **CLI command** (great for automation and muscle memory) *and* as a point-and-click action in the TUI. Same capabilities, your choice of interface.
The TUI has ten tabs:
| # | Tab | What you see |
|---|-----|--------------|
| 1 | **Dashboard** | Today's writes, pending approvals, and a live grid of your connected agents |
| 2 | **Activity** | Live audit feed, color-coded by provider, local vs. SSH-remote |
| 3 | **Files** | Browse, view, edit, and download your memory files โ press **`e`** to export the whole vault to `~/Downloads` (also `auxly export`) |
| 4 | **Approvals** | Review pending diffs โ approve or reject |
| 5 | **Memory Org** | On-demand memory organization with a preview-and-confirm review (see below) |
| 6 | **Analytics** | Writes per agent + (opt-in) live usage meters |
| 7 | **Settings** | Trust levels and Live Usage โ plus an **Agents** sub-tab to show/hide which agents appear on the dashboard |
| 8 | **Remote** | Manage memory hosts and connected boxes over SSH |
| 9 | **Skills** | The installed slash commands at a glance |
| 0 | **Audit Trail** | Full, queryable history with a **Type** column and `f` to filter (Memory Org / Writes / Sessions / Approvals) |
The agent grid is **dynamic** โ it shows only the agents detected or active on this machine, so it stays readable whether you run two agents or twenty. Any agent that connects and writes appears automatically (even one wired by hand); hide the ones you don't want to see under **Settings โ Agents**.
**Mouse or keyboard โ your call.** The TUI is fully mouse-aware: click a tab, an agent card, a file, or a button, and scroll through lists. Prefer keys? `1โ9`/`0` jump tabs, `โ/โ` or `j/k` navigate, `Tab`/`[`/`]` cycle, `Enter` opens or confirms, `q` quits โ and `[u]` pops the live usage panel from anywhere. Anything you can do here you can also do from the [command line](#command-reference), and vice-versa.
<div align="center">
<img src="screenshots/audit-trail.png" alt="The Audit Trail tab โ full, queryable history of every memory access" width="820" />
<sub>The <strong>Audit Trail</strong> tab (<code>0</code>): every read and write โ local and SSH-remote โ with a <code>Type</code> filter.</sub>
</div>
### Memory Organization
The **Memory Org** tab (`5`) runs an AI pass that consolidates and re-files your memory vault โ deduplicating facts, moving misplaced lines to the right category, and tidying each file โ **without writing anything until you approve it**.
1. **Pick a provider + model.** Any installed CLI agent (Claude, Codex, Gemini, Cursor, Antigravity) runs headless on your existing subscription โ no API key. Or choose a local/API endpoint (Ollama, OpenAI, Gemini, or any OpenAI-compatible Custom URL, with models auto-fetched). The idle screen shows roughly how many tokens and files will be sent before you launch.
2. **Run.** The model reorganizes a copy of your vault in an isolated, read-only sandbox. Press `esc` any time to cancel the run.
3. **Review every change.** A two-pane before/after diff per file, color-coded by added/removed lines. Approve (`a`), reject (`r`), or edit (`e`) each file; `A` approves all. Approving auto-advances to the next file.
4. **Submit.** Only the files you approved are written. A confirmation screen lists exactly what changed, and every write is recorded in the **Audit Trail** (tagged **Memory Org**) so you have durable history.
**Scope & safety:** organize only ever touches your *user-memory* files. Agent setup/instruction files (`agents.md`, `CLAUDE.md`, `AGENTS.md`, `providers.md`, โฆ) are never read or rewritten. Nothing is saved until you approve, and the agent runs with no tools, an empty working directory, and a scrubbed environment so it can never reach your real vault on its own.
---
## Remote memory over SSH
Run your agents on a server, a NAT'd box, or another laptop while keeping **one** memory host as the source of truth โ over **plain SSH**. There is **no daemon, no open listening port, no auth token, and no custom protocol**. A remote session is literally:
```bash
ssh host auxly mcp-server
```
The agent on the remote machine spawns that over SSH and speaks MCP over stdio; the host serves its memory and audits every access as if it were local. Anything that gives you `ssh host` already gives you Auxly โ bring your own LAN, VPN, bastion, or relay.
### Two roles
```mermaid
flowchart LR
subgraph consumer["CONSUMER box"]
c["your agent runs here<br/>auxly connect …"]:::node
end
subgraph host["MEMORY HOST"]
h["memory lives here<br/>audits every access"]:::node
end
c -->|"ssh host auxly mcp-server"| h
h -.->|"memory over stdio"| c
classDef node fill:#73CBAD,stroke:#A7E6D2,color:#08231B,stroke-width:1px;
style consumer fill:#241F38,stroke:#917FD1,color:#D7D0F2,stroke-width:1px;
style host fill:#241F38,stroke:#84DCFB,color:#BFE9FB,stroke-width:1px;
linkStyle default stroke:#8E7BD0,stroke-width:1.5px;
```
| Role | What it does | Command |
|------|--------------|---------|
| **Memory host** | Serves the shared memory and audits every access | runs `auxly mcp-server` (invoked over SSH) |
| **Consumer box** | Where an agent runs; reaches the host's memory | `auxly connect` |
### Connecting a machine to a host
On the **consumer** box, run the wizard and pick how the two machines reach each other:
```bash
auxly connect # wizard: relay / LAN / VPN / bastion / public
auxly connect list # show configured hosts + connected boxes
auxly connect auto # one-command bootstrap when a host advertises an offer
```
The wizard's steps are **method โ host โ name โ permissions โ connect**. For a **relay** connection (the first option โ serve *this* machine's memory to a NAT'd box), the **permissions** step lets you pick what the box may access per file โ **Off / Read / Read+Write** (`โ/โ` to cycle, `a` all-read, `n` none) โ *before* it connects. Non-personal files default to **Read+Write**; `personal.md` is **Off** with an exposure warning. Consumer methods (LAN/VPN/bastion/public) only read the *remote's* memory, so they skip the permissions step.
`auxly connect auto` also carries your setup onto the new machine: it wires the MCP launcher + skills **and installs the Auxly statusline** for that box's detected agents (idempotent โ a machine with its own statusline is left alone). To keep a remote on the latest release automatically, enable **Auto-Update** in **Settings** (or set `"autoUpdate": true` in `~/.auxly/settings.json`) โ each machine then self-updates in place after a session, so a publish reaches every box without a manual `auxly update`.
Connecting to a host whose auxly is **older** than yours? Add **`--update-remote`** (or set `"updateRemotesOnConnect": true`) and `connect` bumps it **in place over the same SSH** and ensures its statusline โ driven from your already-updated side, so it works even when the remote is too old to self-update. A host serving a **live session is skipped** (it updates on its next idle connect), so a running relay is never interrupted.
**Managing your boxes from the host.** The **Remote** tab shows each connected box's **memory permission** (`read-only` / `read+write` / `read+writeยทNf`) and flags any box running an older auxly with a `โฌ 1.0.10โ1.0.11` badge. Press **`u`** on a box to update it over SSH, or **`B`** on the **Dashboard** to update *every* outdated box at once (live boxes are skipped). When the outdated boxes are all busy, **`f`** force-updates them too (ending their live session). The same is scriptable: `auxly host versions` and `auxly host update <name>|--all [--force]`. To grant write access to your fleet without per-box setup, enable **`"defaultRemoteWrite": true`** โ known boxes (in `clients.yaml`) then default to read+write, while unknown remotes stay read-only and explicit per-file grants still win.
**Push your statusline to the fleet.** When you update a box (or sync from **Settings โ Customizations**, press `s`), its statusline is installed in the **same wrap-vs-replace mode** you use locally. If you run **Live Usage**, the box's **plan-usage line is primed during the sync** (via the box's own `statusline --refresh-usage`) so it renders on the next draw โ even on a box too old to persist the opt-in. The sync manager offers a master **auto-sync** toggle, **per-box** include/exclude, and **sync-now** (all boxes or one at a time).
Auxly is **network-agnostic** and stores **no network credentials** โ you bring the reachability, it rides on top:
| Method | When |
|--------|------|
| **LAN** | Host and box on the same network |
| **VPN** | Your own overlay (Tailscale, WireGuard, โฆ) โ Auxly never configures it |
| **Bastion** | Reach the host through a jump host |
| **Public** | A reachable hostname/IP or custom SSH config entry |
| **Relay** | Serve a NAT'd box through a reverse tunnel you control |
### Serving your memory to NAT'd boxes (relay)
If a box can't reach your machine directly (it's behind NAT), your machine opens an outbound **reverse tunnel** through a relay you both can reach, and the box reaches your memory through it. On the **host**:
```bash
auxly host setup # open the reverse tunnel via a relay; provision the box
auxly host status # every served box + its live tunnel state
auxly host clients # list connected boxes
auxly host down # stop serving
```
**Multiple boxes stay connected at the same time** โ each gets its own independent, self-healing tunnel, supervised by a single keep-alive. Connecting one box never disconnects another.
### One-command pairing
Pairing a consumer machine with a memory host is as simple as generating an invite token on the host and joining from the client. Note that the joiner must already have SSH login access to the host; the invite authorizes the Auxly memory pairing, not OS-level user access.
1. On the **host**, run `auxly host invite` (or press `i` in the TUI's Remote tab). This mints a secure, single-use token pinned to the host's SSH public key, complete with a configurable time-to-live (TTL). You can manage invites with `auxly host invite --list` and `auxly host invite --revoke`.
2. On the **consumer**, run `auxly join <token>` (or `auxly join <token> --host <ip>` if connecting across custom network topologies or VPNs).
The join command connects to the host, verifies the host key pin directly on the connection carrying the secret (utilizing temporary `known_hosts` and `StrictHostKeyChecking=yes` for injection safety), provisions the consumer via the existing self-test path, and atomically burns the invite token on the host. Token fields are strictly validated and shell-quoted as hostile input to prevent exploit vectors.
### Choose what each box can see
A remote never gets your whole vault by default โ every served box carries its **own** per-remote file-sharing allow-list. You set it at connect time in the relay wizard's **permissions** step, and you can change it anytime: in the dashboard's **Remote** tab, highlight a connected box and press **`s`** to open its **Share files** checklist (listed in taxonomy order), then toggle individual files and set **Off / Read / Read+Write** for that box specifically.
It's **fail-closed for what matters**: `personal.md` (and the aggregate profile) are **never** shared unless you explicitly turn them on, and an **unmatched/unknown remote is never granted write**. So a trusted laptop can be a full read+write peer while a CI box sees only `projects.md` read-only โ and your private life facts stay on your machine.
### See where writes come from
Sessions opened from a remote machine appear in the **Activity** and **Audit Trail** tabs tagged **SSH-remote**, annotated with the connecting client's **IP** and **OS** โ so you always know which writes came from a remote agent versus a local one. `auxly connect` also runs an OS-aware doctor that installs `auxly` on a macOS/Linux host automatically (and prints guided steps on Windows), so linking a new machine is usually a single command.
---
## Live Usage
Auxly can show each agent's **live subscription quota** โ session and weekly usage โ right in the dashboard, by reusing each agent's own locally-stored login token. It reads:
- **Claude** / **Claude Code**, **Codex (ChatGPT)** โ session & week %, plus plan/tier
- **Gemini**, **Antigravity** โ overall quota %
- **Cursor** โ local AI-code activity (no network call)
This is the **only** feature that makes outbound network calls, it is **off by default**, and you enable it in **Settings**. Tokens are never logged, cached, or forwarded; each provider is called only for its own usage. Antigravity needs a one-time login:
```bash
auxly usage show # print quota for every agent
auxly usage auth antigravity # one-time browser consent for Antigravity
```
<div align="center">
<img src="screenshots/agent-usage.png" alt="Live Usage โ session and weekly quota for Claude, Codex, Gemini, Antigravity, and Cursor side by side" width="820" />
<sub>Session and weekly quota for every connected agent, reusing each one's own login โ no API key.</sub>
</div>
---
## Statusline (Claude Code ยท Cursor ยท Antigravity)
Auxly ships a productized statusline for **Claude Code, Cursor CLI, and Antigravity CLI** โ a rich, multi-line status bar that surfaces your working context, your memory link, and your live plan usage without leaving the editor. Wire it into one agent or all of them (additive and fully reversible โ each agent's existing statusline, even a hand-rolled `statusline.sh`, is backed up and restored on uninstall):
```bash
auxly statusline install # Claude Code (default)
auxly statusline install --agent cursor # Cursor CLI
auxly statusline install --agent antigravity # Antigravity CLI
auxly statusline install --agent all # every detected agent at once
auxly statusline install --wrap # keep your own statusline and append the Auxly segment
auxly statusline uninstall --agent <name> # restore that agent's backed-up original
```
It renders four lines: **where** (folder ยท branch ยท model ยท version), **session** (thinking/params ยท effort ยท tokens ยท context bar), **Auxly memory** (link ยท role ยท last op ยท pending), and **live plan usage for whichever agent renders it** โ Claude's 5h + weekly bars, Cursor's plan/auto, or Antigravity's overall, each with reset countdowns. Each provider reads **only its own usage cache**, so one agent's numbers never bleed into another's line.
The render path **never makes a network call** โ it reads only the last-good usage snapshot on disk, so it's safe to run on every prompt. When Live Usage is enabled, the usage line stays **live** during an active session: after printing instantly it triggers a guarded, detached background refresh that updates the snapshot for the next render (debounced, and rate-limited by the same circuit breaker as the dashboard). You can also manage it in the dashboard under **Settings โ Customizations**, where an agent switcher (`a` to cycle) gives each agent its own replace/wrap/none choice with a live preview before you apply; applying one auto-advances to the next agent, and an agent already running Auxly offers **Restore my original statusline** from the backup.
Each agent is wired in its own config file, and the installed command carries a `--provider` flag so the right plan usage shows:
| Agent | Config file wired |
|-------|-------------------|
| Claude Code | `~/.claude/settings.json` |
| Cursor CLI | `~/.cursor/cli-config.json` |
| Antigravity CLI | `~/.gemini/antigravity-cli/settings.json` |
> Agents without a scriptable statusline (Codex, Gemini CLI) aren't wired โ your memory still works everywhere.
<div align="center">
<img src="screenshots/statusline.png" alt="Settings โ Customizations โ per-agent statusline picker with a live preview" width="820" />
<sub>Settings โ Customizations: switch agents (Claude ยท Cursor ยท Antigravity) and pick each one's statusline mode with a live preview before applying.</sub>
</div>
---
## Auto-capture (opt-in)
Let sessions teach your memory without lifting a finger. `auxly capture`
extracts durable facts from a session transcript with your configured LLM,
dedups them against the vault, and queues them as **pending changes** โ it
never writes memory directly, so you review everything with `auxly pending`.
```bash
auxly hooks install # Claude Code: adds a Stop hook running `auxly capture`
auxly hooks uninstall # removes exactly that hook, touching nothing else
```
Throttled by design: sessions under ~2K tokens are skipped, at most one
capture per 10 minutes, at most 10 facts per run.
Every agent, one command:
| Agent | Install |
|-------|---------|
| Claude Code | `auxly hooks install` |
| Codex CLI | `auxly hooks install --agent codex` |
| Gemini CLI | `auxly hooks install --agent gemini` |
| Kimi CLI | `auxly hooks install --agent kimi` |
`auxly hooks status` shows what's actually wired right now, agent by agent.
Honest caveat: Gemini and Kimi have no session-end hook, so their wrappers
capture raw terminal output via `script`, not a structured transcript โ still
enough signal to extract durable facts from. Codex capture reads conversation
messages only โ function calls, tool output, and reasoning traces are
filtered out before anything reaches the extraction LLM.
---
## Git sync
Your memory is a folder โ so version it. Auxly auto-commits on write and pushes only when you ask:
```bash
auxly sync # commit + push to your configured remote
```
```yaml
# git.yaml
auto_commit: true
auto_push: false
commit_message_prefix: "auxly:"
branch: main
```
---
## Connect any MCP-capable agent (manual setup)
Auxly is a standard **stdio MCP server**, so *any* MCP-capable tool can share the same memory โ even ones Auxly doesn't auto-detect, or whose config lives somewhere `auxly setup` can't write (Android Studio's Gemini settings sync to your Google account, for example). It's the same three pieces everywhere.
**1. Add the server entry** wherever your agent keeps MCP servers โ its config file, or an "Add MCP server" dialog:
```json
{
"mcpServers": {
"auxly-memory": {
"command": "/absolute/path/to/auxly",
"args": ["--path", "/Users/you/.auxly/memory", "mcp-server"],
"env": {
"AUXLY_MEMORY_PATH": "/Users/you/.auxly/memory",
"AUXLY_PROVIDER": "your-agent-id"
}
}
}
}
```
**2. Fill in the three values:**
| Field | What to put | How to find it |
|-------|-------------|----------------|
| `command` | Absolute path to the `auxly` binary | `which auxly` โ e.g. `/usr/local/bin/auxly` |
| `--path` / `AUXLY_MEMORY_PATH` | Your vault folder | Default `~/.auxly/memory` (use the full absolute path) |
| `AUXLY_PROVIDER` | A short, unique id for *this* agent | e.g. `perplexity`, `android-studio` โ this is how the audit trail and dashboard label its writes, so **never reuse another agent's id** or its writes get mislabeled |
**3. Reload the agent.** Some clients pick the server up instantly; others need a restart or a one-time "approve this server" before the tools go live.
**4. Verify.** From the agent's chat run `/auxly-status` (if it has skills), or just open `auxly` โ the moment the agent connects and writes, it appears on the dashboard grid, is labeled by its `AUXLY_PROVIDER` id in the **Audit Trail**, and can be hidden or re-shown under **Settings โ Agents**.
> **Schema variations:** most clients use the `{ "mcpServers": { โฆ } }` wrapper above (Claude Desktop, Warp, Void, Cursor, JetBrains AI Assistant, โฆ). A few accept only the inner `{ "auxly-memory": { โฆ } }` object โ if the wrapped form is rejected, paste just the inner block. On Windows, use a full path with escaped backslashes (`"C:\\Users\\you\\auxly.exe"`) or a forward-slash path.
>
> **App-specific entry points:** Android Studio โ the Gemini **"Configure MCP servers"** dialog, or **JetBrains AI Assistant โ Settings โ MCP** (which can also *Import from Claude* once you've run `auxly setup`). Perplexity and most desktop clients โ their **Settings โ Connectors / MCP** panel.
---
## Command reference
| Command | Description |
|---------|-------------|
| `auxly` | First run: setup wizard. After that: open the dashboard. |
| `auxly setup` | Detect and wire every local agent (MCP + skills) |
| `auxly list` / `view <file>` | List or view memory files |
| `auxly search <query>` | Search across all memory |
| `auxly write โฆ` | Write a change (used by agents/wrappers) |
| `auxly pending` | List queued memory changes awaiting approval |
| `auxly approve \| reject <id>` | Apply or discard a pending change (`--all`, `--agent <name>`, `--file <target>` for bulk) |
| `auxly review` | Walk the review queue interactively to prune or restamp stale facts |
| `auxly organize` | LLM consolidation of the vault (`--split-projects` migrates project files; `--contradictions` runs embeddings-based sweep) |
| `auxly organize --contradictions` | Spot similar pairs using embeddings, resolve duplicates/clashes via LLM, queue for pending review |
| `auxly capture` | Extract durable facts from a session transcript into the pending queue |
| `auxly hooks install \| uninstall \| status` | Wire/unwire auto-capture (`--agent claude\|codex\|gemini\|kimi`); status shows what's wired |
| `auxly doctor` | One-screen health check (vault, agents, remote links, host topology) |
| `auxly trust list \| set <provider> <level>` | Manage access control |
| `auxly trust suggest` | Propose trust level promotions or demotions based on approval stats |
| `auxly tail` | Stream the audit log |
| `auxly stats` | Memory & recall statistics (`stats --recall` for hit statistics) |
| `auxly sync` | Commit + push memory to Git |
| `auxly connect โฆ` | Link this machine to a remote memory host |
| `auxly host โฆ` | Serve this machine's memory to other boxes |
| `auxly host invite` | Mint a single-use token pinned to host SSH key for one-command pairing |
| `auxly join <token>` | Pair with an inviting memory host securely (`--host` and `--port` optional) |
| `auxly usage show \| auth` | Live agent quota (opt-in) |
| `auxly index rebuild` | Wipe and rebuild the semantic recall index from the vault |
| `auxly index status` | Show semantic index stats (provider, model, chunk count) |
| `auxly encrypt init \| file <name> \| status` | Manage vault encryption-at-rest (age) โ generate the key, encrypt one file, or show key reachability |
| `auxly decrypt file <name>` | Remove encryption-at-rest from one file (asks for confirmation) |
| `auxly mcp-server` | Run the MCP server (invoked by agents) |
| `auxly update` | Self-update to the latest release |
---
## Configuration
Auxly is config-light: it works with zero setup, and everything it *does* persist lives under `~/.auxly/` as plain text you can read, edit, and version.
### Config files
All optional โ Auxly creates and manages these for you; edit them by hand any time.
| File | What it controls |
|------|------------------|
| `~/.auxly/memory/trust.yaml` | Per-provider trust levels (`auto` / `require_approval` / `read_only`) โ or use `auxly trust set โฆ` |
| `~/.auxly/memory/git.yaml` | Git sync remote and behavior (see [Git sync](#git-sync)) |
| `~/.auxly/settings.json` | Dashboard preferences: `liveUsage` + `autoUpdate` opt-ins (off by default) and `hiddenAgents` โ toggled in **Settings** |
| `~/.claude/settings.json` | Claude Code statusline wiring โ managed by `auxly statusline install/uninstall` |
| `~/.cursor/cli-config.json` | Cursor CLI statusline wiring โ `auxly statusline install --agent cursor` |
| `~/.gemini/antigravity-cli/settings.json` | Antigravity CLI statusline wiring โ `auxly statusline install --agent antigravity` |
### Environment variables
| Variable | Purpose |
|----------|---------|
| `AUXLY_MEMORY_PATH` | Override the memory folder location (default `~/.auxly/memory`) |
| `AUXLY_INSTALL_BASE` | Override the download/update base (default `https://auxly.io`) |
| `AUXLY_PROVIDER` | Override the provider id for a write |
| `AUXLY_LLM_BASE` | Override the LLM endpoint used by smart sync |
| `AUXLY_EMBED_BASE` | Override the embedding endpoint for semantic recall |
| `AUXLY_EMBED_ALLOW_CLOUD` | Set to `1` to allow a cloud embedding endpoint (off by default) |
Auto-update polls `auxly.io/version` and, when a newer release exists, prints a one-line notice; `auxly update` performs a one-click self-update from the official release channel.
---
## Security & privacy
- **Local-first.** Memory lives only on your machine; nothing is uploaded unless you push to your own Git remote.
- **No telemetry.** Auxly phones home only for version checks and the opt-in Usage feature.
- **Credentials stay put.** Auxly stores no SSH keys, VPN config, or network secrets. Usage tokens are read in place and never persisted or logged.
- **Auditable by design.** Every read and write is recorded with who/what/when/why and reviewable in the dashboard.
- **You hold the keys.** Trust levels and the approval queue mean no agent writes anything you didn't allow.
### Vault encryption at rest
Auxly supports file-level encryption at rest for the memory vault using the `age` X25519 standard. This ensures that Git sync commands can securely ship ciphertext without exposing your secrets, as the keys reside outside the vault.
- **Initialization & Keys:** Run `auxly encrypt init` to generate a key. The key is securely stored in the macOS Keychain (using stdin via `security -i` to avoid command-line argument exposure) or falls back to a `0600` permissions file outside the vault. A backup key is printed once during initialization with a hard warning. Keys cannot be overwritten once set to prevent orphaned ciphertext.
- **Commands:** Manage encryption with `auxly encrypt file <name>`, `auxly decrypt file <name>`, and `auxly encrypt status`. Once encrypted, an `age` header in the file ensures all future writes stay encrypted automatically.
- **Security & Fail-Closed:** The implementation is strictly fail-closed: decryption failures never fall back to treating files as empty, CLI-agent organization commands are refused for encrypted content, backups and archives keep the ciphertext encrypted, and `auxly export` skips encrypted files (with a manifest note) rather than writing plaintext copies. The sqlite recall index is pruned and VACUUMed on encryption; recall commands will report how many encrypted files were excluded from search.
- **v1 Limitations:** While the vault files themselves are encrypted, current workspace copies of memory files and transient diffs in the pending queue (`.pending/`) are handled in plaintext (secured with local `0600` file permissions).
Found a vulnerability? See [SECURITY.md](SECURITY.md) for private disclosure.
---
## Contributing
Contributions are welcome โ see [CONTRIBUTING.md](CONTRIBUTING.md) for the build, test, and PR flow, and our [Code of Conduct](CODE_OF_CONDUCT.md).
```bash
make build && go test -race ./...
```
---
## License
[MIT](LICENSE) ยฉ Tzamun Arabia IT Co.
<div align="center">
<br/>
<sub>Built with care by</sub>
<br/><br/>
<img src="assets/brand/tzamun-banner.png" alt="Tzamun Arabia IT Co." width="200" />
<br/><br/>
<sub><a href="https://auxly.io">auxly.io</a> ยท your memory, every agent, on your machine</sub>
</div>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessUnresponsive