Connect dsh to a local Obsidian vault: search, read, write, move, and trash notes through `obsidian_*` tools.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-obsidian
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:mingzeng21/dsh-obsidian
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
Connect DeepSeek Harness (dsh) to a local Obsidian vault. Because an Obsidian vault is just a folder of Markdown files on disk, your dsh agent can search, read, write, move, and trash notes directly — no MCP server, no OAuth.
中文 | English
What it does
Once dsh-obsidian is installed, your dsh agent can read and write a local Obsidian vault directly. On startup the plugin detects your vault (or reads the path you configured) and mounts 12 obsidian_* tools covering search, read, write, append, move, delete, and backlink lookups.
Features
- Zero server — reads/writes the vault filesystem directly; no Local REST API community plugin, no standing MCP server.
- Safe by default — deletes move notes into
.trash/(reversible), paths can't escape the vault root, and.obsidian/is never touched.
How it works
dsh agent calls obsidian_* tools
│
▼
VaultAccess interface
└─ FsAccess — node:fs + hand-written frontmatter/wikilink parsing (default, pure filesystem)
On startup the plugin resolves the vault root as "explicit vaultPath wins, else auto-detect from obsidian.json"; when useCli is on and the CLI is detected, property:set/property:remove delegate to it and everything else stays on FsAccess; any CLI failure silently falls back to FsAccess.
Install
dsh plugin --profile web add dsh-obsidian
Replace web with the profile you run your agent in (web, headless, tui, …).
Update
Re-running add pulls the latest (latest):
dsh plugin --profile web add dsh-obsidian
Or pin a specific version:
dsh plugin --profile web add dsh-obsidian@0.2.6
Restart the harness (dsh web) or refresh the Web UI after updating; verify with dsh plugin --profile web list.
Uninstall
dsh plugin --profile web remove dsh-obsidian
Configuration
| Key | Default | Description |
|---|---|---|
vaultPath |
(auto-detected) | Absolute path to the vault; leave empty to auto-detect the currently-open vault from obsidian.json |
useCli |
false |
Delegate property:set/property:remove to the obsidian CLI when available |
vaultWorkspaceOnly |
false |
Expose obsidian_* tools only to agents whose session working directory is inside the vault; agents without a working directory receive no tools |
excludeDirs |
[".obsidian", ".git", ".trash"] |
Directories excluded from search and list |
Paths and Windows compatibility
- Tool paths are vault-relative and are always returned with
/; inputs may use either/or\\. - Tool path arguments must be relative. Unix absolute paths, Windows drive-letter paths, and UNC absolute paths are rejected; the configured
vaultPathmay be a local Windows path or a UNC vault root. - Windows note identity is case-insensitive and recognizes
.md,.MD, and other case variants; Unix keeps case-sensitive behavior and the existing.mdsemantics. - Search removes
\\rfrom CRLF lines while preserving Unicode paths and content.ripgrepis an optional accelerator: if it is unavailable or fails, the built-in scanner is used automatically. - Vault discovery prefers the platform-native
obsidian.jsonlocation (Windows%APPDATA%, macOSLibrary/Application Support, Linux.config) before trying other known locations..exe/.cmdCLI forms are supported and filesystem access remains the fallback.
Tools
| Tool | Purpose |
|---|---|
obsidian_list |
List notes in the vault (filter by subdirectory, limit results) |
obsidian_search |
Full-text search with match lines + context (case-insensitive; Windows recognizes mixed-case .md extensions) |
obsidian_read |
Read a note (body + parsed frontmatter) |
obsidian_frontmatter |
Read only a note's YAML properties |
obsidian_backlinks |
Find notes linking to a note via [[wikilinks]] |
obsidian_write |
Create or overwrite a note (creates parent directories) |
obsidian_append |
Append text to the end of a note |
obsidian_move |
Move/rename a note (updates [[wikilinks]] in pure filesystem) |
obsidian_delete |
Trash a note into .trash/ (reversible, never permanently deletes) |
obsidian_set_property |
Set or update a single frontmatter property (YAML) on a note |
obsidian_delete_property |
Remove a frontmatter property from a note |
obsidian_tags |
List all tags in the vault with usage counts |
All tool path arguments are relative to the vault root (e.g. Folder/note.md); paths returned to the agent always use /.
Safety
- Path containment — every path argument is resolved and checked to stay inside the vault root; escapes (
../, Unix/Windows absolute paths, or UNC paths) are rejected. - Reversible delete —
obsidian_deleteonly moves notes into the vault's.trash/, never permanently deletes. - Hands off
.obsidian/— search and list exclude.obsidian/,.git/, and.trash/by default. - Preserves frontmatter and wikilinks — reads/writes don't break YAML properties or
[[links]](unless the task explicitly asks).
Requirements
- DeepSeek Harness (
dsh) - Node.js ≥ 22.12.0
Compatibility has been verified with dsh v0.1.7-rc.2: the new profile loader accepts the plugin bundle, all 12 tools register, and obsidian_list and obsidian_read execute successfully against a temporary vault. Earlier checks covered v0.1.5-alpha.1, v0.1.3-alpha.2, v0.1.3-alpha.1, v0.1.2-rc.1, v0.1.2-alpha.5, v0.1.2-alpha.4, v0.1.2-alpha.3, v0.1.2-alpha.2, v0.1.2-alpha.1, v0.1.1-rc.2, and v0.1.0-rc.8.
Development
npm install
npm run build # tsdown → lib/
npm run typecheck # tsc --noEmit
npm test # vitest
Changelog
0.2.6
- Add the optional
vaultWorkspaceOnlysetting to exposeobsidian_*tools only to agents whose working directory is inside the vault. It defaults tofalseto preserve cross-workspace access.
To show Obsidian tools only in DSH workspaces inside the vault, set this in the active profile's cordis.patch.yml:
- id: obsidian
config:
vaultPath: /absolute/path/to/ObsidianVault
vaultWorkspaceOnly: true
0.2.5
- Fix double quoting of Windows
.cmdscripts so commands work when script paths or arguments contain spaces or Unicode characters.
0.2.4
- Harden Windows compatibility: standardize agent-facing paths on
/, accept\\inputs, and reject drive-letter/UNC absolute path escapes. - Fix Windows search, backlink, move/delete result paths, and wikilink rewriting; cover CRLF, Unicode, and mixed-case Markdown extensions such as
.MD. - Support Windows
.exe/.cmdforms forripgrepand the Obsidian CLI, with automatic fallback to built-in implementations when unavailable or failing.
0.2.3
- Fix source typecheck/build compatibility after
dshv0.1.2-alpha.2/alpha.3 stopped re-exportingJsonValuefrom@deepseek-ai/dsh-tools, while preserving compatibility with older dsh releases.
0.2.2
obsidian_tagsand inline#tagextraction now support CJK and other Unicode characters.obsidian_backlinks/obsidian_moveresolve[[wikilinks]]uniquely following Obsidian's rules: same-named notes are no longer over-matched, and ambiguous links are no longer mis-rewritten.obsidian_set_property/obsidian_delete_propertypreserve existing YAML comments, anchors/aliases, and block formatting instead of re-serializing.- Reliability: atomic writes when
obsidian_moveupdates links, fallback for cross-filesystem moves/deletes, and consistent search results with or without ripgrep.
License
MIT © 2026 MingZeng
Links
More in this category
vectorize-io/hindsight#coding-agents★ 42988
Hindsight, agent memory that learns: long-term project memory with auto recall and retain, knowledge pages, deep reflection, and per-repo memory banks.
volcengine/OpenViking#examples/dsh-memory-plugin★ 38990
OpenViking memory and context bundle for DeepSeek Harness: pre-step auto-recall and profile injection, session capture, `viking://` URI guarding, and recall/write memory tools backed by an OpenViking server.
agentscope-ai/ReMe#dsh★ 3534
Connects DeepSeek Harness to ReMe's local-first, self-evolving personal knowledge base: automatically captures completed main-agent conversations as user-owned Markdown memory, searches conversations and source material through reme_search with BM25, optional embeddings, and wikilink expansion, and schedules daily memory consolidation.
zilliztech/memsearch#MemSearch★ 2682
Shared Markdown memory for DSH and other coding agents, with automatic capture, pre-step context injection, searchable recall, and memory-to-skill self-evolution through a review panel.
vshulcz/deja-vu#extensions/dsh★ 1093
Reads the session files thirty-three other coding agents on this machine already wrote — Claude Code, Codex, Cursor, VS Code Copilot Chat, opencode, OpenClaw, Hermes, Kimi, Cline, Zed and more — including sessions from before it was installed: six tools (deja_recall, deja_session, deja_blame, deja_fix, deja_how, deja_remember), a /deja command, and optional automatic recall added to the runtime context. Local BM25 index, no LLM, no embeddings, no network (dsh plugin --profile web add dsh-deja).
adoresever/graph-memory★ 633
Traceable, searchable cross-session memory for DeepSeek Harness — conversation knowledge as typed graph nodes (TASK/SKILL/EVENT) and typed edges.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.