Skip to content

Releases: MrRefactoring/obsidian-mcp-rs

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 13 Jul 10:43

What's Changed

Full Changelog: v0.5.1...v0.6.0

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 13 Jul 09:45

What's Changed

Full Changelog: v0.5.0...v0.5.1

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 13 Jul 08:32

What's Changed

Full Changelog: v0.4.0...v0.5.0

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 21:54
e2cd2e6

What's Changed

New Contributors

Full Changelog: v0.3.0...v0.4.0

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 11 Jul 21:31
8a52e61

What's Changed

  • Release v0.3.0: hardening, MCP 2025-11-25 conformance, rmcp 2.2 by @MrRefactoring in #4

Full Changelog: v0.2.1...v0.3.0

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 22 May 21:04
e45551f

obsidian-mcp-rs v0.2.1

A small follow-up to v0.2.0. delete-note now cleans up after itself: deleting the last note in a folder removes that now-empty folder too, mirroring the behaviour move-note gained in v0.2.0. Same public MCP API and config-file output as v0.2.0.

🧹 Changed

  • delete-note prunes an emptied source folder. When deleting a note leaves its containing folder empty, that folder is removed as well.
    • Best-effort — a failed remove_dir is logged via tracing::warn! and never propagated, so cleanup can't fail the delete itself.
    • The vault root is never removed, even if it becomes empty of notes.
  • The empty-folder pruning shared by move-note and delete-note is now a single prune_empty_parent helper (DRY) instead of duplicated inline logic.

✅ Tests

Three new regression tests: delete_note_removes_emptied_source_folder, delete_note_keeps_nonempty_source_folder, delete_note_does_not_remove_vault_root. Suite is at 197 passing; cargo fmt --check and cargo clippy -- -D warnings are clean.

📦 Install

npx obsidian-mcp-rs install

Full changelog: v0.2.0...v0.2.1

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 22 May 10:31
8b6e1c1

obsidian-mcp-rs v0.2.0

Vault-wide operations now run in parallel, frontmatter parsing moved to a real YAML library, and the crate ships with a benchmark suite. This release also carries the security fixes made during the internal refactor. Same public MCP API and config-file output as v0.1.6.

⚠️ Behaviour changes

  • .gitignore / hidden files are now respected. Vault walks (search-vault, rename-tag) moved from walkdir to the ignore crate, so gitignored and hidden notes are skipped — including by rename-tag.
  • Strict frontmatter parsing. tags: is now parsed with serde_yml instead of a hand-rolled scanner. A note whose frontmatter body is invalid YAML yields no tags (no best-effort line scraping), and non-string tag values (e.g. tags: [2024]) are ignored. Well-formed vaults are unaffected.

🚀 Performance

Vault walks now process files in parallel with rayon. Measured with the new criterion suite on a 2000-note synthetic vault (Apple Silicon, 10 logical cores) vs. the same code pinned to one thread (RAYON_NUM_THREADS=1):

Operation Serial (1 thread) Parallel Speedup
Content search (2000 notes) 52.8 ms 26.3 ms ~2.0×
Tag search (2000 notes) 45.6 ms 24.4 ms ~1.9×
Tag rename (500 notes) 84.3 ms 60.0 ms ~1.4×
  • Case-insensitive content search now lowercases each file once instead of once per line.
  • Single-note operations (read-note, create-note, edit-note, …) touch one file and are unaffected.

🔒 Security

  • Path traversal in add-tags / remove-tags. The v0.1.6 sandbox routed every other path-bearing tool through safe_join, but the two tag tools still used a bare root.join(file) per entry — a crafted files: ["../../../etc/hosts"] (or any absolute path) could read/overwrite files anywhere the server process could reach. Both tools now resolve every entry through safe_join. Regression tests added.

🐛 Fixed

  • Frontmatter terminator false-positives — the closing --- was located with find("\n---"), which also matched \n----, \n---foo, etc., splitting frontmatter at the wrong byte and corrupting the body on later writes. A new find_closing_fm requires --- to stand alone on a line.
  • Inline-tag rewrites corrupted overlapping tags — renaming foo also clobbered #foobar/#foo-extra. A new replace_inline_tag enforces a right-boundary check.
  • Vault basename collisions silently shadowed earlier paths — colliding basenames are now disambiguated as <name>-2, <name>-3, … with a warning.

✨ Added

  • move-note prunes empty source folders. When a move leaves the source directory empty it is removed (best-effort — a failed cleanup never fails the move; the vault root is never deleted).
  • Benchmark suite (benches/vault_bench.rs) covering content/tag search and tag rename; CI compiles it via cargo bench --no-run so it can't bitrot.
  • CLAUDE.md onboarding notes; Russian README (README.ru.md) synced.

🔧 Internal

  • Split the 1700-line src/vault.rs into a src/vault/ module (mod orchestrator + path, frontmatter, tags, search, walk).
  • Reworked install/writer.rs around a ConfigBackend trait — adding a JSON-shaped client is now one match arm.
  • Split the crate into a library (src/lib.rs) + thin binary (src/main.rs) so benches and tests can link the domain logic; cargo test --lib now works.
  • Removed the unused regex dependency and dead code; the build is warning-clean.

📦 Install

npx obsidian-mcp-rs install

Full changelog: v0.1.6...v0.2.0

v0.1.6

Choose a tag to compare

@github-actions github-actions released this 21 May 16:42

Security

This release fixes a path traversal vulnerability (CWE-22, CVSS 8.1 High) affecting all prior versions. Crafted filename or folder arguments to the vault tools could read, write, or delete files outside the configured vault root. Symlinks inside the vault pointing outside it were also followed.

Users of obsidian-mcp-rs should upgrade immediately.

See GHSA-qcqq-h5q6-69qq for the full advisory; a CVE ID will be assigned by MITRE shortly.

Reported by Luca King — thank you.

What's new

Security

  • Path traversal in vault tools (CWE-22) — every path argument (filename, folder, search_path) now goes through a safe_join helper that canonicalizes the deepest existing ancestor and rejects anything outside the canonicalized vault root. Absolute paths in filename / folder are rejected outright. Symlink escapes (a symlink inside the vault pointing outside it) are also blocked.

Added

  • install / uninstall / list support for 12 additional MCP clients:
    Windsurf, VS Code (Copilot), Gemini CLI, Antigravity, Cline, Kiro,
    LM Studio, Factory, Amp, opencode, Codex CLI, Goose
  • TOML and YAML config writers (Codex config.toml, Goose config.yaml)

Changed

  • logs subcommand now colorizes output (ERROR red, WARN yellow, DEBUG/TRACE dim)

Upgrade

# npm / npx users
npx -y obsidian-mcp-rs@0.1.6 --version

# cargo users
cargo install obsidian-mcp-rs --version 0.1.6 --force

Full Changelog: v0.1.5...v0.1.6

v0.1.5

Choose a tag to compare

@MrRefactoring MrRefactoring released this 13 Apr 21:36

[0.1.5] - 2026-04-14

Fixed

  • install, uninstall, list, and logs subcommands not recognized by the published binary — the platform packages (@obsidian-mcp-rs/*) were pinned to 0.1.2 in optionalDependencies instead of the current version, so npx resolved an old binary without these subcommands
  • prepare-release.sh now updates optionalDependencies unconditionally (previously only matched entries at CURRENT_VERSION, silently skipping them when platform packages lagged behind)

Full Changelog: v0.1.4...v0.1.5

v0.1.4

Choose a tag to compare

@MrRefactoring MrRefactoring released this 13 Apr 21:02

[0.1.4] - 2026-04-13

Changed

  • Dependencies updated to latest versions: dirs 5 → 6, dialoguer 0.11 → 0.12, console 0.15 → 0.16
  • rust-version set to 1.94 in Cargo.toml; MSRV in clippy.toml updated to match
  • Code modernised for Rust 1.94: nested if let chains collapsed using stabilised let_chains; manual_strip and if_same_then_else lints resolved in vault.rs

[0.1.3] - 2026-04-13

Added

  • install subcommand — interactive wizard and direct CLI to write MCP config into AI client config files
    • Clients: Claude Desktop, Claude Code (local .mcp.json + global ~/.claude.json), Cursor (local .cursor/mcp.json + global ~/.cursor/mcp.json), OpenClaw
    • --global flag selects global config for claude-code and cursor (local is default)
    • --dry-run, --force flags; auto-backup before any write (.json.bak)
    • Cross-platform config path resolution (macOS / Windows / Linux)
  • uninstall subcommand — interactive or direct removal of MCP config entry
  • list subcommand — show installation status across all detected AI clients
  • logs subcommand — print log file path, last 100 log entries, and a GitHub issue link for bug reports
  • --no-edit flag — starts the server in read-only mode; all write tools (create-note, edit-note, delete-note, move-note, create-directory, add-tags, remove-tags, rename-tag) return an error immediately
  • --verbose / -v flag — enables DEBUG-level logging to stderr without needing RUST_LOG
  • --log-file <FILE> flag — override the automatic log file path; pass - to disable file logging entirely
  • Automatic DEBUG log file written on every server start:
    • macOS: ~/Library/Logs/obsidian-mcp-rs/obsidian-mcp-rs.log
    • Linux: ~/.local/share/obsidian-mcp-rs/obsidian-mcp-rs.log
    • Windows: %LOCALAPPDATA%\obsidian-mcp-rs\obsidian-mcp-rs.log
  • Structured startup log: version, PID, no_edit state, and each vault path logged at INFO on start
  • tracing::debug! on every MCP tool invocation with key parameters; tracing::error! on every tool failure
  • scripts/prepare-release.sh — automates version bump across all 9 package files and updates CHANGELOG.md
  • codecov.yml — Codecov flag configuration for separate Rust and TypeScript coverage reporting
  • Code coverage badge in README (Codecov)
  • platform.ts — platform detection logic extracted from bin.ts into a separate, testable module with named exports
  • platform.test.ts — 16 vitest unit tests covering detectPlatform, detectMusl, and resolveBinaryPath
  • vitest.config.ts — vitest configuration with @vitest/coverage-v8 lcov reporter
  • Russian README (README.ru.md) with language switcher on both README files

Changed

  • README: added Quick setup section near the top with wizard and direct install examples
  • README: added Troubleshooting section with log file locations, --verbose, --log-file usage, and bug-report instructions
  • README: added language switcher (English | Русский) below the header
  • CI: workflow branch target changed from main to master; all action versions updated to latest
  • CI: added coverage job — cargo llvm-cov --lcov for Rust and vitest --coverage for TypeScript, both uploaded to Codecov with separate flags
  • bin.ts refactored into a thin launcher (spawnSync); all detection logic moved to platform.ts
  • tsconfig.json: test and config files excluded from the build output

Fixed

  • CI was not running on master branch (was targeting non-existent main)
  • bin.ts platform logic was untestable due to inline require() calls; fixed by moving to static imports in platform.ts

Full Changelog: v0.1.2...v0.1.4