Skip to main content
AI/MLlatebit-io

soul-memory

Use when the user wants to remember, save, recall, or query personal notes that should persist across Claude Code sessions. Routes through the demarkus-memory MCP tools against a local versioned markdown store organized by project.

Stars
13
Source
latebit-io/demarkus
Updated
2026-05-31
Slug
latebit-io--demarkus--soul-memory
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/latebit-io/demarkus/HEAD/plugins/claude-code/skills/soul-memory/SKILL.md -o .claude/skills/soul-memory.md

Drops the SKILL.md into .claude/skills/soul-memory.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

Soul Memory

This skill routes "remember" / "recall" intents through the demarkus-memory MCP server (a local demarkus-server), which provides a versioned, link-graph-aware personal memory store. The store is organized by project: top-level /index.md is a project list, and each project lives at /<slug>/ with a consistent internal structure.

When to trigger

Trigger on phrases and intents like:

  • "remember this", "save to memory", "note that", "jot down"
  • "what do I know about X", "do I have notes on Y", "recall Z"
  • "add this to my notes", "put this in my soul"
  • "find anything about ...", "what have I saved about ..."

Do NOT trigger for ephemeral context ("remember that in this conversation we're using Python 3.12") — that belongs in the current session, not the persistent store.

Determining the current project

Before reading or writing, resolve the project slug:

  1. Use the basename of CLAUDE_PROJECT_DIR env var (via the Bash tool: basename "$CLAUDE_PROJECT_DIR"). Convert to a lowercase slug if needed (spaces → hyphens).
  2. If CLAUDE_PROJECT_DIR is unset or the user is clearly asking about a different project, ask which project.
  3. If the project doesn't yet exist in the soul (no /<slug>/ subtree), create it on first write by publishing the relevant file(s) and adding a link to /index.md.

Per-project structure

The canonical layout lives in /project-template.md at the soul root (seeded on first session, user-customizable). Fetch it when in doubt — it is the single source of truth. In brief, each /<project>/ subtree uses:

  • /<project>/index.md — the project hub; links to every doc below and anchors discovery
  • /<project>/architecture.md — system design, module boundaries, key decisions
  • /<project>/patterns.md — code patterns, conventions, idioms
  • /<project>/guidelines.md — hard rules for code quality; read before writing code
  • /<project>/debugging.md — lessons from bugs and investigations
  • /<project>/roadmap.md — done, next, deliberately not prioritized
  • /<project>/debt.md — technical debt and improvement opportunities
  • /<project>/thoughts.md — open questions, reflections, ideas
  • /<project>/adr/<NNNN>-<slug>.md — Architecture Decision Records (one per decision, zero-padded 4-digit sequence)
  • /<project>/plans/<name>.md — plan documents (lifecycle carried in the text)
  • /<project>/journal/<YYYY-MM-DD>.md — dated session notes, one file per day

Tool routing

Read intents → start with mark_lookup (the catalog), then mark_fetch:

  1. mark_lookup with url=/<project>/ (or / to span every project) and a subject query — returns an importance-ranked markdown table of matching docs (path, importance, title, tags), not bodies. This is a catalog lookup, not full-text search: it finds only what was tagged or titled. Narrow with the optional filter arg (tag=, modified-after=, modified-before=) and cap with limit.
  2. mark_fetch the rows worth reading. Also mark_fetch /index.md / /<project>/index.md directly — lookup won't surface untagged docs, so the index hub still anchors discovery.
  3. Use mark_backlinks or mark_graph to surface related documents across projects
  4. If nothing relevant is found, say so honestly rather than fabricating

Write intents — route to the right file for the content type:

  • Fleeting observation / daily note → append to today's /<project>/journal/<YYYY-MM-DD>.md. If the file does not exist yet, create it with mark_publish (expected_version: 0) and a header like # <Project> journal — <YYYY-MM-DD>, then append on subsequent calls. The /soul-journal command handles this automatically.
  • Architecture decision → create a new ADR at /<project>/adr/<NNNN>-<slug>.md with mark_publish (expected_version: 0). Pick the next sequence number by listing the adr/ directory. Standard ADR template: # <NNNN>. <Title>, ## Status, ## Context, ## Decision, ## Consequences.
  • Pattern / convention learned → append to /<project>/patterns.md. Fetch first if updating an existing section; otherwise mark_append with expected_version unset.
  • Hard rule for code quality/<project>/guidelines.md.
  • Lesson from a bug / a gotcha/<project>/debugging.md (high recall value — capture the non-obvious why).
  • Architecture change → fetch /<project>/architecture.md, update the relevant section, publish with the correct expected_version.
  • What's next / done / not prioritized/<project>/roadmap.md.
  • Technical debt/<project>/debt.md.
  • Plan document/<project>/plans/<name>.md (carry active / completed / archived in the text).
  • Open question / idea, not yet decided/<project>/thoughts.md.
  • Cross-project or global note → if it does not fit a project, ask the user where it belongs. Do not create ad-hoc top-level files (the soul root holds only /index.md and /project-template.md).

On every mark_publish, set metadata: tags (comma-separated subjects — the primary match target for mark_lookup) and, sparingly, importance (0–1, default 0.5; reserve high values for genuinely central docs like index hubs and architecture). An untagged document can only be found by words in its title, so tagging on write is what makes later recall work. The server does not infer either field — you choose them. Reserved keys are rejected; any other metadata key is stored opaquely and reachable through lookup's filter axis.

mark_append carries no metadata, so a doc's tags/importance are whatever its last mark_publish set. When an append introduces a materially new subject, re-publish the doc (full body, correct expected_version) with extended tags rather than letting the catalog drift.

Always reference what you saved by full path so the user can find it again.

Creating a new project

When the user wants to start memory for a project that does not exist in /index.md yet (fetch /project-template.md first if you need the full layout):

  1. Confirm the slug (basename of CLAUDE_PROJECT_DIR, lowercased, spaces → hyphens)
  2. Create the project hub /<slug>/index.md with mark_publish expected_version: 0 — a short page that will link to the project's docs as they appear. Don't pre-create empty stubs for every template file; add docs when there's something real to put in them.
  3. Create the first content doc (today's journal entry, or an architecture.md stub) and link it from /<slug>/index.md.
  4. Fetch /index.md, add a bullet - [<Project Name>](/<slug>/) under the project list, and publish with the correct expected_version

Don't

  • Don't fabricate memory. If mark_fetch returns not-found, the document does not exist — say so.
  • Don't invent expected_versions. Use 0 for new documents; fetch first when updating.
  • Don't bypass the MCP tools with shell commands — the soul is the source of truth.
  • Don't create top-level files outside /<project>/ subtrees except for /index.md itself.
  • Don't save secrets, credentials, or anything the user has not explicitly authorized.