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
[!WARNING] Not on PyPI yet. The package has not been published; a release to PyPI is only planned. Commands such as
pipx install obsidian-multivault-searchwill therefore fail. Until then, install from a clone of this repository.
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
There are no dependencies, so plain pip install . into a virtual environment
works just as well.
Once the package is published on PyPI, the following will work — these commands do not work yet:
pipx install obsidian-multivault-search
# or
uv tool install obsidian-multivault-search
# or, to try the tool without installing it:
uvx --from obsidian-multivault-search obmvs TERM
Every variant installs the two commands obsidian-multivault-search and
obmvs.
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
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 shows the match with up to three words before and after it.
Markdown formatting (headings, */_/`, links, wikilinks, table rules,
HTML tags …) 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 |
words before/after the match (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.0.tar.gz.
File metadata
- Download URL: obsidian_multivault_search-0.1.0.tar.gz
- Upload date:
- Size: 13.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7bb8325e007eccb3de512a87402a62451f3a7f95d38d734e057d4861a7653476
|
|
| MD5 |
57702f911819dceabe70f263a901674d
|
|
| BLAKE2b-256 |
766f5580fad795f97ce6fd7292eeff7e2dd20a6ec24314d772a7e6a75cbade23
|
Provenance
The following attestation bundles were made for obsidian_multivault_search-0.1.0.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.0.tar.gz -
Subject digest:
7bb8325e007eccb3de512a87402a62451f3a7f95d38d734e057d4861a7653476 - Sigstore transparency entry: 2759953859
- Sigstore integration time:
-
Permalink:
saltedmatt/obsidian-multivault-search@b635f818c56fcebfe249654ffa372ed0a9616290 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/saltedmatt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b635f818c56fcebfe249654ffa372ed0a9616290 -
Trigger Event:
release
-
Statement type:
File details
Details for the file obsidian_multivault_search-0.1.0-py3-none-any.whl.
File metadata
- Download URL: obsidian_multivault_search-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.8 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 |
d40de2bc2c3235706fbcee9f640b5b3d36ddd8492e07cab142d27851f2069dff
|
|
| MD5 |
e59c38a603cd4a829490f71b67651a36
|
|
| BLAKE2b-256 |
d0d7cb1160070039c9264cde1442019797a1ff6b488e63ca9a47bc8728fb4b77
|
Provenance
The following attestation bundles were made for obsidian_multivault_search-0.1.0-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.0-py3-none-any.whl -
Subject digest:
d40de2bc2c3235706fbcee9f640b5b3d36ddd8492e07cab142d27851f2069dff - Sigstore transparency entry: 2759954121
- Sigstore integration time:
-
Permalink:
saltedmatt/obsidian-multivault-search@b635f818c56fcebfe249654ffa372ed0a9616290 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/saltedmatt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b635f818c56fcebfe249654ffa372ed0a9616290 -
Trigger Event:
release
-
Statement type: