obsidian-multivault-search
Command-line search for notes across multiple Obsidian vaults. Pure Python, standard library only, no dependencies (Python ≥ 3.11).
The command is available under two names: obsidian-multivault-search and the
short alias obmvs. Both do exactly the same; this README uses obmvs.
Installation
Try the tool without installing it:
uvx --from obsidian-multivault-search obmvs TERM
Installation with pipx or uv tool:
pipx install obsidian-multivault-search
# or
uv tool install obsidian-multivault-search
Installation from a clone of this repository:
git clone https://github.com/saltedmatt/obsidian-multivault-search
cd obsidian-multivault-search
uv tool install . # installs both commands
# or, without installing anything:
python -m obsidian_multivault_search TERM # with src/ on PYTHONPATH
Project layout
src/obsidian_multivault_search/
├── __init__.py public API: cli(), main(), __version__
├── __main__.py python -m obsidian_multivault_search
├── _meta.py version and invoked program name
├── markdown.py stripping markdown formatting off note text
├── vaults.py finding vaults and their notes
├── search.py matching terms, extracting context
└── cli.py argument parsing, search run, output
Usage
obmvs TERM [TERM ...] # searches the whole home directory; AND semantics
obmvs -d ~/w/vaults TERM # searches only below that path
obmvs -L # list the vaults that were found
- Vault = a directory containing an
.obsidiansubfolder; the vault name is the name of that directory. Only such directories are searched. If a vault lies inside another vault, its notes belong to the inner (nearest) vault. - Note = a
.mdfile. Hidden folders (.obsidian,.trash,.git…) are skipped, symlinks are not followed by default. - Search: substring, case-insensitive. Multiple terms are ANDed together.
Quote phrases containing spaces:
obmvs "open invoice" 2025. - Exclusion:
-n TERMexcludes notes containing the term (repeatable). Exclusions always apply in addition to the search terms,-oincluded. If only-nis given, every note that contains none of the terms is listed – without a context column in that case.
Output
One line per matching note, fields separated by tabs, sorted by vault name and note name:
vault-name<TAB>note-name<TAB>context
The context is a window of up to six adjacent words around the match: three
per side, and whatever one side cannot use goes to the other one. A match at
the beginning of its line therefore comes with six words behind it rather than
three. -C N sets the number per side, so the window holds at most 2 × N
words; -C 0 shows the match on its own.
The window never leaves the note line the match was found on — the words behind a line break usually belong to another paragraph or heading and would only mislead.
Markdown formatting is stripped; for links the display text is kept. Only the
first match per note and search term is shown; with multiple terms the
contexts are separated by |.
Options
| Option | Meaning |
|---|---|
-n, --not TERM |
term that must not occur (repeatable) |
-d, --dir PATH |
search area (repeatable, default: $HOME) |
-C, --context N |
adjacent words before/after the match, on its line (default: 3) |
-s, --case-sensitive |
respect upper/lower case |
-w, --word |
match whole words only |
-e, --regex |
treat search terms as regular expressions |
-o, --or |
combine with OR instead of AND |
-p, --relpath |
print the path relative to the vault instead of the note name |
-F, --sep CHAR |
output field separator (default: tab) |
-L, --list-vaults |
only list the vaults that were found |
--max-depth N |
maximum depth when looking for vaults |
--follow |
follow symlinks |
--color auto|always|never |
highlight matches (default: auto, terminal only) |
-j, --jobs N |
parallel reads |
-V, --version |
print the version and exit |
Exit codes: 0 = matches, 1 = no matches / no vaults, 2 = usage error.
Examples
# notes containing both terms
obmvs kubernetes deployment
# kubernetes, but without any mention of helm or docker
obmvs kubernetes -n helm -n docker
# all notes that do not contain "status"
obmvs -n status
# whole words only, more context, readable columns
obmvs -w -C 6 backup | column -t -s $'\t'
# post-process note names only
obmvs -p invoice | cut -f1,2
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option (SPDX: Apache-2.0 OR MIT).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you shall be dual licensed as above, without any additional terms or conditions.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file obsidian_multivault_search-0.1.1.tar.gz.
File metadata
- Download URL: obsidian_multivault_search-0.1.1.tar.gz
- Upload date:
- Size: 14.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a15caab6d9b09addeff33576e4c77002fb12d0785e94907a0ae82390073bf16
|
|
| MD5 |
a2bd55f6913ce699bbcde624ffa51d8a
|
|
| BLAKE2b-256 |
a58444584248899fd833e858aaa0ea43d3865bf571bfc0fcf27f8bf60571456f
|
Provenance
The following attestation bundles were made for obsidian_multivault_search-0.1.1.tar.gz:
Publisher:
release.yml on saltedmatt/obsidian-multivault-search
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
obsidian_multivault_search-0.1.1.tar.gz -
Subject digest:
4a15caab6d9b09addeff33576e4c77002fb12d0785e94907a0ae82390073bf16 - Sigstore transparency entry: 2771213817
- Sigstore integration time:
-
Permalink:
saltedmatt/obsidian-multivault-search@c3060f7caad4dafed51190606ae90f566b03f759 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/saltedmatt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c3060f7caad4dafed51190606ae90f566b03f759 -
Trigger Event:
release
-
Statement type:
File details
Details for the file obsidian_multivault_search-0.1.1-py3-none-any.whl.
File metadata
- Download URL: obsidian_multivault_search-0.1.1-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d6ca8f52068297cb8b5147623c8f5da07ce6bbf4576ba6e81726e81081dfaf7
|
|
| MD5 |
f8608970eb1556cd599fb87f60ce7abc
|
|
| BLAKE2b-256 |
3f07b31d8a992e1dcc1ec2ff64014e7490b0dd4262c726d5ae9089f290a94446
|
Provenance
The following attestation bundles were made for obsidian_multivault_search-0.1.1-py3-none-any.whl:
Publisher:
release.yml on saltedmatt/obsidian-multivault-search
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
obsidian_multivault_search-0.1.1-py3-none-any.whl -
Subject digest:
6d6ca8f52068297cb8b5147623c8f5da07ce6bbf4576ba6e81726e81081dfaf7 - Sigstore transparency entry: 2771213871
- Sigstore integration time:
-
Permalink:
saltedmatt/obsidian-multivault-search@c3060f7caad4dafed51190606ae90f566b03f759 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/saltedmatt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c3060f7caad4dafed51190606ae90f566b03f759 -
Trigger Event:
release
-
Statement type: