Use
Mobile apps
Omnesis has native iOS and Android apps. Each is two things at once: a full client for your gateway — chat, search, people, devices — and the runtime for sources whose data only exists on the phone. This page covers getting an app onto your phone, pairing it, the phone-only sources, voice and quick capture, and what to do when phone data does not arrive. It assumes a running gateway (see Install).
Getting the apps
An official build is signed by the Omnesis maintainer under the published app identities; its notifications work without any setup on your gateway. A self-built app is one you build from the source repository and sign yourself; it needs your own push credentials for background notifications.
The official iOS app is distributed through one external TestFlight group, which Apple limits to 10,000 testers. The official Android app is in closed testing on Google Play: join the tester group, then opt in with the same Google account and install the app from the Play listing that page links to.
| Platform | Official build | Self-built |
|---|---|---|
| iPhone | Install through TestFlight | Build with Xcode |
| Android | Join the tester group, then opt in on Google Play; does not include the Call Log source | Build with Gradle; includes Call Log |
How each build receives notifications is covered in Notifications → Choose a transport.
Build and install iOS
You need a Mac with Xcode, XcodeGen, and an Apple development team. Copy
ios/Local.xcconfig.example to ios/Local.xcconfig and set
DEVELOPMENT_TEAM. Unless your team is authorized for the official App ID,
also set OMNESIS_BUNDLE_ID to a base identifier registered under your team
(for example com.example.myomnesis); the extension and Watch targets derive
their identifiers from it. Then generate the project:
# one-time dependency
❯ brew install xcodegen
❯ cp ios/Local.xcconfig.example ios/Local.xcconfig
# set DEVELOPMENT_TEAM and OMNESIS_BUNDLE_ID in ios/Local.xcconfig
❯ cd ios && xcodegen generate && open Omnesis.xcodeproj
In Xcode, select your physical iPhone as the destination and run the app. The simulator works for basic UI testing, but it does not provide your phone's HealthKit data. The App IDs and capabilities each target needs are listed in the iOS contributor guide.
Build and install Android
You need JDK 17, the Android SDK, and adb. The full edition you build
includes the Call Log source, which the Google Play app does not include. Build with the
committed Gradle wrapper, connect a phone with USB debugging enabled, and install the APK:
❯ cd android
❯ ./gradlew :app:assembleFullDebug
❯ adb install -r app/build/outputs/apk/full/debug/app-full-debug.apk
Choose your own package id, so your build never collides with the Google Play app. Run
omnesis push setup before building if you want background notifications; it
writes the package id and Firebase client values to the ignored
android/local.push.properties. Without push, you can put only
OMNESIS_ANDROID_APPLICATION_ID=dev.example.omnesis in that file. Keep the
same id for later updates to your build. See the
Android contributor guide
for the full process.
Pairing
On the gateway host, mint a pairing QR with the CLI:
❯ omnesis devices pair --kind ios
Expires in 599s. Scopes: admin, read, push:claim, write:apple-health, write:activity-segments, write:photos, write:core-location-visits
Scan this QR with the Omnesis app on your iPhone:
# … QR code rendered in the terminal …
Can't scan the code? In the Omnesis app, choose Paste JSON and paste:
# … the same payload as text …
● Works at home and away, as long as Tailscale is connected on the phone.
Address: Tailscale name · studio.tail-example.ts.net
Use --kind android for the Android app. The portal's Devices page and both
apps mint the same code with a kind picker. The QR carries the gateway URL, a pairing code
that expires after ten minutes, and how the phone should trust the gateway's certificate.
If the camera is unavailable, both apps accept the same payload through
Paste JSON. Manual entry, which takes the gateway URL
and pairing code typed by hand, carries no fingerprint, so it works only with a
certificate the phone trusts; the portal and the CLI print the code for it in that case.
The phone names its own device entry, which you can rename later with
omnesis devices rename.
For a gateway on a public HTTPS address, the phone checks the certificate the normal way,
so a routine certificate renewal does not require pairing again. For a private or
self-signed address, the QR instead carries the certificate's SHA-256 fingerprint, and the
app pins that gateway. If the public address differs from
gateway.publicBaseUrl — including a different port — add its exact origin to
gateway.pairingSystemTrustOrigins. The address you pair with also decides
where the phone works: a LAN or .local address only works at home. To use the
phone away from home, follow
Setup → Remote access before pairing.
The gateway chooses the address to put in the QR code, and the portal and the CLI show its
choice. It offers only addresses the phone being paired can use, puts the one that reaches
furthest first, and says where each works. Under the QR code, the portal lists the other
usable addresses under Use a different address, and the CLI prints each
with the --gateway-url that selects it. An address the phone would refuse is
named with the reason instead of being offered. An iPhone accepts the gateway's own
self-signed certificate only on the local network, at a private LAN address or a
.local name. Anywhere else, including at a Tailscale IP, iOS requires a
certificate it trusts, such as a Tailscale certificate for the gateway's Tailscale name.
An Android phone accepts the pinned certificate at any address it can reach.
The .local name offered is the one the gateway advertises itself (omnesis.local
unless gateway.mdns.hostname sets another), which it announces with the
machine's LAN addresses only. Give each gateway on one network its own name with
gateway.mdns.hostname; two that announce the same name answer for each other.
The machine's own .local name is not offered: on a host running Docker or
virtual machines its announcements can include addresses a phone cannot reach. A phone
paired by fingerprint on a gateway whose certificate renews, such as a Tailscale
certificate, stops connecting at the next renewal; the pairing screen gives the date, and
the Tailscale name avoids it.
--gateway-url states the address instead, and the CLI refuses one the phone
cannot use, with the reason and the alternatives. On a host with several network
interfaces, set OMNESIS_IOS_GATEWAY_URL in the CLI's environment to use one
address for every phone QR code, iOS and Android alike, from
omnesis devices pair and omnesis devices repair; a
--gateway-url flag still takes precedence.
On scan, the app exchanges the code for its own device token. The default grant is a
full-client token: admin (the app manages sources, devices, and models),
read (search and the agent), push:claim (fetching its
notification text), and write access for its on-device sources. To withhold management,
mint the code from the CLI with an explicit list:
omnesis devices pair --kind ios --scopes read,push:claim. The gateway always
restores write access for the phone's own on-device sources when it connects. The full
scope list is in Devices and connections.
iOS stores the credentials in the device-only Keychain; Android in encrypted preferences. Re-pairing and unpairing live in the app's Settings. Pair every iPhone or iPad separately: each receives its own gateway identity and token, and iOS pairing credentials do not sync through iCloud Keychain or a device restore. If iOS says Pair this device again, the app found a pairing credential that had reached it through iCloud rather than being issued to this device, and removed it. Your gateway data is untouched; mint a fresh code and pair it.
A paired phone reports its app version to the gateway, and
omnesis devices list and the portal's Devices page show it beside a reading:
current, behind or unsupported. Behind is ordinary rather than a fault;
the gateway keeps serving the app. Only unsupported asks you to update
the app, which you do on the phone: a
fleet update never updates phone apps.
Version compatibility explains each reading.
Settings → About on the phone shows the version, build and protocol
number to quote when asking for help.
Finding your way around
Both apps open on the agent chat. The menu reaches Search, Sources, People, Tell Omnesis and Audit, lists recent conversations, and carries Settings and a new conversation at its foot. Swipe right, or use the menu button, and the screen you are on slides aside to uncover it; tap the strip still showing to come back. There is no tab bar.
Settings → Gateway holds Configure Models, Configure Devices, Policies, and Authorize an MCP connection. The first three open as child pages; Authorize opens the code-gated access flow (a sheet on iPhone) described under Privacy controls.
If you return within an hour, the app reopens the conversation you were using. After an hour away, it opens the agent on a fresh empty conversation with the composer ready; the earlier conversation remains available from the menu.
The apps reach your data only through your gateway, and contain no telemetry or third-party analytics SDK. The phone is one more paired device, so when the gateway is unreachable the app is offline. Notification text also stays on the gateway: Apple's and Google's push services carry a fixed, content-free wake, and the app fetches the text over its paired connection. See Notifications.
Phone-only sources
Some data never leaves the phone by any other route — there is no server to sync from. For these, the app reads the data on-device and pushes extracted text and typed rows to the gateway. For photos, that means OCR text and labels computed on the phone, plus captions on supported iPhones — never the image itself.
Every source is off until you turn it on. After the first pairing, the app opens a short setup flow: you choose which of this phone's sources to add, and each chosen source gets a page that lists what is sent to your gateway and what stays on the phone before the platform's own permission prompt appears.
Nothing is preselected, and you can skip it: Settings → Set up this iPhone (or Set up this phone) reopens the same flow, and each source's card in Settings keeps its own toggle and a summary of what it sends. The app asks for notification permission only from the setup flow or from the Turn on notifications action in Settings; it does not prompt on its own. On Android it offers to exempt Omnesis from the system's pause for unused apps, so sources keep syncing on a phone you rarely open.
Each enabled source shows this phone's sync state, last successful update, errors, and a Sync now action. Once synced, the data is searchable like everything else and the structured rows are queryable with SQL — see Search, and the full catalogue in Available sources.
On iOS:
| Source | What it adds | Permission |
|---|---|---|
| Apple Health | HealthKit samples — activity, workouts, vitals, body composition, sleep, nutrition, mindfulness, environmental exposure, and mood (mood asks for separate confirmation) | HealthKit read consent, per data type |
| Photos & Screenshots | On-device OCR text and scene labels, plus optional captions on supported iPhones; place names reverse-geocoded from the photo's GPS metadata via the platform's geocoding service (coordinates only — never pixels) | Photo library (full or limited) |
| Activity Segments | Motion history — walking, running, cycling, driving segments | Motion & Fitness |
| Location Visits | Places you spend time — arrivals, departures, coordinates, accuracy, and resolved place details | Always-Allow location |
On iOS, Limited Photos access indexes only the items selected in the system picker. A Limited or Denied library view is never treated as proof that previously indexed photos were deleted. After Full access returns, Omnesis performs a complete library pass and republishes newly visible items without reducing the analysis already stored for them. Each sync also scans one small page of the accessible library, which eventually finds older imports and items newly exposed through Limited access.
HealthKit does not reveal after the prompt which data types you allowed, so Omnesis reports that consent as unknown rather than treating an empty result as proof that access is healthy. Background App Refresh is reported separately for every iOS source that depends on it.
On Android:
| Source | What it adds | Permission |
|---|---|---|
| Health Connect | Health records — activity and exercise, body measurements, vitals, sleep, nutrition and hydration, mindfulness, cycle tracking | Per-type Health Connect consent |
| Call Log (self-built only) | A document per day of calls, plus per-call analytics rows | Call log — included only when you build the app yourself; the Google Play app does not include it |
| App Usage | A screen-time document per day (total time, pickups, top apps), plus per-session and per-app daily analytics rows | Usage access (system Settings) |
| Photos & Screenshots | On-device OCR text and scene labels; place names reverse-geocoded from the photo's GPS metadata via the platform's geocoding service (coordinates only — never pixels) | Photos / media; optional media-location access for place names |
| Activity Segments | Activity-recognition segments | Physical activity |
On Android 14 and later, selected-photo access is usable but incomplete: Omnesis indexes the selected items, labels the source as limited, and never treats hidden items as deletions. Granting full access starts a complete library pass so older newly visible photos are included. Access to embedded photo locations is a separate, optional permission: denying it keeps photo text and labels syncing but omits place names.
Health Connect reports record-type consent separately from background-read and history access, so the app can say exactly which part is reduced. If Health Connect fails to read an enabled record type, the sync reports an incomplete result and names the affected types; data already uploaded is kept, and a later sync retries the failed reads. The permissions action opens general Health Connect settings when Android does not allow a direct link to the app's permissions. Re-enabling Activity Segments restores the activity history the phone still holds, both day summaries and analytics rows.
Permission health
Each enabled phone-only source regularly reports its permission state to the gateway. When access is reduced, the app shows the affected capability, its impact and the platform's repair action, and your phones receive a reminder. If a phone stops reporting, Omnesis says the source check is overdue; it never concludes that a permission was revoked from an empty sync or a quiet period.
A source can also show permission-degraded,
background-access-missing, or unavailable: the last sync
finished, but the phone reported that some collection is incomplete. Repair the source in
the app. omnesis sources sync --wait treats these states as completed but
unsuccessful, so automation receives a non-zero exit instead of waiting until timeout.
On several phones
Apple Health is shared across your Apple devices: they all read the same HealthKit library and Omnesis keeps one copy. If another iPhone already hosts it, setup offers three choices: leave it there, use both iPhones, or move it to this iPhone. Activity Segments, Location Visits, Health Connect, Call Log, App Usage and Photos are per device: turning one on for a second phone adds that phone's data alongside the first and keeps the first phone's history. These choices happen in the app before any system permission prompt; phone-only sources cannot be added from the portal or the CLI.
Photos from each phone are indexed separately, so an image that several devices can see through iCloud or another cloud service can appear several times, with different extracted text. Only text and metadata are uploaded, never the image bytes.
Turning a source off in the app stops this phone's uploads and detaches the phone from the source; the confirmation says what happens to the data, which depends on the source's mode and whether other devices still host it. Pause on source details keeps the source and its data. What detach, pause and remove do in each mode is described in Sources on several devices and Managing sources.
Voice and quick capture
Both apps can ask the agent or capture a note without navigating through the app. Asking requires an agent model assigned on the paired gateway. Capturing does not: notes go straight into the built-in Omnesis Notes source, where they join the searchable index. A capture made while the gateway is unreachable stays in the app's private on-device queue and syncs later. The portal offers the same typed capture on its Tell Omnesis page, which also lists every captured note newest-first so individual notes can be amended or deleted; see Sources.
On iPhone, say “Hey Siri, Ask Omnesis”; Siri then asks what you want to know. Say “Hey Siri, Omnesis note” or “Hey Siri, Omnesis capture” and Siri asks what to remember. Siri requires that follow-up because App Shortcut phrases cannot insert unrestricted dictated text into the opening phrase. On iOS 18 or later, add the Tell Omnesis control from the Control Center controls gallery; tapping it opens the capture screen and starts listening.
The same Ask Omnesis and Omnesis note shortcuts are available on the Apple Watch and relay through its paired iPhone. The Watch app also offers Ask Omnesis and Omnesis note complications: add them to a watch face, and tapping one opens dictation straight away; tap Done to send. When the iPhone app does not pick up a question or note within about twenty seconds, the watch queues it for the next time the iPhone app runs: a queued note is saved with its original time, and a queued question is answered by notification, or dropped if the iPhone receives it more than ten minutes later.
On Android, Gemini or Google Assistant can invoke the installed App Actions for Ask Omnesis and Tell Omnesis. The custom one-utterance phrases are English (United States) only. Long-press the Omnesis launcher icon for matching Ask Omnesis and Tell Omnesis shortcuts. For one-tap capture from anywhere, open the expanded Quick Settings shade, choose Edit, and add the Tell Omnesis tile.
The Android App Actions have not been properly tested. Invocation depends on the assistant, device, locale and Android version, and a phrase may not work on yours. We are looking for contributors to help test and harden them; see Help and support to report a device and locale combination or to get involved.
Voice questions wait a bounded time in the foreground. If the answer takes longer, the assistant tells you it is still working; once the answer is ready, your phone gets an Answer ready notification and fetches the answer directly from your gateway. Notification services never receive the question or answer text.
Privacy controls
The Audit screen lists what external agents asked and what left the gateway, and lets the phone approve or deny each pending answer. While a decision is waiting, the Audit entry in the menu carries a count, and opening the app presents the pending answer without waiting for a notification tap — once per app session, and again on the next launch if it is still waiting.
When an AI agent asks to connect, the phone gets a notification with no details in it. Tap it, or scan the QR code on the agent's approval page with the phone's camera, to open the request in the app, choose its access level, and approve or deny it; the same screen is under Settings → Gateway → Authorize an MCP connection. Access levels and the approval flow are described in Bring your own agent.
Privacy policies are read-only on the phone: Settings → Policies lists every policy, marks the default, and opens each one's text, and an exchange reviewed under a named policy says so on its detail screen. Edit policies in the portal under Settings → Policies.
A document can be deleted from its page or from a source's recent list, and the prompt offers both forms, Delete for good and Delete this copy; see Search → Beyond search for the difference. A day's quick-capture document cannot be deleted directly: its Manage notes action opens the portal's Tell Omnesis page at that day, where the original notes can be amended or deleted.
When data doesn't arrive
A phone sync is two steps: reading from the operating system, and uploading what it read. They fail independently, so a source can report a completed sync while its data sits on the phone. The app watches the upload step separately and warns about it above the source list and in Settings — the only place that state is visible, since every other indicator reads healthy. It warns about three problems:
- Refusing a source. This phone's token lacks the source's write scope. Grant it on the gateway and the held data is retried.
- Backlog aging. The gateway is unreachable or uploads are failing. Retry drains the backlog now and reports what happened; on iPhone that includes batches that belong to a paused source, which wait until the source is resumed.
- Could not be delivered. Some batches failed repeatedly and were set aside, out of the queue, so they stop counting as pending.
Activity still in progress is not an upload backlog. Android Activity Segments counts completed intervals ready for its next sync, not the raw transitions it keeps while waiting for an activity to end. An interval becomes ready when it ends or reaches the source's safety cutoff, and backlog age starts at that point.
Set-aside batches stay on the phone, but only the most recent are kept, and discarding them is final. Whether the data comes back on a re-sync depends on the source. One that re-reads a window of history each time, like Apple Health, can resend retained data. An ordinary Photos sync does not replay its whole library; resyncing that phone's contribution, or turning Photos off and on again, re-reads the photos it can still access. Deleted or no-longer-accessible originals cannot be recovered that way. Treat a set-aside batch as data that did not make it.
Mobile app support
When you ask for help with a mobile-app issue, include the platform, the three readings from Settings → About, and the screen or permission state where the problem occurred. Never include a gateway token, pairing payload, private indexed content, or other credentials. Data handling and deletion controls are described in the mobile privacy policy.