Sunday, August 23, 2026

Obsidian MCP — engineering memory that stays Markdown

Assistant memory should be files you can open. obsidian-mcp (0.1.0) is a local MCP server that gives Cursor and GitHub Copilot persistent engineering memory — stored as ordinary Markdown in an Obsidian vault. Obsidian does not need to be running. There is no community plugin and no hosted memory API.

The vault is the source of truth. Notes stay readable in Obsidian, git, or any text editor. The same stdio process works for both Cursor (.cursor/mcp.json) and Copilot / VS Code (.vscode/mcp.json).

The loop

Cursor / Copilot
        │  MCP stdio
        ▼
obsidian-dev-memory
        │
        ▼
Obsidian Markdown vault
  AI Memory/Projects/<slug>/
    Project State.md
    Sessions/YYYY-MM-DD.md
    Decisions/YYYY-MM-DD-<slug>.md
  1. Before substantial work, the assistant calls get_project_context.
  2. After a real implementation, it calls capture_work_session.
  3. When an architecture choice lands, it calls record_decision.
  4. When overall status changes, it calls update_project_state.

Typo fixes and one-line mechanical edits are not memory. The Cursor rule and Copilot instructions say so explicitly, so the vault does not fill with noise.

The seven tools

Tool What it does
get_project_context Project State plus newest sessions and decisions. Empty sections if the project is new — never the whole vault.
capture_work_session Append a timestamped section to today’s session note. Optional Git snapshot: repo, branch, short SHA, dirty flag, short file list. No full diffs.
record_decision Write YYYY-MM-DD-<slug>.md. Collision adds -2, -3 — never overwrite.
update_project_state Replace the concise current-state note. Not a session log.
search_memory Local filename and text search over that project’s memory.
read_note One vault-relative Markdown file.
append_daily_note Append to Daily/YYYY-MM-DD.md. Never overwrite existing contents.

Safety is the product

This is not a general filesystem API. Every note path must resolve inside OBSIDIAN_VAULT_PATH. Absolute paths, ../ traversal, and detectable symlink escapes are rejected. Writes are atomic (tempfile + os.replace).

Secrets never land in the vault on purpose. Values that look like keys, tokens, JWTs, private keys, or password= assignments are replaced with [redacted-secret] before write. The assistant instructions also forbid persisting .env contents, database credentials, and customer data.

Wire it into a project

export OBSIDIAN_VAULT_PATH="$HOME/Documents/ObsidianVault"
uv sync
uv run python -m obsidian_dev_memory

./scripts/install-project.sh \
  --project /path/to/your-app \
  --vault "$OBSIDIAN_VAULT_PATH"

The installer merges MCP JSON (it does not wipe unrelated servers) and drops the Cursor rule plus Copilot instructions so both assistants use the same memory habits. Point OBSIDIAN_VAULT_PATH at a real vault directory; the server does not auto-load .env files.

0.1.0 is the first cut that is worth installing: seven tools, vault confinement, Git context on sessions, and an installer that does not destroy existing MCP config. Next work is whatever the vault teaches us we forgot to remember.

Source: github.com/jmjava/obsidian-mcp

No comments: