Set up Mnemex for the user — bind the current project (or the user account) to a knowledge-graph repo, or scaffold a brand-new graph. Use this when no Mnemex graph is configured yet (a read/write skill reported "No Mnemex graph configured"), when the user says "set up mnemex", "create a knowledge graph", "point mnemex at my repo", or wants to change which graph this project uses. Establishes the binding that every other Mnemex skill resolves.
Installs into .claude/skills of the current project.
Are you the author of Mnx Init?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/kritird-mnx-init)
---
name: mnx-init
description: Set up Mnemex for the user — bind the current project (or the user account) to a knowledge-graph repo, or scaffold a brand-new graph. Use this when no Mnemex graph is configured yet (a read/write skill reported "No Mnemex graph configured"), when the user says "set up mnemex", "create a knowledge graph", "point mnemex at my repo", or wants to change which graph this project uses. Establishes the binding that every other Mnemex skill resolves.
---
# mnx-init — preflight setup and binding
> **Speak in the graph's labels.** The preset chosen here SETS this graph's vocabulary — `root_label`
> and `space_label`, the words it uses for its root and its spaces (e.g. `area`, `repo`, `client`).
> From the moment it is picked, say those words ("your first area: main"), never hard-code
> "team"/"org". Folders stay `space-*` on disk — that's storage, not what you say.
Mnemex separates two repos: the **project** the author works in, and the **graph** repo where knowledge
is stored. This skill establishes the **binding** between them. Every other skill (`mnx-read`,
`mnx-capture`, `mnx-promote`, `mnx-doctor`) resolves that binding before doing anything; if it is missing
they stop and send the user here. (`mnx-capture` is the exception that needs only the binding, not a
synced clone — it writes to the local staging tier.) Background: `docs/binding-and-graph-sync.md`.
Helper you call: `scripts/mnx_binding.py` (resolve / sync / status / probe-remote).
## 1. Check current state first
Run `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_binding.py" resolve --session <sid>` — `<sid>` is the
session id the SessionStart hook gave you earlier this session (baked into the opt-in/opt-out commands
it showed you); omit `--session` if you never got one (a host with no session-start hook). Passing it
lets `resolve` see a graph the user already switched to mid-session — every other skill's own preflight
does the same, so pass `--session <sid>` there too whenever you have it.
- If it resolves (exit 0), tell the user the current binding (`graph_remote` + `source`) and ask whether
they want to **keep**, **re-point** (durable — rewrites the binding file), **switch just for THIS
session** (`mnx_binding.py use-graph <slug> --session <sid>`, picking from `list-graphs`'s candidates
— reverts automatically at session end or a bounded TTL, or explicitly via `clear-graph-override
--session <sid>`), or **add a project-level override**. Do not silently overwrite.
- If it does not resolve (exit 2), proceed to choose a setup mode.
## 1b. Fast path — no answer needed (the default when the user just wants to start)
Most first-time users have **no graph yet and no opinion** about where it lives. Do not make them
choose. Propose a **local-folder** default and take it unless they object:
```
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_init.py" suggest-default
```
This returns `{path, root, space, preset, naming, rationale}` — a plain local folder under the mnemex
home named after this project, proposed as a **personal** graph (`preset: personal`): its spaces are
called **areas** and the first one is `main` (`space-main/` on disk). It **writes nothing**. Show the
user the one-line `rationale`, then, unless they want a different location, a git remote (step 2), or a
different graph type (step 2b):
1. Create + bind it in one step:
`python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_binding.py" write-user-default --path <path>` (writes the
`<mnemex_home>/config.md` user default; refuses to clobber an existing one without `--force`), then
scaffold with **step 3a**'s `init` call on that same `<path>`.
2. Echo the resulting `resolution_line()` (run `mnx_binding.py resolve`) so the user sees exactly which
graph, and via which source, they are now bound to.
Local first: a plain folder needs no git remote and no credentials, so it **always succeeds** — the
point of onboarding is that nobody hits a dead end. Only go to step 2 if the user wants a git remote or
a specific location.
## 2. Choose a mode (ask the user)
| Mode | When | Result |
|---|---|---|
| **Create a new graph** | The user has no graph yet. | Scaffold a graph (git repo **or** local folder), then write a binding to it. |
| **Bind this project** | A graph already exists; this project should use it. | Write `<project>/.mnemex.md`. |
| **Set user default** | The user wants one fallback graph for all projects. | Write `~/.claude/mnemex/config.md`. |
Independently, the graph can live as a **local folder** (`graph_path` — used in place; no git, no
credentials, always works) or a **git remote** (`graph_remote` — cloned, synced, pushed; for sharing a
graph across machines or a team). **Default to a local folder** (step 1b's proposal) — it never fails on
auth or network. Offer a git remote only when the user explicitly wants to share the graph or already
has a repo for it.
`.mnemex.md` (project) **overrides** the user-level file, which is overridden only by the
`MNEMEX_GRAPH_REMOTE` / `MNEMEX_GRAPH_PATH` env vars (the resolution chain). Pick the narrowest scope that
fits the intent.
## 2b. Pick the vocabulary (preset) — infer, state it, only ask if ambiguous
A graph's structure is always `graph → space → cluster`, but the **words** for a space are per-graph.
Choose a **preset** when creating (`--preset` on the `init` call); it sets what a space is called and
the first space's name. Folders stay `space-*` on disk either way — this is display only, no migration.
| Preset | space called | first space | use when |
|---|---|---|---|
| `personal` | area | `main` (`space-main`) | one person's notes; a local folder, no org/team talk |
| `team` | team | `core` (`space-core`) | today's model — an org with teams; **the default when org/team language or a shared remote is in play** |
| `org-repos` | repo | *(you must name it)* | an org organized by repository |
| `client` | client | *(you must name it)* | a consultancy/agency organized by client |
| `custom` | *(you choose)* | *(you must name it)* | none of the above — pass `--root-label` and `--space-label` |
**Infer, don't interrogate.** Read the context and **state** the preset you're using in your echo;
ask a one-liner only when genuinely ambiguous. **Explicit user words always win** (if they say "team"
/ "repo" / "client", use that preset).
- Local folder + no org/team language → `personal`.
- `--remote`, or the user talks about an org/team/sharing → `team`.
- "organized by repo" / "per repository" → `org-repos`; "by client" / consultancy → `client`.
- For `org-repos`/`client`/`custom` the engine **requires the first space's name** — ask for it in the
same breath as the graph name (pass it as `--space <name>`).
Pass the choice to the `init` call in step 3a: `--preset <name>` (and `--space <name>` when required;
`--root-label`/`--space-label` for `custom`). `--space` is the preset-neutral alias of the old `--team`
flag; passing `--team`/`--org` still works and implies the `team` preset (fully backward compatible).
## 3a. Create a new graph
In the location the user will use as their graph — a **git repo** or a **local folder** (create the
folder if it does not exist):
- Scaffold via `mnx_init.py init --path <dir>|--remote <url> --preset <name>` (plus `--space <name>`
when the preset requires it — step 2b). This lays down (never overwriting existing files): `index.md`
(root router), `mnemex.config.md` (from `config/mnemex.config.md` defaults, **plus the preset's
`root_label`/`space_label` when they differ from org/team**), the `.mnemex/` state directory, a
`.gitignore` (from `templates/gitignore.template`, so a stranded lock/pass-plan under `.mnemex/locks/`
or `.mnemex/plans/` is never committed into the graph), and the first space skeleton
(`space-<name>/` on disk — `main` for personal, `core` for team, the name you gave otherwise) with
`index.md`, `registry.md`, `cross-links.md`. The result payload carries `naming`.
- Explicitly tell the user that **pattern nodes persist ~30% longer than domain facts**
(`pattern_halflife_bonus`, default +30%) and how to change it.
- State the **two time horizons** and ask the user to confirm or adjust them, since both are conscious
policy: (1) `half_life_days` (default 180) — how long an *unused* fact keeps half its relevance; and
(2) `freshness_ttl_days` (default 30) — how long after it was last **verified** a fact is flagged
**stale** so the agent re-checks it (a separate axis from decay; patterns get +30% here too). Mention
that individual facts can be tagged `volatility: timeless` (never stale, never auto-dies) or
`volatile` (short horizon). Write the chosen `freshness_ttl_days` into `mnemex.config.md`.
- **Git remote:** have the user create the remote and push, then capture its remote URL → `graph_remote`,
and run the **remote pre-flight** below before binding (so an auth/URL problem surfaces now, not at sync).
- **Local folder:** capture its path → `graph_path`. If it is a git repo, writes commit locally; if it is
a plain folder, writes append an audit trail to `.mnemex/history.log` (mention this to the user).
- Then write the binding (step 4).
## 3b / 3c. Bind to an existing graph
Get the graph's **git remote URL** (`graph_remote`) **or local folder path** (`graph_path`) from the
user — set exactly one. **Do not clone a remote manually** — the session-start sync (`mnx_binding.py
sync`) materializes it. Then write the binding (step 4).
### Remote pre-flight (do this BEFORE writing a remote binding)
For any `graph_remote` (whether creating or binding), test reachability + auth *before* you write the
binding, so the user fails fast with a fix instead of hitting a sync error later:
```
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_binding.py" probe-remote --remote <url>
```
- `reachable: true` → proceed to write the binding (step 4). If `empty: true`, tell the user the remote
has no branches yet — they must push an initial commit first so `sync` has a HEAD to clone.
- `reachable: false` → **do not write the binding.** Report `message` + the `remediation` text verbatim
(it is tailored to the `category`: `auth` / `not-found` / `network`). Then **offer the local-folder
fallback** (the `fallback` field): re-run as local-folder mode (`graph_path`), which needs no git auth.
Only retry the remote after the user fixes the cause (keys/token/URL).
This probe is read-only (`git ls-remote` with prompts disabled) — it never clones or writes.
## 4. Write the binding
- **Project scope:** write `<project-root>/.mnemex.md` from `templates/binding.template.md`, filling
exactly one of `graph_remote` / `graph_path` and `default_space`/`author` if known. Ask whether to
commit it (shared) or add it to `.gitignore` (personal).
- **User scope:** write `~/.claude/mnemex/config.md` from `templates/user-config.template.md`. Create the
`~/.claude/mnemex/` directory if absent. Never write user config into `${CLAUDE_PLUGIN_ROOT}` — it is
wiped on plugin updates.
## 5. Verify — and leave the graph doctor-clean on day one
Run `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_binding.py" sync`. Confirm `action` is `cloned` or
`resynced`. If `error` (rare once the pre-flight passed — e.g. credentials changed between probe and
sync), surface the git message, re-run `probe-remote` for a categorized diagnosis + remediation, and
offer the local-folder fallback.
Then finish the setup **inside the synced `graph_root`** (skipping these leaves two permanent doctor
warnings on a brand-new graph — inv-1 and inv-15):
1. `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_regen.py" install <graph_root>` — registers the
merge driver for generated files (git config is per-clone, so this runs after sync, in the clone).
2. `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_config.py" stamp <graph_root>/space-<name>` — stamp each
scaffolded space (its folder is `space-<name>` on disk whatever the label) so config-drift detection
has a baseline and the overdue nag starts its clock now.
3. `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_doctor.py" check <graph_root>` — expect **E0/W0**; then
`mnx_binding.py persist --message "mnx-init: day-one stamp"` to commit/push the stamp.
On success, tell the user mnemex is ready and which graph it is bound to.
## 6. Offer to fill it, if you just created a graph
A **freshly created** graph (mode = create, step 3a) is always empty — `mnx-read`'s first
`read_frontier` call would discover this and offer the same fork on its own (onboarding plan
Phase 3), but don't make the user wait for that round-trip. Offer it now, right after step 5
succeeds:
*"This graph is empty. Seed it from a repo/docs now, or just keep working — I'll remember as
we go."*
- **Seed now** → hand off to `/mnemex:mnx-ingest` (its own consent gate #1 still applies — this
offer does not skip it).
- **Keep working** → nothing further needed; episodic capture (`/mnemex:mnx-capture`) already
fills the graph as the session goes.
Skip this step when the mode was **bind** or **user default** to an *existing* graph — only a
graph this skill just scaffolded is guaranteed empty; an existing graph may already be full.
## 6b. Second-or-later graph — say what happens next (multi-graph selection)
If the graph you just created/bound is the user's **2nd+ graph** (check
`python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mnx_binding.py" list-graphs`), tell them one thing so the
follow-on UX reads as intended, not as a regression:
*"You now have several graphs. In each folder you work in, the next session start will offer this
graph for that folder's read set — once per folder, since the read-many/write-one choice is a
per-folder contract (`reading a · b → writing a`). It is offered, never added silently; folders
where you already saved a selection just get a one-time 'new graph appeared' nudge."*
Do not create or edit any folder selection from this skill — the session-start menu (and
`mnx_binding.py select-graphs`) owns that choice.
## First-contact graph behavior config
If the bound graph has **no** `mnemex.config.md` yet (a freshly created remote), write it from the
defaults and state the half-life and pattern bonus. The behavior config is owned by the graph repo and
lives **only** there — never copy it into the project binding.
## Never
- Never write decay/tier parameters into `.mnemex.md` or the user config — those belong to the graph.
- Never overwrite an existing binding without confirmation.
- Never clone the graph by hand from this skill — that is `sync`'s job.