<div align="center">
  <img src="https://raw.githubusercontent.com/tappunk/.github/refs/heads/main/assets/muthr.webp" alt="muthr" width="280"/>

# muthr

**Zero-trust orchestrator for local AI on Apple Silicon.**

Run llama.cpp inference on the host, isolate agent runtimes inside per-project containers, and expose stable MCP + search endpoints. Host OS, SSH keys, and the home directory stay on the host.

[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
[![Crates.io](https://img.shields.io/crates/v/muthr?color=orange)](https://crates.io/crates/muthr)
[![GitHub Release](https://img.shields.io/github/v/release/tappunk/muthr)](https://github.com/tappunk/muthr/releases)
[![X Follow](https://img.shields.io/twitter/follow/tappunk?style=social)](https://x.com/tappunk)

[Quick Start](#quick-start) · [Features](#features) · [Architecture](#architecture) · [Commands](#commands) · [Configuration](#configuration) · [Full Docs](https://tappunk.com/muthr/)
</div>

---

## Quick Start

```bash
brew install tappunk/muthr/muthr    # or: cargo install muthr
muthr init                          # populate config from muthr-specs
muthr config init                   # create ~/.config/muthr/muthr.toml
muthr run                           # boot engine + services
```

Then enter a project sandbox:

```bash
cd ~/src/myproject
muthr sandbox shell
```

The agent runs in a container that mounts only the project workspace.

## Features

- **Host inference management**: runs `llama-server` with an OpenAI-compatible API surface
- **Per-project sandbox containers**: deterministic lifecycle, profile-aware provisioning, interactive shell with TTY resize forwarding
- **Persistent MCP services**: MCP bridge + SearXNG search in a long-lived services container
- **Zero-trust isolation**: only the project workspace mounts into the container
- **Session audit trail**: optional NDJSON logs (`session_start`, `exec_invocation`, `session_exit`) for forensics
- **Golden images**: pre-bake profile images for restricted or air-gapped environments
- **Doctor diagnostics**: proactive backend checks including arm64 buildkit/Rosetta probing
- **Full lifecycle**: `muthr run` boots engine + services, `muthr shutdown` tears down everything
- **Machine-readable output**: `--output json|ndjson` on status/list commands
- **Shell completions**: bash, zsh, fish, powershell

## Architecture

```
┌──────────────────── macOS Host ──────────────────────┐
│                                                      │
│  ┌──────────────┐          ┌──────────────────┐      │
│  │ llama-server │          │ muthr-services   │      │
│  │              │          │  MCP Bridge      │      │
│  │              │          │  SearXNG         │      │
│  │              │          │                  │      │
│  │              │          │                  │      │
│  └──────┬───────┘          └──────────────────┘      │
│         │                                            │
│  ┌──────┴───────┐                                    │
│  │ Sandboxes    │                                    │
│  │ (container)  │                                    │
│  └──────────────┘                                    │
│                                                      │
│  Agent access: workspace mount + OpenAI URL          │
│  Host secrets/SSH/home remain outside sandbox        │
│                                                      │
└──────────────────────────────────────────────────────┘
```

muthr manages three planes:

1. **Host inference runtime**: `llama-server` managed by `muthr engine`
2. **Persistent services plane**: `muthr-services` + `muthr-searxng` managed by `muthr services`
3. **Per-project sandbox**: one container per project directory, managed by `muthr sandbox`

Run `muthr run` to boot the engine and services. Enter project sandboxes with `muthr sandbox shell`.

## Usage

### Engine

```bash
muthr engine start --runtime llama --preset llama-default
muthr engine status --output json
muthr engine presets --runtime llama --output json
muthr engine stop --all
```

### Sandbox

```bash
cd ~/src/myproject
muthr sandbox start --audit-log ~/audit.ndjson
muthr sandbox shell                          # interactive shell
muthr sandbox shell -c "cargo test"          # non-interactive command
muthr sandbox shell -e API_KEY=abc --no-tty  # explicit env + automation
muthr sandbox ls --quiet                     # one name per line for scripting
muthr sandbox stop --all
muthr sandbox delete --dry-run               # preview before deleting
muthr sandbox stop --name muthr-myproject
```

### Golden images

```bash
muthr image build --profile hermes-agent
```

### Services

```bash
muthr services start --dry-run
muthr services status --output json
muthr services restart --dry-run
muthr services stop --dry-run
muthr services delete --yes
```

### Full lifecycle

```bash
muthr run --verbose
muthr shutdown --yes
```

## Commands

| Command | Purpose |
|---|---|
| `muthr engine start/stop/status/presets` | Manage inference runtime |
| `muthr sandbox start/shell/stop/delete/ls` | Per-project sandbox lifecycle |
| `muthr services start/status/restart/stop` | Persistent MCP + SearXNG services |
| `muthr run` | Boot engine + services together |
| `muthr shutdown` | Tear down all managed components |
| `muthr init` | Populate `~/.config/muthr/` from specs |
| `muthr config init/show` | Create or inspect config |
| `muthr doctor` | Prerequisite diagnostics |
| `muthr image build` | Pre-bake golden profile images |
| `muthr completion <shell>` | Generate shell completions |

## Configuration

Config lives in `~/.config/muthr/muthr.toml`:

```toml
server_port = 8080
workspace_root = "~/src"
model_dir = "~/opt/models"
default_provision_profile = "pi"
default_engine_runtime = "llama"
default_engine_preset = "llama-default"
default_engine_bind_host = "0.0.0.0"
# container_host_gateway = "192.168.1.1"  # optional, set if DNS resolution fails inside containers
```

Key environment overrides: `MUTHR_SERVER_PORT`, `MUTHR_WORKSPACE_ROOT`, `MUTHR_MODEL_DIR`, `MUTHR_PROVISION_PROFILE`, `MUTHR_ENGINE_RUNTIME`, `MUTHR_ENGINE_PRESET`, `MUTHR_ENGINE_BIND_HOST`, `MUTHR_CONTAINER_HOST_GATEWAY`.

Profiles (`base`, `pi`, `opencode`, `hermes-agent`) define container provisioning. Profile assets are managed via [muthr-specs](https://github.com/tappunk/muthr-specs).

## Security

Agents execute package installers, shell commands, and network clients with broad filesystem access. muthr reduces risk by:

- Running agents inside sandbox containers, never on the host shell
- Mounting only the project workspace (`/workspace`) into containers
- Exposing inference endpoints via explicit env vars, not ambient host access
- Using [Apple container](https://github.com/apple/container) for native virtualization-backed isolation
- Cutting network access after provisioning for restricted-profile sandboxes

See [Security](https://tappunk.com/muthr/security) for the full threat model.

## Acknowledgements

Built on:

- [Apple container](https://github.com/apple/container)
- [muthr-specs](https://github.com/tappunk/muthr-specs)

AI coding agents:

- [pi](https://github.com/earendil-works/pi) (default sandbox profile)
- [OpenCode](https://github.com/anomalyco/opencode)

Inference runtimes:

- [llama.cpp](https://github.com/ggml-org/llama.cpp) (default, included with Homebrew install)
- [mlxcel](https://github.com/lablup/mlxcel) (optional)
- [vllm-mlx](https://github.com/waybarrios/vllm-mlx) (optional)

---

**Full documentation:** https://tappunk.com/muthr/
