Skip to main content

Portable local memory seed for file-reading AI coding agents

Project description

Memory Seed

PyPI Python License: MIT Publish to PyPI

Memory Seed is a portable local memory system for AI coding agents. It plants a small Markdown control plane into a project so agents can recover project purpose, conventions, risks, decisions, and recent work without depending on vendor-hosted memory.

It is built first for solo developers who move between Codex, Claude Code, Gemini CLI, and other file-reading agents. Teams can also use it to standardize local agent memory across repositories without introducing a database or hosted memory service.

Demo

https://github.com/user-attachments/assets/b1c64d9e-4a67-4bc2-a030-d8ba7f17ccfe

â–¶ Watch the 30-second demo if the player above does not load.

Quickstart

From the root of a project where you want local agent memory:

uvx --from memory-seed memory-seed init --dry-run
uvx --from memory-seed memory-seed init

Then ask your coding agent to read AGENTS.md and follow nearest-runtime discovery. The project receives a seeded .memory-seed/ control plane:

.memory-seed/
  agent-rules.md
  project-bootstrap.md
  skills/
  sessions/
  archive/

The first bootstrap pass generates .memory-seed/index.md and .memory-seed/policy.md from local inspection and user answers.

For an existing project that already has Memory Seed:

uvx --from memory-seed memory-seed update --dry-run
uvx --from memory-seed memory-seed update

For agent-native memory search over MCP:

{
  "command": "uvx",
  "args": ["--from", "memory-seed", "memory-seed-mcp", "--stdio"]
}

Validate the search workflow manually:

uvx --from memory-seed memory-seed-mcp-validate "bootstrap mode check"

See It Work

You can validate the local search workflow without configuring an agent client:

uvx --from memory-seed memory-seed-mcp-validate "bootstrap mode check"

Representative output:

# MCP Memory Validation

Query: bootstrap mode check

Top results:
1. .memory-seed/sessions/2026-05-25.md: v2 runtime migration started
   score=...
   heading=2026-05-17 - Bootstrap mode check fix

Fetched top chunk:
Source: .memory-seed/sessions/2026-05-25.md:...
Heading: 2026-05-17 - Bootstrap mode check fix
...

The validator performs the same search-then-fetch flow an MCP-capable agent uses: rank matching memory chunks, fetch the selected chunk by id, and print the exact source text for human review.

Memory Lense

Memory Lense is an optional local browser UI for exploring a project's Memory Seed runtime. It serves read-only search, filters, timeline, graph, and reader/details views from Markdown session files, backed by a rebuildable local SQLite cache outside the repository.

Install the optional web dependencies when you want to use it:

python -m pip install "memory-seed[lense]"
memory-seed lense --cwd . --host 127.0.0.1 --port 8765 --no-open

Without the extra, the memory-seed lense command is still present but prints:

Install with: pip install "memory-seed[lense]"

Why This Exists

AI coding agents are useful, but their project context is fragile. They forget decisions between sessions, vendor memory is not portable, and stuffing full history into prompts wastes context.

Memory Seed keeps the durable memory layer local, inspectable, and boring on purpose:

  • Markdown files live with the project.
  • Tool-specific entry files route into the nearest .memory-seed/ runtime.
  • Generated project memory stays separate from reusable seed files.
  • Session logs capture what changed and why.
  • MCP search lets agents retrieve precise historical context without reading every log.

The result is a lightweight memory workflow you can understand, commit, review, copy, and repair.

Goals

  • Keep project memory local, inspectable, and portable.
  • Support file-reading AI coding agents through predictable Markdown files.
  • Route tool-specific entry files into the nearest .memory-seed/ runtime.
  • Support nested sub-project runtimes with local active state and local skills.
  • Keep policy separate from functional runbooks.
  • Archive reusable control-plane versions while keeping generated project memory outside version archives.

Agent Support

Agent or client Support path
Codex Starts from AGENTS.md; MCP server auto-registered in .codex/config.toml (loads once the project directory is trusted).
Claude Code Starts from CLAUDE.md; MCP server auto-registered via uvx --from memory-seed.
Gemini CLI Starts from GEMINI.md; MCP server auto-registered in .gemini/settings.json.
Cursor Starts from AGENTS.md; MCP server auto-registered in .cursor/mcp.json.
GitHub Copilot CLI starts from AGENTS.md; MCP auto-registered in .github/mcp.json (mcpServers key). VS Code via .vscode/mcp.json (servers key) + a thin .github/copilot-instructions.md router. The coding agent reads AGENTS.md; its MCP is configured in repo/org settings (manual).
Other file-reading agents Start from AGENTS.md and follow nearest .memory-seed/ runtime discovery.
MCP-capable clients Use memory_search and memory_get_chunk through memory-seed-mcp --stdio.

Choosing which agents to install

By default memory-seed init installs files for every supported agent. To keep a repo clean, install only the agents you use:

memory-seed init --agents claude,codex     # only Claude + Codex artifacts
memory-seed init                            # interactive prompt on a terminal; all agents otherwise

AGENTS.md, the .memory-seed/ runtime, and .agents/ personas are always installed (they are agent-agnostic). Only the agent-specific routing files (CLAUDE.md, GEMINI.md, .github/copilot-instructions.md) and per-agent hook/MCP configs are gated by the selection. codex and cursor have no routing file — they read AGENTS.md natively.

The selection is persisted to .memory-seed/project.yaml (agents: list), which doctor and update respect — so an unselected agent's files are never flagged missing or re-added. A project with no project.yaml behaves as before (all agents). Reconfigure later:

memory-seed agents list           # show the selected agents
memory-seed agents add gemini     # install an agent's files
memory-seed agents remove gemini  # back up + remove an agent's files (foreign config preserved)

Agent Hooks

memory-seed init and memory-seed update install lifecycle hooks that keep memory current without relying on the agent to remember. Each hook is merged into the agent's own config file (existing settings are preserved), so it works regardless of which agent opens the project:

Agent Config file Session-log reminder Memory-retrieval reminder Session-start orientation
Claude Code .claude/settings.json Stop UserPromptSubmit SessionStart
Codex CLI .codex/hooks.json Stop UserPromptSubmit SessionStart
Gemini CLI .gemini/settings.json AfterAgent BeforeAgent SessionStart
Cursor .cursor/hooks.json afterAgentResponse sessionStart sessionStart
GitHub Copilot CLI .github/hooks/memory-seed.json — — sessionStart (prompt)

Both reminders are cross-platform Python scripts in .memory-seed/hooks/:

  • session-log-check.py - after a turn, reminds the agent to append a session-log entry if none was written in the last 15 minutes, and warns if the day's entries are out of ascending time order. When a local user is configured, it checks only that user's per-day file (sessions/YYYY-MM-DD/<user>.md) so another contributor's recent entry does not suppress the reminder.
  • memory-retrieval-check.py — before substantive work, reminds the agent to use memory_search for topical recall and to read the newest session file directly for current state. Gated by an 8-hour marker file so it fires about once per working session.
  • session-start-context.py - at session start, injects the newest relevant session file's entries (path, all headings, and the most recent entry body) so the agent establishes current state by recency rather than semantic search. With a configured user it injects that user's newest entry and lists same-day co-contributor files by path and entry count; without a configured user it preserves legacy flat-file behavior. Fires once per session. Copilot CLI cannot run command hooks at session start, so it gets a static prompt hook with the same directive instead.

The hooks nudge; they never block. The scripts use Python 3.11+, which Memory Seed already requires.

Beyond the hooks, the end-of-session routine in agent-rules.md ("End Of Turn") includes a diff-scoped orphan & artifact sweep: before closing a session the agent reviews what it changed, confirms new files/features are actually wired in, resolves references left dangling by deletions or renames, and flags scratch debris — so half-removed features and stray files are caught as they happen rather than accumulating. It is language-agnostic and never installs tooling; a project's own dead-code tool (vulture/ruff, knip, ArchUnit, cppcheck) can be run for deeper whole-codebase checks when one is already present.

The routine also runs a consolidation review (promote durable, reusable facts from the session logs into index.md/policy.md via the memory_consolidation skill) and a baseline-promotion check (flag any approved adaptation general enough to reuse beyond this project, recorded in .memory-seed/plans/). The whole routine ships as a seeded /esr command for the agents with a repo-level command mechanism: Claude (.claude/commands/esr.md) and Gemini (.gemini/commands/esr.toml); Codex, Cursor, and other agents run the same routine directly from agent-rules.md. There is intentionally no blocking end-of-turn hook — evolution needs reasoning and user approval, which a hook cannot do.

Reusable Seed Files

AGENTS.md
CLAUDE.md
GEMINI.md
.claude/commands/esr.md
.gemini/commands/esr.toml
.github/copilot-instructions.md
.memory-seed/
  agent-rules.md
  project-bootstrap.md
  hooks/
    session-log-check.py
    memory-retrieval-check.py
    session-start-context.py
  skills/
    index.md
    agent_collaboration.md
    code_search.md
    copywriter-conversion.md
    data_architecture.md
    document_ingestion.md
    end_of_turn.md
    history_retrieval.md
    local_compilation.md
    memory_consolidation.md
    memory_doctor.md
    memory_hygiene.md
    office_document_editing.md
    release_publishing.md
    security_triage.md
    session_logging.md
    subproject_runtime.md
  sessions/
  archive/

Runtime Files

.memory-seed/
  agent-rules.md
  project-bootstrap.md
  index.md
  policy.md
  hooks/
  skills/
  sessions/
  archive/

Current Version

The current reusable control-plane version is 2.13.

Legacy .AGENTS/ projects remain supported as a fallback during migration.

Skill Trigger Registry

.memory-seed/skills/index.md is the deterministic trigger registry for universal skills. Agents read it during startup, evaluate triggers in listed order, and lazy-load only the full skill runbooks that match the task.

Project and sub-project runtimes may override or disable inherited skills in their generated index.md. Parent skill registries apply only when inheritance is enabled and not locally overridden.

Sub-project runtimes keep detailed logs local. Parent/root memory should receive only brief coordination summaries when sub-project work changes parent-visible topology, shared design, release behavior, policy inheritance, dependencies, risks, or active priorities.

Python CLI

Memory Seed includes a small Python CLI.

Use uvx for one-off execution. It runs Memory Seed in an isolated tool environment, so you do not need a global install and you avoid stale local commands:

uvx --from memory-seed memory-seed doctor
uvx --from memory-seed memory-seed init --dry-run
uvx --from memory-seed memory-seed update --dry-run
uvx --from memory-seed memory-seed compact

Use uv tool install memory-seed when you want Memory Seed installed persistently as a local machine tool with console scripts on PATH:

uv tool install memory-seed
memory-seed doctor
memory-seed-mcp --stdio
memory-seed-mcp-validate "bootstrap mode check"

Use uv add memory-seed only when the current Python project itself depends on Memory Seed as a package:

uv add memory-seed

Use uv pip install memory-seed when installing Memory Seed into the active virtual environment rather than as a standalone tool:

uv pip install memory-seed

For repeatable team or production usage, pin the package version:

uvx --from memory-seed==2.13.0 memory-seed doctor
uvx --from memory-seed==2.13.0 memory-seed update --dry-run

If you are not using uv, install or upgrade the CLI with pip:

python -m pip install --upgrade memory-seed
python -m pip show memory-seed

python -m pip show memory-seed reports the installed Python package version, such as 2.13.0. memory-seed version reports the reusable control-plane version, currently 2.13; it is not the package-version check.

To discover commands and flags, use memory-seed help (also shown when you run memory-seed with no command), memory-seed -h, or memory-seed <command> -h for a specific command.

From this repository checkout, run:

python -m memory_seed.cli version
python -m memory_seed.cli doctor
python -m memory_seed.cli init --dry-run
python -m memory_seed.cli update --dry-run
python -m memory_seed.cli compact

The init command copies only the reusable seed files into the current folder:

AGENTS.md
CLAUDE.md
GEMINI.md
.memory-seed/agent-rules.md
.memory-seed/project-bootstrap.md
.memory-seed/archive/.gitkeep
.memory-seed/hooks/session-log-check.py
.memory-seed/hooks/memory-retrieval-check.py
.memory-seed/hooks/session-start-context.py
.memory-seed/skills/agent_collaboration.md
.memory-seed/skills/index.md
.memory-seed/skills/code_search.md
.memory-seed/skills/copywriter-conversion.md
.memory-seed/skills/security_triage.md
.memory-seed/skills/data_architecture.md
.memory-seed/skills/document_ingestion.md
.memory-seed/skills/end_of_turn.md
.memory-seed/skills/history_retrieval.md
.memory-seed/skills/local_compilation.md
.memory-seed/skills/memory_consolidation.md
.memory-seed/skills/memory_doctor.md
.memory-seed/skills/memory_hygiene.md
.memory-seed/skills/office_document_editing.md
.memory-seed/skills/release_publishing.md
.memory-seed/skills/session_logging.md
.memory-seed/skills/subproject_runtime.md
.memory-seed/sessions/.gitkeep

It creates a minimal .memory-seed/ control plane with reusable procedures, generic skill templates, and empty session/archive anchors. Fresh projects are seeded but not yet bootstrapped. init does not create .memory-seed/index.md or .memory-seed/policy.md; the first agent bootstrap pass generates those files after scanning the project and asking targeted questions. The generated index.md is the rich project-orientation manifest, and policy.md contains behavioral constraints only.

It does not copy MCP server code or Python modules into the target project. Commands such as memory-seed-mcp and memory-seed-mcp-validate run from the installed or uvx package. The target project receives only the Markdown runtime files.

Use --dry-run to preview the files init would copy without changing files. If any reusable seed file already exists, plain init refuses to overwrite it and exits with an error. Use --force only when you intentionally want to back up and replace existing seed files.

When --force creates backups, Memory Seed adds .memory-seed/backups/ to the target project's .gitignore to reduce the chance of committing replaced local memory files. init --force is a reinstall operation: it writes all bundled seed files, including files that were already on the current memory-system-version.

The update command refreshes routing files, reusable runtime procedure files, and generic skill templates by version, sourcing them from the installed package rather than from PyPI — upgrade the package first to get newer templates (see Updating). Before replacing stale reusable control-plane files, it backs them up under .memory-seed/backups/<timestamp>/ and archives their old version under .memory-seed/archive/<old-version>/ or .memory-seed/archive/unknown-<timestamp>/ when the old version is missing. Generated local memory files such as index.md, policy.md, and sessions are preserved.

Use update --dry-run to list the reusable control-plane targets without writing files. Current behavior is conservative but broad: dry-run lists bundled seed paths rather than calculating which files are missing or version-mismatched. The real update command skips files already at the current memory-system-version or newer — so a stale installed tool never downgrades a project — and preserves existing .memory-seed/ runtime files.

The compact command summarises recent session activity from the nearest runtime so an agent can identify durable facts to promote into index.md, policy.md, or skills. It reads both the legacy flat layout (sessions/YYYY-MM-DD.md) and the per-day/per-user layout (sessions/YYYY-MM-DD/<user>.md):

memory-seed compact              # last 7 days (default)
memory-seed compact --days 30    # last 30 days
memory-seed compact --all        # all sessions
memory-seed compact --output summary.md  # write to file

The output is a structured Markdown report with session headings and full entry text. The CLI summarises; the agent (or user) decides what to promote. No files are modified automatically.

To opt into per-user session targets on a clone, configure a local user slug:

memory-seed user set jean
memory-seed user show
memory-seed session target
memory-seed session target --create
memory-seed user clear

The local selection is stored in .memory-seed/local.yaml, which Memory Seed adds to .gitignore. MEMORY_SEED_USER overrides the local file for one shell, and memory-seed session target --user <slug> overrides both. With no configured user, session targets remain the legacy flat file (sessions/YYYY-MM-DD.md). With a configured user, new targets are sessions/YYYY-MM-DD/<user>.md and --create initializes file frontmatter with schema_version: 2, session_date, immutable hash_id, user, and created_at.

To migrate existing flat session files into the per-user layout, add a tracked participant registry to .memory-seed/project.yaml:

participants:
  - slug: jean
    initials: JN
    display_name: Jean

Then preview and apply the migration:

memory-seed migrate sessions-layout --dry-run
memory-seed migrate sessions-layout

The migration parses each legacy sessions/YYYY-MM-DD.md entry, maps its user_initials to a participant slug, appends to sessions/YYYY-MM-DD/<user>.md, preserves existing entry_id values, backs up the flat source under .memory-seed/backups/<timestamp>/sessions/, and removes the flat source after a successful apply so permanent dual-read support does not create duplicate entry IDs. It blocks rather than guessing when initials are missing, unknown, duplicated in the participant registry, or when an existing per-user file already contains an incoming entry_id.

Existing-Project Command Behavior

When run in a project that already has Memory Seed files:

  • memory-seed version prints the bundled reusable control-plane version. It does not inspect the project.
  • memory-seed doctor checks reusable seed files, reports missing files or memory-system-version mismatches, and separately reports incomplete bootstrap when generated index.md or policy.md is missing. It also warns (non-fatally) when a .memory-seed/skills/*.md runbook is not registered in skills/index.md (an orphan skill agents would never load), and when a .memory-seed/ runtime exists but an entry-point file is foreign and carries no routing block (an orphaned runtime nothing points at).
  • memory-seed init --dry-run lists the seed files it would copy and changes nothing, even if those files already exist.
  • memory-seed init refuses to overwrite existing owned seed files unless --force is used. A pre-existing foreign entry-point file (AGENTS.md/CLAUDE.md/GEMINI.md/.github/copilot-instructions.md owned by another tool, i.e. no memory-system-version frontmatter) no longer blocks init — its content is preserved and a routing block is merged in instead.
  • memory-seed init --force backs up and rewrites owned seed files. It still does not overwrite a foreign entry-point file — that is always merged, never clobbered.
  • memory-seed update refreshes stale routing files, reusable runtime procedure files, and generic skill templates; archives replaced control-plane versions; and preserves generated local memory. For a foreign entry-point file it injects (or re-syncs in place) a marker-delimited <!-- BEGIN memory-seed -->…<!-- END memory-seed --> block that routes into .memory-seed/, leaving the host's own content untouched.
  • memory-seed compact reads dated session logs from the nearest .memory-seed/ runtime, including both sessions/YYYY-MM-DD.md and sessions/YYYY-MM-DD/<user>.md, with legacy .AGENTS/ fallback. It prints a Markdown summary and writes only when --output is provided.
  • memory-seed user set/show/clear manages a gitignored local user slug for opt-in per-user session files.
  • memory-seed links check validates session-memory integrity across both layouts: duplicate entry_id/hash_id, dangling related_entries/related_memories (including entry-level related_entries in session-entry YAML), and per-user-file frontmatter problems (filename↔frontmatter user/date mismatch, missing/malformed hash_id, unsupported schema_version). It names the offending file and value and exits non-zero on any issue, so it doubles as a CI gate; doctor surfaces a one-line summary pointing at it.
  • memory-seed migrate sessions-layout [--dry-run] splits legacy flat session files into per-user files using .memory-seed/project.yaml participants, backs up migrated sources, and refuses ambiguous or unsafe merges.
  • memory-seed link suggest [--for <entry_id>] [--top-k N] ranks older session entries to link from a target entry (default: the newest entry), skips the target and its already-linked entries, and prints a copy-pasteable related_entries: snippet. Read-only.
  • memory-seed link show <entry_id> prints an entry's stored outbound related_entries plus its computed inbound backlinks, so the related-entry graph is bidirectional at read time without editing any historical entry. Read-only.
  • memory-seed lense serves the optional local Memory Lense UI when installed with memory-seed[lense]; without the extra it prints the install hint.
  • memory-seed session target [--create] prints the active session log path and can create the file if needed.

Known behavior to understand: update --dry-run currently lists all control-plane targets, not only files that would actually change. init --force intentionally rewrites all bundled seed files and should be used as a reinstall command rather than a targeted refresh.

Updating

Two separate things stay current, and they are not the same operation:

  1. The installed package — the CLI, MCP server, and the seed templates bundled inside it.
  2. Each project's .memory-seed/ files — the seed files copied into a given repository.

memory-seed update copies seed files from the package version currently installed or resolved. It does not fetch from PyPI. So getting newer seed content into a project is a two-step process for persistent installs:

# 1. Upgrade the tool (new code + new bundled seed templates)
uv tool upgrade memory-seed
# or, with pip:
python -m pip install --upgrade memory-seed

# 2. Propagate the new seed files into the project
memory-seed update --dry-run
memory-seed update

With uvx, pin to the latest to force the newest package before updating a project:

uvx --from memory-seed@latest memory-seed update

A bare uvx --from memory-seed memory-seed update may serve a cached package version; use @latest to force the newest, or pin ==X.Y.Z for reproducibility.

For the version distinction (pip show memory-seed reports the package version; memory-seed version reports the control-plane version), see Python CLI.

MCP Memory Search

Memory Seed also includes a lightweight MCP server that lets agents search local session memory through structured tool calls instead of shelling out to broad compact summaries.

Auto-registration: memory-seed init and memory-seed update automatically register uvx --from memory-seed memory-seed-mcp --stdio in each supported vendor's MCP config — .mcp.json at the project root (Claude Code), .cursor/mcp.json (Cursor), .gemini/settings.json (Gemini CLI), and .codex/config.toml (Codex CLI). No manual config is needed for projects initialised with Memory Seed. The uvx --from form is used so the command works regardless of whether ~/.local/bin is on the agent's PATH.

Claude Code reads project-scope MCP servers from .mcp.json, not .claude/settings.json — the latter is for hooks and permissions only. Versions 2.2.0–2.3.0 wrote the server into .claude/settings.json, where Claude Code silently ignored it; memory-seed update now writes .mcp.json and removes the dead entry. Restart Claude Code and approve the project server, then confirm with claude mcp list.

Codex loads a project .codex/config.toml only for trusted directories. Memory Seed writes the [mcp_servers.memory-seed] table there, but Codex ignores it until you trust the project (Codex prompts on first use of a directory, or set trust in Codex settings). After trusting, confirm with codex mcp list. memory-seed doctor warns if Codex hooks are present without this registration. If you hand-wrote the memory-seed entry in a non-standard TOML form (dotted keys, an inline table, or a header with a trailing comment) and it is outdated, memory-seed update will not auto-migrate it — memory-seed doctor flags it as needing a manual fix instead of silently leaving stale settings in place.

If you are configuring the server manually, run it over stdio:

uvx --from memory-seed memory-seed-mcp --stdio

Recommended MCP client command configuration:

{
  "command": "uvx",
  "args": ["--from", "memory-seed", "memory-seed-mcp", "--stdio"]
}

For repeatable team or production usage, pin the package version:

{
  "command": "uvx",
  "args": ["--from", "memory-seed==2.0.0", "memory-seed-mcp", "--stdio"]
}

If you installed Memory Seed globally, use the console script directly:

{
  "command": "memory-seed-mcp",
  "args": ["--stdio"]
}

If the console script is not on PATH, use the module form from the active Python environment:

{
  "command": "python",
  "args": ["-m", "memory_seed.mcp_server", "--stdio"]
}

The server exposes:

memory_search(query, cwd=".", top_k=8, lambda_days=0.01, recency_enabled=true, recency_floor=0.15, semantic_enabled=true, user=null, date_from=null, date_to=null)
memory_get_chunk(chunk_id, cwd=".")

memory_search also accepts granularity="entry" by default or granularity="section" for narrower section-level results. It discovers session entries in both sessions/YYYY-MM-DD.md and sessions/YYYY-MM-DD/<user>.md. Entry granularity returns one coherent chunk per ## session entry and normally uses the entry YAML entry_id as chunk_id, such as ms-db2d715c for legacy entries or mse_0123456789abcdef for new generated entries. Section granularity returns ids such as ms-db2d715c#decisions/d1-use-draft-for-compact-decision-records while preserving the parent entry_id.

memory_search returns JSON with source path, path, session_date, optional per-user user, optional file_hash_id, entry-level related_entries, line range, heading path, score fields, matched fields, matched terms, semantic status, entry metadata, granularity, and an excerpt. The user, date_from, and date_to filters are applied before ranking so top_k is selected from the filtered corpus. This is intended to be both agent-efficient and human-validatable.

The ranking engine stays local and CPU-friendly. MCP search uses a Model2Vec static embedding provider by default with the general-purpose minishlab/potion-base-8M model, combines semantic score with lexical and metadata scoring, then applies recency. If Model2Vec or the model cannot load or score a query, the server falls back to lexical, metadata, and recency ranking without failing the request. Use --no-semantic on memory-seed-mcp --stdio or semantic_enabled=false in memory_search to force fallback behavior.

Performance characteristics

memory_search is a relevance-and-recall tool, not a faster grep. A plain grep will out-scan it on raw exact-match throughput; the search wins instead on semantic recall over session history (surfacing relevant entries that lack the literal query words) and on agent-token efficiency (returning a small ranked set of self-contained chunks with stable chunk_ids, so an agent fetches only the one or two full entries worth reading). The two are complementary: use memory_search for "what did we decide and why," and grep for exact-string scans across the whole repo.

Per-query latency, measured in-process on this repo (81 chunks across the session logs), is roughly 30 ms, of which about 22 ms is reading and parsing the session .md files — the search re-reads and re-parses every discovered session document on each call, with no persistent chunk or vector cache — and the embed + cosine + rank step adds only a few ms on top. Cold start adds a one-time cost on the first ever call on a machine: the Model2Vec weights download into the local HuggingFace cache (tens of MB); afterwards the static model loads in a few ms. Because the static model has no transformer forward pass, the dominant cost is file I/O, so per-query time grows linearly with total session-log size rather than with model complexity.

When driving the server through an MCP client (Claude Code, Cursor, Gemini), the latency you actually perceive is dominated by one-time startup, not per-query work: spawning uvx --from memory-seed memory-seed-mcp resolves and may install the package into an ephemeral environment the first time the server launches in a session. Once the server is up, each memory_search is the ~30 ms compute above plus a small JSON-RPC round-trip. At current log sizes there is no need to optimize; should logs grow large enough that the ~22 ms parse cost becomes noticeable, caching parsed chunks and their vectors keyed by file modification time would remove most of the per-query cost.

Session entries should include a YAML metadata block with entry_id, user_initials, agent_type, project_path, and subproject_path. New generated entry_id values use deterministic 80-bit mse_ IDs encoded as 16 lower-case Base32 characters; legacy ms- IDs remain valid and are not rewritten. Session entry YAML may include entry-level related_entries pointing at either old or new entry IDs. Session entry headings may include optional minute-level timestamps, such as ## 2026-05-19 20:42 - Durable memory consolidation. Legacy session filenames stay date-only; the opt-in per-user layout uses a date directory plus a bare user slug (sessions/YYYY-MM-DD/jean.md). Timestamped headings are backward compatible with older untimed headings and are exposed as entry_datetime in MCP search results when present.

For human-validatable search behavior, see the fixture-style tests in tests/test_mcp_server.py. They assert that specific queries return expected dated session entries first and include enough evidence for manual review.

To manually validate the search-then-fetch workflow without configuring an agent client, run:

uvx --from memory-seed memory-seed-mcp-validate "bootstrap mode check"

or, with a pinned package:

uvx --from memory-seed==2.0.0 memory-seed-mcp-validate "bootstrap mode check"

If installed globally or running from this checkout:

memory-seed-mcp-validate "bootstrap mode check"
python -m memory_seed.mcp_validate "bootstrap mode check"

The validation report shows the ranked search results, then fetches the top result by chunk_id and prints the exact source, heading, and full chunk text.

Ranking behavior should remain stable on main. If you want to experiment with ranking changes, use a separate branch and merge back only when fixture tests show a clear improvement.

For Code Projects

When Memory Seed is planted into a software, library, or API project, agents will use Semble for code search. Semble returns only the relevant code chunks, using ~98% fewer tokens than grep+read.

Install it once, globally:

claude mcp add semble -s user -- uvx --from "semble[mcp]" semble

During bootstrap, the agent adds a Code Search section to the project's AGENTS.md so all future agents, including sub-agents, can call semble search directly. No per-project setup is needed after that.

Public Memory Hygiene

Memory Seed files are plain Markdown and may be committed with a project. Treat .memory-seed files as publishable unless the project is explicitly private.

Do not put secrets, credentials, tokens, private keys, sensitive account details, client confidential information, or unnecessary personal data into generated memory files or session logs.

Publishing

This repository is configured for PyPI trusted publishing from GitHub Actions.

PyPI pending publisher settings should match:

PyPI Project Name: memory-seed
Owner: jnl-tshi
Repository name: memory-seed
Workflow name: publish.yml
Environment name: pypi

The publish workflow lives at .github/workflows/publish.yml. It runs tests, builds the package with uv build, and publishes through PyPI's trusted publisher flow.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

memory_seed-2.16.0.tar.gz (216.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

memory_seed-2.16.0-py3-none-any.whl (179.1 kB view details)

Uploaded Python 3

File details

Details for the file memory_seed-2.16.0.tar.gz.

File metadata

  • Download URL: memory_seed-2.16.0.tar.gz
  • Upload date:
  • Size: 216.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for memory_seed-2.16.0.tar.gz
Algorithm Hash digest
SHA256 f300af0607538c9731e23efe3c957b801e1f5c5f2463a2d3dc4418b1750fbf55
MD5 9301b8516e8f25650ee8f98dbaf45793
BLAKE2b-256 813adcff2c8f4fa876dc226902eb596ba60f7777b6ab4efe0ced304d2b4cf141

See more details on using hashes here.

Provenance

The following attestation bundles were made for memory_seed-2.16.0.tar.gz:

Publisher: publish.yml on jnl-tshi/memory-seed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file memory_seed-2.16.0-py3-none-any.whl.

File metadata

  • Download URL: memory_seed-2.16.0-py3-none-any.whl
  • Upload date:
  • Size: 179.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for memory_seed-2.16.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bb794ca413a0fdd021d01c1e7f317a412fbc2e7e6a1847bcd777a9ca9c0b186f
MD5 470ba8d4a7532a4cc51fca7b649ab665
BLAKE2b-256 f4c35f262ef4f37949da9d407c43bff09d14d548c582d04e5264d829e22e3a04

See more details on using hashes here.

Provenance

The following attestation bundles were made for memory_seed-2.16.0-py3-none-any.whl:

Publisher: publish.yml on jnl-tshi/memory-seed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page