Version 2 · Standalone Native Android

Not a wrapper.
A control room.

The MIGI Android app is a native client for the MIGI agent fleet — the 46 autonomous agents that handle Suman Debnath's brand work, applications and monitoring. It puts the fleet's approval queue on a phone, so the agents are not stalled waiting for someone to reach a desktop.

MIGI is 46 autonomous agents running on schedules — triaging roles, watching sites, reconciling spend, drafting posts. Version 2 is a real native Android client for all of it: 22 screens drawn in Compose, instant push, on-device voice — and not a single API key on the phone.

Kotlin + Compose22 native screens0 API keys in the APK~15 MB
Private build · in daily use
Tightly coupled to a private agent server and gated behind two factors. Not distributed publicly.
MIGI overview screen

46

Agents

in the fleet

22

Screens

drawn natively

20+

API routes

consumed

0

API keys

inside the APK

1

Backend file

changed, total

~15

MB

release APK

Version 1 · 2026 · The WebView wrapper

A wrapper is a bookmark.

The first MIGI app did one honest job. It wrapped the mobile view of the agent dashboard in a WebView, put a biometric prompt in front of it, persisted the session for seven days so the passphrase and 2FA code were not needed on every open, and hid the browser chrome edge-to-edge.

It worked. It removed the real friction — opening a tab and logging in just to check whether anything had failed overnight. Two of the three phases that got there were spent making the dashboard itself genuinely responsive on a phone, which the app still benefits from today.

But it rendered the dashboard’s own HTML. That is the ceiling. A wrapper can never do anything a browser tab could not already do — and the things worth having on a phone were all on the other side of that line.

v1
Version 1 wrapper dashboard

The version 1 archive

All twenty screens of the wrapper, kept for the record. Scroll the strip, tap any to enlarge.

20 screens · superseded
drag the strip · tap to enlarge
Why it had to be rebuilt

Five things a wrapper structurally cannot do.

None of these are polish. Each one is blocked by the platform, not by effort — which is what made a rewrite the only honest option.

CapabilityV1V2

Voice input

The dashboard sends a permissions policy that blocks microphone access in any browser context — a WebView included.

Push notifications

No web page can hold a background connection once it is closed. Alerts had to arrive through Telegram instead.

Home-screen widget

Widgets are drawn by a native process. A page in a box cannot put fleet health on the launcher.

Share target & quick tile

Android intent surfaces. Unreachable from web, so nothing could be captured from another app.

Instant cold start

A wrapper refetches and relayouts on every open. Nothing is on disk to paint from.

Version 2 · The rebuild

Rebuilt from the API up.

Version 2 does not render the dashboard. It calls the dashboard’s JSON API and draws every screen itself in Jetpack Compose — which is what buys voice, push, widgets and instant cold starts. The dark palette is a deliberate divergence from the web dashboard’s cream: a phone checked at 1 a.m. has different needs from a monitor in daylight.

Graphite, not black

Lime on pure black vibrates. On a ground from the same colour family it sits properly, which is why the page background carries a green bias.

Two accents, not one

A single accent on a dark ground reads cheap. Aqua already existed in ECHO’s identity, so the second register is grounded in the brand rather than invented.

Lime carries a fifth

Reserved for four jobs only: the hero statistic, the primary action, the active nav indicator, and positive quantities. Anything more and it stops being a signal.

Status hues off the ramp

Healthy, running and failing sit outside the brand ramp on purpose — otherwise “healthy” starts competing with “this is a button”.

Density over decoration

The first pass was one card per record: a column of identical slabs where a failing agent looked exactly like a healthy one. Grouped rows gave roughly four times the density.

Monospace for figures

Labels, numbers and timestamps are monospaced — the native vernacular of agent tooling, and it ships with the platform so no webfont can silently fail.

The tokens

Bg

#0C100E

Graphite with a green bias — never pure black

Card

#111613

Raised surface, one step up from ground

Lime

#C6F24E

The brand. Roughly a fifth of any screen

Aqua

#35E0FF

Second accent, inherited from ECHO

Ok

#6FD37A

Healthy — deliberately off the brand ramp

Bad

#FF6B54

Failing. The only colour that interrupts

Inside the app

Four screens that earn
the rewrite.

Overview · Agents

The whole fleet, at a glance.

Every screen opens with one hero figure — the number that screen exists to answer. Overview answers “is anything broken right now?” before you have finished unlocking the phone.

  • 46 agents grouped by category, each with a run-history strip
  • Needs-attention list capped at eight, failures sorted first
  • One-tap dispatch on any agent, straight from the list
  • Search across the whole roster, schedules and last-run times inline
MIGI Android overview screen showing fleet health
Jobs

Roles, already scored.

The job agents run overnight and score every new role against the CV. The app is where that queue gets triaged — usually in under a minute, standing up.

  • Circular fit meter, match reasoning and the specific gaps
  • Swipe to dismiss, long-press to multi-select
  • Bulk status changes sent as a single request
  • Application packet and drafted cover letter per role
MIGI Android jobs screen with fit meters
ECHO · on-device voice

Talk to your own knowledge.

ECHO is the retrieval layer over everything the fleet has read and written. On the phone it gained the one feature the web version can never have: speech.

  • Recognition runs on-device — only the transcript is ever sent
  • The backend needed no change at all to support it
  • Teach it a note, a URL or a repo from inside the app
  • Forget by source, so a bad import can be undone cleanly
MIGI ECHO conversational knowledge screen
MAS

Missions, not prompts.

The multi-agent orchestrator, launchable from the command deck. Manual-only by design: agents plan and delegate, every action waits for approval.

  • Fleet triage, market scan, warroom, content, operator, memo
  • The full plan and per-action trace, live as it runs
  • Also bound to the quick-settings tile — read-only triage
  • A mis-tapped tile costs nothing, which is why it is read-only
MIGI MAS mission launcher screen
The full tour

Twenty-two destinations.
Four in the bottom bar.

Overview, Agents, Jobs and More carry the navigation. Everything else lives in a single sheet of lime-washed tiles, one tap from anywhere — because a five-tab bar with a hamburger is how apps stop being usable one-handed.

MIGI locked screen

App lock

Biometric gate before anything renders

MIGI overview

Overview

Fleet health and what needs attention

MIGI agents

Agents

46 agents, grouped, with history strips

MIGI jobs

Jobs

Scored roles with fit meters and triage

MIGI more sheet

More

Every other destination, one sheet

MIGI team observability

Team

LLM calls, spend and rate limits

MIGI free tier

Free tier

Provider closest to its ceiling, first

MIGI database health

Databases

Reachability probes across projects

MIGI brand health

Brand

Performance, SEO and the weakest property

MIGI agent responses

Responses

What the agents actually sent

MIGI LinkedIn drafts

LinkedIn

Draft-only — nothing auto-posts

MIGI finance

Finance

Budgets, trend and quick capture

MIGI build compass

Build

Scored ideas the compass picked up

MIGI outreach

Outreach

Leads with intros already drafted

MIGI skills gaps

Skills

Gaps found in the roles you matched

MIGI launch

Launch

Repos tracked, launch post in one tap

MIGI data

Data

Ideas, reading, habits and journal

MIGI health

Health

Sleep, mood and weekday patterns

MIGI resume review

Resume

ATS score history, upload a new CV

MIGI ECHO

ECHO

Ask, or tap the mic

MIGI MAS

MAS

Mission launcher and command deck

MIGI devices

Devices

This phone badged, panic switch below

MIGI account

Account

Exactly what this app can reach

MIGI settings

Settings

App lock, refresh interval, push

drag · or tap a screen
Beyond the screens

The parts that only exist because it’s native.

Six surfaces that live outside the app itself — on the lock screen, the launcher, the settings shade and the share sheet. This is the actual difference between an app and a page in a box.

Push, without Firebase

All 46 agents already funnel every message through one file to reach Telegram. One HTTP POST added there covers the entire fleet — no Firebase project, no service account, no token registry.

Home-screen widget

Fleet health on the launcher, built with Glance. It reads the app’s own disk cache rather than the API, because a widget has no session and duplicating auth would put the token in a second place.

Quick-settings tile

One swipe from anywhere starts a read-only fleet triage. Read-only deliberately: a tile that dispatched real work would be a hazard one accidental tap away.

Share target

Share a link from any app and pick a destination: read later, watch later, save as an idea, or teach the knowledge base. It files and finishes without ever opening the app or asking for an unlock.

On-device voice

Speech recognition runs on the phone and only the transcript is sent, as an ordinary question. The backend needed no change — and the web version cannot do this at all.

Offline-first

Every response is cached to disk, so a cold start paints last-known state immediately and refreshes underneath. A failed refresh keeps the cached content instead of blanking the screen.

Engineering notes

Four problems worth writing down.

01

Authentication without a single new endpoint

The obvious path was to add a device-token API to the dashboard. Reading the existing code showed it was unnecessary.

The app signs in through the login route that was already there — passphrase plus a TOTP code — and keeps the returned session token in EncryptedSharedPreferences behind a keystore key. The passphrase and the code are never stored.

Because that session is a row in the database like any other, the phone appears in the dashboard’s own Devices screen and can be revoked from either side. Nothing new to protect, and no second credential path to keep in sync.

The interesting engineering was reading someone else’s auth carefully enough to discover the feature already existed.

02

Push for 46 agents, in one file

Firebase is the default answer, and it wanted a project, a service-account key, a token-registration endpoint and a sender — two repositories and a new external dependency, for one phone.

The fleet had a property that changed the arithmetic: every agent already routes its messages through a single notification helper. One HTTP POST added there covers all 46. The transport is ntfy — publish to a topic, subscribe from the phone.

A central classifier then tiers every message: failures arrive loudly, approvals quietly, routine digests silently. Individual agents know nothing about priority, so uptime checks are silent while everything is healthy and loud the moment a site goes down.

The best backend change is the one you don’t make.

03

Six identical bugs, and the lesson underneath

Six screens shipped rendering zeros. Each looked correct in source. Every one was a guessed JSON key — skills instead of items, ideas instead of projects.

The failure was not the guessing. It was fixing instances rather than the class: each was corrected as it was reported, and the next appeared a day later.

The actual fix was an audit — extract every field the app reads, diff it against every route’s selected columns, in one pass. It found two more bugs in code already believed correct. The same shape had appeared in the design system, where one colour token meant for text on lime, used as a general text colour, made figures invisible on six screens at once.

One line, six symptoms. Fix the class, not the instance.

04

Adding to a codebase you rely on daily

The backend was treated as read-only throughout. When two capabilities genuinely needed server support — capturing shared links, and deleting from the knowledge base — they were added as new files only, in new directories, with the diff against the previous commit verified empty before pushing.

No existing route changed by a single line.

Every change to a locked repository is recorded with its commit hash, a revert command, and a note on what the fleet does without it. The push integration also has a kill switch that needs no code change at all: remove one environment secret and the new code returns on its first line.

The goal is not “it works” — it is “I can prove nothing else changed”.

Postscript · what to be honest about

The first two versions were poor. The wrapper was a bookmark, and the initial native build was structurally sound but visually inert — a single column of identical cards with no hierarchy at all. It took a research pass and a blunt round of feedback to establish that the problem was information design, not colour. That is a better story than a straight line, and it has the advantage of being true.

Security model

Losing the phone
loses nothing.

The app carries no secrets of its own. Everything it can do, it does through a session that can be ended from either side — and the Account screen states in plain language exactly what it can read, what it can write, and what it can never touch.

No keys, no credentials

Zero API keys in the APK. The passphrase and TOTP code are never written to the device — only the session token, encrypted behind a keystore key.

Biometric app lock

Fingerprint or screen lock required each time the app opens, so an unlocked phone in someone else’s hand still reaches nothing.

Revocable from anywhere

The phone is one row in the sessions table. Revoke it from the app, from the web dashboard, or hit the panic switch and end every session everywhere at once.

A ceiling it cannot raise

The app cannot change the passphrase, the TOTP secret, or any dashboard setting. Its reach is bounded by the session it holds, and nothing more.

MIGI biometric lock screen
MIGI devices and panic switch
Built with
KotlinJetpack ComposeMaterial 3Navigation ComposeGlance widgetsOkHttpkotlinx.serializationEncryptedSharedPreferencesBiometricPromptSpeechRecognizerntfyCoroutines + Flow

Talking to a Next.js dashboard on Vercel, backed by Supabase, GitHub Actions and free-tier LLM providers. The app holds none of that — it holds a session.

MIGI app icon

One phone, forty-six agents.

The app is the access layer. The work happens in the fleet behind it — scheduled agents, an orchestrator, and a knowledge base that has been reading along the whole time.

Questions this page answers

What is the MIGI Android app?
The MIGI Android app is a native client for the MIGI agent fleet — the 46 autonomous agents that handle personal brand work, job applications, expense tracking and monitoring. It puts fleet control and approvals on a phone rather than requiring the desktop dashboard.
Why does an agent fleet need a phone app at all?
Because the agents run continuously and the human approvals they wait on do not. A fleet that can only be approved from a desktop stalls every time its operator is away from one, so the queue backs up and the automation stops paying for itself. Putting the approval gate on a phone is what keeps the loop moving.
Is the MIGI Android app built natively or with a cross-platform framework?
Natively for Android. The V2 client is the current build; V1 is archived. Native was the right call for a control surface that needs background notifications and fast cold starts — an approval that arrives late is an approval that has already cost the fleet an hour.

Let's Build
What Comes Next.

Suman Debnath Signature

Open to meaningful collaborations, AI-native systems, product strategy, and future-focused conversations.

“Human instinct. AI amplification.
Systemic execution.”

Suman Debnath

·

Brand Marketing Leader & AI Product Builder

© 2026

This site records visit data — pages viewed, time and scroll depth, device, your IP address and the approximate location and network provider derived from it — and sends it to me privately. It also runs Google Analytics and Vercel Analytics. Full detail and how to opt out.

This site, its code and its content are © 2026 Suman Debnath. All rights reserved — none of it is open source, and copying it needs permission first. Terms of use.