Skip to main content

retain-memory

retain-memory is a small command-line tool and MCP server for keeping categorized memories in one local SQLite database. Memories have priorities from 1 (lowest) to 5 (highest) and UTC creation/update timestamps.

Categories are managed through the CLI or web interface. MCP clients can list categories and create, retrieve, update, or delete memories within them.

Category names can form a hierarchy using the Anki-style :: delimiter, for example projects::retain::release. Each part must be non-empty and cannot contain a colon. Categories can also have an optional description explaining what belongs in them. MCP category listings include these descriptions so clients can choose the appropriate leaf.

Installation

Install uv, then install the CLI from PyPI:

uv tool install retain-memory

To install the current source checkout instead:

uv tool install .

No setup is required before the first run. By default, Retain creates its database and settings at $XDG_DATA_HOME/retain/memory.db, or $HOME/.local/share/retain/memory.db when XDG_DATA_HOME is unset.

Set MEMORY_FILE to use a different database location:

export MEMORY_FILE="$HOME/.local/share/retain/memory.db"

CLI

Create and inspect categories:

retain category create projects
retain category list
retain category delete projects
retain category delete projects --force

Category deletion moves the full branch and its memories to the recoverable archive. --force is required to archive a branch that contains memories through the CLI.

Manage memories:

retain memory add projects "Publish the first release" --priority 5
retain memory list projects
retain memory get MEMORY_ID
retain memory update MEMORY_ID --content "Publish version 1.0" --priority 4
retain memory delete MEMORY_ID

Commands that return data print JSON. Category memory lists are ordered by priority descending and creation time descending.

Web interface

Start the local Flask interface with:

retain web

It provides memory and category editing, displays hierarchical categories as trees, and includes settings for the default priority, category size limit, memory word limit, and web host/port. Categories initially allow 100 memories and memories initially allow 500 words. Lowering a limit does not delete existing data. Saved host and port changes take effect on the next start. They can be overridden for one run:

retain web --host 0.0.0.0 --port 8080

MCP Installation

The PyPI package includes the retain-mcp stdio server. An MCP client can launch it without a separate installation through uvx. For clients using the common mcpServers configuration format:

{
  "mcpServers": {
    "retain": {
      "command": "uvx",
      "args": ["--from", "retain-memory", "retain-mcp"],
      "env": {
        "MEMORY_FILE": "/absolute/path/to/memory.db"
      }
    }
  }
}

If the package was installed with uv tool install retain-memory, use "command": "retain-mcp" and omit args. For development from this checkout, use "command": "uv" with "args": ["run", "--directory", "/absolute/path/to/retain", "retain-mcp"].

The MCP server exposes:

  • list_categories
  • create_category
  • update_category
  • delete_category
  • get_memories
  • add_memory
  • update_memory
  • delete_memory

list_categories exposes only leaf categories, and get_memories rejects categories that have subcategories. Reads never implicitly combine a parent with its descendants.

MCP delete_category archives the full category branch and its memories rather than permanently deleting them. Users can restore or permanently delete archive entries in the web UI. Clients such as OpenCode can independently allow, ask, or deny each category tool.

Development

uv sync --all-groups
uv run ruff check .
uv run ruff format --check .
uv run pytest
uv build

Publishing

The retain-memory PyPI project and its trusted publisher are already configured. No PyPI API token is stored in GitHub.

To prepare a release, update the package version and push the release commit:

uv version 0.2.0
git add pyproject.toml uv.lock
git commit -m "Release 0.2.0"
git push origin main

After CI passes, create and push an annotated tag matching the version in pyproject.toml:

git tag -a v0.2.0 -m "Release 0.2.0"
git push origin v0.2.0

The tag triggers publish.yml, which builds and publishes the wheel and source distribution through PyPI trusted publishing. Tags must use the v prefix and match the package version exactly.

Metadata

Release files for retain-memory 0.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for retain-memory 0.5.1
File Size Uploaded Provenance Actions
retain_memory-0.5.1.tar.gz 77.7 kB With provenance Details for retain_memory-0.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for retain-memory 0.5.1
File Interpreter ABI Platform Actions
retain_memory-0.5.1-py3-none-any.whl Python 3 none any Details for retain_memory-0.5.1-py3-none-any.whl

Total release size: 101.5 kB

Release files / retain_memory-0.5.1.tar.gz

Download URL retain_memory-0.5.1.tar.gz
Size 77.7 kB
Tags Source
SHA-256 checksum
How to use checksums
dd87a548462f46e55945dc743e906ff4de81aeff09387aa42a11b8ee2e4705f5
BLAKE2b-256 checksum
How to use checksums
cf7b47e56b8a41c4255c635728e754e25c08ae89b22367dae39fcd8ef232e996
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.

Transparency log

Release files / retain_memory-0.5.1-py3-none-any.whl

Download URL retain_memory-0.5.1-py3-none-any.whl
Size 23.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9265033566a5aabd28090faa0995de97b985f4b9665267389523193fe649c4e8
BLAKE2b-256 checksum
How to use checksums
edc1c269b209140f3c389fcb0839e1010f4ebe1c2febdce5d79373d8f21677a2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.

Transparency log

Security for retain-memory 0.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for retain_memory-0.5.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page