ฮผ (mu)
AI agent harness with full local machine access. Wraps any OpenAI-compatible model behind Vercel AI SDK v6, executing tool calls directly on the host system with verbose step-by-step logging.
Built by Muse Mesh.
Table of Contents
- Quick Start
- Installation
- Configuration
- Usage
- Tools
- Permission Modes
- Provider Compatibility
- MCP Integration
- Deployment
- Audit Logging
- Project Structure
- Development
Quick Start
# Clone and install
git clone https://github.com/muse-mesh/mu.git && cd mu
pnpm install
# Configure
cp .env.example .env
# Edit .env โ set MU_BOT_API_KEY at minimum
# Run interactively (CLI REPL)
pnpm dev
# Run with web UI
pnpm dev -- --web
# Open http://localhost:3141
Installation
Requirements
- Node.js 22+
- pnpm (corepack-managed, v10.30.1)
Local (bare metal)
git clone https://github.com/muse-mesh/mu.git && cd mu
corepack enable && corepack prepare [email protected] --activate
pnpm install
# Copy and configure environment
cp .env.example .env
# Edit .env with your API key and model settings
# Development mode (tsx, hot reload)
pnpm dev
# Production build
pnpm build
pnpm start # CLI mode
pnpm start:web # Web UI mode
Docker
cd mu
# 1. Configure environment (MU_BOT_API_KEY is the only required variable)
cp .env.example .env
# Edit .env โ set MU_BOT_API_KEY at minimum, plus MU_BOT_API_BASE_URL and MU_BOT_MODEL if not using OpenAI
# 2. Build and start with docker compose (recommended)
docker compose up -d --build
# 3. Verify it's running
docker ps --filter name=mu
curl http://localhost:3141/api/health
# โ {"status":"ok","uptime":...,"model":"..."}
The Web UI is available at http://localhost:3141.
To view logs: docker logs -f mu
To stop: docker compose down
Alternative โ run without compose:
docker build -t mu:latest .
docker run -d \
--name mu \
-p 3141:3141 \
--env-file .env \
-e MU_BOT_WEB_UI_ENABLED=true \
mu:latest
The Docker image:
- Uses
node:22-slimwith common CLI tools (git, curl, wget, jq, ripgrep, tree, python3) - Runs as non-root
muuser - Application code at
/appis read-only (owned by root) - Agent working directory is
/โ full filesystem read access - Persists data at
/home/mu/.mu(mount a volume to retain across restarts) - Health check at
GET /api/health
Raspberry Pi / ARM64
For resource-constrained devices (1 GB RAM), run natively without Docker:
# On the Pi โ install Node.js 22
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt-get install -y nodejs
# Transfer the built project (from your dev machine)
# On dev machine:
pnpm build
rsync -avz --exclude node_modules --exclude .git . user@pi-ip:~/mu
# On the Pi:
cd ~/mu
corepack enable && corepack prepare [email protected] --activate
pnpm install --frozen-lockfile --prod
# Configure
cp .env.example .env
# Edit .env
# Run
MU_BOT_WEB_UI_ENABLED=true node dist/index.js --web
# Access at http://<pi-ip>:3141
Optional: Create a systemd service for auto-start:
sudo tee /etc/systemd/system/mu.service > /dev/null << 'EOF'
[Unit]
Description=mu AI Agent
After=network.target
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/mu
EnvironmentFile=/home/pi/mu/.env
ExecStart=/usr/bin/node /home/pi/mu/dist/index.js --web
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable mu
sudo systemctl start mu
Configuration
Configuration loads from multiple sources (highest priority first):
- CLI flags (
--model,--web, etc.) - Environment variables (
MU_BOT_*) - Config file (
.mu.jsonin cwd or~/.mu.json) - Defaults
Environment Variables
Copy .env.example to .env and customise:
Config File
Create .mu.json in your project root or ~/.mu.json:
{
"apiBaseUrl": "http://localhost:11434/v1",
"model": "llama3",
"maxSteps": 100,
"permissionMode": "default"
}
CLI Flags
mu [prompt] [options]
Options:
-m, --model <model> Model identifier
-b, --base-url <url> API base URL
-k, --api-key <key> API key
-s, --max-steps <n> Max tool loop steps
-v, --verbose Verbose output
-d, --debug Debug output
-w, --web Enable web UI
-p, --port <port> Web UI port (default: 3141)
--permission <mode> Permission mode
--output <format> Output format: text|json|ndjson
--tools <tools> Comma-separated list of enabled tools
-c, --config <path> Config file path
Usage
Headless Mode
Pass a prompt as an argument โ mu executes the task and exits:
pnpm dev -- "list the files in the current directory"
pnpm dev -- -m gpt-4o "explain this codebase"
pnpm dev -- -s 5 "find all TODO comments in src/"
pnpm dev -- --tools file_read,grep "search for imports in src/"
Interactive REPL
Run without a prompt for multi-turn conversation:
pnpm dev
Web UI
Browser-based interface with real-time streaming:
pnpm dev -- --web
# Open http://localhost:3141
Features:
- Real-time streaming responses (AI SDK UI protocol)
- Session management (create, switch, resume, delete)
- Tool call visualization with collapsible detail panels
- Token usage and cost tracking
- Dark/light theme toggle
- Mobile-responsive layout with collapsible sidebar
NDJSON Output
Machine-readable output for scripting:
pnpm dev -- --output ndjson "echo hello" | jq '.type'
Tools
mu ships with 11 built-in tools:
Tool Filtering
# Read-only exploration
pnpm dev -- --tools file_read,grep,glob,list_dir "explore this codebase"
# File operations only
pnpm dev -- --tools file_read,file_write,file_edit "refactor the config module"
Permission Modes
Provider Compatibility
mu works with any OpenAI-compatible API endpoint:
# OpenAI
MU_BOT_API_BASE_URL=https://api.openai.com/v1
MU_BOT_MODEL=gpt-4o
# Ollama (local)
MU_BOT_API_BASE_URL=http://localhost:11434/v1
MU_BOT_MODEL=llama3
# OpenRouter
MU_BOT_API_BASE_URL=https://openrouter.ai/api/v1
MU_BOT_MODEL=anthropic/claude-sonnet-4-20250514
# LM Studio
MU_BOT_API_BASE_URL=http://localhost:1234/v1
MU_BOT_MODEL=local-model
# Mume Gateway
MU_BOT_API_BASE_URL=https://mume.ai/api/v1
MU_BOT_MODEL=z-ai/glm-5v-turbo
MCP Integration
Connect external MCP servers for additional tools:
{
"mcpServers": [
{
"name": "my-tools",
"transport": "stdio",
"config": { "command": "my-mcp-server", "args": [] }
},
{
"name": "remote",
"transport": "sse",
"config": { "url": "https://mcp.example.com/sse" }
}
]
}
Set via .mu.json or the MU_BOT_MCP_SERVERS env var (JSON string). MCP tools are namespaced as mcp__{server}__{tool}.
Deployment
Docker Desktop
cp .env.example .env # configure API key & model
docker compose up -d # builds, starts on port 3141
docker compose logs -f # watch logs
docker compose down # stop
Raspberry Pi (native)
# Prerequisites: Node.js 22, pnpm
# Transfer built artifacts, install prod deps, run
# See "Raspberry Pi / ARM64" under Installation for full steps
Security Model
When deployed in Docker:
- Application code (
/app) is owned byroot:rootwith755permissions โ the agent user (mu) can read but cannot modify its own code - Working directory is
/โ the agent can browse and read the entire filesystem - Writable storage is limited to
/home/mu/.mu(logs, sessions, memory) - Non-root execution โ the container runs as the unprivileged
muuser
Audit Logging
Every session creates a JSONL audit log at ~/.mu/logs/{sessionId}.jsonl:
# View the latest log
cat ~/.mu/logs/$(ls -t ~/.mu/logs/ | head -1)
# Filter for tool calls
cat ~/.mu/logs/*.jsonl | jq 'select(.type == "tool_call_start")'
Event types: session_start, session_end, user_message, step_start, step_finish, tool_call_start, tool_call_finish, model_response.
Project Structure
src/
โโโ index.ts # CLI entry point (Commander)
โโโ agent.ts # Agent loop (streamText + tools)
โโโ config.ts # Zod-validated config loader
โโโ logger.ts # Pino structured logger + JSONL audit
โโโ state.ts # Reactive state store
โโโ types.ts # Shared types (MuToolDef, LogEvent, etc.)
โโโ shutdown.ts # Graceful SIGTERM/SIGINT shutdown
โโโ cost.ts # Cost tracking with model pricing
โโโ retry.ts # Retry with exponential backoff
โโโ context.ts # Context window sizes + token estimation
โโโ cli/
โ โโโ renderer.ts # Terminal output formatter
โ โโโ repl.ts # Interactive REPL mode
โโโ compaction/
โ โโโ index.ts # Context compaction pipeline
โ โโโ prompts.ts # Compaction & memory extraction prompts
โโโ memory/
โ โโโ index.ts # 3-tier memory system (MEMORY.md, entries, session)
โโโ tools/
โ โโโ index.ts # Tool registry + execution pipeline
โ โโโ build-tool.ts # buildTool() factory with safe defaults
โ โโโ shell-exec.ts # Shell command execution
โ โโโ file-read.ts # File reading with line ranges
โ โโโ file-write.ts # File writing
โ โโโ file-edit.ts # Find-and-replace editing
โ โโโ glob.ts # File glob matching
โ โโโ grep.ts # Regex search (ripgrep + fallback)
โ โโโ list-dir.ts # Directory listing
โ โโโ http-fetch.ts # HTTP requests
โ โโโ system-info.ts # System information
โ โโโ think.ts # Reasoning scratchpad
โ โโโ task-complete.ts # Task completion signal
โโโ permissions/
โ โโโ index.ts # 4-mode permission system
โ โโโ prompt.ts # CLI permission prompting
โโโ mcp/
โ โโโ client.ts # MCP server client
โโโ web/
โโโ server.ts # Hono API server + static serving
โโโ sessions.ts # Session store (JSON file-backed)
web/ # React frontend (Vite)
โโโ src/
โ โโโ App.tsx # Main app component (useChat hook)
โ โโโ main.tsx # React entry point
โ โโโ app.css # Styles (dark/light themes)
โโโ index.html
โโโ vite.config.ts
Development
# Dev mode (tsx, auto-reload)
pnpm dev
# Dev with web UI
pnpm dev -- --web
# Frontend dev server (hot reload, proxied to backend)
pnpm dev:web
# Type-check
pnpm exec tsc --noEmit
# Production build (frontend + backend)
pnpm build
# Production run
pnpm start # CLI mode
pnpm start:web # Web UI mode (port 3141)
License
Apache 2.0 โ see LICENSE for details.
Copyright 2025 Muse Mesh.