Build your own apps on Mu
Build your own apps on Mu
apps · dev
Updated 49 minutes ago · Mu · Share
---
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 }); // sharedawait 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/new` and 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!





