Releases: MrRefactoring/obsidian-mcp-rs
Release list
v0.6.0
What's Changed
- fix: verify the vault path, and stop the installer rewriting user configs by @MrRefactoring in #31
- fix: make the tool surface something a model can actually use by @MrRefactoring in #32
- fix: the structured tools can report an error the model can act on by @MrRefactoring in #33
- chore: release v0.6.0 by @MrRefactoring in #34
Full Changelog: v0.5.1...v0.6.0
v0.5.1
What's Changed
- fix: stop move-note relocating a rename, and cap what read-note returns by @MrRefactoring in #29
- chore: release v0.5.1 by @MrRefactoring in #30
Full Changelog: v0.5.0...v0.5.1
v0.5.0
What's Changed
- Phase 7: safe delete, honest --no-edit, vault-info, periodic notes by @MrRefactoring in #24
- feat(http): Streamable HTTP transport (optional feature) by @MrRefactoring in #25
- feat(search): match by pattern with regex, filter by frontmatter fields by @MrRefactoring in #27
- chore: release v0.5.0 by @MrRefactoring in #28
Full Changelog: v0.4.0...v0.5.0
v0.4.0
What's Changed
- chore(deps): bump codecov/codecov-action from 4 to 7 by @dependabot[bot] in #5
- chore(deps): bump toml_edit from 0.22.27 to 0.25.12+spec-1.1.0 by @dependabot[bot] in #10
- chore(deps): bump actions/checkout from 4 to 7 by @dependabot[bot] in #6
- chore(deps): bump actions/setup-node from 4 to 6 by @dependabot[bot] in #7
- chore(deps-dev): bump vitest and @vitest/coverage-v8 to 4.1.10 by @MrRefactoring in #14
- chore: lower MSRV from 1.94 to 1.88 (actual syntax/dependency floor) by @MrRefactoring in #15
- fix: stop corrupting frontmatter in tag operations by @MrRefactoring in #16
- fix: stop concurrent writes losing each other by @MrRefactoring in #22
- Release 0.4.0 by @MrRefactoring in #23
New Contributors
- @dependabot[bot] made their first contribution in #5
Full Changelog: v0.3.0...v0.4.0
v0.3.0
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
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-noteprunes an emptied source folder. When deleting a note leaves its containing folder empty, that folder is removed as well.- Best-effort — a failed
remove_diris logged viatracing::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.
- Best-effort — a failed
- The empty-folder pruning shared by
move-noteanddelete-noteis now a singleprune_empty_parenthelper (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 installFull changelog: v0.2.0...v0.2.1
v0.2.0
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 fromwalkdirto theignorecrate, so gitignored and hidden notes are skipped — including byrename-tag.- Strict frontmatter parsing.
tags:is now parsed withserde_ymlinstead 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 throughsafe_join, but the two tag tools still used a bareroot.join(file)per entry — a craftedfiles: ["../../../etc/hosts"](or any absolute path) could read/overwrite files anywhere the server process could reach. Both tools now resolve every entry throughsafe_join. Regression tests added.
🐛 Fixed
- Frontmatter terminator false-positives — the closing
---was located withfind("\n---"), which also matched\n----,\n---foo, etc., splitting frontmatter at the wrong byte and corrupting the body on later writes. A newfind_closing_fmrequires---to stand alone on a line. - Inline-tag rewrites corrupted overlapping tags — renaming
fooalso clobbered#foobar/#foo-extra. A newreplace_inline_tagenforces 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-noteprunes 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 viacargo bench --no-runso it can't bitrot. CLAUDE.mdonboarding notes; Russian README (README.ru.md) synced.
🔧 Internal
- Split the 1700-line
src/vault.rsinto asrc/vault/module (modorchestrator +path,frontmatter,tags,search,walk). - Reworked
install/writer.rsaround aConfigBackendtrait — 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 --libnow works. - Removed the unused
regexdependency and dead code; the build is warning-clean.
📦 Install
npx obsidian-mcp-rs installFull changelog: v0.1.6...v0.2.0
v0.1.6
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 asafe_joinhelper that canonicalizes the deepest existing ancestor and rejects anything outside the canonicalized vault root. Absolute paths infilename/folderare rejected outright. Symlink escapes (a symlink inside the vault pointing outside it) are also blocked.
Added
install/uninstall/listsupport 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, Gooseconfig.yaml)
Changed
logssubcommand 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 --forceFull Changelog: v0.1.5...v0.1.6
v0.1.5
[0.1.5] - 2026-04-14
Fixed
install,uninstall,list, andlogssubcommands not recognized by the published binary — the platform packages (@obsidian-mcp-rs/*) were pinned to0.1.2inoptionalDependenciesinstead of the current version, so npx resolved an old binary without these subcommandsprepare-release.shnow updatesoptionalDependenciesunconditionally (previously only matched entries atCURRENT_VERSION, silently skipping them when platform packages lagged behind)
Full Changelog: v0.1.4...v0.1.5
v0.1.4
[0.1.4] - 2026-04-13
Changed
- Dependencies updated to latest versions:
dirs5 → 6,dialoguer0.11 → 0.12,console0.15 → 0.16 rust-versionset to1.94inCargo.toml; MSRV inclippy.tomlupdated to match- Code modernised for Rust 1.94: nested
if letchains collapsed using stabilisedlet_chains;manual_stripandif_same_then_elselints resolved invault.rs
[0.1.3] - 2026-04-13
Added
installsubcommand — 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 --globalflag selects global config forclaude-codeandcursor(local is default)--dry-run,--forceflags; auto-backup before any write (.json.bak)- Cross-platform config path resolution (macOS / Windows / Linux)
- Clients: Claude Desktop, Claude Code (local
uninstallsubcommand — interactive or direct removal of MCP config entrylistsubcommand — show installation status across all detected AI clientslogssubcommand — print log file path, last 100 log entries, and a GitHub issue link for bug reports--no-editflag — 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/-vflag — enables DEBUG-level logging to stderr without needingRUST_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
- macOS:
- 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 failurescripts/prepare-release.sh— automates version bump across all 9 package files and updatesCHANGELOG.mdcodecov.yml— Codecov flag configuration for separate Rust and TypeScript coverage reporting- Code coverage badge in README (Codecov)
platform.ts— platform detection logic extracted frombin.tsinto a separate, testable module with named exportsplatform.test.ts— 16 vitest unit tests coveringdetectPlatform,detectMusl, andresolveBinaryPathvitest.config.ts— vitest configuration with@vitest/coverage-v8lcov 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-fileusage, and bug-report instructions - README: added language switcher (
English | Русский) below the header - CI: workflow branch target changed from
maintomaster; all action versions updated to latest - CI: added
coveragejob —cargo llvm-cov --lcovfor Rust andvitest --coveragefor TypeScript, both uploaded to Codecov with separate flags bin.tsrefactored into a thin launcher (spawnSync); all detection logic moved toplatform.tstsconfig.json: test and config files excluded from the build output
Fixed
- CI was not running on
masterbranch (was targeting non-existentmain) bin.tsplatform logic was untestable due to inlinerequire()calls; fixed by moving to static imports inplatform.ts
Full Changelog: v0.1.2...v0.1.4