Changelog
What's new
in MIRA.
Every release is a self-hostable single-binary build, AGPL-licensed and signed under vexillon.ai. Updating is one command — the same one you installed with.
New here? Install or update MIRA
- v0.350.1 Current build
Security fix — per-user notification scoping
- The real-time notification stream is now scoped per user. The server-sent-events endpoint
GET /api/notifications/streamwas subscribing to the shared notification bus without filtering by the authenticated caller — so on a multi-user install, every connected client could receive every user’s notifications, and a notification carries the actual message text (proactive follow-ups, companion check-ins, inbound-message previews). The stream now filters strictly per user: a user-addressed notification reaches only that user, while global system/health notices reach regular users but not ephemeral guest sessions. The web-push path was already per-user and was unaffected. - Who’s affected. This was latent on a single-user self-host, but a genuine cross-user information disclosure the moment a second account connects — so it matters for any multi-user / RBAC / SSO deployment. Anyone running MIRA for more than one account should upgrade. Single-user installs are unchanged in behaviour (you still receive all of your own notifications) and need no action, though upgrading is safe and recommended. Clients need no update.
A security-only patch — no features, API changes, config changes, or migration. Safe to upgrade in place. Details in the security advisory.
Security advisory - The real-time notification stream is now scoped per user. The server-sent-events endpoint
- v0.350.0
Restricted Mode — safely expose MIRA
- Fail-closed by design. Turn on a restriction profile and every side-effecting capability is denied unless it’s on an explicit allow-list. The check sits at each chokepoint — the tool registry, the skill→builtin path, outbound HTTP, and the proactive/companion message senders — so there’s no back door around it, the model can’t talk its way past it, and no user, UI, API, or prompt path can widen it at runtime. It’s off by default: existing installs behave exactly as before, and upgrading is safe in place (no config or on-disk migration).
- A built-in “hardened” profile. Permits chat and reasoning, per-user memory, and the wiki — and denies shell, code execution, filesystem writes, real outbound channel messages, care-network escalations, home-automation actuation, and arbitrary web fetch. Anything not explicitly allowed is denied, so a newly-added tool is denied by default rather than newly exposed.
- Resource & cost caps. Per-user message rate, a per-turn token cap, a context budget, global concurrency, and a global daily token ceiling. A tripped cap degrades gracefully with a brief, friendly in-chat reply instead of a raw error or unbounded spend — ideal for bounding cost and load on a public instance.
- Ephemeral guest sessions. Anonymous “try it” access via a new public endpoint (
POST /api/auth/guest). Each guest is a throwaway, sandboxed account with its own seeded, isolated memory and wiki, wiped on a TTL, on a periodic global reset, and unconditionally on restart — guests never persist. Fail-closed: a guest is only ever minted when a restriction profile is also active. - Admin visibility. A read-only Restricted Mode panel in admin Settings shows the active profile, what’s denied, the caps, and guest status at a glance.
Off by default and safe to upgrade in place — existing installs are unchanged. Turn it on only when you mean to expose MIRA (a public “try it” demo, a kiosk, a shared guest instance) or to shrink the blast radius of a prompt-injection attack. It’s defence-in-depth, not a replacement for a VPN when reaching your own instance.
Guide: Safely expose MIRA (Restricted Mode) - v0.346.1
Reliable self-upgrades, and a Settings tidy-up
- The in-app self-upgrade now shows real progress. It always worked, but a fixed timeout expired before a typical upgrade finished, so it looked like it had failed. The banner and Settings now show the real phases — downloading → verifying → installing → restarting — and only report a problem on an actual error or a genuine stall.
- No racing upgrades. Starting a second upgrade while one is already running now safely re-attaches to the in-progress job instead of launching a competing swap.
- Windows fixes. Old-binary cleanup now runs when MIRA is installed as a Windows service, so upgrades no longer leave large leftover files behind, and the Upgrade and Rollback buttons now appear correctly in Settings on Windows service installs.
- Settings tidy-up. Finishing the “My Preferences” move from last release, the per-user controls still duplicated in admin Settings are now consolidated: mobile pairing, browser push, and their test buttons live in My Preferences → Notifications & devices; the daily-briefing toggle stays on the Presence page; and the Settings “Appearance” section is now Terminal (TUI) — TUI theme only, since the web theme lives in My Preferences. Nothing per-user is trapped behind admin-only Settings anymore.
Safe to upgrade in place — no breaking changes. When you run the in-app upgrade, just let it finish: a repeat click only re-attaches to the running job, and the page reloads itself onto the new version automatically.
Guide: Updating & rolling back - v0.345.1
A My Preferences page for every user
- Every user gets a My Preferences page. There’s now a per-user My Preferences page at
/preferences, with its own sidebar link, open to everyone — not just admins. It fixes a real gap: mobile pairing and browser push notifications are per-user, but they used to live on the admin-only Settings page, so a non-admin couldn’t pair their phone at all. Now they can. - Your per-user settings, in one place. My Preferences gathers the settings that are genuinely yours: Notifications & devices — pair the mobile app by QR and manage browser push; Appearance — pick your web theme; and Voice replies — your per-channel voice-reply policy and voice override, moved here from the Profile dialog. The Profile dialog is now just your account details — name, contact, password, avatar — while global and server configuration stays admin-only.
- Steadier sessions across your devices. Refresh-token handling was hardened so a harmless refresh race on one device — a lost response, or an app the OS killed — no longer revokes every session across all your devices. Each device now stands on its own, and a just-rotated token gets a short grace window to retry cleanly.
Safe to upgrade in place — a small, automatic, backward-compatible database migration runs on first boot, with no manual steps. Existing sessions adopt the new per-device behavior on their next refresh (or log in once more per device to switch immediately).
Guide: Pair the mobile app - Every user gets a My Preferences page. There’s now a per-user My Preferences page at
- v0.344.0
Fail-closed messaging webhooks
- Breaking change — set a webhook secret before upgrading. Inbound Telegram and WhatsApp webhooks are now fail-closed: an inbound webhook for an account with no per-account secret configured is rejected instead of accepted unverified, closing a hole where anyone who learned your (non-secret) account id could POST forged inbound messages. Migrate each account one of two ways — recommended: set the account’s secret from the Channels page in the web UI (Telegram
secret_token, included in your setWebhook call, or WhatsAppapp_secret); or, only if you can’t register a secret and accept the risk, explicitly opt in withchannels.telegram.allow_insecure_webhook = true/channels.whatsapp.allow_insecure_webhook = true(default false). Telegram polling mode is unaffected — this is webhook delivery only. - Account recovery & stronger passwords. A new
mira reset-admin-password [--user <name>]gets you back into a locked-out admin account: run it locally and it prompts for a new password, writes it through the auth service, and revokes existing sessions (it needs filesystem access to the auth database, so it’s an operator-on-the-host recovery path). The minimum admin-password length is raised from 8 to 12, with a nudge toward a passphrase, on both first-run setup and the reset flow. - Tighter governance. Member-device anti-spoof is now enforced at a single shared, fail-closed checkpoint, so every actuation path — including direct app-tool calls — verifies a device really belongs to the member it claims. Guardian approvals are widened so a ward’s designated guardian, not just the operator, can approve an action, and member-device approvals now surface in the web UI instead of silently failing. App iframes now carry a runtime-enforced Content-Security-Policy (
connect-src 'none'), so an embedded app can’t make network calls even if its markup tries. - Docs. The
video_generatetool is now documented correctly as multi-backend (local ComfyUI / WAN2GP), not tied to a single provider.
No data migration is required — upgrade is safe in place. The only action is the per-account webhook step above: if you use Telegram or WhatsApp inbound webhooks, register the account’s secret (or opt into unverified inbound) before or right after upgrading, or those inbound messages will be rejected.
Reference: CLI (mira reset-admin-password) - Breaking change — set a webhook secret before upgrading. Inbound Telegram and WhatsApp webhooks are now fail-closed: an inbound webhook for an account with no per-account secret configured is rejected instead of accepted unverified, closing a hole where anyone who learned your (non-secret) account id could POST forged inbound messages. Migrate each account one of two ways — recommended: set the account’s secret from the Channels page in the web UI (Telegram
- v0.340.1
Purpose-built health probes: /livez and /readyz
- Breaking change — monitors pointed at
/healthshould move. MIRA’s single overloaded/healthendpoint is now split into two purpose-built probes. Point external uptime monitors and containerHEALTHCHECKs at/livez(or/readyzfor readiness). MIRA’s own supervisor auto-migrates a configured …/health probe URL to …/livez, and the bundled Docker image already uses /livez — so most setups need no change, but hand-rolled monitors on /health should be updated. -
/livez— liveness. “Is the process up?” Answers instantly, with no provider, database, or subsystem calls — so it stays responsive even when a dependency is momentarily wedged. -
/readyz— readiness. “Can it actually serve?” Returns 200 or 503 on provider reachability, and the verdict is cached so a fleet of load-balancer probes can never hammer your provider or block — at most one real check per window. Tunable viaserver.readiness_cache_ttl_secs(default 30s; 0 disables caching). -
/healthis now the in-app System Health page — the admin view in the web UI — rather than a machine endpoint. - Automations gain reach and control. An admin can create a schedule on behalf of another user (the owner’s quota applies; the admin action is audited separately), the editor adds per-run iteration and time-budget controls, and sub-daily schedules now default to a fresh conversation per run. Built-in tools invoked through a skill now receive the caller’s user, conversation, channel, and timezone, so wiki, memory, and calendar work through skills exactly as they do directly.
- Housekeeping. Refreshed dependencies clear the outstanding security advisories (React Router 7, PostCSS, js-yaml, and others), and auto-titles no longer pick up a model’s reasoning scaffolding — a conversation is named from its real title, not a line like “1. Analyze User Input:”.
Upgrading is safe in place. If you only wire one probe, wire /livez — a liveness check that can block on a dependency is a self-inflicted outage, and /livez never does dependency I/O. Both probes are unauthenticated and return no instance detail.
Guide: Health checks & monitoring - Breaking change — monitors pointed at
- v0.338.0
A care role for adults who need support
- A care role that fits an adult who needs support. The Presence care network used to offer only Just me, A child, or An older adult — so a grown-up who wants someone actively looking out for them (recovery, a chronic condition, living alone, a hard stretch) had to miscast themselves as “an older adult.” There’s now An adult who needs support: monitored like the child and older-adult roles — a care contact is alerted on distress or a worrying silence, and can see an aggregate wellbeing view (engagement signals over time, recent distress flags, never message content).
- On the person’s own terms. The wellbeing view is gated by a hard floor — the person must be in a monitored care role and have consented after being told — and the role is framed as a peer: supportive tone, no age framing. The care-role selector is now Just me / An adult who needs support / A child / An older adult.
- Clearer update checks. The built-in update check now explains why a release-source check failed instead of failing silently, and shows the configured source (credential-stripped) in Settings. It only compares versions — it never downloads or installs.
The arrangement is always disclosed to the watched person, consent-gated, shares only a minimal signal (never transcripts), and is a heads-up — not emergency dispatch. Even a “Just me” user’s safety contact is still alerted in a genuine emergency; the role only changes tone and the ongoing wellbeing view, not whether a contact is reached when it matters.
Guide: Proactive check-ins & safety contacts - v0.335.0
Care network, easier to set up
- Pick a safety contact by name. Choosing a Presence safety contact — or anyone in a people-picker — no longer means pasting a raw user id: just start typing a person’s name and MIRA searches over username and display name. It searches active users only and returns just the name and id, never anyone’s email, role, or profile details.
- Name more than one contact. On every path you can now name several — both parents of a child, or two adult children looking after an older parent — and a distress or missed-check-in alert reaches all of them.
- The care network is for any adult. It isn’t only for children and older adults: any adult can name their own safety contact for emergency escalation. The care-role setting only changes tone and the ongoing wellbeing view — never whether a contact is actually reached.
The arrangement is always disclosed to the watched person, consent-gated, and shares a minimal signal — never message content.
Guide: Proactive check-ins & safety contacts - v0.334.0
Research that reaches the wiki
- Long research runs aren’t cut short. A per-action time limit is now configurable (
automations.max_action_secs, default 300s), and a research prompt can raise its own ceiling — so a genuine multi-cycle job (search → fetch → write, ~15 min) runs to completion instead of being killed mid-way. Automation runs are also dispatched off the main loop, so one slow task can’t stall other scheduled actions or the next tick. - Enough rounds to actually write. A research prompt’s iteration budget is honoured directly, so it gets the search → fetch → write rounds it needs to record what it found — too small a budget was the classic “searches all day but never saves.” You can always edit anything the agent wrote to your wiki, and a write that keeps getting blocked stops hammering the review queue after a few tries.
- A rich wiki UI. Pages now render as markdown with a View / Edit toggle — headings, tables, task lists, syntax-highlighted code blocks, blockquotes — and editing shows a live preview. Pages can embed images: click Insert image or paste / drag-and-drop into the editor. Images live in the wiki’s own assets/ folder, content-addressed so they travel with git sync and tarball export (PNG/JPEG/WebP/GIF, up to 10 MB).
- Wiki controls in one place. A new Settings → Wiki tab gathers the review-gate controls — extraction mode, minimum confidence, max updates per turn, an auto-apply threshold, and the model’s own write mode.
Wiki extractions go through a review gate you control: confident ones can auto-apply while uncertain ones queue for your approval. Nothing is written silently, and you can correct or delete anything MIRA wrote.
Guide: Run long research automations - Long research runs aren’t cut short. A per-action time limit is now configurable (
- v0.333.0
Family governance
- More than one guardian per ward. A ward — a child or an older adult you look after — can now have several guardians, both parents for example. A distress or gone-silent heads-up reaches all of them and counts as delivered if it reaches any one, so a single unreachable guardian can never silence the alert.
- A quiet wellbeing view. A guardian sees an aggregate wellbeing view of each ward they look after — engagement signals over a trailing window and any recent distress flags, never the person’s messages. It’s gated by a hard floor: the person must be a monitored care role and have consented, and an ordinary adult’s data is never visible to a contact, even to an admin.
- Member-scoped protective actions. In Active mode the Guardian can propose a bounded, reversible action on a family member’s device — pausing a ward’s internet plug through a Home Assistant integration, say — with approval routed to that member’s guardian(s), and only ever after a human approves.
- Delegated approvers. An owner can let a trusted family adult approve or decline the Guardian’s household fixes — “your Signal bridge is stuck, approve the restart?” — without handing them full admin.
- Container-backed apps. An app package can now declare a managed service container — a long-running backend MIRA supervises for you: started detached, restarted on failure, reaped on uninstall, and reconciled on startup, using whichever engine you have (Docker or Podman). It makes a homelab stack like Wazuh sustainable for a family, because MIRA babysits it and the Guardian watches its health. Ports stay loopback-only unless you explicitly mark them public.
The safety arrangement is always disclosed to the watched person — never covert — consent-gated, and shares only a one-line signal summary, never transcripts. It’s a heads-up to a trusted human, not emergency dispatch.
- v0.332.0
Time-aware memory recall
- MIRA now knows what “now” is. Every turn carries the current date and time resolved to your timezone (UTC as a fallback), and each recalled fact is tagged with when it was recorded — “recorded 3 weeks ago” — so the model can tell a fresh fact from a stale one instead of surfacing a month-old plan as if it were still current.
- Old facts are read in context. Durable facts — your name, home, relationships, ongoing preferences — hold regardless of age, while time-bound ones like a trip or an appointment are treated as possibly already past, so a “tomorrow” recorded weeks ago is understood as likely done, and MIRA asks rather than assumes when it matters.
- Nothing is silently rewritten. Memories aren’t auto-expired or edited — a past appointment stays stored, just labelled with its age — and MIRA reasons from those labels, so a weaker local model may occasionally still miss the reconciliation.
- v0.331.0
Security & reliability hardening
- Every setting does what it says. The whole configuration surface was reviewed declared-vs-wired, so no config key silently does nothing: dead no-op keys were removed and several settings that were previously inert are now honored — including video defaults, session max-turns, calendar scopes, and TUI display options. Old configs still load, with removed keys dropped automatically by an upgrade-safe migration, and the bundled settings reference is now generated from the schema so docs and config can’t drift.
- “Off the record” is auditable and honored. Going off the record is now written to the tamper-evident audit log as a consent-skip, and an off-the-record turn no longer stores a companion engagement label — while genuine distress still escalates.
- Safety alerts reach a real person. Care-net escalations now deliver over the contact’s own messaging channel — Signal, Telegram, email, whichever they last used — with the web thread kept as a durable record. The “no one was alerted” alarm fires only if both paths fail.
- Streaming TTS and log rotation now work as configured. The chat text-to-speech streaming toggle actually gates streaming vs. full-buffer playback, and size-based log rotation is honored with the live log stream following the rotated file.
- Guardian gains an opt-in autonomy on-ramp. When the Guardian can’t reach you, it can take a narrow, allowlisted action — a per-action allowlist (default: re-run an audit only), an explicit confirm in Settings → Guardian → Autonomous action, and a hard code ceiling that configuration cannot widen. Observe-only and off by default.
- v0.321.3
Security & reliability hardening
- Stronger sign-in. Single sign-on now requires a verified email before it will link or create an account, closing an account-takeover path (a per-provider opt-in covers providers you deliberately trust, default off). “Sign out everywhere” now takes effect immediately for every active session and token, instead of waiting for short-lived tokens to expire.
- Permissions enforced everywhere. Tool endpoints and scheduled automations now honor your role’s permissions, so a restricted user can’t reach a tool their role forbids; several admin-only operations are properly gated, with per-route upload size limits.
- Safer outbound requests and email. User- and admin-supplied URLs — CalDAV calendar sync, health webhooks, provider fetches — are checked against server-side request forgery: loopback and cloud-metadata addresses are refused while your self-hosted LAN services stay reachable. A new opt-in per-account option only trusts an allowlisted email sender whose mail actually passed SPF/DKIM/DMARC, so a forged “From:” can’t impersonate one.
- Quieter about secrets. The first-run admin password prints to the console only, never the log file, and a member’s “don’t record this” request is honored server-side across both memory and the wiki.
- Companion safety. Distress de-duplication is severity-aware, so an urgent alert is never masked by a milder one and very short messages like “help” aren’t dropped. Check-in tracking is more accurate — inbound on any channel resets the missed counter, and a web check-in counts only once delivery is confirmed. Safety-path failures now surface on the health page with a toast instead of a silent log entry.
- Reliability. Releases are gated on the full test suite, config saves are atomic so an interrupted save can’t truncate your live config, and interval schedules no longer drift.
- v0.318.7
Leaner prompts, steadier local models
- Up to ~83% fewer prompt tokens per turn. With prompt caching and adaptive tool selection on, MIRA now sends a small, stable core toolset plus on-demand tool search instead of every tool’s full schema every turn — a measured chat turn dropped from ~24K to ~4K prompt tokens. Cheaper, faster, and far easier for a small local model to handle.
- Context budgeted to what the model can actually use. MIRA sizes the working window to a model’s reliable range instead of an inflated advertised maximum, keeps injected memory and wiki context to a modest share of it, and now counts tool schemas in its token estimate. A startup sanity check for LM Studio and Ollama warns when your configured context length doesn’t match the model’s actually-loaded window — a common cause of silent truncation.
- Steadier thinking. The degeneracy guard now also watches the reasoning stream, so a model stuck repeating itself while “thinking” is caught and the turn fails early instead of running to the token cap. Large tool results are clamped to the effective window mid-conversation so they can’t overflow a small model.
- Fewer sharp edges. System content is coalesced into one leading block, so strict local chat templates no longer return HTTP 400 from stacked system messages. Config saves are atomic — an interrupted or racing save can’t truncate your live config. And a provider key you set in the UI wins over a stale .env value, with a warning when .env would shadow it.
- v0.318.0
Sturdier apps and more reliable local models
- Apps talk to HTTP services more reliably. App HTTP-tool base URLs work with or without a trailing slash — no more doubled slash sending an app pointed at, say, a Home Assistant instance into spurious 404s. Large API responses are trimmed to a small model-facing size before the model sees them, so a big reply can’t blow up the context, and an app can now declaratively project a few fields (with a row limit) to collapse a large JSON reply into a compact list — no code execution involved.
- Edit app settings in the UI. The in-app config panel for apps (from v0.317.0, folded into this build) lets you change an app’s settings right in the interface.
- Local models kept in their reliable zone. MIRA now budgets local providers to a small, dependable effective context window (default 8192 tokens) instead of trusting an advertised size that quantized local models don’t genuinely attend to — keeping prompts reliable and enabling compaction. An explicit context length still wins.
- Degenerate-output guard, on by default. If a model gets stuck emitting pathologically repetitive text, MIRA cuts it off early, discards the bad turn, and counts it as a provider error so failover can take over. Guardian also picks a sensible triage model when none is configured.
- v0.316.1
Guardian and tool-selection bug fixes
- Guardian stops proposing pointless channel restarts. A quiet Signal channel — no inbound in 72h — reflects your activity, not daemon health, so it no longer escalates to a Red alert; it’s at most an informational note, and Guardian validates any restart target against real channel accounts before proposing one.
- MIRA stops claiming it lacks a tool it has. With adaptive tool selection on, MIRA now knows how many tools are loaded versus loadable on demand, and searches before telling you a capability is unavailable — fixing cases where a not-yet-loaded tool was wrongly reported as missing.
- v0.316.0
Built web apps work behind a reverse proxy
- Open your built web apps from anywhere — including behind a reverse proxy. MIRA now serves each app the coding agent builds from its own main URL, at /a/
/. Because that is the same address you already expose, built apps open correctly behind a reverse proxy (Traefik, Caddy, nginx) or tailscale serve — no separate app port to expose, and no extra proxy config. They keep working on your LAN and from the mobile app too. - Isolation preserved. Untrusted, model-generated app code still runs in a sandboxed frame with its own opaque origin, so it cannot read your MIRA session or call the API even though it is served from the same host.
- Open your built web apps from anywhere — including behind a reverse proxy. MIRA now serves each app the coding agent builds from its own main URL, at /a/
- v0.313.0
Guardian sentinel: faster alarms, reliable delivery, one-click enable
- Faster down-alarms. The “MIRA is down” alarm now fires immediately when the sentinel declares MIRA down; the optional local-model triage that adds detail runs afterward, so a slow or unavailable model can never delay the alarm.
- No more silent failures. If an alarm reaches no device, that’s now treated as a failure — logged loudly and recorded — instead of looking like a success. The Guardian panel warns when the sentinel is watching but can’t reach anyone, and checks this at startup.
- One-toggle enable. Turning on the liveness sentinel in Settings → Guardian now automatically registers and starts it as its own supervised service, and turning it off stops and unregisters it — no separate install step (the CLI commands remain for headless setups).
- Configurable logging. The sentinel shares MIRA’s main log file by default, or point it at its own file under Settings → Guardian → Sentinel log file.
For a down-alarm to reach you while MIRA is offline, register at least one push device — open MIRA in a browser and allow notifications.
- v0.311.0
Guardian sentinel installer, now on macOS and Windows
- The independent Guardian liveness sentinel — the watchdog that keeps watching even when MIRA crashes, hangs, or restart-loops, and raises a direct alarm to your device — now installs as a supervised service on all three desktop platforms, not just Linux.
- mira guardian-install registers the sentinel as its own service, deliberately separate from the main MIRA service so it outlives a MIRA crash: a systemd unit on Linux, a launchd agent on macOS, and a dedicated service on Windows. mira guardian-uninstall removes it, and mira uninstall cleans up both.
- Still off by default — enable and tune it under Settings → Guardian → Liveness sentinel, then run mira guardian-install.
- v0.310.0 covers v0.307–v0.310
The fully independent, agentic Guardian
- Agentic triage. Guardian now investigates before it diagnoses — actively calling read-only tools for a full health snapshot and logs, its built-in docs, and relevant past context, then reasoning over what it finds. Fail-closed local-only throughout.
- Delivered in MIRA’s voice when it can. While MIRA is up, Guardian hands its message to MIRA over a local shared-secret endpoint, so you hear it across your usual channels — Signal, Telegram, email — with direct web-push as the fallback.
- Optional full-time watch. An opt-in setting lets Guardian own the whole watch and triage, running even while MIRA is up, while MIRA’s in-process watcher stands down so the two never double-alert.
- v0.306.0
Independent triage in Guardian’s own process
- With a local model configured, Guardian runs a real, fail-closed local-only triage turn in its own process — reasoning over the health data to deliver a charter-voiced alert with a concrete next step, independent of a down MIRA. If no local model is reachable it falls back to the plain alarm, so an alert never fails to fire.
- v0.305.0
Alarms carry MIRA’s last-known health
- A “MIRA is down” alarm now also reports what Guardian last saw — e.g. “last health check 2h ago showed Red: db.integrity, disk.free” — so you get context, not just “it’s down.”
- v0.304.0
Guardian installs as its own service
- mira guardian-install / guardian-uninstall register Guardian as its own service unit, deliberately not bound to MIRA’s, so it survives a MIRA crash. Linux/systemd today; macOS and Windows to follow.
- v0.303.0
Out-of-process liveness sentinel
- mira guardian-watch is a separate, supervised process that probes MIRA’s health and, if MIRA goes down for a sustained window, sends a direct web-push alarm — working even with MIRA fully offline. Off by default.
- v0.302.0
Universal duty-of-care safety floor
- A short, non-overridable safety instruction now rides every user-facing turn, not just companion chats: never describe methods of self-harm, and take self-harm or acute physical symptoms seriously — with warmth and a crisis line. It’s the final word in the system prompt, so no persona or setting can silence it.
- v0.301.0
Guardian gets its own voice and a tiered local model
- The watchdog now speaks in its own charter — quiet, precise, non-alarmist — and runs a tiered local model: a light model for routine notes, escalating to a stronger one only for real triage. Both tiers are fail-closed local-only. Configurable in Settings → Guardian.
- v0.300.1
Web-app links, service-account CLI resolution, automation spawns
- Built web apps always open at their link. If a build names its single page something other than index.html (e.g. game.html), MIRA promotes it, so the app stays discoverable and openable.
- Honest web-app links. MIRA only ever hands you a URL a tool actually returned — never a guessed or reconstructed one — and reports a failed build plainly instead of inventing a link. In the web chat, app links now open in a new browser tab, so opening a built app never navigates you away from the conversation.
- External coding CLIs resolve under a service install. claude and opencode are now found when MIRA runs as a supervised service — it looks under the configured data directory and the owning user’s home, fixing “CLI not on PATH” under a Windows or systemd service.
- Scheduled automations can spawn background tasks. An automation’s turn now carries caller identity, so delegating long-running work from a scheduled task no longer fails instantly.
- v0.300.0
Provider & tooling hardening
- Portable tool calls. Tools use a portable schema dialect, with a registration-time linter that warns when any tool — including MCP tools — uses something a provider can’t accept.
- The provider you pick is the provider that runs. Your selected model provider now drives the entire turn, for every provider.
- Clearer failures. Uniform, legible provider errors; failover aggregates each provider’s reason, with a concise per-turn summary.
- Trustworthy health signals. A primary provider going down is raised as a persistent health degradation that auto-clears on recovery.
- Bad models caught at config time. Saving a provider runs a real 1-token generation test that catches deprecated or unauthorised models a plain catalog listing would miss.
- v0.299.0
Context management + cross-provider caching
- Long conversations, managed. Threads are packed to a token budget you set (Settings → Agent). When a thread grows past the budget, older turns fold into a rolling summary — facts, decisions, open threads, preferences — while recent turns stay verbatim, with a safeguard that captures each turn before it can be dropped so nothing is silently lost.
- Prompt caching that works across providers, with cached-token accounting and per-turn cache instrumentation.
- Tool calls that work on every provider. Tool schemas are normalised per provider, with real API errors surfaced instead of silent failures.
- v0.298.0
Keep conversations on-device
- Fail-closed, local-only provider failover — MIRA won’t silently fall back to a cloud provider when a local one is unavailable.
- v0.297.0
Remote access
- Reach your self-hosted server from anywhere over Tailscale — including a docker-compose sidecar recipe.
- v0.296.0
Built web apps, live
- The coding agent serves the apps and games it builds at a clickable link.
- v0.295.0
Self-update & rollback
- Update MIRA and roll back to an earlier build from a new Settings → Updates card.
Older releases and full notes live on GitHub
Get the latest build.
Free and open source. Up and running in one command. Yours forever.