Install
$ agentstack add skill-gerodp-hermes-productivity-skills-obsidian-notes ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Obsidian Notes
Read and write notes in an Obsidian vault — which is just a folder of Markdown (.md) files. Four things:
list— list notes, all of them or only those **modified in a time
window** (--period this-week, --days 7, --start/--end).
show— print a single note's contents.save— write a new note into the vault, e.g. save the current chat.check— verify the vault loads (run this first).
Zero dependencies (Python stdlib only). Windows are computed in local time with Monday-start weeks (same vocabulary as the other Hermes report skills). Hidden/internal folders (.obsidian, .trash, .git, any dot-folder) are skipped.
Script path: ~/.hermes/skills/notes/obsidian-notes/scripts/obsidian_notes.py
When to Use
- "What notes did I take this week?" →
list --period this-week - "List all my notes" →
list - "Show me my Ideas note" →
show Ideas - "Save this chat to my vault" →
save(pipe the transcript — see below) - "Notes I created last month" →
list --period last-month --by created
For a prose weekly summary, run list --period this-week --json to find the week's notes, show the relevant ones, then summarise them yourself.
Prerequisites
Python 3.8+ (stdlib only — no installs). One environment variable, injected automatically into the sandbox from ~/.hermes/.env:
OBSIDIAN_VAULT— absolute path to the vault folder (the directory you
opened in Obsidian; it contains your .md files and a .obsidian/ folder).
Set it once (don't paste the path into chat repeatedly):
hermes config # edit config, or
$EDITOR ~/.hermes/.env # add: OBSIDIAN_VAULT=/Users/you/Obsidian/MyVault
Always run check first to confirm the vault loads. You can override the configured path ad hoc with --vault PATH on any command.
Finding the vault when OBSIDIAN_VAULT isn't set
An Obsidian vault is any folder containing a .obsidian/ subfolder. If the path isn't configured, locate it (replace $HOME as needed for another user):
# Search a few levels deep for the marker folder that defines a vault:
find "$HOME" -maxdepth 4 -type d -name .obsidian 2>/dev/null
# Or match common naming patterns:
find "$HOME" -maxdepth 3 \( -iname '*obsidian*' -o -iname '*vault*' \) -type d 2>/dev/null
Vaults commonly live in ~/Documents//, in a project folder (e.g. ~//_vault/), or another work directory — not always under ~/Documents. Point OBSIDIAN_VAULT at the folder that holds .obsidian/, never at a single .md file. Verify with check --vault /full/path, then save it once: echo "OBSIDIAN_VAULT=/full/path" >> ~/.hermes/.env.
Commands
SCRIPT=~/.hermes/skills/notes/obsidian-notes/scripts/obsidian_notes.py
check — verify the vault loads + summary
python3 $SCRIPT check
Prints the vault path, note count, total size, and the modified-date span. Run this first; if it errors, fix OBSIDIAN_VAULT before anything else.
list — list notes (all, or modified in a window)
python3 $SCRIPT list # ALL notes, newest-modified first
python3 $SCRIPT list --period this-week # modified this week
python3 $SCRIPT list --period last-week
python3 $SCRIPT list --days 7 # modified in the last 7 days
python3 $SCRIPT list --start 2026-06-01 --end 2026-06-15
python3 $SCRIPT list --by created --period this-month # filter on creation time
python3 $SCRIPT list --folder Daily # only notes under a subfolder
python3 $SCRIPT list --sort name # sort by path instead of time
python3 $SCRIPT list --limit 0 --json # everything, machine-readable
With no window flag, list returns every note. Add a window (--period / --days / --start/--end) to filter to notes touched in that range — by modified time, or created time with --by created. Output columns: Note (path relative to the vault), Modified, Created, Size, sorted newest-first by default. Text output caps at --limit rows (default 50; --limit 0 = no cap); --json is never capped.
show — print a note's contents
python3 $SCRIPT show Ideas # by note name (basename)
python3 $SCRIPT show "Daily/2026-06-24.md" # by path relative to the vault
python3 $SCRIPT show Ideas --no-frontmatter # body only, no YAML block
python3 $SCRIPT show Ideas --json # {frontmatter, content, ...}
Resolves a bare name (with or without .md) by matching note basenames; if a name is ambiguous it lists the candidates so you can pass the full relative path. Pass a relative path to be exact.
save — write a note (e.g. save the current chat)
The script writes whatever content it's given; the agent supplies the text. To save the current session chat, compose the transcript/summary as Markdown and pipe it on stdin (or pass --content-file):
# Save the current chat — agent pipes the transcript on stdin:
printf '%s' "$CHAT_MARKDOWN" | python3 $SCRIPT save \
--title "Chat 2026-06-26 — weekly summary" --folder Chats --tag chat
python3 $SCRIPT save --title "Quick note" --content "One-liner body."
python3 $SCRIPT save --title "Log" --content-file /tmp/notes.md
python3 $SCRIPT save --title "Log" --append --content "more" # add to an existing note
python3 $SCRIPT save --title "Log" --overwrite --content "replaced"
The title becomes the filename (path separators and filesystem-illegal characters are replaced with spaces). A note is created with YAML frontmatter (title, created = today, any --tags, source: hermes) followed by the body. Options:
| Flag | Meaning | | --- | --- | | --title | required — note title → filename | | --folder | subfolder within the vault to write into (created if needed) | | --tag | a frontmatter tag (repeat for several) | | --content / --content-file | body inline / from a file (else read from stdin) | | --append | if the note exists, append the new content under a dated ## Added … separator | | --overwrite | if the note exists, replace it entirely | | --source | frontmatter source: value (default hermes) |
If the target file already exists and neither --append nor --overwrite is given, save refuses and tells you — it never silently clobbers a note.
How to save the current chat (agent guidance)
- Build a Markdown transcript of the conversation (e.g.
**User:** …/
**Claude:** … turns, or a summary if the user asked for one).
- Pick a descriptive
--title(include the date) and, optionally, a
--folder (e.g. Chats) and --tags.
- Pipe the Markdown into
saveon stdin. Confirm the written path back to
the user.
Weekly summary workflow (agent guidance)
When the user asks for a summary of the notes they took this week (or any window), the script gathers; you summarise. Steps:
- Find the week's notes — machine-readable, never capped:
``bash python3 $SCRIPT list --period this-week --json ``
(Use --days 7, --start/--end, or --period last-week as asked. If the user's vault is mostly daily notes named by date, --by created can be closer to "notes I took" than --by modified.)
- Read each note in the returned
notes[].rellist:
``bash python3 $SCRIPT show "" --no-frontmatter ``
Read all of them before writing — don't summarise from titles alone.
- Write the recap yourself — synthesise themes, decisions, open questions,
and tasks across the notes (this is the LLM's job; the script does not do it).
- Optionally save the recap back into the vault so it's a note too:
``bash printf '%s' "$RECAP_MARKDOWN" | python3 $SCRIPT save \ --title "Weekly summary 2026-06-22 — 2026-06-26" --folder Summaries --tag weekly ``
Ask before writing if the user only wanted to read the summary in chat.
Keep the gather step deterministic (one list, then show per note) so the same week always yields the same source material.
Windows (shared by list)
| Flag | Meaning | | --- | --- | | --period | today, this-week, last-week, this-month, last-month, this-year, last-year | | --days N | the last N days, inclusive of today | | --start / --end | explicit YYYY-MM-DD range (both required, end inclusive) | | --by | modified (default) or created — which timestamp the window filters on |
Precedence: --start/--end > --days > --period. Current periods (today, this-week, this-month, this-year) are capped at today.
How dates are determined (read before interpreting list)
- Modified = the file's filesystem modification time (
mtime). - Created = the OS creation time where available (
birthtimeon macOS);
on Linux that isn't always exposed, so it falls back to the inode-change time (ctime), which can be later than the true authoring date.
- Both are converted to local dates. Note that **copying or syncing a vault
can reset these timestamps** — if creation dates look wrong, prefer a created: field in your notes' frontmatter and filter on that yourself (visible via show --json).
Pitfalls
- Vault path: point
OBSIDIAN_VAULTat the vault folder (the one with a
.obsidian/ inside), not at a single note.
- Timestamps after sync: Dropbox/iCloud/Git syncs often rewrite mtimes, so
"modified this week" may include notes you didn't actually edit. For a stable notion of "when I wrote this", use frontmatter dates.
- Ambiguous names: two notes with the same basename →
show NAMElists both;
pass the relative path to disambiguate.
savenever clobbers: existing file + no--append/--overwrite→ error.--start/--endmust be given together (YYYY-MM-DD); end is inclusive.
Verification
python3 ~/.hermes/skills/notes/obsidian-notes/scripts/obsidian_notes.py check
# → "OK — loaded Obsidian vault." with note count and modified-date span.
python3 ~/.hermes/skills/notes/obsidian-notes/scripts/obsidian_notes.py list --period this-week
# → table of notes modified this week.
Offline unit tests (temporary vault, no network) live next to the script:
python3 ~/.hermes/skills/notes/obsidian-notes/scripts/test_obsidian_notes.py
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: gerodp
- Source: gerodp/hermes-productivity-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.