Skip to main content
Glama
README.md
# funes

**Durable memory for your AI coding agents.** `funes` indexes your past sessions across Claude
Code, Codex, pi, and Hermes and lets any agent recall the past decisions, rationale, and findings.
Your memory is a dataset you can publish to the Hugging Face Hub — then any machine, teammate, or
agent can recall from it.

![Asking a published memory why funes is append-only; funes recalls the relevant sessions and a coding agent answers, grounded, naming its sources](docs/img/ask.gif)

*Put a question to a memory and borrow a coding agent to answer it: funes recalls the relevant sessions, hands them over, and you get one grounded answer that names the sessions it drew from — nothing installed. Here it reads the public `huggingface/funes-memory` dataset named right in the command.*

## Features at a glance

- **Your agent recalls your past work.** The model spontaneously uses `funes` to recall prior decisions, rationale, and findings mid-task.
- **One memory across your agents.** Index Claude Code, Codex, pi, and Hermes into a single memory;
  recall spans all of them, and every hit shows which agent it came from.
- **Your memory is a Hugging Face dataset.** Publish it to the Hugging Face Hub; a teammate,
  another of your machines — or anyone, if you make it public — recalls from it with one flag.

![A coding agent, mid-task, reaches for funes on its own and recalls from the public huggingface/funes-memory dataset, then answers grounded, naming the session it drew from](docs/img/recall.gif)

*And it happens on its own: with funes added, your agent reaches for `recall` mid-conversation — no command to run. Here it recalls to answer a question about funes's own design, grounded, naming the session it drew from.*

## Get funes

The [installer](scripts/install.sh) detects your platform, downloads the matching prebuilt binary,
verifies its tagged release checksum and version, and puts it on your PATH (`~/.local/bin` by
default):

```bash
curl -fsSL "https://huggingface.co/buckets/huggingface/funes/resolve/install.sh?src=readme" | sh
```

Then add it to your agent:

```bash
funes add claude    # or codex, pi, hermes
```

Another agent? Integrations their authors maintain are listed in
[funes-integrations/COMMUNITY.md](https://github.com/huggingface/funes-integrations/blob/main/COMMUNITY.md),
and `funes add <id> --from …` installs one from wherever it is published.
To build and share your own, start with [Writing an integration](CONTRIBUTING.md#writing-an-integration).

One command onboards you: your agent gets `recall` and `get` as tools, and — for Claude, Codex, and
Hermes — funes builds your first index, installs a hook that keeps it current every turn, and (with a
memory bound) publishes at each session boundary. From here you just work. See
[docs/add.md](docs/add.md) for the agents, memory binding, and what a run does; `funes status` tells
you whether recall is reading your own memory yet.

Tagged binaries and their `SHA256SUMS` manifest are also available in the
[release bucket](https://huggingface.co/buckets/huggingface/funes):

| Platform | Binary |
| --- | --- |
| Linux x86_64 | `funes-x86_64-linux` |
| Linux aarch64 | `funes-aarch64-linux` |
| macOS Apple Silicon | `funes-arm64-apple-darwin` |

The checksum detects corrupt, truncated, or mismatched release downloads. Because the binary and
checksum share the same bucket, it does not authenticate the bucket itself.

Already installed? **`funes update`** replaces the binary in place with the latest build for your
platform (`--force` reinstalls the current one), then brings your agent integrations to their newest
release; `funes status` tells you when a newer release is out. To build it yourself, see
[Building from source](#building-from-source).

funes names itself to the Hub: the User-Agent of its Hugging Face requests carries its version and
an anonymous install id. The id is a random UUID kept in `~/.funes/install-id`, created on the
first run. It derives from nothing (not your hostname, user, hardware, or Hugging Face account) and
only lets the project count installs and active installs, local-only ones included. It goes
nowhere but the Hub. Set `DO_NOT_TRACK=1` or `FUNES_NO_TELEMETRY=1` to leave it out. Deleting the
file starts a new one. The installer's own downloads say only which script revision and platform
they are for.

## Works across your agents (and models)

Your memory isn't tied to one tool. Because Claude Code, Codex, pi, and Hermes all index into a single
memory, you can **switch agents without losing anything** — start a task in Claude Code, pick it up
in Codex next week, and each one recalls the *entire* history, not just its own sessions (every hit
shows which agent it came from). Another agent can join by writing its sessions as
[funes JSONL](docs/funes-jsonl.md) turns files.

Models work the same way. funes runs pinned local embedding and reranking models, but no generative
model of its own: you reason with whatever your agent uses — through **pi**, any local model or one
served through the Hugging Face router. Switch models between sessions and the memory doesn't move.

## Your memory on the Hub

Your local memory is a dataset, and it shares the way one does: publish it to a Hugging Face
**dataset** repo you own and it becomes an artifact on the Hub like any model or dataset — owned by
your account or org, gated by your token, readable by whoever you say. Not just the code of a
project, but the *process* behind it — the decisions, dead ends, and rationale — becomes something
an agent can recall.

Dataset repositories created by funes are **private by default**. Existing repositories retain their
current visibility, and making a funes-created memory public is a deliberate change on the Hub.

Bind your host to a memory, `funes bind <user|org>/funes-memory` or the memory named when you add
an agent, and every agent recalls from it and keeps it current on its own; or run the two commands
directly:

```bash
funes push <user|org>/funes-memory                    # publish your local memory's new chunks
funes recall "..." --memory <user|org>/funes-memory   # read any remote memory for one call
```

That second form is how you read **someone else's** published memory on a topic, without touching
your own setup. Publishing is guarded: funes redacts credentials at index time, and a separate,
always-on gate refuses to push any chunk that still contains a secret. And because a published memory
is just a dataset, you can try recall **right now**, before indexing anything of your own:

```bash
funes recall "why is funes append-only" --memory huggingface/funes-memory
```

And to get an **answer** rather than ranked passages, borrow an agent for one question — nothing
installed:

```bash
funes ask claude "why is funes append-only" --memory huggingface/funes-memory   # or: funes ask codex
```

See [docs/push.md](docs/push.md) for publishing, the secrets gate, selecting what to publish, and
inspecting a memory; [docs/ask.md](docs/ask.md) for grounded answers;
[docs/hub-caching.md](docs/hub-caching.md) for how remote recall caches to local speed.

## Commands

`funes add` wires all of this into your agent; each command is also usable on its own. Browse the
workflow-oriented [documentation index](docs/README.md) for the complete guides.

| Command | Docs |
| --- | --- |
| `funes add <agent> [memory]` / `funes bind <memory>` / `funes remove <agent>` / `funes mcp [memory]` | [docs/add.md](docs/add.md) — supported agents, integration lifecycle, memory binding, generic MCP clients, and hooks |
| `funes index [path]` / `funes compact [memory]` | [docs/index.md](docs/index.md) — build/update the memory and compact it; sources, incremental, flags |
| `funes recall "…"` / `funes get …` | [docs/recall.md](docs/recall.md) — recall passages and drill into them |
| `funes sessions` / `funes sketch …` / `funes scan …` | [docs/sessions.md](docs/sessions.md) — list sessions, digest one, find a literal in one |
| `funes ask <agent> "…"` | [docs/ask.md](docs/ask.md) — borrow an agent for a grounded answer |
| `funes push <memory>` (+ `scrub`, `status`) | [docs/push.md](docs/push.md) — publish and share a memory |
| `funes update` | [installation and updating](#get-funes) — replace the installed binary with a verified release, and update the agent integrations |

The per-turn indexing and session-boundary publishing the hooks run are detailed in
[docs/automation.md](docs/automation.md).

## How it works

`funes add` runs one loop: **index** what you've done, **recall** it when it matters — and index what
you just did, so it's recallable next time. Both halves are one deterministic pipeline: each source
is parsed into a generic turn/block shape, chunked, written to a local Lance dataset, and embedded
with a pinned local model; recall fuses vector + BM25 search, and reranks the pool with a cross-encoder.
Integrations convert each agent's transcripts into the shared [turns format](docs/funes-jsonl.md).
Adding an agent means publishing an [integration](CONTRIBUTING.md#writing-an-integration) of your
own; the indexing and query pipeline already reads that format.

`funes` shapes its output for agents, not people — so to put a question to a memory yourself, borrow
an agent: `funes ask` recalls from the memory and answers grounded in what it finds, installing
nothing. `funes recall` prints the raw ranked passages behind an answer, and `funes get` reassembles
any cited turn in full.

- [docs/index.md](docs/index.md) — sources, progress, and incremental indexing.
- [docs/recall.md](docs/recall.md) — retrieval, drill-down with `get`, and reading a shared memory.
- [docs/sessions.md](docs/sessions.md) — browsing a memory by session: `sessions`, `sketch`, `scan`.
- [docs/ask.md](docs/ask.md) — borrow an agent for a grounded answer, nothing installed.
- [docs/automation.md](docs/automation.md) — the per-turn hooks that keep it all fresh.

## Building from source

Needs a Rust toolchain and **`protoc`** — `lance`'s build scripts compile protobuf at build time
(the finished binary does not need it). Install it one of two ways:

```bash
# System-wide:
sudo apt-get install -y protobuf-compiler   # Debian/Ubuntu
brew install protobuf                        # macOS
```

Then `cargo build --release` (binary at `target/release/funes`); `cargo test` runs the suite. The
integration test downloads the embedder/reranker weights on first run.

Inference (embedding + reranking) runs on a built-in backend — Accelerate on macOS, pure Rust on
Linux — so the default build has no ML runtime dependency and runs on any glibc ≥ 2.35 (Ubuntu
22.04). On macOS 15 or later, indexing embeds and recall reranks on the GPU through Metal, falling
back to the CPU where no GPU starts. An ONNX Runtime backend is available as an opt-in variant:

```bash
cargo build --release --no-default-features --features onnx   # ONNX backend instead
cargo run --release --features onnx --example bench_backends  # A/B both backends
```

## Notes

- **Each memory names its embedding model**, and funes embeds a query with the model of the memory
  it searches. A memory holds one model's vectors: funes indexes into it with that model, and refuses
  to push another model's vectors into it. To change it, rebuild from the transcripts (the memory is a disposable derived
  artifact — the raw text is retained in every row). This is separate from the model you *reason*
  with, which is free to change.
- **Subagent transcripts** (`.../subagents/agent-*.jsonl`) are indexed too.

## Why funes

> *"To think is to forget differences, generalize, make abstractions."*
> — Jorge Luis Borges, *Funes the Memorious*

Why `funes` is built the way it is — and how it compares to other memory tools — is documented in
[docs/RATIONALE.md](docs/RATIONALE.md).

## License

`funes` is licensed under the [Apache License 2.0](LICENSE).

TDQS

A3.9/5.0

Scored across 6 tools

Disambiguation4/5

The tools mostly have distinct roles: recall is semantic search across sessions, scan is literal string search within one session, sessions lists metadata, get reads raw turns, sketch summarizes a session, and status reports health. The only mild overlap is between get and sketch, since both read one session, but the descriptions make their different purposes fairly clear.

Naming Consistency4/5

All tool names are single lowercase words with no mixed casing or underscores, which is a consistent convention. The set mixes verbs (get, recall, scan, sketch) with nouns (sessions, status), so it does not follow a strict verb_noun pattern, but it remains readable and predictable.

Tool Count5/5

Six tools is well within the appropriate range and each tool covers a distinct retrieval or diagnostic operation. There are no obviously redundant tools, and the surface is compact for a memory-retrieval server.

Completeness4/5

The surface covers the core read-only lifecycle for past sessions: enumerate, semantically search, literal scan, read raw turns, summarize a session, and check memory health. Minor gaps could exist around managing multiple memories or write/forget operations, but for a retrieval-focused server the coverage is strong.

Maintenance

ActivityActive
ResponsivenessWithin a week