Sign inSign up

tessaridb/agent-memory

By tessaridb

•Updated 8 days ago

Memory and coordination for AI agents, with TessariDB inside. Connect by URL over MCP.

Image
Machine learning & AI
0

2.3K

tessaridb/agent-memory repository overview

TessariDB Agent Memory

⁠TessariDB Agent Memory

Memory and coordination for a fleet of AI agents — goals and the evidence behind them, plans, tasks and claims, checklists, decisions, and what each agent learned — as queryable records instead of files. The database it keeps them in, TessariDB⁠, is inside the same image.

An agent connects by URL, like any remote MCP server. The first time it needs to, it opens your browser, you sign in, and from then on every agent on the machine works under that sign-in and renews it by itself.

What it does beyond keeping records:

  • Recall by words and meaning at once — a memory keeps the vector it arrived with, and a search with text and a vector is ranked by both in one database read, each hit saying which of the two found it.

  • An answer cache — keep a model's answer for as long as you say, reuse it only above a similarity you name, and get it back marked as reused.

  • Replay — keep a witness of a recall and later see each hit as it was when the agent read it, beside what it says now.

  • Teams — a team names people and agents, a grant may name a team, a memory may be kept private or for one team, and one team reads another's facts only through a grant that ends.

  • Clean by default — credentials are redacted before anything is stored, a repeat re-confirms the memory it repeats instead of adding a copy, and a fact knows when its evidence was withdrawn.

  • Site — https://tessaridb.com⁠

  • Documentation — https://docs.tessaridb.com⁠


⁠Start one

Choose the first owner's passphrase — it is what you type in the browser when an agent asks to be authorized — then start the container:

mkdir -m 700 -p ~/.tessaridb
read -rs "p?Passphrase for the first owner: " && printf '%s\n' "$p" > ~/.tessaridb/owner-passphrase; unset p
chmod 644 ~/.tessaridb/owner-passphrase

docker run -d --name agent-memory --restart unless-stopped --stop-timeout 30 \
  -p 127.0.0.1:39142:39142 \
  -v tessaridb-agent-memory:/var/lib/tessaridb \
  -v ~/.tessaridb/owner-passphrase:/run/secrets/owner-passphrase:ro \
  -e TESSARI_AM_OWNER=ada -e TESSARI_AM_OWNER_IDENTITY=acme \
  -e TESSARI_AM_OWNER_PASSPHRASE_FILE=/run/secrets/owner-passphrase \
  tessaridb/agent-memory

(read -rs "p?…" is zsh; in bash it is read -rsp "…" p.) --stop-timeout 30 gives docker stop the time the store needs to close cleanly; Docker's own default is shorter.

⁠Connect Claude Code

With the plugin — it registers this address and carries a skill that says when to use the memory. In Claude Code:

/plugin marketplace add tessaridb/tessaridb-agent-plugins
/plugin install tessaridb-agent-memory@tessaridb

Or register the server yourself:

claude mcp add --transport http -s user --client-id claude-code --callback-port 39143 \
  tessaridb-am http://127.0.0.1:39142/mcp

In Claude Code, /mcp → tessaridb-am → Authenticate opens the browser. Sign in as ada with the passphrase and approve. That is the whole setup:

  • every Claude Code on the machine shares that one sign-in and renews it without asking again — several of them renewing at the same moment share one renewal;
  • each agent opens its own session in the folder it works in; the identity comes from the sign-in and the folder decides the group and the project. The first time a folder is seen, the agent is told to ask you whether it is a group of projects — and which subfolders are its projects — or one project, and every agent after it lands there without asking;
  • several agents can work on one project at once — each has its own session, and a task one of them claims is not handed to another.

⁠Connect Codex

The same plugin installs in Codex, from the same marketplace; then sign in once:

codex plugin marketplace add tessaridb/tessaridb-agent-plugins
codex plugin add tessaridb-agent-memory@tessaridb
codex mcp login tessaridb-am

The browser returns to 127.0.0.1:39144; sign in as ada and approve. Codex needs 0.3.0-alpha or later, which knows the codex client.

⁠The one thing to get right

The store is never open. A database with no users runs anything for anybody who reaches it, so this image always declares one: the account memory, with a password drawn on the first start and kept in the volume at /var/lib/tessaridb/db-password. Nothing prints it, and this image ships no default credential — one would open every store that pulls it with a password the whole internet knows. Pass TESSARIDB_INITIAL_USER and TESSARIDB_INITIAL_PASSWORD to choose your own; a password without a user is refused rather than started.

The first owner is created once, on an empty store, from TESSARI_AM_OWNER and TESSARI_AM_OWNER_IDENTITY, with the passphrase read from the file. Every later start leaves the owner alone, so the passphrase file can be removed after the first start — the variables are not a way to reset a passphrase. The owner's machine token is printed once to docker logs.

⁠Ports

PortSurfaceWhat speaks it
39142HTTP — MCP at /mcp, OAuth, and the JSON API at /v1Claude Code and any MCP client, curl

Only the memory service is published. The database binds to the container's own loopback; -e TESSARIDB_ADDRESS=0.0.0.0:9080 plus a published 9080 is the deliberate act that exposes it.

There is no TLS. Publish on 127.0.0.1 as above, or terminate TLS in front.

⁠Environment

VariableDefaultWhat it does
TESSARI_AM_OWNERunsetthe first owner's name, created once on an empty store
TESSARI_AM_OWNER_IDENTITYunsetthe identity that owner administers. Both or neither — half is refused
TESSARI_AM_OWNER_PASSPHRASE_FILEunseta file holding that owner's passphrase, for the browser sign-in. A file and never a variable, because variables are readable by docker inspect
TESSARIDB_INITIAL_USERmemorythe database's own account
TESSARIDB_INITIAL_PASSWORDdrawnits password; unset, it is drawn on the first start and kept in the volume
TESSARIDB_ADDRESS127.0.0.1:9080the database's wire protocol, inside the container
TESSARI_AM_HTTP0.0.0.0:39142the memory service's address
TESSARIDB_LOGinfoerror, warn, info, debug or trace

⁠Volumes

/var/lib/tessaridb — the store and the drawn database password, together. Mount the whole directory so the two survive together. The container runs as uid 10001, so a bind mount must be owned by it (chown 10001:10001 ./data); a named volume needs nothing. The passphrase file is mounted read-only and must be readable by that uid.

⁠Health

HEALTHCHECK asks the memory service for its OAuth metadata over HTTP, which needs no credential. It answers only once the database inside is ready and the service has started on top of it.

⁠Stopping

The container holds two processes — the database and the memory service — and stops when either of them stops, because a container that is half up is harder to notice than one that is down. docker stop stops the memory service first and the database second, so the store is closed before the container exits, and a requested stop exits 0. The database first says not ready for five seconds and then finishes what is in flight, so give the stop 30 seconds (--stop-timeout 30, or stop_grace_period: 30s in Compose).

⁠Compose

services:
  agent-memory:
    image: tessaridb/agent-memory:latest
    restart: unless-stopped
    stop_grace_period: 30s
    ports:
      - "127.0.0.1:39142:39142"
    volumes:
      - agent-memory:/var/lib/tessaridb
      - ~/.tessaridb/owner-passphrase:/run/secrets/owner-passphrase:ro
    environment:
      TESSARI_AM_OWNER: ada
      TESSARI_AM_OWNER_IDENTITY: acme
      TESSARI_AM_OWNER_PASSPHRASE_FILE: /run/secrets/owner-passphrase

volumes:
  agent-memory:

⁠Tags

TagWhat it is
latestthe most recent release
0.4.1-alphaTessariDB 0.33.1-beta inside; fix: tessari-am read from the command line works again; no schema change, a store written by 0.4.0-alpha opens as it is
0.4.0-alphaTessariDB 0.33.1-beta inside; teams, private and team memories, write attribution, readable hits with read, credential redaction, repeats re-confirmed, anchors to files, withdrawn evidence; a store written by 0.3.x gets the new tables on first use
0.3.2-alphaTessariDB 0.31.0-beta inside; no schema change, a store written by 0.3.x opens as it is
0.3.1-alphaTessariDB 0.20.1-beta inside; status hands back the last context snapshot with its text, and a repeated session_start on one connection resumes the held session
0.3.0-alphaTessariDB 0.20.1-beta inside; recall ranks memories and facts as one collection, Codex signs in, and a store written by 0.2.x gets the new search on first use
0.2.5-alphaTessariDB 0.19.0-beta inside; no schema change, a store written by 0.2.x opens as it is
0.2.4-alphaTessariDB 0.17.1-beta inside; no schema change, a store written by 0.2.x opens as it is
0.2.3-alphaTessariDB 0.16.0-beta inside; no schema change, a store written by 0.2.x opens as it is
0.2.2-alphaTessariDB 0.11.0-beta inside; docker stop closes the store and exits 0, and MCP results are encoded in one pass
0.2.1-alphaTessariDB 0.11.0-beta inside; the HTTP surface no longer queues requests on one lock, and a node too old for fused recall is refused at opening
0.2.0-alphaTessariDB 0.9.0-beta inside; fused recall, the answer cache, recall replay, and calls about ten times faster
0.1.1-alphathat version, pinned — a session is placed by its folder
0.1.0-alphathe first release

Every tag is a manifest list carrying linux/amd64 and linux/arm64.

⁠Licence

Business Source License 1.1⁠, converting to Apache-2.0 on 2030-09-23. All production use is free, including inside a commercial organisation; the one restriction is providing it to third parties as an agent memory service, which needs a commercial licence — [email protected]⁠.

Tag summary

Content type

Image

Digest

sha256:156a8cdfe…

Size

41.5 MB

Last updated

8 days ago

docker pull tessaridb/agent-memory