The agent is the kernel

Möbius grew an app store. Install an app by pasting a URL, tweak it by asking, run it offline, save it to your home screen. The interesting part is not the store but what an editable, recoverable, single-owner operating system lets the agent do for you.

TL;DR. The agent is the kernel. Möbius grew an app store, but the store is just the visible part of an operating system you own and can reshape. A Möbius app is a public git repo with a manifest and one entry file. You install by pasting a URL, tweak it by asking the agent, save it to your home screen, and use it offline. Breaking something is cheap because the system is built around recovery.
  • The store is a curated starter pack, not a registry. A Möbius app is a public repo with a mobius.json and an index.jsx entry point. Sharing one means sharing a URL.
  • Updates are URL-keyed. Bump the version upstream, the store shows "Update available", reinstalling patches the code and keeps your data.
  • Recovery is the philosophy made concrete. Atomic installs that cannot half-land, a /recover route, and a git history of your whole instance. Breaking is allowed because it is reversible.
  • Offline plus home screen. Apps install to your home screen as standalone PWAs and keep working with no network. Writes queue and sync when you reconnect.
  • The honest edges. Cross-app composition and per-app rollback are not built yet, and I say so where it matters.

This is the third post about Möbius, a personalized AI agent you self-host. The first post is about the agent building the tools you ask for and editing the interface around them. The second is about the loop that makes it slowly better at doing that. This one is about what those apps became once they stopped being one-offs and grew a place to live.

The through-line across all three is that Möbius has one job, to be as useful to you as it can. The first post built the tools; the second built the loop the developers use to make the agent better at building them; this one is about handing you that same reshaping power.

Calling it an app store undersells it. Underneath the surface you tap is a small operating system where the agent turns a request into software, and the apps, the data, the shell, and the rules are yours to keep, move, rewrite, or throw away.

Möbius · a self-hosted AI OS

The agent is the kernel.

A self-hosted agent you grow from a single chat into apps, and from apps into an operating system you own.

The chat is the system call Your apps are user space The agent is the kernel
The framing, stated plainly.

The agent is the kernel

In a normal operating system the kernel is the privileged core. It owns the hardware, schedules the work, and everything you use runs on top of it. Möbius keeps that shape and swaps the core. The privileged thing in the middle is not a scheduler. It is the agent. You describe what you want; it writes the app, installs it, schedules its background jobs, and wires it into the shell. The apps are user space. The chat is the system call.

The analogy bends in places. A real kernel does not write your programs, and a system call is a fixed, narrow interface rather than an open conversation. What carries over is the part that matters. One privileged layer sits between you and the metal, everything routes through it, and nothing reaches your data or hardware except by asking it. This one also writes the software.

Your appsuser space · News, Workout, Atlas, …
The shellchat · canvas · drawer · theme
The agentturns a request into running software
Your server & dataone container · git history · storage
The stack, with the agent where the kernel usually sits. The chat is the system call. You describe a thing, the agent builds it into the layer above, and it lands on the hardware you own at the bottom.

That changes what the primitives are. An app is not a binary you trust and cannot inspect; it is a single file of source the agent (or you) can rewrite in place. An update is a new version of that file. Installing is a transaction the platform can roll back. The rest of this post walks those primitives one at a time, and marks where each is solid versus where it is still a plan.

The store is a starter pack, not a registry

The app store is itself a Möbius app. On first boot the platform installs it through the exact same path you use for everything else, the first sign there is no privileged install channel hiding somewhere.

News app icon
News runs daily
An AI-curated morning digest, written for you by a background job at 10:00.
Workout app icon
Workout on-device
A natural-language workout logger. Type "3×5 deadlift at 100kg" and it parses the sets, all on your device.
Atlas app icon
Atlas offline
A draggable 3D globe; tap the countries you have been to and watch the count climb toward 195.
Mind app icon
Mind memory
An Obsidian-style graph of everything the agent has learned, every interaction and lesson, made browsable.
LaTeX app icon
LaTeX AI
An Overleaf-style editor with a file drawer and a real tectonic engine, where an AI sub-agent writes .tex as you watch it typeset.
Dreaming app icon
Dreaming nightly
Overnight, Möbius interviews the agents that worked that day and writes itself notes for tomorrow.
The curated catalog, the starter-pack apps the in-app store installs.

What is in it today is a hand-picked set, not a gate you have to pass:

App What it does
News A daily AI-curated digest. A background job wakes at 10:00, runs the agent with web search only, and writes the morning’s report.
Workout A natural-language workout logger. Type what you did, like “3×5 deadlift at 100kg”, and it parses the sets. No agent, no cloud, all on your device.
Atlas A draggable 3D globe; tap the countries you have been to and the count climbs toward 195.
Mind An Obsidian-style graph of everything the agent has learned, every interaction and lesson, made browsable.
LaTeX An Overleaf-style editor with a file drawer and a real tectonic engine; an AI sub-agent writes .tex while you watch it typeset.
Dreaming Overnight, the agent interviews the day’s work and writes itself notes, so it starts the next day a little sharper.

Each of those is a public git repo in the mobius-os organization, named app-<something>, with a mobius.json manifest, an index.jsx entry point, and a 1024×1024 icon. The smallest apps are that single file; larger ones pull in a few more, but the manifest plus an entry point is the whole contract. There is no submission queue, no review board, no registry to be blessed by. “Publishing” an app means making a repo public and sharing its manifest URL. The list above is a starter pack I picked. The install button takes any manifest URL you paste, and the store warns, but does not stop you, when it comes from a host it has not seen before.

index.jsx the app itself, one React component the agent wrote
mobius.json the manifest: name, version, what it may reach
icon.png a 1024×1024 icon
job.jsoptional a background job, if the app has one
What an app is, in full. One component, a manifest, an icon, an optional job. No build config, no server, no framework to learn; make the repo public and its URL is installable.

What “install” actually does

When you tap Install, the work happens on the server in one transaction. The platform fetches the manifest (and because that URL can point anywhere, it refuses private networks and cloud metadata endpoints and re-checks every redirect), then the app’s source, icon, background job, and any starter data it ships. It compiles off to the side and goes live only after the database row commits, so a half-written app is never something you can open. If anything fails, the whole thing rolls back and leaves nothing behind.

That all-or-nothing property is the foundation for the next two sections. It is what lets an update patch your app in place, and it is what lets recovery treat any break as something to undo.

Updates: version bumps you can see, data you keep

An installed app remembers the URL it came from, and that URL is its identity. Not its name, not a version number, the URL. The store periodically checks each app’s upstream manifest, and when the version there is newer than yours it shows an “Update available” pill.

Tapping Update reinstalls from the same URL. The backend switches into update mode and patches the parts that should change (the code, description, permissions, icon, schedule), then recompiles and remounts. Your data is not in that list. Starter data is only seeded for keys that do not exist yet, so an update can ship new defaults without trampling your logged workouts, your visited countries, your notes.

Upstream repo a new version is pushed to mobius.json
Update available the store sees a newer version than yours
Reinstall, same URL mode = update matched by URL, not name or version
Code patched, data kept new defaults seed only missing keys
An update is a reinstall from the same URL. The platform patches the source, description, permissions, icon, and schedule, and leaves the data you have created untouched.

One sharp edge worth naming. If you ask the agent to customize an installed app and then tap Update, the update overwrites those customizations; there is no three-way merge. For a single-owner system that is a defensible default and a real trade-off. The direction I want is one git repo per installed app, so an update becomes a merge that carries your edits forward and a conflict becomes a chat where the agent resolves it. Designed, not built.

Recovery: breaking is allowed because it is reversible

An agent that can rewrite its own interface will eventually ship a CSS rule that hides the composer or a layout change that buries the drawer. The answer is not to wrap it in enough guardrails that it can never make a mistake. The answer is to make mistakes cheap to undo. Recovery has three layers:

  • A failed install cannot half-land. The atomic transaction from earlier restores the previous working version of the app from a snapshot. You do not get a corrupted app; you get the old one back.
  • /recover is the bookmark you keep. It is a route rendered by a separate, server-side codepath the agent does not edit. It resets the shell to its baseline while keeping your chats, apps, and data. If a theme paints text the same color as the background, that page still works, because it does not go through the shell at all.
  • Your whole instance is a git repo. The agent commits the changes it makes to your shell, themes, app source, and schedules. When something breaks, the recovery path is the one a developer would use: read the log, find the change, restore it, except the agent does the reading.
layer 1 Atomic install a broken update cannot half-land; the previous version is restored from a snapshot
layer 2 /recover a server-side page the agent cannot edit; resets the shell, keeps chats, apps, and data
layer 3 Your instance is a git repo shell, themes, app source, schedules, where the agent reads the log and restores
Three independent safety nets, not a single rollback button. Breaking is cheap to undo, so the agent does not have to be wrapped in guardrails that stop it from being useful.

There is no one-click “roll back this app to last week’s version” button yet. Recovery today is uninstall-and-reinstall, plus /recover, plus the git history. When an update breaks something, you tell the agent what went wrong and it walks the commit log back to the working version, the third layer run for you.

Recovery paths should make agent mistakes cheap to inspect and repair.

Your home screen, with or without Möbius

An app you install is not trapped inside the chat. Each one is also served at its own address, with its own web manifest and icon, as a standalone progressive web app. Add it to your phone’s home screen and it launches like any native app: full screen, no drawer, no chat. Gym opens straight to today’s workout; Atlas opens to the globe.

Run standalone, an app has no Möbius shell around it to supply shared libraries, so the page vendors its own copy of React from your server. Nothing it needs lives on a CDN, which is exactly what lets it render with the network off, the subject of the next section.

Offline, and the sync that catches up

“Works offline” is easy to claim and hard to land on a phone, so this is the part that got the most unglamorous engineering, and it holds.

When an app is marked offline-capable, a service worker caches the shell and the app’s code, so opening it with the network off renders the real app, not the browser’s offline page. Storage works offline for every app, not just the offline-capable ones. Reads come instantly from a local cache and refresh in the background; writes you make offline queue in a local outbox and sync to your server the moment you reconnect.

Offline app + storage served from a local cache; the real app renders with no network
You make changes writes land in a local outbox; reads reflect them immediately
reconnect
Synced the outbox drains to your server; last-write-wins per item
Log a set in airplane mode, mark a country from a plane, jot a note on the subway. The outbox catches up the moment you reconnect. Listing and chat deliberately stay online.

So your data survives a dead connection, and I have checked it on a real phone, not a desktop pretending to be one. Two operations stay online by design (a cached listing could resurrect things you deleted, and chat is online-only), and conflicts are last-write-wins per item, which is right for a single owner and needs more thought for a shared one.

Tweaking an app, and the composition I have not built

Tweaking an app you have is real and easy. Open it, tell the agent what you want different (a darker palette, a new column, a weekly view instead of daily), and it edits the app’s source in place and recompiles. No fork button, no project to set up; the app is one file, and the agent edits that file the same way it would write a new one. It is the same loop as building from scratch, pointed at something that already exists.

Composing several apps into a new one is not a feature yet. The idea is a health dashboard that reads across your workout tracker, calorie log, gratitude journal, and dream diary and surfaces the metrics you actually care about. The substrate exists. An app can declare that it reads another app’s data, and the backend enforces the handshake on both sides. But almost nothing uses it today, each app’s storage is scoped to itself by default, and there is no “build me an app that unifies these” flow. When I build it, this is the example I will build it against.

Gymworkouts, PRs
Caloriesintake
Gratitudedaily notes
Dreamingsleep, streaks
not built yet Health dashboard reads across your apps and surfaces the metrics you care about
The composition I want and have not built. The dashed box is a promise, not a feature.

Building a good one, in practice

Two things make the difference when the goal is for the agent to build apps well, not just build them.

The first is the introspection loop from the companion post on the harness: have the agent build one app, ask it why it made the choices it did while the transcript is still in front of it, and fold the answer back into its system prompt. Iterating the instructions is the lever, and introspection is how I find the edit worth making.

The second is the design phase, where I do not let one model decide alone. I drive with Claude and use the Codex plugin to adversarially review the design before the build starts. Two models disagreeing about an interface, a data model, or an edge case surface the questions a single model tends to skip. The build is cheap, so the leverage is in the design.

Claude · the driver
proposes the design and writes the code, holding the whole plan in view
Codex · the second opinion
ensembles alternatives and reviews adversarially, asking where this breaks
propose ⇄ refute,
a few rounds
A design that survived the critique what's left once the disagreements are resolved, then the harness validates it in real use
How a good app gets designed, in practice: drive with Claude, pressure-test with Codex. The two argue across a few rounds; the design that comes out the other side is the one worth building, and the same introspection loop validates it once it ships.

The philosophy under all of it

Code empowers the agent; it does not police it. When the agent needs to install an app, write to your shell, or schedule a job, the platform’s job is to make that possible and reversible, not to second-guess it. Validators show up only where a failure would be silent and catastrophic; everywhere else the lever is a clear contract and a good recovery path, not a wall.

Low floor, high ceiling, no walls. A personal tracker that stores a little data and works offline should take one sentence; the storage primitive is a convenience, not a cage, and an app that wants its own local database is free to reach for one. The one real wall right now is that apps cannot open arbitrary network connections to outside services, a deliberate security line I have not yet built a careful door through.

You own all of it. Your data is on a server you control. Your apps are files you can read. Your shell is a git repo you can revert. Nothing here is tuned to keep you engaged. The whole series has argued the opposite, an assistant whose one job is to be useful, that builds you the thing, gets out of the way, and leaves you holding something you can keep.

Where this goes

An app store was the obvious next thing once the agent could build apps reliably. The less obvious thing is what it turns Möbius into. A place where the unit of software is small enough for the agent to write, own, and repair, where installing and breaking are reversible, and where the privileged core turns “I wish I had a thing that…” into a thing that is there the next time you open your phone.

The apps above are a starter pack; the interesting ones do not exist yet. If you deploy an instance and build something, or tear one of these apart and rebuild it as something better, that is exactly the point, and I would love to see it.

The source is on GitHub, the app repos are under mobius-os, and the deploy button gets you a working instance in about three minutes. </content> </invoke>