Skip to main content
Glama

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

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

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.

Related MCP server: agent-history-mcp

Get funes

The installer 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):

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

Then add it to your agent:

funes add claude    # or codex, pi, hermes

Another agent? Integrations their authors maintain are listed in funes-integrations/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.

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 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:

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.

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 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:

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: an always-on gate redacts credentials from what it publishes, and holds back what it can't redact. And because a published memory is just a dataset, you can try recall right now, before indexing anything of your own:

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:

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

See docs/push.md for publishing, the secrets gate, selecting what to publish, and inspecting a memory; docs/ask.md for grounded answers; 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 for the complete guides.

Command

Docs

funes add <agent> [memory] / funes bind <memory> / funes remove <agent> / funes mcp [memory]

docs/add.md — supported agents, integration lifecycle, memory binding, generic MCP clients, and hooks

funes index [path] / funes compact [memory]

docs/index.md — build/update the memory and compact it; sources, incremental, flags

funes recall "…" / funes get …

docs/recall.md — recall passages and drill into them

funes sessions / funes sketch … / funes scan …

docs/sessions.md — list sessions, digest one, find a literal in one

funes ask <agent> "…"

docs/ask.md — borrow an agent for a grounded answer

funes push <memory> (+ scrub, status)

docs/push.md — publish and share a memory

funes update

installation and updating — 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.

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. Adding an agent means publishing 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.

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:

# 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:

cargo build --release --no-default-features --features onnx   # ONNX backend instead
cargo run --release --features onnx --example score_models    # score the built-in backend against it

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.

License

funes is licensed under the Apache License 2.0.

Available Tools

6 tools
getA

Read one session's turns as they were written — whole blocks, splits reassembled, nothing ranked or summarized. Typically the follow-up to a search verb: expand a result into the turns around it. Sessions run to thousands of turns: read the stretch you need, not the session.

Inputs: session_id (required), to, from, memory.

recallA

Semantic search over the user's past AI agent sessions: describe what you are after, get back the verbatim passages — what was decided, tried, measured or investigated. Call it when they refer to earlier work, or when you are about to re-derive something a session may already have settled. Call it too before claiming that something was never built, was dropped, or was never discussed: the code cannot show that, only the sessions can. Ranked top-k, so it gives you a foothold on a topic, not every session touching it. Ranking weighs relevance, not age: for the latest word on a topic, or one stretch of time, bound it with since/until. Each hit is a passage framed by its exchange, the prompt that asked, the assistant's last word on it and the user's reply, so the answer is usually in the reply itself: k is the token cost, candidates the reach, and a pool larger than k is reranked, at seconds of latency that grow with the pool, so the reach can grow without the reading. oneline lists the hits without their passages, to choose what to read.

Inputs: query (required), k, repo, role, +7 more.

scanA

Find every occurrence of a literal string in one session — exhaustive, unranked, in reading order. For when you already know the wording and want where it occurs, rather than what a topic is about. Scope is one session and one spelling: a zero result clears only that.

Inputs: needle (required), session_id (required), to, from, +3 more.

sessionsA

Enumerate a memory's sessions, oldest first. Metadata only — when it started and when its last indexed turn was, harness, repo, turn count, id, and the prompt each opened with, which is the ask a session started from, not what it became. Filter by repo or date to get the session ids the other verbs take; a whole memory can run to thousands of rows.

Inputs: repo, limit, since, until, +2 more.

sketchA

What one session was about, worked on, and ended up at: the passages most distinctive within it, verbatim, always including its opening ask and its last word. Takes a session id; there is no query. Enough to tell the user what a session was, in one call; not a way to find a particular thing in it.

Inputs: session_id (required), to, from, units, +2 more.

statusA

Health and size of a memory: indexed chunks, the languages its sessions are written in, local chunks awaiting embedding, source sessions awaiting indexing, and for a remote this host pushes to what it has yet to push. Call it when a read comes back empty or thinner than expected — it says whether the memory is the problem rather than the call.

Inputs: memory.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 6 tools

    Disambiguation5/5

    Each tool has a distinct retrieval role: semantic recall, literal scan within a session, full-turn get, session sketch, metadata enumeration, and index health. The potential overlaps between recall/scan and get/sketch are explicitly disambiguated by scope and output.

    Naming Consistency3/5

    Names are concise lower-case single words, but they mix verb-style actions (get, recall, scan, sketch) with noun-style resources (status, sessions). The set remains readable, though it does not follow a predictable verb_noun pattern or a single part-of-speech convention.

    Tool Count5/5

    Six tools is well within the ideal range and each maps to a distinct memory operation. None appears redundant, thin, or tacked on.

    Completeness4/5

    The read-only memory surface covers semantic search, literal search, session reading, summarization, enumeration, and health checks. The main gap is no exhaustive cross-session literal search — scan is scoped to one session — though agents can work around it by enumerating sessions and scanning each.

    Maintenance

    ActivityActive
    ResponsivenessUsually handled

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Persistent memory + FTS5 full-text search for Claude Code conversation history. Indexes ~/.claude/projects/ JSONL into SQLite, exposes 10 MCP tools (store/recall/search memories, browse sessions, get summaries) plus prompts. Includes a web UI for visual exploration
      10
      102 npm
      97
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Provides local, agentic semantic recall over Claude Code session history, enabling the agent to search past discussions semantically, expand turns, and grep transcripts.
      5
      13
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Provides local-first, cross-session memory for Claude Code, enabling semantic search across past sessions to retrieve procedures, decisions, or answers without exposing secrets.
      Apache 2.0