Skip to main content

OpenMuse

OpenMuse

An open-source version of Meta's Muse: a personal agent that works for you from your phone, keeps going while the app is closed, and asks before it does anything you can't undo. Self-hosted, any model.

CI PyPI MIT Python 3.11+
English · 简体中文

OpenMuse on a phone: one task from the request to the finished page, with one scoped approval on the way

One task, start to finish: "Make me a packing list for 4 days in Kyoto… then commit it to my kyoto-notes repo." The agent finds the repo, stops once before its first git command — approved for this task, so the commit later needs no second tap — writes a page you can tick off, commits it, and the reply links the file. A real run on DeepSeek V4.1 Flash, 52 s; the wait in the middle is cut.

Chat with an approval card A goal with its plan Ideas tab Sentinel settings and the sandbox

Start here

You want to... Go to
Install and open the app on your phone InstallQuick start
Use it from the terminal instead CLI
Point it at DeepSeek, OpenAI, Ollama, or an internal gateway Models · Configuration
Understand what it will and won't do without asking Sentinel · docs/sentinel.md
Connect email, a calendar, your contacts, a browser, or MCP servers Configuration → Connectors
Read the code Architecture · docs/architecture.md
Run it in Docker Deployment
See it as an app on a (simulated) phone, notifications included demo/mobilegym

What it does

Meta's Muse is an agent that does things rather than answering questions: it researches, plans, writes files, sends mail, works on goals over weeks, and every risky action passes through a separate gatekeeper. OpenMuse rebuilds that shape in the open:

  • One long conversation with your agent, plus side chats for separate tasks. Tool calls show up inline as chips you can expand.
  • Approval cards. Anything hard to undo (a shell command, an email, a network call after reading private data) stops and waits for a tap. An approval is scoped — once, this task, until restart, 24 hours, always — and bound to what it was for: git commands, email to one address, one website. Every permission you granted is listed under the avatar and can be revoked on its own.
  • Goals that outlive the chat. The agent breaks a goal into steps, updates them as it works, and can keep advancing goals on a timer while the app is closed, posting updates to the main chat.
  • Ideas: suggested next actions based on your goals, memory and recent conversations.
  • Memory you can read and edit. Durable facts about you are saved by the agent and shown in a tab; anything can be forgotten with one tap. When a fact changes, the line is updated rather than doubled, and a periodic tidy-up merges what says the same thing and drops what was never a fact — every change listed with an undo.
  • A Sentinel, a credential vault, taint tracking and an append-only audit log. See Sentinel.
  • Skills: how a job is done, written down once. Five ship with it (a weekly review, a trip plan, an inbox triage, a comparison, a meeting prep); the agent picks one when a request fits, or you type /trip-plan Kyoto in November. After a job went well, "save this as a skill" writes the steps down — with your approval. The Agent Skills SKILL.md format, so skills written for other agents work here.
  • Tools: files, shell, Python, web search and fetch, email (with one-time codes scrubbed before the model sees them), your calendar (read from its private .ics link; events it proposes arrive as a card you add with a tap), your contacts (a .vcf export or the people you mention in chat — it looks up who is who instead of guessing an address), an optional Playwright browser, and any MCP server.
  • Runs on any OpenAI-compatible model. DeepSeek, OpenAI, OpenRouter, Ollama, vLLM, or a company gateway with custom headers.

Why OpenMuse

  • It is a Muse, not a bot framework. One agent with a name and a face, a phone app with Chat / Feed / Ideas / Goals / Library tabs, approval cards, background work. If you want a bot in Telegram or Discord, see Related projects.
  • Safety is the architecture, not a setting. The agent never touches tools directly. A separate Sentinel decides allow / ask / deny per call, resolves {{vault:NAME}} placeholders so secrets never reach the model, tracks taint (private data read → new destinations need approval), and logs everything.
  • Bring your own model. Chat Completions or Responses API, streaming, <think> handling, native or prompt-based tool calling.
  • Small enough to read. About 7k lines of typed Python and 3k lines of TypeScript. No orchestration framework underneath.

Install

Python 3.11 or newer. The phone app is pre-built and included in the package; Node is only needed if you change web/.

uv tool install openmuse
# or: pip install openmuse

Latest from git: uv tool install git+https://github.com/OpenMuseAgent/OpenMuse.git. From a checkout, for development:

git clone https://github.com/OpenMuseAgent/OpenMuse.git && cd OpenMuse
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"

Optional: openmuse[browser] adds the Playwright browser tool (then playwright install chromium).

Quick start

openmuse config init                 # writes config/config.toml
export DEEPSEEK_API_KEY=sk-...       # the default config uses DeepSeek; see Models below
openmuse serve --host 0.0.0.0        # prints a URL and a QR code

Scan the QR code with your phone (same Wi-Fi), or open the URL on this machine. The link carries a one-time access token; add the page to your home screen and it behaves like an app. Then try:

  • "Compare the Sony WH-1000XM6 and Bose QuietComfort Ultra for long flights and save a short comparison to headphones.md"
  • "Check how much free disk space this machine has" — this one produces an approval card.
  • "Set up a goal: conversational Japanese before my Kyoto trip in December, 30 minutes a day" — then open the Goals tab.

Prefer a terminal? openmuse chat gives you the same agent with approvals in the console, and openmuse run "task" runs one task and exits. Something off? openmuse doctor checks the config, the model and the connectors and says what to fix. See docs/cli.md.

The app

openmuse serve starts an always-on agent and serves a mobile-first web app from the same process (FastAPI + a WebSocket for live events; React on the client, bundled into the Python package).

Research with tool chips and a file artifact Skills: the built-in ones and yours Memory tab An event the agent drafted, ready to add to the calendar

Screen What you get
Chat Message-style conversation, streaming replies, tool chips with output, file artifacts (a file named in a reply opens on tap), approval and question cards, side chats. You can keep typing while the agent works; new messages are folded into the running turn. When it browses, a live browser card shows the page after every step — tap it to watch, take over to sign in or fix something yourself, hand it back and the agent continues.
Feed What happened while you were away: the result of each background pass, files it made, and every card still waiting for you, from any chat. Next up says what runs next.
Ideas Five suggested actions, regenerated on demand. Tap one to send it as a message.
Goals Goals by area of life (health, finance, career, learning…), each with a plan, step status and notes, a target date and an optional check-in cadence — a short message at that time, nothing more. When what the agent learns no longer fits the plan it proposes a change and you accept or keep yours. A proactivity dial (Off / Low / Default / High) and quiet hours decide how often it works on goals while you are away and when it speaks up — a pass with nothing to report stays a one-liner instead of a message.
Reminders "Remind me at six to call mum" — one message at that time, in the chat you said it in. "Every weekday at 07:30, a one-line weather check for my ride" — a routine: the agent does the work then and reports. Kept whatever the proactivity level or quiet hours; listed under Upcoming and in the terminal.
Skills Recipes the agent follows: the built-in five, the ones you write or paste a link to, and the ones it saves after a job went well (it asks first). Type / in the chat to pick one; switch any off; your copy of a built-in replaces it.
Triggers Work that starts from the world, not the clock. "When the landlord writes back, summarise it and draft a reply" (new mail), "half an hour before any review, brief me" (calendar), "when my deploy script calls you, check the site" (a webhook URL any program can POST to). The mail, event or request is the agent's context — treated as data, never as instructions — and the result lands in the Feed.
Library Everything the agent made — pages, documents, trackers, images — opened in the app. Pages render in a sandbox that cannot reach your token or the API.
Avatar The menu: the approvals queue across all chats, the activity log, permissions you granted (revoke any one), what is upcoming (background work, check-ins, reminders, triggers), memory, skills, connections, and settings (name, avatar, personality, Sentinel mode, background work, language).
Connections Plug things in from the phone: the model (provider presets, key straight into the vault, one-tap test), your mailbox (read and send, with a sign-in check), your calendar (the private .ics link of Google / Outlook / iCloud / Fastmail, kept in the vault; today's events show in the Feed), your contacts (upload a .vcf export; the agent looks people up before writing to them and the approval card names the recipient), the browser, MCP servers, and the vault itself. Keys and passwords never reach the model.

The first time you open it, a short setup runs instead: your name, your Muse's name and style, the model and key, optionally your mail, calendar and contacts. Skip it if config.toml already says it all.

Add it to the home screen and turn on notifications (Settings): the phone buzzes when the agent needs an approval, has a question, finished something in the background, or a reminder or check-in is due — standard Web Push through the browser, no account with anyone — and the icon shows how many cards are waiting. Needs https:// or localhost; see deployment.

The app talks to a small REST + WebSocket API, documented in docs/app.md, so other front-ends can be built on the same server.

To see it the way Muse is meant to be seen — an app among other apps, coming through the notification shade when it needs you — demo/mobilegym installs OpenMuse as a native app on MobileGym, a browser-hosted Android simulator. One browser tab, no device.

Sentinel

Every tool call goes through Sentinel before it runs. Tools declare a risk level (safe / moderate / sensitive) and can escalate a specific call (shell on rm -rf, python_execute when the code reaches the network or the environment, web_fetch on a private IP — including through redirects). Evaluation order, first match wins:

  1. deny_tools → deny
  2. [[sentinel.rules]] matching glob patterns on the arguments → the rule's action
  3. always_allow_tools / always_ask_tools
  4. Taint: the session has read private data (email, memories, files outside the workspace) and this call sends data to a host outside egress_allowlist → ask
  5. Risk × mode: ask asks for sensitive calls, strict also for moderate ones, auto allows everything not denied
  6. A call with a warning (sudo, curl | sh, code that deletes files) asks regardless of mode; only an explicit rule can allow it
[sentinel]
mode = "ask"                              # ask | strict | auto
always_ask_tools = ["send_email", "shell"]
egress_allowlist = ["*.wikipedia.org", "github.com", "*.github.com"]

[[sentinel.rules]]
tool   = "shell"
match  = { command = "*rm -rf*" }
action = "deny"

Secrets live in a Fernet-encrypted vault (openmuse vault set EMAIL_PASSWORD, or the Connections screen). Config and tool arguments reference them as {{vault:EMAIL_PASSWORD}}; Sentinel substitutes the value right before execution and redacts it from tool output, so the model never sees it. Shell commands and Python scripts run with credential-looking environment variables stripped. Every decision is appended to ~/.openmuse/audit.jsonl. Details, and an honest list of what is not covered, in docs/sentinel.md; reporting in SECURITY.md.

Models

Edit [llm] in config/config.toml. Any OpenAI-compatible endpoint works:

[llm]
provider = "openai"                    # Chat Completions; "openai_responses" for the Responses API
model    = "deepseek-flash"
base_url = "https://api.deepseek.com"
api_key  = "${DEEPSEEK_API_KEY}"

# OpenAI:      model = "gpt-5.6-sol"  base_url = "https://api.openai.com/v1"   api_key = "${OPENAI_API_KEY}"
# Ollama:      model = "qwen3:8b"     base_url = "http://localhost:11434/v1"   api_key = "ollama"
# OpenRouter:  model = "deepseek/deepseek-flash"  base_url = "https://openrouter.ai/api/v1"
# A gateway that needs headers:  extra_headers = { "X-End-User-Id" = "openmuse" }
# An endpoint that silently ignores `tools`:  tool_mode = "prompt"   (rejections are handled by the default "auto")

The same settings can be set with OPENMUSE_LLM_MODEL, OPENMUSE_LLM_BASE_URL, OPENMUSE_LLM_API_KEY, OPENMUSE_LLM_PROVIDER. Full reference: docs/configuration.md.

Local models work: qwen3:8b on Ollama passes the provider check (five everyday tasks) with native tool calling, gemma3:4b through the prompt fallback. Results and settings in docs/configuration.md → Local models; python scripts/provider_check.py tells you about yours in a minute.

Architecture

flowchart LR
    P([Phone / browser]) <-- WebSocket + REST --> S[MuseService<br/>threads, scheduler, ideas]
    C([Terminal]) <--> A
    S <--> A[MuseAgent loop]
    A <--> LLM[(any OpenAI-compatible model)]
    A --> G{{Sentinel}}
    G -- allow --> T[Tools]
    G -- ask --> P
    G --> AU[(audit.jsonl)]
    G <--> V[(vault.enc)]
    T --> F[files · shell · python]
    T --> W[web_search · web_fetch · browser]
    T --> E[email · calendar · contacts]
    T --> MCP[MCP servers]
    T <--> M[(memory.db)]
    T <--> GO[(goals.db)]
Area Files
Agent loop, system prompt, context window openmuse/agent/core.py, openmuse/prompts.py
Sentinel: policy, approvals, taint, audit openmuse/sentinel/
Credential vault openmuse/vault/
Tools and MCP adapter openmuse/tools/
LLM providers, <think> filter, prompt-based tool calling openmuse/llm/
Memory and goals (SQLite) openmuse/memory/, openmuse/goals/
App server: service, REST/WebSocket API, timeline openmuse/server/
Phone app (React, Vite, Tailwind) web/ → built into openmuse/server/static/
Terminal UI and CLI openmuse/console.py, openmuse/cli.py

More in docs/architecture.md.

OpenMuse and Meta Muse

Meta Muse OpenMuse
Runs in a per-user Secure VM Runs on your machine or in Docker; on Linux every shell / Python call gets its own bubblewrap namespace — workspace-only writes, no home directory, no network unless the call needs it
Sentinel approves sensitive actions Sentinel policy engine: allow / ask / deny, rules, taint tracking, egress allowlist
Credentials never reach the model Encrypted vault with {{vault:NAME}} placeholders and output redaction
Remembers you SQLite memory the agent maintains and you can edit
Works on goals in the background Goals with steps; scheduler advances them and reports to the chat
Mobile app with chat, goals, approvals Mobile-first web app served by openmuse serve, installable to the home screen
Meta's models Any OpenAI-compatible model
Closed MIT

Docs

Roadmap

  • Agent loop, Sentinel, vault, audit, memory, goals, tools, MCP, CLI
  • Mobile-first app: Chat · Feed · Ideas · Goals · Library, approvals as scoped grants, side chats, background goal work
  • Push notifications when an approval is waiting or a goal posts an update
  • Browser view: watch the agent browse live, take over for sign-ins
  • Local models (Ollama) with automatic prompt-mode fallback
  • Triggers: new mail, calendar events and webhooks start work; routines cover cron
  • Calendar connector: any private .ics link or file; agenda, free time, drafted events as Add to calendar cards
  • Contacts connector: .vcf exports and links, the agent's own book, recipients named on approval cards
  • Memory that stays tidy: rare-word recall, updates instead of duplicates, a periodic tidy-up with undo
  • Memory recall with embeddings
  • Per-call sandboxes for shell and python_execute (bubblewrap on Linux)
  • Skills: reusable task recipes in the Agent Skills SKILL.md format — built in, yours, or saved by the agent
  • The app in 简体中文 (Settings → App language); more languages welcome — one dictionary file each

Contributing

Use it for a real task, report what broke, then pick something focused. CONTRIBUTING.md has the development setup; CI runs ruff, pytest and the web build.

  • nanobot: a lightweight personal assistant framework that lives in chat apps (Telegram, Discord, Slack, WeChat...). Pick it if you want a bot in the channels you already use. OpenMuse is one agent with Muse's product shape and safety model; it does not try to be a channel framework.
  • OpenClaw: the always-on gateway approach many assistant projects follow.
  • browser-use: the element-annotation idea behind the browser tool.
  • Model Context Protocol: how OpenMuse gets connectors without writing each one.

Disclaimer

OpenMuse is an independent community project. It is not affiliated with, endorsed by, or derived from Meta Platforms, Inc. or its Muse product.

License

MIT

Release files for openmuse 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openmuse 0.4.0
File Size Uploaded
openmuse-0.4.0.tar.gz 403.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for openmuse 0.4.0
File Interpreter ABI Platform
openmuse-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 837.1 kB

Release files / openmuse-0.4.0.tar.gz

Download URL openmuse-0.4.0.tar.gz
Size 403.2 kB
Tags Source
SHA-256 checksum
How to use checksums
90d683a94505264cc0dfccfd4c9b36d8c2bdbfebb05b5759404cbfc207e62903
BLAKE2b-256 checksum
How to use checksums
6bda56d80cb2b749c072e0236accdbd43118d15b31e84c9e3c5fa991b22d3d89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release files / openmuse-0.4.0-py3-none-any.whl

Download URL openmuse-0.4.0-py3-none-any.whl
Size 433.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b48cf65768a8798864a0bfbb458cf9ade806f5edb00de0ab4452847587100123
BLAKE2b-256 checksum
How to use checksums
8e67cc0fdf3de408d41f554fbe401d24e1a79c502717502b02da818aa9ebe294
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.0

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page