# Obsidian agent memory: setup instructions for an AI agent

You are an AI coding agent (Claude Code, Codex or Cursor). The user wants to use their Obsidian vault as long-term project memory for their agents. Follow these instructions to set it up. Work step by step, ask when something is unclear, and never change a file before the user approves the plan.

Background: https://tarik.kavaz.org/blog/obsidian-as-memory-for-ai-agents/

## Ground rules

- Ask before you change anything outside the vault. Show every file you plan to create or edit, with its full path.
- Never overwrite an existing file. If a target exists, show the diff you would apply and wait for approval. For JSON config such as `settings.json`, merge into the existing content and keep everything already there.
- Edit files with your file editing tools, not with shell redirects or `sed -i`, so the user can review and undo changes.
- Never read or write any vault other than the one the user names.
- Never put secrets, tokens, passwords, API keys, recovery codes, personal ID numbers or server IP addresses into a note or into any file you create.
- If you cannot verify a path, setting or file format for the user's agent, say so and ask. Do not guess.

## Step 1: ask the user

Ask these questions first, in one message. Offer the default in brackets.

1. Which agents should use the vault? Claude Code, Codex, Cursor, or a mix.
2. What is the absolute path of the Obsidian vault the agents may use? [`~/Vault`]
3. Is there another vault the agents must never touch? If so, what is its path?
4. What is the root folder that contains your code repositories? [`~/Code`]
5. Where should the shared rules file live, so every agent reads the same copy? [`~/.agents/obsidian-vault-rules.md`] If the user keeps dotfiles in git, suggest putting it there and symlinking.
6. Do you want handoffs (notes to continue work in a later session)? [yes]
7. Do you want the `vault-init` skill, which creates the vault project for a repo? [yes]
8. Should the vault be a git repository? If it is not, offer to run `git init` in it. Do not add a remote.

Wait for the answers. Then restate them in a short list and continue only when the user confirms.

## Step 2: inspect the current state

Read, without changing anything:

- The vault folder: does `Projects/` and `System/` exist? Is it a git repo?
- Each chosen agent's existing instruction file and settings (see the table in step 4). Note what is already there.
- Whether the hooks folder and the skills folder for each agent exist.

Report what you found in a few lines. Flag anything that conflicts with the plan below.

## Step 3: show the plan

List every file you will create or edit, one line each, with the full path and what it does. Wait for approval. The files are:

1. The shared rules file (step 4a).
2. A line or section in each agent's instruction file that points to the rules (step 4b).
3. The hook script (step 5), for agents that support hooks.
4. The hook registration in the agent's settings (step 5).
5. The `vault-init` skill (step 6), if wanted.
6. The vault folders `Projects/` and `System/` if missing.

## Step 4: rules

### 4a. Shared rules file

Create the file at the path the user chose. Replace `<VAULT>`, `<OTHER_VAULT>` and `<CODE_ROOT>` with the user's answers. Remove the "other vault" sentence if there is none. Remove the handoff section if the user declined handoffs.

```markdown
## Project notes (Obsidian)

- The vault is `<VAULT>`. Writing project notes there is pre-approved. Never read or write `<OTHER_VAULT>` unless the user asks.
- A repo under `<CODE_ROOT>` maps to `Projects/<path relative to <CODE_ROOT>>/`. Any other repo maps to `System/<repo folder name>/`. In these rules `<project>` means that mapped folder.
- Each project folder holds `Overview.md` (what it is, repo path, stack, status, and an index), `Decisions/` (one note per decision: context, choice, why), `Log/` (short dated session notes named `YYYY-MM-DD <topic>.md`) and `Handoffs/`.
- Every note you write has frontmatter: `project`, `date`, `type` (`decision`, `log`, `howto` or `handoff`) and `source: agent`.
- Write a note when a piece of work is done or a decision is made, not only at the end of the session. Update the Overview status and index in the same pass.
- The Overview index lists every note as a wikilink followed by a one-line summary, so notes can be chosen without opening them.
- Do not duplicate what the repo already records (README, agent instruction files, code, git history). Note the reasoning and context around it.
- Reusable knowledge that is not tied to one project (gotchas, commands, setup recipes) goes in a topic folder such as `Dev/Recipes/`. Link it from the project Overview.
- Never put secrets, tokens, passwords, API keys, recovery codes, personal ID numbers or server IP addresses in a note.
- At the start of work in a repo, read `<project>/Overview.md` if it exists. Open `Decisions/` or `Log/` notes only when the task touches that topic. Do not read the whole project folder.
- When the user says "note this" or "add this to the vault", capture what was just discussed in the current project, like meeting minutes. Use a Decision note for a choice with its reason or a project rule. Otherwise use a Log note dated today, and add to today's Log note on the same topic instead of creating a second one. Mark guesses "unverified". Reply with the path in one line.
- When the user says "save a handoff", write `<project>/Handoffs/YYYY-MM-DD Handoff <short title>.md` with frontmatter `project`, `date`, `type: handoff`, `status: open`, `source`. Sections: Goal, Current state, Done, Next steps, Open questions, Files touched, How to resume. When the user says "close the handoff", set `status` to `done`. Reply with the path in one line.
- Before committing in the vault, run `git status` and stage only the files you wrote. The user edits the vault too, so never use `git add -A`. Use short plain commit messages.
```

### 4b. Point each agent to the rules

| Agent | Where to add the rules |
| --- | --- |
| Claude Code | Append the rules to `~/.claude/CLAUDE.md`, or add a line there that points to the shared file. Check first whether that file is a symlink and edit the real target. |
| Codex | Append the rules to `~/.codex/AGENTS.md`, or point to the shared file. Check for a symlink first. |
| Cursor | Cursor user rules live in the app settings and not in a file you can write. Print the rules and ask the user to paste them into Settings, Rules, User Rules. |

If the user chose a shared rules file, the pointer line is: `Read <path to shared rules file> once at the start of work in a repo and follow it.`

## Step 5: session-start hook

Only for agents with hooks. Claude Code supports a `SessionStart` hook. For Codex and Cursor, add one line to their rules: "Before implementing a feature, run `<hook path> </dev/null` from the repo and read its output."

Save this script as `~/.claude/hooks/vault-context.sh` (or next to the shared rules file if the user wants one copy). Replace `VAULT` and `CODE_ROOT`.

```bash
#!/usr/bin/env bash
# Print the vault Overview for the current repo at session start.
# Read-only: never creates or edits anything.
set -uo pipefail
command -v jq >/dev/null 2>&1 || exit 0

VAULT="$HOME/Vault"
CODE_ROOT="$HOME/Code"

payload="$(cat)"
cwd="$(jq -r '.cwd // empty' <<<"$payload")"
[ -n "$cwd" ] || cwd="$PWD"

root="$(git -C "$cwd" rev-parse --show-toplevel 2>/dev/null)" || exit 0
[ "$root" = "$VAULT" ] && exit 0
name="$(basename "$root")"

case "$root" in
  "$CODE_ROOT/"*) rel="Projects/${root#"$CODE_ROOT/"}" ;;
  *) rel="System/$name" ;;
esac

overview="$VAULT/$rel/Overview.md"
if [ -f "$overview" ]; then
  printf 'Vault project notes for "%s": %s\n' "$name" "$overview"
  printf 'Read the Overview before implementing a feature. Open Decisions/ or Log/ notes only when the task touches that topic.\n'
  printf -- '--- Overview.md ---\n'
  head -n 120 "$overview"

  # Open handoffs: frontmatter contains "status: open".
  open_list=""
  for f in "$VAULT/$rel"/Handoffs/*.md; do
    [ -f "$f" ] || continue
    head -n 12 "$f" | grep -qE '^status:[[:space:]]*open[[:space:]]*$' \
      && open_list="${open_list}- $(basename "$f" .md)"$'\n'
  done
  [ -n "$open_list" ] && printf -- '--- Open handoffs (read the newest first) ---\n%s' "$open_list"
else
  printf 'No vault project found for "%s" (expected %s).\n' "$name" "$overview"
  printf 'When real work starts, create %s/ with Overview.md, Decisions/ and Log/. Skip this for a one-off question.\n' "$VAULT/$rel"
fi
```

Then:

1. Run `chmod +x` on the script.
2. Check that `jq` is installed. If not, tell the user and stop this step.
3. Merge this into the `hooks` section of `~/.claude/settings.json`, keeping existing hooks. If a `SessionStart` array exists, add the new entry to it.

```json
{
  "matcher": "^(startup|resume|clear|compact)$",
  "hooks": [
    {
      "type": "command",
      "command": "~/.claude/hooks/vault-context.sh",
      "timeout": 10
    }
  ]
}
```

If the vault is not on macOS or Linux (for example Windows), tell the user this bash script needs a rewrite or WSL, and ask how they want to proceed.

## Step 6: the vault-init skill (optional)

Create `vault-init/SKILL.md` in each chosen agent's skills folder. Known locations: `~/.claude/skills/` for Claude Code and `~/.cursor/skills/` for Cursor. For Codex, check its documentation or ask the user. If the user keeps one shared copy, create it once and symlink it.

```markdown
---
name: vault-init
disable-model-invocation: true
description: Create the vault project for the current repo (Overview.md plus an init log). Use when the user runs vault-init or asks to set up a vault project for this repo.
---

# vault-init

Create the vault project for the repo in the current directory. Follow the project notes rules.

## Steps

1. Run `git rev-parse --show-toplevel`. Stop if this is not a git repo.
2. Map the repo path to the vault path with the rules. If that folder already exists, report what is there and stop. Never overwrite or move anything.
3. Read, without running anything: `README.md`, the repo's agent instruction files, the package manifest, the top-level listing and `git log --oneline -20`. Never copy secrets into a note.
4. Write `Overview.md` using only facts from step 3. Mark anything unclear "unverified" instead of guessing. Frontmatter: `project`, `date`, `type: howto`, `source: agent`.
5. Create empty `Decisions/` and `Log/` folders and write one Log note for today named `YYYY-MM-DD Project initialised.md`.
6. Reply with the new path in one line.
```

## Step 7: verify

1. Create the vault folders from step 3 if missing.
2. Run the hook script from inside one of the user's repos with `echo '{"cwd":"'"$PWD"'"}' | <script path>` and show the output. The expected result is either an Overview or the "No vault project found" message.
3. Ask the user to open a fresh agent session in a repo and confirm that the Overview appears in the context.
4. Summarize what you changed: a list of files created or edited, and what the user must still do by hand (for example, pasting the Cursor rules).

## If something fails

Stop and report the exact error. Do not retry with broader permissions, and do not work around a refusal by editing files another way. Ask the user how to proceed.
