Metadata filters
Every search box accepts inline metadata filters that AND with the remaining free text — narrow results by folder, tag, or frontmatter field without leaving the query. On the desktop/CLI/MCP path, filter terms compile to bases where-clause lines and feed through the bases parser, so bases stays the single grammar/semantics authority.
Easy mode
path:Tasks/— only notes under that folder (segment-aware:Tasks/never matches a sibling likeTasksArchive/). Compiles towhere __path under "Tasks/".tag:ml— notes whosetagsarray containsml(case-insensitive). Compiles towhere tags is "ml".has:status/-has:status— frontmatter field present / absent. Compile towhere status exists/where status missing.[status:active]— frontmatter field equals a value (case-insensitiveis). Quote values with spaces:[status:"in progress"].- Mix filters with free text —
path:Tasks/ [status:active] renewalfinds notes underTasks/withstatus: activementioning "renewal".
A query with no filter syntax at all behaves byte-identically to the pre-filter engine (this is a load-bearing invariant of the parser, not just a convenience) — filters never change behavior for a plain-text search.
Power
[key:!value]→is not.[key:~value]→contains.[key:>n],[key:>=n],[key:<n],[key:<=n]→gt/gte/lt/lte(numeric/date compares), e.g.[modified:>=2026-07-01].modifiedis a special-cased alias for the computed__modifiedmeta field (core parses ISO dates on it); the dunder spelling[__modified:>=…]also works.- Quoted text is never parsed as a filter —
"path:Tasks/"searches for that literal string instead of applying it. This applies to any fully double-quoted token, not justpath:. - Values with spaces must be double-quoted:
[status:"in progress"]. Apath:value may be quoted the same way:path:"My Folder/Sub". - A malformed bracket term (no colon, empty key or value, unbalanced/half quoting, a key containing whitespace/quotes/backslashes, or the literal key
or— which would collide with bases' OR-line splitting) is never an error: it degrades to literal free text and is matched verbatim, exactly like any other search word. - Multiple filter terms AND together (bases' AND-of-lines semantics); there is no OR across filter terms.
- From the CLI:
solomon search "renewal" --path Tasks/ --where 'status is "active"'ANDs a folder prefix and a full bases where-clause onto the query, on top of whatever inlinepath:/[key:value]terms the query text itself contains. The MCPsearchtool takes the samepath/whereparameters, with identical semantics — one grammar, three ways to reach it (inline text, CLI flags, MCP params), all composing with AND. - Regex mode (
--regexon the CLI,regex: trueon the MCP tool) never minespath:/tag:/has:/[key:op value]out of the pattern itself — a regex like[a-z]or a literaltag:urgentruns as written. Only the structuredpath/whereparams are consulted in regex mode; inline filter syntax is not extracted from a regex pattern. - A malformed
whereclause (CLI--where, or the MCPwhereparam) is surfaced asresult.error({message, line}), never a thrown/tool-call error — the same conventionbase_query/solomon baseuse for a bad DSL string.
Where each piece of syntax works
| Surface | path: / tag: / has: / -has: |
[key:value] |
not-equal / contains / numeric compares |
|---|---|---|---|
| Desktop, CLI, MCP | full | full | full |
| Webapp, iOS | path: / has: / -has: only (no tag:) |
yes (is, case-insensitive, array-any) |
degrades to plain equality — no is not/contains/numeric/date compares, no meta fields, no OR |
The webapp's mirror is a deliberately minimal reimplementation supporting exactly is/exists/missing plus a segment-aware path: prefix — chosen because those three need no numeric/date coercion and so can't silently drift from core's evaluator the way a second full bases grammar in TypeScript could. Anything outside that subset (a bracket term using !/~/>/>=/</<=, or tag:) is not specially parsed there and falls through to plain equality/exists/missing on the literal key/value written, or is left as free text.
Recipes
- Active tasks:
path:Tasks/ [status:active] - Tasks missing a status:
path:Tasks/ -has:status - Recently touched notes:
[modified:>=2026-07-01](desktop/CLI/MCP) - Not-done, not archived:
[status:!done] -has:archived - Assignee substring match:
[assignee:~david] - CLI, combining inline + flags:
solomon search "renewal" --path Tasks/ --where 'status is "active"' - MCP
searchtool, same effect:{"query": "renewal", "path": "Tasks/", "where": "where status is \"active\""}
Related
- [[solomon CLI reference]] —
solomon search's--path/--whereflags use this same grammar. - [[MCP tool surface]] — the
searchtool'spath/whereparams. - [[Query your vault with bases]] — the shared bases where-clause grammar these filters compile down to.