What is RustFox?
An open-source, self-hosted Telegram AI assistant written in Rust. It solves a simple problem: most AI assistants are locked inside proprietary chat UIs with no access to your files, tools, or schedule. RustFox lives in Telegram — your everyday messaging app — and acts as a full agentic AI teammate.
Why RustFox?
Drop a file, ask a question, schedule a task — RustFox handles it. Powered by OpenRouter LLM (Kimi K2.6), it runs an agentic loop: receive your message, call sandboxed tools (file I/O, command execution, web search via MCP), and loop until done. It remembers context via SQLite + vector RAG, runs skills and sub-agents, and even verifies its own work.
Self-hosted, no cloud dependency. Single binary. Setup wizard. Runs as systemd/launchd service. cargo install and you're running in 2 minutes.
Star the repo ⭐, fork to contribute, or open an issue for feedback.
docs: README.md · GUIDE.md · ARCHITECTURE.md
| 🤖 AI Agent | OpenRouter LLM (default: moonshotai/kimi-k2.6), agentic loop with tool calling, configurable max iterations |
| 🔧 Built-in Tools | File read/write, command execution, file sending, task scheduling — all sandboxed |
| 🧩 MCP Servers | Connect any MCP-compatible server (Git, Brave Search, GitHub, Filesystem, Threads…) |
| 🧠 Persistent Memory | SQLite-backed conversation history, vector embedding search (hybrid + FTS5), RAG |
| 🧬 Skills & Agents | Folder-based skill instructions auto-loaded at startup; subagent skills with own model and tool whitelist |
| 🤝 Agent Layer | Isolated agentic mini-loops in agents/ with own model/tools; invoke_agent, spawn_agents, zero-trust verifier |
| 🔄 Task Scheduling | Cron and one-shot task scheduler with SQLite persistence |
| 🌐 Web Portal | Built-in browser UI (chat, agents, memory, tasks, settings) served from the same binary — token-auth, loopback by default |
| 📦 Self-Hosting | Single binary, 2-min setup wizard, background service (systemd/launchd/Windows Service) |
→ Full feature reference: docs/GUIDE.md
| Capability | Description |
|---|---|
| Self-Upgrade | Trigger an in-place upgrade: pulls from git source or downloads the latest GitHub release binary. Auto-restarts after upgrade — no SSH, no manual steps. |
| Model Switching | Switch OpenRouter models at runtime via /models. Interactive picker lets you choose the best model per task: fast/cheap for simple queries, powerful for complex reasoning. |
| Soul Files | SOUL.md (persona), AGENTS.md (behaviour), USER.md (preferences) — persistent identity files auto-injected into every system prompt. Session-end self-reflection with .bak backups. |
⚠️ Planning phase — not yet implemented. This section captures ideas explored in thefeat/readme-improve-multi-session-brainstormbranch.
The vision: run multiple concurrent chat sessions, each with its own model and isolated context.
| Use Case | Description |
|---|---|
| Parallel execution | Run a cheap model for quick tasks while a powerful model tackles deep analysis — concurrently, not sequentially |
| Per-user isolation | Each Telegram user gets their own session with independent conversation context and model preference |
| Sub-agent delegation | Spawn sub-agents with different models (e.g., GPT-4o for code review, Claude for writing) without polluting the main session |
Topics to explore:
- Session lifecycle — create, switch, merge, archive
- Per-session model binding vs global default model
- Context isolation between sessions (independent or shared RAG?)
- Telegram UX for multi-session management (inline buttons? slash commands?)
- Persistence and RAG across session boundaries
See docs/roadmap/multi-session.md for detailed design notes.
Option A — Download a release (recommended)
Download from the Releases page:
tar xzf rustfox-*.tar.gzOption B — Build from source (recommended script)
git clone https://github.com/chinkan/RustFox && cd RustFox
./scripts/build-all.sh --installbuild-all.sh builds the web portal frontend first (npm ci + vite build), then
the Rust binary — the portal UI is compiled into the binary via include_dir!, so
build order matters (see Building & Verifying). If you don't
need the portal, plain cargo install --path . --locked still works.
# Browser wizard
./rustfox --setup
# Or terminal wizard
./rustfox --setup --cliThe wizard guides you through: Telegram bot token, allowed user IDs, OpenRouter API key, model, and optional MCP tools.
rustfox
# or with a custom config:
rustfox --config /path/to/config.tomlrustfox --service install # Linux (systemd), macOS (launchd), or Windows
rustfox --service status| Setting | Description |
|---|---|
telegram.bot_token |
Telegram Bot API token (from @BotFather) |
telegram.allowed_user_ids |
Comma-separated user IDs allowed to use the bot |
openrouter.api_key |
OpenRouter API key (openrouter.ai/keys) |
openrouter.model |
LLM model ID (default: moonshotai/kimi-k2.6) |
sandbox.allowed_directory |
Directory for sandboxed file/command operations |
mcp_servers |
List of MCP servers to connect (see GUIDE.md) |
→ Full configuration reference: docs/GUIDE.md
RustFox can serve a built-in web UI from the same binary — no separate frontend
deploy. Open http://127.0.0.1:8090 in your browser to chat with the agent (live
SSE token streaming), browse memory, manage scheduled tasks and sub-agents, and
inspect your config.
Enable it in config.toml:
[portal]
enabled = true
port = 8090
bind = "127.0.0.1" # keep loopback/private-network only
token_sha256 = "<sha256>" # hash of your login token (preferred over plaintext)Generate a token + hash:
python3 -c 'import hashlib,secrets; t=secrets.token_hex(32); print("token:", t); print("token_sha256:", hashlib.sha256(t.encode()).hexdigest())'| Page | What you can do |
|---|---|
| 💬 Chat | Talk to the agent in the browser, watch tool calls stream live; history persisted and isolated from Telegram |
| 🧬 Agents | Browse configured sub-agents, filter by name |
| 🧠 Memory | Search conversation/knowledge store (FTS5 hybrid), browse recent entries |
| 🔄 Tasks | List cron/one-shot tasks, view run history, pause/resume |
| ⚙️ Settings | Inspect active config (secrets masked) |
🔒 The portal is off by default and intended for loopback/private networks (e.g. a Tailscale IP). Public exposure/TLS is out of scope for now.
| Tool | Description |
|---|---|
read_file / write_file |
Read and write files within the sandbox |
send_file |
Send a file from the sandbox to the current chat |
self_upgrade |
Trigger self-upgrade from git source or GitHub release, auto-restart |
read_soul_file |
Read SOUL.md, AGENTS.md, or USER.md soul files |
update_soul_file |
Append or replace content in a soul file with .bak backup |
revert_soul_file |
Restore a soul file from its most recent .bak backup |
try_new_tech |
Sandboxed experiment — run Rust/JS code and check results |
execute_command |
Run shell commands within the sandbox |
schedule_task |
Schedule recurring (cron) or one-shot tasks |
invoke_agent |
Run a predefined agent from the agents/ directory |
→ Full tool reference: docs/GUIDE.md
RustFox runs an agentic loop: user message → LLM (OpenRouter) → tool calls → execute → loop until final response. Tools dispatch to built-in functions, MCP servers, or skill/agent directories.
→ Full architecture with source tree and data flow: docs/ARCHITECTURE.md
./scripts/build-all.sh # web (vite) → dist → cargo build --release
./scripts/build-all.sh --install # ...then install to ~/.cargo/bin/rustfox
./scripts/build-all.sh --skip-web # reuse existing web/dist (Rust only)
./scripts/build-all.sh --profile dev # debug build (faster compile)Why a script? The portal frontend is embedded into the binary at compile time
(include_dir!("web/dist")). Two traps this guards against:
- Build order — cargo before
vite buildembeds a stale/empty dist → the portal renders a white screen.build-all.shenforces web-first and fails fast ifweb/dist/index.htmlis missing. - Stale embedding —
include_dir!has no cargo change-fingerprint, so updating dist alone won't trigger a rebuild. The script touches the embedding module to force re-embedding.
cargo run --release --example portal_preview # serves the real embedded UI + seeded demo datanode e2e-verify.mjs # Playwright: login → chat SSE → agents → memory → tasks → settingsCovers every portal page against the real embedded-dist binary (same code path as production), including a stub-dist control test that catches white-screen regressions. Zero console errors is part of the gate. CI runs the web build before cargo tests, and the same sequence applies to release builds.
MIT License. See CONTRIBUTING.md for how to open issues and submit PRs.
