agentsclimarketplace

Setup

Skill jojoprison/mnemo/plugins/mnemo/skills/setup

Persistent memory layer for Claude Code — Obsidian vault health, connection discovery, brain dump, session notes, email bridge. Five lightweight skills, CLI-first, any taxonomy.

Install
npx -y skills add jojoprison/mnemo --skill setup

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use on first install, when reconfiguring mnemo, or when the user says 'setup mnemo', 'mnemo not configured', 'change vault', 'reset config', 'мнемо настрой', 'настрой мнемо', or similar — also invoked automatically when any other mnemo skill detects a missing config. Interactive onboarding that creates ~/.mnemo/config.json (vault name, taxonomy, links-section language, cascade defaults).

SKILL.md

12.0 KB, as published. Nobody here has run it

mn:setup — Interactive Onboarding

Invocation marker (both runtimes): begin your reply with the exact line 🧠 mn:setup (mnemo) → running — the user-visible confirmation that this skill actually loaded. Emit it once per invocation, before any other output.

Portable paths

Resolve <mnemo-root> once to the absolute plugin root before reading bundled files or running bundled scripts. In Claude Code, use ${CLAUDE_PLUGIN_ROOT}; in Codex, derive it from this loaded SKILL.md path (skill directory → skills/ → plugin root). Replace <mnemo-root> with that quoted absolute path in every command — never execute the placeholder literally and never hunt versioned cache directories.

When another mnemo skill must run, use the runtime-native path: Claude Code invokes mn:<skill> through its Skill tool; Codex reads <mnemo-root>/skills/<skill>/SKILL.md completely and follows it with the prepared input. For user-facing explicit syntax, render /mn:<skill> in Claude Code and $mnemo:<skill> in Codex.

First-time setup for mnemo. Creates config.json with all settings.

Workflow

Step 1: Welcome

🧠 Welcome to mnemo — persistent memory for Codex and Claude Code.

Let's set up your configuration. This takes about 30 seconds.

Step 2: Vault Name

What's your Obsidian vault name?
(The name shown in Obsidian's vault switcher)
> main

Verify vault exists:

python3 "<mnemo-root>/scripts/safe-read.py" search <<'JSON'
{"query":"test","vault":"{input}"}
JSON

If error → "Vault not found. Is Obsidian open? Check the vault name."

Step 3: Note Taxonomy

Which note taxonomy do you use?

[1] Atom/Molecule/Source/Session/MOC (Zettelkasten-inspired)
[2] PARA (Projects/Areas/Resources/Archive)
[3] Custom (you'll define prefixes and tags)

> 1

Map the selection to two adjacent config objects:

  • taxonomy defines physical note types. Each entry is { "prefix": "…", "tag": "…" }, and every prefix must end in a filename-safe separator such as , : , or -. Never allow /, #, or . in a prefix.
  • taxonomy_roles maps the stable semantic roles fact, insight, source, session, and moc to keys that exist in taxonomy. This is the only routing layer skills consume; never infer a destination from a display prefix or tag.

Always keep session and moc in taxonomy and map those two roles to themselves — they are functional types. The canonical workflows still resolve them through taxonomy_roles.session and taxonomy_roles.moc; they never bypass the role map.

[1] Zettelkasten — use the full blocks shown in Step 5 below. The role map is deterministic: fact → atom, insight → molecule, source → source, session → session, moc → moc.

[2] PARA:

"taxonomy": {
  "project":  { "prefix": "Project — ",  "tag": "project" },
  "area":     { "prefix": "Area — ",     "tag": "area" },
  "resource": { "prefix": "Resource — ", "tag": "resource" },
  "archive":  { "prefix": "Archive — ",  "tag": "archive" },
  "session":  { "prefix": "Session — ",  "tag": "session" },
  "moc":      { "prefix": "MOC — ",      "tag": "moc" }
},
"taxonomy_roles": {
  "fact": "resource",
  "insight": "resource",
  "source": "resource",
  "session": "session",
  "moc": "moc"
}

PARA organizes by actionability rather than knowledge shape, so propose resource for the three durable-memory roles, show the mapping, and ask the user to confirm or choose a different existing PARA key for each role. Never silently guess project versus area from content.

[3] Custom — ask the user for each type's key + prefix + tag; enforce the separator rule on every prefix; still include session and moc (add them yourself if the user doesn't name them). Then show the final type keys and ask once which key receives each of fact, insight, and source; keep session → session and moc → moc. Reject a role target that is not an exact taxonomy key.

Existing config migration: preserve a taxonomy_roles object only when its key set is exactly fact, insight, source, session, and moc, every target is an existing taxonomy key, and session → session plus moc → moc. If it is absent and taxonomy contains the legacy Zettelkasten keys atom, molecule, source, session, and moc, add the deterministic [1] map without asking. For any other missing/invalid custom map, show the existing taxonomy keys and ask once for the three content-role targets; keep the functional self-maps, do not rename types, and do not guess from prefixes/tags. Preserve all unrelated config fields.

Step 4: Links Section Name

What heading do you use for note cross-references?

[1] ## Связи (Russian)
[2] ## Links
[3] ## Related
[4] ## Connections
[5] Custom

> 1

Step 4.5: Cross-runtime Recall (opt-in)

Let Codex read this project's Claude memory, and Claude read this project's Codex memory?

[1] No (default — Obsidian + the active runtime only)
[2] Yes (read-only, exact git-project match, no copying or syncing)

> 1

Map the choice to recall.runtimeMemory.enabled. This is intentionally off by default because runtime memory may contain agent-generated or sensitive local context. Enabling it adds a bounded read-only overlay to ask; it does not create symlinks, share writers, scan transcripts, or change where either runtime stores memory. globalSources: "explicit" still requires the user to ask for global/cross-project memory in that specific query.

Step 5: Save Config

Write ~/.mnemo/config.json:

{
  "vault": "main",
  "taxonomy": {
    "atom": { "prefix": "Atom — ", "tag": "atom" },
    "molecule": { "prefix": "Molecule — ", "tag": "molecule" },
    "source": { "prefix": "Source — ", "tag": "source" },
    "session": { "prefix": "Session — ", "tag": "session" },
    "moc": { "prefix": "MOC — ", "tag": "moc" }
  },
  "taxonomy_roles": {
    "fact": "atom",
    "insight": "molecule",
    "source": "source",
    "session": "session",
    "moc": "moc"
  },
  "links_section": "## Связи",
  "handoff_note": "Meta — Session Handoff",
  "handoff": {
    "keepDays": 31,
    "maxKB": 56,
    "maxLineBytes": 200
  },
  "hot": {
    "scope": "project",
    "windowDays": 7,
    "maxKB": 8
  },
  "cascade": {
    "obsidian": { "enabled": true },
    "claude_mem": { "enabled": false, "url": "http://127.0.0.1:37777" },
    "memory_dir": { "enabled": true },
    "project_rules": { "enabled": true },
    "claude_md": { "enabled": false }
  },
  "recall": {
    "codeGraph": null,
    "runtimeMemory": {
      "enabled": false,
      "globalSources": "explicit",
      "maxHits": 5,
      "maxExcerptBytes": 12288
    }
  },
  "hooks": {
    "sessionStartNudge": true,
    "stopNudge": false,
    "invocationEcho": true,
    "hotDigest": true
  }
}

hooks.stopNudge ships false — flip it to true if you want the end-of-session save/session reminder (see <mnemo-root>/references/config-schema.md). hooks.invocationEcho (Claude Code only, default true) prints a 🧠 mnemo: /mn:<skill> → skill body loaded confirmation when a /mn:* command expands. hooks.hotDigest (default true) injects the open-tails digest at session start. Everything works on these defaults even if the whole hooks block is omitted.

The handoff block bounds the handoff index: keepDays is the rotation rule (the note holds the last month of pointers), maxKB a backstop beneath it, maxLineBytes the per-line ceiling in bytes. The shipped numbers come from a measured vault (7.5 sessions/day); on a much busier one, raise maxKB before shortening keepDays.

Use the Step 4.5 answer for recall.runtimeMemory.enabled; the JSON above shows the safe default. If an existing config is being edited, preserve every unrelated field and change only the requested setting.

Step 6: Create Handoff Note (only if missing)

First check — skip this step entirely if the handoff note already exists:

python3 "<mnemo-root>/scripts/safe-read.py" read <<'JSON'
{"file":"{handoff_note}","vault":"{vault}"}
JSON

If empty output, create through the bundled shell-free writer in either runtime:

python3 "<mnemo-root>/scripts/vault-write.py" <<'JSON'
{"action":"create","vault":"{vault}","note":"Meta — Session Handoff","content":"{one JSON-escaped Markdown string: meta frontmatter, an H1, and one line stating that this note is an index of pointers to session notes — the last handoff.keepDays days — not a store of open work}"}
JSON

create is exclusive and atomic. If it reports conflict, re-read the note rather than overwriting it.

Step 6.5: Project Hub Note (optional)

Offer: "Create a hub note for short-name navigation? E.g. [[ProjectName]] → its MOC."

Why: Obsidian's resolver ignores frontmatter aliases for bare [[Name]] links (by design) — only a real file named ProjectName.md makes [[ProjectName]] resolve. See <mnemo-root>/references/tool-routing.md ("Hub notes"). Without it, every short [[ProjectName]] reference is a broken ghost.

If user confirms, resolve taxonomy_roles.moc to its configured prefix and create through the same writer:

python3 "<mnemo-root>/scripts/vault-write.py" <<'JSON'
{"action":"create","vault":"{vault}","note":"{short-name}","content":"{one JSON-escaped Markdown hub body linking to the mapped moc note}"}
JSON

Skip if a file with that name already exists (obsidian read returns content). Note name must not contain # / . / / (see <mnemo-root>/references/tool-routing.md naming rules).

Step 7: Done

Render the completion message with one runtime-native {prefix}: /mn: in Claude Code or $mnemo: in Codex. Replace the placeholder before showing the message.

🧠 mnemo is ready!

Your skills:
  {prefix}ask       — search & synthesize
  {prefix}save      — memory routing cascade
  {prefix}session   — session notes + handoff
  {prefix}review    — session completeness review
  {prefix}connect   — discover hidden links
  {prefix}setup     — configure or reconfigure mnemo
  {prefix}health    — vault audit & analytics

Config saved to: ~/.mnemo/config.json
Handoff note created: Meta — Session Handoff

Try: {prefix}health

Gotchas

Common failures in <mnemo-root>/references/gotchas.md. Full config schema in <mnemo-root>/references/config-schema.md. Skill-specific rules:

  • Run once — if ~/.mnemo/config.json exists, show current values and ask before overwriting. User may just want to change one field, not rebuild everything.
  • Verify Obsidian is open during vault name step — run the Step 2 safe-read.py search probe with {"query":"test","vault":"{input}"}. It fails fast if the vault name is wrong or Obsidian isn't running, while keeping the user-provided name out of shell syntax.
  • Don't create vault structure — mnemo works with existing vaults. Do not create folders, templates, or sample notes. The user's vault is theirs.
  • PARA taxonomy selection — create project/area/resource/archive types plus functional session/moc, then confirm the explicit taxonomy_roles targets. Custom taxonomy accepts any prefixes as long as each ends in a filename-safe separator such as , : , or -; never /, #, or ..
  • Role-map integrity — write exactly the five stable role keys and require every value to name an existing taxonomy key. Never route by comparing human-facing prefixes or tags.
  • One write path in both runtimes — all vault Markdown goes through scripts/vault-write.py; never require an external Obsidian MCP and never use inline obsidian create/append content=.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.