memory-routing

Use when user says 'remember this', 'save to memory', 'запомни', 'в память', 'сохрани', or when significant facts, decisions, or findings need to be persisted. Routes to multiple storage backends with graceful degradation.

mnemo:save — Memory Routing Cascade

Save information to multiple memory backends with graceful degradation. Each backend is tried independently — if one fails, others still work.

Prerequisites

  • Obsidian should be open — but skill works even if it's not (skips Obsidian, uses other backends)

Config

Read from ~/.mnemo/config.json:

{
  "vault": "main",
  "cascade": {
    "obsidian": { "enabled": true },
    "claude_mem": { "enabled": true, "url": "http://127.0.0.1:37777" },
    "memory_dir": { "enabled": true },
    "claude_md": { "enabled": false }
  }
}

If cascade section is missing, defaults: obsidian=true, claude_mem=true, memory_dir=true, claude_md=false.

Workflow

Step 0: Classify the Input

Determine what type of information is being saved:

TypeGoes toExample
factObsidian Atom + claude-mem"Heroku standard-0 has 25 auto-backups"
insightObsidian Molecule + claude-mem"CLI-first is 70,000x cheaper because of token savings"
decisionObsidian Atom + claude-mem + memory/"We chose SCOPE over TextGrad for self-correction"
gotchaObsidian Atom + memory/ + possibly CLAUDE.md"execSync with shell=true is banned in antomate"
sourceObsidian Source + claude-memExternal article, tool, research finding
ruleCLAUDE.md (if error-preventing) + memory/"Never mark Gmail as read without explicit request"
quick thoughtCreate Obsidian inbox noteUnstructured ideas

Step 1: Obsidian (Primary — for the user)

Skip if: cascade.obsidian.enabled is false, or Obsidian CLI returns "Unable to connect"

obsidian search query="{key words}" vault="{vault}"

If duplicate found → ask: update existing or create new?

Create note — MCP (shell-safe for markdown with code blocks):

mcp__obsidian__create(
  path: "{type_prefix}{descriptive title}.md",
  file_text: """---
type: {type}
tags: [{type}, {topic_tags}]
date: {YYYY-MM-DD}
source: "{where this came from}"
---

# {type_prefix}{title}

{content}

{links_section}
- [[{relevant MOC}]]
- [[{ghost notes for entities}]]
"""
)

Why MCP: content may contain code blocks with backticks or $(...). CLI obsidian create content="..." triggers zsh command substitution and can execute embedded shell commands (real incident: 2026-04-21, accidental prod deploy).

Add to MOC — MCP str_replace for targeted insert, or CLI for plain wikilinks:

mcp__obsidian__str_replace(
  path: "{MOC}.md",
  old_str: "{stable anchor line near list}",
  new_str: "{same anchor}\n- [[{note name}]]"
)

CLI fallback for plain wikilink appends (safe — no backticks):

obsidian append file="{MOC}" vault="{vault}" content="- [[{note name}]]"

On error: Log ⚠️ Obsidian: skipped (not connected), continue to next backend.

Step 2: claude-mem (Semantic Search — cross-session recall)

Skip if: cascade.claude_mem.enabled is false

curl -s -X POST http://{claude_mem_url}/api/memory/save \
  -H "Content-Type: application/json" \
  -d '{
    "content": "{one-line summary of what was saved}",
    "metadata": {
      "type": "{type}",
      "project": "{current project or 'general'}",
      "obsidian_note": "{note name if created}"
    }
  }'

On error: Log ⚠️ claude-mem: skipped (port {port} not responding), continue.

Step 3: memory/ (For Claude — error prevention)

Skip if: cascade.memory_dir.enabled is false

Only write here if the information prevents Claude from making errors in future sessions:

  • Gotchas, commands, conventions
  • NOT business context (that's Obsidian's job)

Path resolution (CRITICAL): The "memory/" directory is Claude Code's auto-memory directory, NOT ./memory/ in the project root.

To find the correct path, look for the MEMORY.md file that is already loaded in your conversation context. Its path follows the pattern:

~/.claude/projects/-{slugified-cwd}/memory/

For example: ~/.claude/projects/-Users-jkaseq-Documents-projects-bts-holding/memory/

NEVER create or write to ./memory/ in the project root — that would put memory files in the git repo.

Write or append to relevant topic file in that directory. Use ~/.claude/memory/ only for cross-project info.

On error: Log ⚠️ memory/: skipped (directory not found), continue.

Step 4: CLAUDE.md (Only critical error-preventing rules)

Skip if: cascade.claude_md.enabled is false (default)

Only write here if the rule is:

  • 1-2 lines max
  • Violation would cause a real error or bad behavior
  • Not already covered by Obsidian or memory/

This is almost never needed. Most things go to Obsidian + claude-mem.

Step 5: Report

💾 Memory saved:

Content: "{short summary}"
Type: {atom/molecule/source/decision/gotcha}

Backends:
  1. Obsidian  ✅ → "Atom — {title}" in MOC — {name}
  2. claude-mem ✅ → semantic search indexed
  3. memory/   ⏭  skipped (not error-preventing)
  4. CLAUDE.md ⏭  skipped (not critical rule)

Or with failures:

💾 Memory saved (partial):

  1. Obsidian  ⚠️ skipped (not connected — restart Obsidian)
  2. claude-mem ✅ → indexed
  3. memory/   ✅ → ~/.claude/memory/topic.md updated

⚠️ Run /mnemo:save again after restarting Obsidian to complete sync.

Decision Matrix

Information typeObsidianclaude-memmemory/CLAUDE.md
Fact (atomic)✅ Atom
Insight (synthesized)✅ Molecule
External source✅ Source
Decision✅ Atom✅ if prevents errors
Gotcha✅ Atom✅ if critical
Command/convention✅ Atom
Error-preventing rule
Quick unstructured thought✅ Inbox

Gotchas

  • "Unable to connect to main process" — Obsidian IPC hung. Fix: quit Obsidian (Cmd+Q), reopen, wait 3 seconds, retry
  • Graceful degradation is the point — never fail completely, always save to at least one backend
  • Don't duplicate Obsidian content in memory/ — Obsidian = user's memory, memory/ = Claude's memory. Different audiences
  • claude-mem is optional — many users won't have it. Skip silently
  • CLAUDE.md is almost never written to — only 1-2 line rules that prevent actual errors. Target: <120 lines total
  • Tool choice: MCP-first hybrid — CLI for search/read/orphans (fast, indexed); MCP for any create/update with markdown body (shell-safe, no zsh backtick expansion). Never use obsidian create content="..." with markdown containing code blocks
  • memory/ path is NOT ./memory/ — it's ~/.claude/projects/-{slug}/memory/. Writing to project root creates files in git. Find the correct path from MEMORY.md in context
  • Always check duplicates before creating Obsidian notes
  • Ghost notes generously — wrap entities in [[wikilinks]]
  • MOC link mandatory for Obsidian notes (except inbox)