Build your own apps on Mu
Mu is a set of everyday services you own — news, mail, markets, weather, and the rest — with an agent that drives them. But not everything belongs in the core. You shouldn’t have to fork Mu to get a bookmarks tool, a reading list, or whatever small thing fits your day. That’s what apps are for.
A Mu app is just an HTML page with a little JavaScript. What makes it more than a static page is the SDK — a global mu object that gives the page real backend building blocks, without you standing up a backend.
<script src="/apps/sdk.js"></script>
Who’s using it
mu.user() tells you who is signed in, so an app can greet them and keep their data separate from everyone else’s:
const u = await mu.user(); // { account: 'alice', admin: false }
Storage that knows who you are
mu.db is a small database, not just a key-value bucket. Each record has an owner (you) and a public flag, so one app can hold your private data and a shared public set at the same time:
await mu.db.create('notes', { title: 'Idea', body: '...' }); // private to me
await mu.db.create('notes', { title: 'Public tip' }, { public: true }); // shared
await mu.db.list('notes'); // my notes
await mu.db.list('notes', { scope: 'public' }); // everyone's public notes
await mu.db.list('tasks', { where: { done: false, priority: { gte: 2 } } });
The owner is set on the server from your session — never from the page — so an app can’t read or write someone else’s private data even if it tries.
Reach the web, server-side
mu.web.fetch makes an HTTP request from the server, so your app gets past CORS and can keep API keys off the client. It’s SSRF-guarded — public hosts only:
const res = await mu.web.fetch('https://api.example.com/data');
const data = JSON.parse(res.body);
The agent, in your app
mu.ai(prompt) for a one-shot answer, mu.agent(prompt) for the full tool-using agent — plus typed wrappers for every service (mu.weather, mu.markets, mu.news, and more):
const tldr = await mu.ai('Summarise this', { context: text });
const answer = await mu.agent('What changed in the markets today and why?');
A real example: bookmarks
Here’s the whole backend of an app that saves links — privately or shared — and fetches each page’s title for you. Three primitives, working together:
async function add(url, isPublic) {
const res = await mu.web.fetch(url); // read the page
const title = (/<title[^>]*>([\s\S]*?)<\/title>/i.exec(res.body) || [])[1] || url;
await mu.db.create('bookmarks', { url, title }, { public: isPublic }); // save it
}
const mine = await mu.db.list('bookmarks', { scope: 'mine' });
const shared = await mu.db.list('bookmarks', { scope: 'public' });
No server to deploy, no database to provision, no CORS proxy to run. The Bookmarks and Notes apps ship built-in — open them, or fork them from the editor to make your own.
How to build one
- Describe it at
/apps/newand Mu builds a working app. - Ask the agent — “build me a reading list” — it makes the app and gives you a URL.
- Write it yourself — paste HTML at
/apps/new, or hand-edit any app at/apps/{slug}/edit.
Pin the ones you use to the top of your home screen. Keep them private, or make them public for anyone on your instance.
It runs on your Mu — your instance, your data, your account. Same idea as the rest of Mu: instead of renting a service from a platform that keeps your data, you own the whole stack, and apps are how you extend it.
Full SDK reference: /docs/apps.
Comments
Login to add a comment
No comments yet. Be the first to comment!







