setup skill
Performs interactive onboarding to configure Obsidian vault settings, note taxonomies, and memory routing for Codex and Claude Code.
- GitHub stars
- 7
- Files
- 2
- Last commit
- Oct 25, 2026
- License
- MIT
- Allowed tools
- —
What does the setup skill do?
setup performs interactive onboarding to configure Obsidian vault settings, note taxonomies, and memory routing for Codex and Claude Code.
Summary generated from the skill's SKILL.md.
About the setup skill
Configuring persistent memory for Codex and Claude Code is what this skill enables through an interactive onboarding process. It is designed for developers who need to establish a structured connection between their AI coding environments and an Obsidian vault. The tool guides users through defining their vault name, selecting a note taxonomy like PARA or Zettelkasten, and setting up cross-reference headings.
When an agent detects a missing configuration or receives a request to reset settings, it loads this skill to generate a config.json file in the ~/.mnemo/ directory. It uses internal scripts like safe-read.py to verify vault existence and vault-write.py to create essential files such as the Meta — Session Handoff note. The process ensures that semantic roles like facts and insights are correctly mapped to physical note types, allowing other memory skills to route information accurately. It also offers an opt-in for cross-runtime recall, allowing Codex and Claude to share a bounded, read-only memory overlay.
What an agent can do with it
- 1Initial mnemo installationAn agent can trigger the onboarding flow when a user first installs the mnemo system to create the necessary configuration files.
- 2Defining note organizationA developer can choose between Zettelkasten, PARA, or a custom taxonomy to manage how their AI-generated notes are categorized.
- 3Enabling cross-runtime memoryUsers can opt to let Codex and Claude Code share a read-only memory overlay for better project context.
- 4Automating vault file creationThe skill can automatically generate a session handoff note if it is missing from the Obsidian vault.
Written from the skill's SKILL.md. Every use case is checked against a quote from it.
How to install the setup skill
Each command copies the skill folder into the client's skills directory. Restart the client or start a new session to load it.Install the setup skill in Plugin
/plugin marketplace add jojoprison/mnemo /plugin install mnemo@mnemo
Install the setup skill in Claude Code
~/.claude/skills/setup/SKILL.md
$ npx degit jojoprison/mnemo/plugins/mnemo/skills/setup ~/.claude/skills/setupInstall the setup skill in Claude Code (project)
.claude/skills/setup/SKILL.md
$ npx degit jojoprison/mnemo/plugins/mnemo/skills/setup .claude/skills/setupInstall the setup skill in Codex
~/.agents/skills/setup/SKILL.md
$ npx degit jojoprison/mnemo/plugins/mnemo/skills/setup ~/.agents/skills/setupInstall the setup skill in Gemini CLI
~/.gemini/skills/setup/SKILL.md
$ npx degit jojoprison/mnemo/plugins/mnemo/skills/setup ~/.gemini/skills/setupInstall the setup skill in Claude.ai
npx degit jojoprison/mnemo/plugins/mnemo/skills/setup setup && zip -r setup.zip setup # claude.ai → Customize → Skills → + → Create skill → Upload a skill → setup.zip
SKILL.md
View on GitHubmn: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 <<< '{"query":"test","vault":"{input}"}'
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:
taxonomydefines 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_rolesmaps the stable semantic rolesfact,insight,source,session, andmocto keys that exist intaxonomy. 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,
"autocompactNudge": 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.
If the user turns on hooks.autocompactNudge, tell them it may need one Claude Code setting. The nudge needs to know the autocompact window, and on an account with 1M-context access mnemo deliberately refuses to guess it (the transcript records the model id without its [1m] suffix, so a 1M session and a 200k one are indistinguishable — guessing low would block a turn at 15% full). Run python3 "<mnemo-root>/scripts/context-window.py" --explain and pass on its hint. Two things to say plainly, because both are easy to get wrong:
- Compaction happens before the window is full, so the value is the desired threshold plus the reserve (33000 on a model whose max output is ≥ 20k). Wanting compaction at 460000 means setting
493000. - A value above the model's context window does nothing — on a 200k model,
460000silently resolves to200000.
mnemo ships no default for autoCompactWindow and never writes it: it is Claude Code's setting, not mnemo's, and one account's sensible value halves another's usable context.
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 <<< '{"file":"{handoff_note}","vault":"{vault}"}'
If empty output, create through the bundled shell-free writer in either runtime:
python3 "<mnemo-root>/scripts/vault-write.py" <<< '{"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}"}'
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" <<< '{"action":"create","vault":"{vault}","note":"{short-name}","content":"{one JSON-escaped Markdown hub body linking to the mapped moc note}"}'
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.jsonexists, 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 searchprobe 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/archivetypes plus functionalsession/moc, then confirm the explicittaxonomy_rolestargets. 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 inlineobsidian create/append content=.
Files in this skill
2setup skill questions
How do I install the setup skill in Claude Code?
Run npx degit jojoprison/mnemo/plugins/mnemo/skills/setup ~/.claude/skills/setup. Claude Code loads skills from ~/.claude/skills (all projects) or .claude/skills (one project) and uses a skill when its description matches the task.
Which clients can use the setup skill?
Any client that reads the Agent Skills format: Claude Code, Codex, Gemini CLI and claude.ai (upload as a ZIP). Scripts in the skill run only where the client allows code execution.
What does the setup skill do?
It performs interactive onboarding to create a config.json file containing your vault name, note taxonomy, and memory settings.
Can I use my own note taxonomy?
Yes, you can choose from Zettelkasten, PARA, or define a custom taxonomy with your own prefixes and tags.
Does it support Russian language settings?
Yes, you can configure the links section heading to use Russian, such as '## Связи'.