Thanks to visit codestin.com
Credit goes to github.com

Skip to content

A personal AI assistant built in Rust. Single binary, multi-provider LLMs, long-term memory, sandboxed execution, voice, MCP tools, and multi-channel access (web, Telegram, API).

License

Notifications You must be signed in to change notification settings

helloweishi/moltis

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,103 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Moltis

Moltis

A personal AI gateway written in Rust. One binary, no runtime, no npm.

CI codecov CodSpeed License: MIT Rust

FeaturesInstallationBuildCloud DeploymentHow It WorksHooksDiscord


Inspired by OpenClaw — just build it and run it.

Installation

# One-liner install script (macOS / Linux)
curl -fsSL https://www.moltis.org/install.sh | sh

# macOS / Linux via Homebrew
brew install moltis-org/tap/moltis

# Docker (multi-arch: amd64/arm64)
docker pull ghcr.io/moltis-org/moltis:latest

# Or build from source
cargo install moltis --git https://github.com/moltis-org/moltis

Features

  • Multi-provider LLM support — OpenAI Codex, GitHub Copilot, and Local LLM through a trait-based provider architecture
  • Streaming responses — real-time token streaming for a responsive user experience, including when tools are enabled (tool calls stream argument deltas as they arrive)
  • Communication channels — Telegram integration with an extensible channel abstraction for adding others
  • Web gateway — HTTP and WebSocket server with a built-in web UI
  • Session persistence — SQLite-backed conversation history, session management, and per-session run serialization to prevent history corruption
  • Agent-level timeout — configurable wall-clock timeout for agent runs (default 600s) to prevent runaway executions
  • Sub-agent delegationspawn_agent tool lets the LLM delegate tasks to child agent loops with nesting depth limits and tool filtering
  • Message queue modesfollowup (replay each queued message as a separate run) or collect (concatenate and send once) when messages arrive during an active run
  • Tool result sanitization — strips base64 data URIs and long hex blobs, truncates oversized results before feeding back to the LLM (configurable limit, default 50 KB)
  • Memory and knowledge base — embeddings-powered long-term memory
  • Skills — extensible skill system with support for existing repositories
  • Hook system — lifecycle hooks with priority ordering, parallel dispatch for read-only events, circuit breaker, dry-run mode, HOOK.md-based discovery, eligibility checks, bundled hooks (boot-md, session-memory, command-logger), CLI management (moltis hooks list/info), and web UI for editing, enabling/disabling, and reloading hooks at runtime
  • Web browsing — web search (Brave, Perplexity) and URL fetching with readability extraction and SSRF protection
  • Voice support — Text-to-speech (TTS) and speech-to-text (STT) with multiple cloud and local providers. Configure and manage voice providers from the Settings UI.
  • Scheduled tasks — cron-based task execution
  • OAuth flows — built-in OAuth2 for provider authentication
  • TLS support — automatic self-signed certificate generation
  • Observability — OpenTelemetry tracing with OTLP export
  • MCP (Model Context Protocol) support — connect to MCP tool servers over stdio or HTTP/SSE (remote servers), with health polling, automatic restart on crash (exponential backoff), and in-UI server config editing
  • Parallel tool execution — when the LLM requests multiple tool calls in one turn, they run concurrently via futures::join_all, reducing latency
  • Sandboxed execution — Docker and Apple Container backends with pre-built images, configurable packages, and per-session isolation
  • Authentication — password and passkey (WebAuthn) authentication with session cookies, API key support, and a first-run setup code flow
  • Endpoint throttling — built-in per-IP request throttling for unauthenticated traffic when auth is enforced, with strict limits for password login attempts and sensible caps for API/WS traffic (429 + Retry-After on limit hit)
  • WebSocket security — Origin validation to prevent Cross-Site WebSocket Hijacking (CSWSH)
  • Onboarding wizard — guided setup for agent identity (name, emoji, creature, vibe, soul) and user profile
  • Config validationmoltis config check validates the configuration file, detects unknown/misspelled fields with suggestions, and reports security warnings
  • Default config on first run — writes a complete moltis.toml with all defaults so you can edit packages and settings without recompiling
  • Random port per installation — each fresh install picks a unique available port, avoiding conflicts when multiple users run moltis on the same machine
  • Zero-config startupmoltis runs the gateway by default; no subcommand needed
  • Configurable directories--config-dir / --data-dir CLI flags and MOLTIS_CONFIG_DIR / MOLTIS_DATA_DIR environment variables
  • Cloud deployment — one-click deploy configs for Fly.io, DigitalOcean, and Render with --no-tls flag for cloud TLS termination
  • Tailscale integration — expose the gateway over your tailnet via Tailscale Serve (private HTTPS) or Funnel (public HTTPS), with status monitoring and mode switching from the web UI (optional tailscale feature flag)

Build

# Clone and build
git clone https://github.com/moltis-org/moltis.git
cd moltis
cargo build --release

# Start the gateway (gateway is the default command)
cargo run --release

Open https://moltis.localhost:3000

Running with Docker

Moltis uses Docker for sandboxed command execution — when the LLM runs shell commands, they execute inside isolated containers. When running Moltis itself in a container, you need to give it access to the host's container runtime.

# Docker / OrbStack
docker run -d \
  --name moltis \
  -p 13131:13131 \
  -p 13132:13132 \
  -v moltis-config:/home/moltis/.config/moltis \
  -v moltis-data:/home/moltis/.moltis \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/moltis-org/moltis:latest

# Podman (rootless)
podman run -d \
  --name moltis \
  -p 13131:13131 \
  -p 13132:13132 \
  -v moltis-config:/home/moltis/.config/moltis \
  -v moltis-data:/home/moltis/.moltis \
  -v /run/user/$(id -u)/podman/podman.sock:/var/run/docker.sock \
  ghcr.io/moltis-org/moltis:latest

# Podman (rootful)
podman run -d \
  --name moltis \
  -p 13131:13131 \
  -p 13132:13132 \
  -v moltis-config:/home/moltis/.config/moltis \
  -v moltis-data:/home/moltis/.moltis \
  -v /run/podman/podman.sock:/var/run/docker.sock \
  ghcr.io/moltis-org/moltis:latest

Open https://localhost:13131 in your browser and complete the setup.

Moltis generates a self-signed TLS certificate on first run. To trust it and remove browser warnings, download the CA certificate from http://localhost:13132/certs/ca.pem and add it to your system trust store (Keychain on macOS, update-ca-certificates on Linux).

Important notes:

  • Socket mount is required — Without mounting the container runtime socket, Moltis cannot execute sandboxed commands. The agent will still work for chat-only interactions, but any tool that runs shell commands will fail.
  • Security consideration — Mounting the Docker socket gives the container full access to the Docker daemon. This is necessary for Moltis to create sandbox containers. Only run Moltis containers from trusted sources.
  • OrbStack — Works identically to Docker; use the same socket path (/var/run/docker.sock).
  • Podman — Moltis talks to the Podman socket using the Docker API (Podman's compatibility layer). Use the rootless socket path (/run/user/$(id -u)/podman/podman.sock) or rootful path (/run/podman/podman.sock) depending on your setup. You may need to enable the Podman socket service: systemctl --user enable --now podman.socket
  • Persistence — Mount volumes to preserve data across container restarts:
    • /home/moltis/.config/moltis — configuration (moltis.toml, mcp-servers.json)
    • /home/moltis/.moltis — data (databases, sessions, memory)

Cloud Deployment

Deploy the pre-built Docker image to your favorite cloud provider:

Provider Deploy
DigitalOcean Deploy to DO

Fly.io (CLI):

fly launch --image ghcr.io/moltis-org/moltis:latest
fly secrets set MOLTIS_PASSWORD="your-password"

All cloud configs use --no-tls because the provider handles TLS termination. See Cloud Deploy docs for per-provider setup details, persistent storage notes, and authentication.

How It Works

Moltis is a local-first AI gateway — a single Rust binary that sits between you and multiple LLM providers. Everything runs on your machine; no cloud relay required.

┌─────────────┐  ┌─────────────┐  ┌─────────────┐
│   Web UI    │  │  Telegram   │  │  Discord    │
└──────┬──────┘  └──────┬──────┘  └──────┬──────┘
       │                │                │
       └────────┬───────┴────────┬───────┘
                │   WebSocket    │
                ▼                ▼
        ┌─────────────────────────────────┐
        │          Gateway Server         │
        │   (Axum · HTTP · WS · Auth)     │
        ├─────────────────────────────────┤
        │        Chat Service             │
        │  ┌───────────┐ ┌─────────────┐  │
        │  │   Agent   │ │    Tool     │  │
        │  │   Runner  │◄┤   Registry  │  │
        │  └─────┬─────┘ └─────────────┘  │
        │        │                        │
        │  ┌─────▼─────────────────────┐  │
        │  │    Provider Registry      │  │
        │  │  Multiple providers       │  │
        │  │  (Codex · Copilot · Local)│  │
        │  └───────────────────────────┘  │
        ├─────────────────────────────────┤
        │  Sessions  │ Memory  │  Hooks   │
        │  (JSONL)   │ (SQLite)│ (events) │
        └─────────────────────────────────┘
                       │
               ┌───────▼───────┐
               │    Sandbox    │
               │ Docker/Apple  │
               │  Container    │
               └───────────────┘

Gateway startup

When moltis gateway runs, it loads moltis.toml, initializes the credential store (passwords, passkeys, API keys), registers LLM providers and tools, discovers hooks and skills, optionally starts the memory manager, and pre-builds a sandbox image if configured. An Axum HTTP server then listens for WebSocket and REST connections.

Message flow

  1. Connect — A client (web UI, Telegram bot, API key bearer) opens a WebSocket. The server validates auth and Origin headers, then assigns a connection ID.
  2. Send — The client calls the chat.send RPC method with message text and an optional model override. The gateway resolves the session, persists the user message to a JSONL file, loads conversation history, and builds a system prompt (agent identity, project context, discovered skills).
  3. Agent loop — If the chosen provider supports tool calling, an agent loop runs (up to 25 iterations). Each iteration calls the LLM, inspects the response for tool calls, fires BeforeToolCall / AfterToolCall hooks, executes tools inside the sandbox, appends results, and loops until the LLM produces a final text answer. If tools are not available, the provider streams tokens directly.
  4. Broadcast — Every step (thinking, tool start/end, text deltas, final response) is broadcast over the WebSocket as sequenced events. The web UI renders them in real time.
  5. Channel replies — If the message originated from Telegram or another channel, the final response is delivered back through that channel's outbound interface.

Sessions and memory

Conversations are stored as append-only JSONL files under ~/.moltis/agents/<agent>/sessions/. A SQLite database tracks metadata (message counts, model selection, project bindings, channel bindings). When token usage approaches 95% of the context window, the session is auto-compacted: history is summarized and important facts are persisted to the memory store.

The optional memory manager watches memory/ directories for Markdown files, chunks them by heading, embeds the chunks, and stores vectors in SQLite for hybrid (vector + full-text) search. Memory context is injected into the system prompt automatically.

Hooks

Lifecycle hooks let you observe, modify, or block actions at key points. Modifying events (BeforeToolCall, BeforeCompaction, MessageSending) run sequentially — a hook can rewrite arguments or block execution. Read-only events (AfterToolCall, SessionEnd, GatewayStart, …) run in parallel. Hooks are discovered from HOOK.md files and include a circuit breaker that auto-disables after repeated failures.

Security model

Moltis applies defense in depth across several layers:

  • Authentication — On first run a one-time setup code is printed to the terminal. The user enters it to set a password or register a WebAuthn passkey. Subsequent requests are authenticated via session cookies or API key bearer tokens. Connections from loopback addresses (localhost, 127.0.0.1, ::1) are allowed without credentials as a safe default for local use.
  • WebSocket Origin validation — The WebSocket upgrade handler rejects cross-origin requests to prevent Cross-Site WebSocket Hijacking (CSWSH). A malicious webpage cannot connect to your local gateway from the browser.
  • SSRF protection — The web_fetch tool resolves DNS before making HTTP requests and blocks any target IP in loopback, private, link-local, or CGNAT ranges. This prevents the LLM from reaching internal services.
  • Secret handling — Passwords, API keys, and tokens are stored as secrecy::Secret<String>, which redacts Debug output, prevents accidental Display, and zeroes memory on drop. Environment variable values injected into sandbox sessions are redacted from command output (including base64 and hex encoded forms).
  • No unsafe codeunsafe_code is denied workspace-wide. The only exception is an opt-in FFI wrapper behind the local-embeddings feature flag.
  • Hook gatingBeforeToolCall hooks can inspect, modify, or block any tool invocation before it executes, giving you a programmable policy layer over what the agent is allowed to do.

Sandboxed execution

User commands never run directly on the host. They execute inside isolated containers using either Docker or Apple Container as the backend.

At startup the gateway builds a deterministic image from the configured base image (ubuntu:25.10 by default) and the package list in moltis.toml. The image tag is a hash of the base image + sorted packages — if you add or remove a package, the tag changes and a rebuild is triggered automatically.

Each command invocation gets a per-session container. Environment variables configured for the agent are injected into the container, but their values are redacted from any output the LLM sees (plain text, base64, and hex forms) to prevent leaking secrets through tool results.

Getting Started

Build

cargo build              # Debug build
cargo build --release    # Optimized build

Run

cargo run                # Start the gateway server (default command)

On first run, a setup code is printed to the terminal. Open the web UI and enter this code to set your password or register a passkey.

Optional flags:

cargo run -- --config-dir /path/to/config --data-dir /path/to/data

Test

cargo test --all-features

Hooks

Moltis includes a hook dispatch system that lets you react to lifecycle events with native Rust handlers or external shell scripts. Hooks can observe, modify, or block actions.

Events

BeforeToolCall, AfterToolCall, BeforeAgentStart, AgentEnd, MessageReceived, MessageSending, MessageSent, BeforeCompaction, AfterCompaction, ToolResultPersist, SessionStart, SessionEnd, GatewayStart, GatewayStop, Command

Hook discovery

Hooks are discovered from HOOK.md files in these directories (priority order):

  1. <workspace>/.moltis/hooks/<name>/HOOK.md — project-local
  2. ~/.moltis/hooks/<name>/HOOK.md — user-global

Each HOOK.md uses TOML frontmatter:

+++
name = "my-hook"
description = "What it does"
events = ["BeforeToolCall"]
command = "./handler.sh"
timeout = 5

[requires]
os = ["darwin", "linux"]
bins = ["jq"]
env = ["SLACK_WEBHOOK_URL"]
+++

CLI

moltis hooks list              # List all discovered hooks
moltis hooks list --eligible   # Show only eligible hooks
moltis hooks list --json       # JSON output
moltis hooks info <name>       # Show hook details

Bundled hooks

  • boot-md — reads BOOT.md from workspace on GatewayStart
  • session-memory — saves session context on /new command
  • command-logger — logs all Command events to JSONL

Shell hook protocol

Shell hooks receive the event payload as JSON on stdin and communicate their action via exit code and stdout:

Exit code Stdout Action
0 (empty) Continue
0 {"action":"modify","data":{...}} Replace payload data
1 Block (stderr used as reason)

Configuration

[[hooks]]
name = "audit-tool-calls"
command = "./examples/hooks/log-tool-calls.sh"
events = ["BeforeToolCall"]

[[hooks]]
name = "block-dangerous"
command = "./examples/hooks/block-dangerous-commands.sh"
events = ["BeforeToolCall"]
timeout = 5

[[hooks]]
name = "notify-discord"
command = "./examples/hooks/notify-discord.sh"
events = ["SessionEnd"]
env = { DISCORD_WEBHOOK_URL = "https://discord.com/api/webhooks/..." }

See examples/hooks/ for ready-to-use scripts (logging, blocking dangerous commands, content filtering, agent metrics, message audit trail, Slack/Discord notifications, secret redaction, session saving).

Sandbox Image Management

moltis sandbox list          # List pre-built sandbox images
moltis sandbox build         # Build image from configured base + packages
moltis sandbox clean         # Remove all pre-built sandbox images
moltis sandbox remove <tag>  # Remove a specific image

The gateway pre-builds a sandbox image at startup from the base image (ubuntu:25.10) plus the packages listed in moltis.toml. Edit the [tools.exec.sandbox] packages list and restart — a new image with a different tag is built automatically.

Project Structure

Moltis is organized as a Cargo workspace with the following crates:

Crate Description
moltis Command-line interface and entry point
moltis-gateway HTTP/WebSocket server and web UI
moltis-agents LLM provider integrations
moltis-channels Communication channel abstraction
moltis-telegram Telegram integration
moltis-config Configuration management
moltis-sessions Session persistence
moltis-memory Embeddings-based knowledge base
moltis-skills Skill/plugin system
moltis-mcp MCP client, transport, and tool bridge
moltis-plugins Plugin formats, hook handlers, and shell hook runtime
moltis-tools Tool/function execution
moltis-routing Message routing
moltis-projects Project/workspace management
moltis-onboarding Onboarding wizard and identity management
moltis-oauth OAuth2 flows
moltis-protocol Serializable protocol definitions
moltis-common Shared utilities

Star History

Star History Chart

License

MIT

About

A personal AI assistant built in Rust. Single binary, multi-provider LLMs, long-term memory, sandboxed execution, voice, MCP tools, and multi-channel access (web, Telegram, API).

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 79.2%
  • JavaScript 15.9%
  • CSS 2.7%
  • HTML 1.2%
  • Shell 0.9%
  • Just 0.1%