Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 127 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The offline-first terminal client for [agentage](https://agentage.io) Memory.
**One memory. Every AI. Owned by you.** Your memory is plain markdown on your own
disk. Read and write it from the terminal, serve it to Claude / Cursor / any MCP
client on this machine, and sync it to a git remote you control. Everything works
offline; the cloud is optional.
offline; the cloud account is optional.

## Install

Expand All @@ -20,25 +20,55 @@ Requires Node.js >= 22.

## Quickstart

No sign-in required. Register a local vault and start writing:

```bash
agentage vault add notes --local # register a vault at ~/vaults/notes
agentage vault add notes --local # a plain folder at ~/vaults/notes
echo "# My first note" | agentage memory write welcome.md --vault notes
agentage memory list --vault notes
agentage memory search "first" --vault notes
agentage memory search first --vault notes
agentage memory read @notes/welcome.md
```

No sign-in required. Each vault is a plain folder of `.md` files backed by git; every
write commits, so nothing is lost and deletes are recoverable from history.
Each vault is a folder of `.md` files backed by git. Every write commits, so nothing
is lost and deletes are recoverable from history.

Want the same memory on more machines, or reachable by AI beyond this box? Connect an
account (optional, still offline-first):

```bash
agentage setup # browser OAuth 2.1 sign-in
agentage status # version, target, sign-in state, endpoint
```

## Architecture

![Architecture](https://github.com/agentage/cli/raw/master/docs/architecture.svg)

AI clients read and write your memory over MCP: stdio (`agentage mcp`) for a client
you spawn, or the local daemon's HTTP `/mcp` on `127.0.0.1:4243`. The CLI's memory
verbs go through the same daemon, which is the single writer over the vault engine
([`@agentage/memory-core`](https://www.npmjs.com/package/@agentage/memory-core)) and
schedules background sync. Vaults are plain markdown folders on disk, one git repo
per vault. From there they sync out to git remotes you host and, when you sign in, to
your agentage account.

See [`docs/architecture.md`](docs/architecture.md) for a walk-through of the diagram.

## Memory
## Command reference

Run `agentage <command> --help` for the authoritative options. Global flags:
`--no-daemon` runs memory verbs in-process instead of via the daemon, `-V/--version`
prints the version.

### memory

Six offline verbs over your local vaults. Reference a document as `@<vault>/<path>`
or as `<path> --vault <name>`; omit `--vault` to use the default vault. Every verb
accepts `--json` for machine-readable output.

```bash
agentage memory search <query...> # search a vault (git grep); --limit <n>
agentage memory search <query...> # search a vault (git grep); --limit <n> (default 20)
agentage memory read <ref> # print a document
agentage memory write <ref> # create or overwrite (--body <text>, or stdin)
agentage memory edit <ref> # --old/--new (str_replace), or --body (--append)
Expand All @@ -47,88 +77,113 @@ agentage memory delete <ref> # delete (recoverable from git history)
```

`write` reads the body from `--body` or, when omitted (or `--body -`), from stdin;
pass `--frontmatter '<json>'` to set YAML frontmatter. Documents larger than 64 KB
are clamped on read, and the engine refuses to store obvious secrets.
pass `--frontmatter '<json>'` to set YAML frontmatter as a JSON object. `edit` either
replaces an exact, unique substring (`--old`/`--new`, omit `--new` to delete the
match) or replaces the whole body (`--body`, add `--append` to append instead).
Documents larger than 64 KB are clamped on read, and the engine refuses to store
obvious secrets. Errors are friendly: an unknown vault, a missing document, or a
non-unique `--old` match report what went wrong and exit non-zero.

## Connect your AI (MCP)
### vault

`agentage mcp` serves your local vaults to any on-machine AI client over stdio, as
the same frozen six `memory__{search,read,write,edit,list,delete}` tools the cloud
endpoint exposes. Point a client at it by spawning the command:
```bash
agentage vault add <name> # register a vault (account by default)
agentage vault add <name> --local [path] # a local folder (default ~/vaults/<name>)
agentage vault add <name> --git <remote> # synced to an external git remote
agentage vault list # list registered vaults (--json)
agentage vault remove <name> # unregister (files stay on disk)
agentage vault sync [name] # sync now; all vaults, or just one
```

```json
{
"mcpServers": {
"agentage-memory": {
"command": "agentage",
"args": ["mcp"]
}
}
}
`vault add` registers an account vault by default; pass `--local` for a folder that
never leaves this machine, or `--git <remote>` to bind it to a remote you host. For
an account vault, `--path <dir>` sets the local mirror directory.

### setup and status

```bash
agentage setup # browser OAuth 2.1 sign-in (PKCE), then prints status
agentage setup --no-browser # print the sign-in URL instead of opening a browser
agentage setup --reauth # force a fresh sign-in
agentage setup --disconnect # sign out and remove local credentials
agentage status # CLI version, target, sign-in state, endpoint (--json)
```

Drop that into your client's MCP config (for example `~/.cursor/mcp.json`, or via
`claude mcp add`) and the assistant reads and writes the same markdown you do.
No passwords touch the terminal; tokens are stored in `~/.agentage/auth.json`
(mode 0600). `status` also surfaces a passive hint when a newer version is available.

Clients that speak Streamable HTTP can instead use the daemon's endpoint at
`http://127.0.0.1:4243/mcp`. The cloud MCP endpoint, for AI outside this machine, is
`memory.agentage.io/mcp`.
### daemon

## Git sync
```bash
agentage daemon status # pid, uptime, version
agentage daemon start # start it explicitly (idempotent)
agentage daemon stop # stop it
```

Register a vault against an external git remote and the daemon keeps it in sync,
committing and pushing local changes and pulling remote ones on an interval.
### mcp and update

```bash
agentage vault add work --git git@github.com:you/memory.git
agentage vault list
agentage vault sync # sync every git-backed vault now
agentage vault sync work # sync just one
agentage mcp # serve local vaults to on-machine AI over stdio
agentage update # install the latest published version
agentage update --check # report whether an update is available, don't install
```

Conflicts never lose a write: the remote copy is kept alongside yours as
`<file>.conflict.md` for you to reconcile.
## Sync

## The daemon
Two channels keep your markdown in sync, and both are optional.

A small local daemon (loopback only, `127.0.0.1:4243` by default) owns the engine so
vault writes are serialized and git sync runs in the background. It autostarts on the
first memory verb; you rarely touch it directly.
**Git remotes.** Bind a vault to an external remote you host, and the daemon commits
and pushes local changes and pulls remote ones on an interval.

```bash
agentage daemon status # pid, uptime, version, per-vault sync state
agentage daemon start # start it explicitly (idempotent)
agentage daemon stop # stop it
agentage vault add work --git git@github.com:you/memory.git
agentage vault sync work # force a cycle now; progress prints per vault
```

To skip the daemon and run verbs in-process, pass `--no-daemon` or set
`AGENTAGE_NO_DAEMON=1`.
**Account sync.** Sign in with `agentage setup` and your account vaults sync to the
agentage cloud, so the same memory follows you across machines.

## Cloud account
Conflicts never lose a write. When both sides changed the same file, the remote copy
is kept alongside yours as `<file>.conflict.md` for you to reconcile.

Sign in to connect this machine to your agentage account. This is optional; the
memory verbs above work fully offline without it.
## MCP integration

```bash
agentage setup # browser OAuth 2.1 sign-in (PKCE), then prints status
agentage setup --no-browser # print the sign-in URL instead of opening a browser
agentage setup --reauth # force a fresh sign-in
agentage setup --disconnect # sign out and remove local credentials
Any AI client on this machine can read and write your memory through the same frozen
six tools the cloud endpoint exposes: `memory__search`, `memory__read`,
`memory__write`, `memory__edit`, `memory__list`, and `memory__delete`.

agentage status # CLI version, target, sign-in state, endpoint (--json)
**stdio.** `agentage mcp` serves your local vaults over stdio. Point a client at it
by spawning the command:

```json
{
"mcpServers": {
"agentage-memory": {
"command": "agentage",
"args": ["mcp"]
}
}
}
```

No passwords touch the terminal; tokens are stored in `~/.agentage/auth.json`
(mode 0600).
Drop that into your client's MCP config (for example `~/.cursor/mcp.json`, or via
`claude mcp add`) and the assistant reads and writes the same markdown you do.

## Update
**HTTP.** Clients that speak Streamable HTTP can use the daemon's endpoint at
`http://127.0.0.1:4243/mcp`. The cloud MCP endpoint, for AI outside this machine, is
`memory.agentage.io/mcp`.

```bash
agentage update # install the latest published version
agentage update --check # report whether an update is available, don't install
```
## The daemon

`status` also surfaces a passive hint when a newer version is available.
A small local daemon (loopback only, `127.0.0.1:4243` by default) owns the engine so
vault writes are serialized and sync runs in the background. It autostarts on the
first memory verb; you rarely touch it directly. Its API is bound to `127.0.0.1`,
token-guarded, and rejects cross-origin requests, so nothing off the machine can
reach it. If the port is already in use it reports the conflict rather than failing
silently.

To skip the daemon and run verbs in-process, pass `--no-daemon` or set
`AGENTAGE_NO_DAEMON=1`.

## Environment

Expand All @@ -143,8 +198,16 @@ agentage update --check # report whether an update is available, don't in

```bash
npm ci
npm run verify # type-check + lint + format + unit tests + build
npm run build && npm run test:e2e # live e2e (Playwright) against the dev stack
npm run verify # type-check + lint + format:check + unit tests + build
```

End-to-end tests (Playwright) run in tiers. The offline tiers drive the built
`dist/cli.js` in-process and need no network or account; the live tiers exercise the
full OAuth round trip against a running stack.

```bash
npm run build && npm run test:e2e # all e2e tiers
npm run build && npm run test:e2e -- --grep @offline # offline tiers only
```

## License
Expand Down
27 changes: 27 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Architecture

![Architecture](https://github.com/agentage/cli/raw/master/docs/architecture.svg)

The pieces, top to bottom.

- **AI tools** (Claude Code, Cursor, editors) reach your memory over MCP through one
of two entry points:
- **stdio** - a client you spawn with `agentage mcp`.
- **HTTP** - the local daemon's `/mcp` endpoint on `127.0.0.1:4243`.
Both expose the same frozen six tools: `memory__search`, `memory__read`,
`memory__write`, `memory__edit`, `memory__list`, `memory__delete`.
- **agentage CLI** - the `memory`, `vault`, `setup`, `status`, `daemon`, and `mcp`
commands. Memory verbs default to the daemon; `--no-daemon` runs them in-process.
- **Local daemon** (`127.0.0.1:4243`) - the single writer over the vault engine, so
concurrent writes are serialized. It also schedules background sync. The API is
loopback-only and token-guarded.
- **Local vaults** - plain markdown folders on disk, one git repo per vault, backed
by the [`@agentage/memory-core`](https://www.npmjs.com/package/@agentage/memory-core)
engine. Every write commits; deletes are recoverable from history.
- **Sync channels** (both optional):
- **Git remotes** you host - the daemon commits, pushes, and pulls on an interval.
- **Account sync** to the agentage cloud after `agentage setup` (OAuth 2.1 sign-in
at `auth.agentage.io`), so the same memory follows you across machines.

Conflicts never lose a write: when both sides change the same file, the remote copy
is kept alongside yours as `<file>.conflict.md`.
74 changes: 74 additions & 0 deletions docs/architecture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.