Build your own apps on Mu | Mu
Mu
Home<br>Agent<br>Chat<br>News<br>Blog<br>Mail<br>Social<br>Video<br>Search<br>Apps<br>Wallet
Login
Build your own apps on Mu
apps · dev<br>Updated 48 minutes ago · Mu · {this.textContent='Copied!';setTimeout(()=>{this.textContent='Share'},2000)})}" title="Share this post">Share<br>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.
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<br>await mu.db.create('notes', { title: 'Public tip' }, { public: true }); // shared
await mu.db.list('notes'); // my notes<br>await mu.db.list('notes', { scope: 'public' }); // everyone's public notes<br>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');<br>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 });<br>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) {<br>const res = await mu.web.fetch(url); // read the page<br>const title = (/]*>([\s\S]*?)/i.exec(res.body) || [])[1] || url;<br>await mu.db.create('bookmarks', { url, title }, { public: isPublic }); // save it<br>const mine = await mu.db.list('bookmarks', { scope: 'mine' });<br>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<br>Login to add a comment<br>No comments yet. Be the first to comment!<br>← Back to posts
API · Docs · MCP · Status