Use
Search
This page is for anyone looking something up in their own corpus: how a search is ranked, the filters you can type into a query, the commands that read, trace and delete what you find, and read-only SQL over structured data. The same search runs in the portal, the CLI and the mobile apps; the agent uses it too when it answers a question.
Searching
A search runs your query two ways at once: as BM25 keyword matching over full-text chunks, and as vector similarity against embeddings of the same chunks. The two ranked lists are merged with Reciprocal Rank Fusion (RRF), which rewards a document for ranking high on either list, so a document that matches your exact words or only your meaning still surfaces near the top.
-
Query
invoice from:maya after:2026-01-01 - ParseInline filters split from the free text; person filters resolved to people
Keyword
- BM25Full-text match over chunks
Always runs.
Semantic
- EmbedThe free text becomes a vector
- Nearest chunksVector index lookup
Skipped until an embedder is assigned and chunks are embedded.
- FuseReciprocal Rank Fusion of both lists
-
RankType boosts from
search.boostsand a balance across sources - ResultsDuplicates dropped, top results kept, each with a short ID
-
Read
omnesis show <id>
Filters restrict both lanes before anything is ranked. The ranking settings, including
search.boosts.typeBoosts, are described under
Operating → Configuration.
The semantic lane needs an embedder assigned (see Operating → Models) and chunks that have already been embedded. Until both hold, queries still return: keyword matching alone carries them, and meaning-aware ranking joins in for each document as its vectors land. There is nothing to switch on; the pipeline uses whatever signals exist at query time.
A query made only of filters, with no free text (from:maya type:email), skips
ranking altogether and lists the matching documents newest first.
❯ omnesis search "lease renewal"
1. Re: Lease renewal — 12-month extension (8.3%) a1b2c3d4 gmail email 05/14/26 Maya Reeves Attached is the signed renewal for the 12-month extension starting July 1... https://mail.google.com/mail/u/0/?authuser=you%40example.com#all/18f2a9c4e7b1d3a0 2. Lease renewal checklist (6.1%) e5f6a7b8 apple-notes note 05/02/26 Confirm the deposit terms, ask about bike storage, forward the signed copy...
2 results in 41ms, bm25:8ms, vec:23ms
# narrow with inline filters and a result cap
❯ omnesis search "invoice from:maya after:2026-01-01" --limit 5
Each result leads with a short document ID you can paste straight into
omnesis show, and ends with a link to the original when the source provides
one. The portal's search page and the apps run the same pipeline against the same index,
with the same query language.
Query syntax
Filters are typed inline, mixed freely with search text. Whatever is left after the filters are stripped becomes the query.
| Filter | Matches | Example |
|---|---|---|
from: |
Person is the sender, author, or owner. Alias: by: |
from:maya |
to: |
Person is a recipient of a message or an attendee of an event | to:"Jamie Lopez" |
with: |
Person appears in any role | with:maya |
type: |
Document type. Alias: in: |
type:email |
source: |
A source or provider — bare type, full source ID, or provider | source:gmail |
after: |
Date lower bound. Alias: since: |
since:"last week" |
before: |
Date upper bound. Alias: until: |
before:2026-03-01 |
#tag |
Tagged documents. Alias: tag: |
#travel |
Values with spaces take quotes (with:"Maya Reeves"). Dates are ISO
YYYY-MM-DD or a relative keyword: today, yesterday,
"last week", "last month", "last year". A date that
fails to parse is dropped, and the response carries a notice saying so (visible with
--json) rather than silently pretending the filter applied. Relative keywords
resolve to a UTC calendar date on the gateway's clock, not the device you are searching
from; pass an absolute date when a day boundary is what the query turns on.
Person filters resolve to people, not strings. A value is matched as an exact email
address, then as an exact phone number, then as part of a name, so
from:maya matches every person whose name contains "maya" (up to ten). Use a
full name to narrow the match or an email address to pin one person, and
me (from:me) for yourself.
Once resolved, every identity merged into that person counts: Omnesis merges identities
across sources into one person (see
People & graphs), so
from:"Maya Reeves" finds her whether a document carries her work email, her
personal address, or her phone number. A value that matches no one is reported as a notice
(visible with --json). Repeating a person filter widens it (from:maya from:jamie
means either); different filters combine with AND.
Beyond search
Search finds documents; these commands work with what you found. The document commands —
show, trail, and delete — accept the short IDs
printed in search results; any unambiguous prefix works.
# read one document in full
❯ omnesis show a1b2c3d4
# find the indexed document for a page you have open
❯ omnesis lookup "https://docs.google.com/document/d/1AbC.../edit"
# the latest documents from one source (IDs from: omnesis sources)
❯ omnesis recent gmail:you@example.com
# the chronological story around a document — replies, attachments, related events
❯ omnesis trail a1b2c3d4
# the same neighbourhood as a graph: documents, people and the links between them
❯ omnesis graph a1b2c3d4
# fuzzy people lookup by name, email, phone, or handle
❯ omnesis people search maya
# delete a document for good (a later sync or capture will not add it back)
❯ omnesis delete a1b2c3d4
# delete only this copy; the next sync or capture may add it again
❯ omnesis delete a1b2c3d4 --copy
trail walks the reference graph — thread replies, attachments, links, shared
people — outward from a document and lays the connected documents out in time order. One
invoice becomes the whole story: the quote before it, the chat where it was discussed, the
calendar event it paid for.
graph walks the same links but returns the neighbourhood as a graph rather
than a timeline: every document and person reachable from the seed, and the edge that
connects each pair. --edges and --vertex-types limit what the
walk follows, --hops bounds how far it goes (at most 15),
--bound-rows adds the analytics rows bound to the documents it reaches, and
--json prints the raw result.
Deleting has two forms, and the CLI, the portal and the phone apps all offer both. Delete for good removes the document and its extracted attachments, and records that it must stay gone: the source that produced it will not add it back on a later sync or capture, and the analytics rows that were about that page go with it. Removing the whole source clears that record, so a re-added source starts clean. Delete this copy removes the document as well, but the next sync or capture may add it again. Neither touches the original in the provider or on the phone.
omnesis delete asks you to confirm, with Cancel preselected unless you passed
--copy; in a script, or with --json, pass --yes. A
day document built from quick captures cannot be deleted directly: delete or amend its
notes on the portal's Tell Omnesis page instead.
SQL over your analytics
Structured sources — health metrics, screen time, workouts, browser visits — land as typed
rows in an analytics database (DuckDB) alongside the document index.
omnesis analytics lists every table with its description and row count (add
--json for column schemas); omnesis sql queries them directly,
as does the Debug → SQL tab in the portal.
# which apps ate the last 30 days?
❯ omnesis sql "SELECT app_name, round(sum(total_seconds)/3600.0, 1) AS hours FROM screen_time_daily WHERE date >= current_date - INTERVAL 30 DAY GROUP BY app_name ORDER BY hours DESC LIMIT 3"
app_name hours ─────────────── Safari 31.4 Mail 18.2 Messages 12.9
3 rows (12ms)
# monthly running volume this year
❯ omnesis sql "SELECT strftime(start_time_local, '%Y-%m') AS month, round(sum(distance_m)/1000.0, 1) AS km FROM strava_activities WHERE sport_type = 'Run' GROUP BY 1 ORDER BY 1"
Queries are read-only by construction: each one runs inside a read-only transaction on the gateway's own database instance, whose access to the filesystem is switched off, so SQL can inspect your data but never modify it or reach outside the database. Which tables exist depends on which sources you have connected.
From your own tools
Everything on this page is a thin client over the gateway's authenticated HTTPS API. The
portal, the CLI and the apps all call the same endpoints, and so can any script holding a
token; Setup → Tokens covers minting one with
omnesis tokens create and choosing its scopes. To let an AI tool such as
Claude or ChatGPT search your corpus, connect it over MCP instead: see
Agents & MCP. The full command list is in
omnesis --help.
The graph walk behind omnesis graph is one endpoint,
POST /graph/walk, open to any token with the read scope. It
starts from up to 50 documents, named by ID or unambiguous prefix, takes the same limits
as the command's flags, and returns the vertices and edges it
reached, with truncated set when a limit cut the walk short.
curl -s -X POST "$OMNESIS_GATEWAY_URL/graph/walk" \
-H "Authorization: Bearer $OMNESIS_TOKEN" -H "Content-Type: application/json" \
-d '{"start": [{"kind": "document", "id": "a1b2c3d4"}], "maxHops": 2}'