A self-hosted, agentic Telegram AI assistant written in Rust, powered by OpenRouter LLM (default: moonshotai/kimi-k2.5) with built-in sandboxed tools, scheduling, persistent memory, and MCP server integration.
- Telegram Bot — Responds only to configured user IDs
- OpenRouter LLM — Configurable model (default:
moonshotai/kimi-k2.5) - Built-in Tools — File read/write, directory listing, command execution (sandboxed)
- Scheduling Tools — Schedule, list, and cancel recurring or one-shot tasks
- Persistent Memory — SQLite-backed conversation history and knowledge base
- Vector Embedding Search — Hybrid vector + FTS5 search using
qwen/qwen3-embedding-8b - MCP Integration — Connect any MCP-compatible server to extend capabilities
- Bot Skills — Folder-based natural-language skill instructions auto-loaded at startup
- Agentic Loop — Automatic multi-step tool calling until task completion (max iterations configurable, default 25)
- Per-user Conversations — Independent conversation history per user
cargo build --releaseRun the setup wizard — it guides you through all required fields and writes config.toml for you:
# Browser-based wizard (recommended)
./setup.sh
# Terminal wizard (no browser required)
./setup.sh --cliThe wizard will ask for your:
- Telegram bot token (from @BotFather)
- Allowed Telegram user IDs (from @userinfobot)
- OpenRouter API key (from openrouter.ai/keys)
- Sandbox directory, model, and optional MCP tools
Manual setup: Copy
config.example.tomltoconfig.tomland edit it directly if you prefer.
cargo run --bin rustfox
# or with a custom config path:
cargo run --bin rustfox -- /path/to/config.tomlSee config.example.toml for all options.
| Setting | Description |
|---|---|
telegram.bot_token |
Telegram Bot API token |
telegram.allowed_user_ids |
List of user IDs allowed to use the bot |
openrouter.api_key |
OpenRouter API key |
openrouter.model |
LLM model ID (default: moonshotai/kimi-k2.5) |
sandbox.allowed_directory |
Directory for file/command operations |
memory.database_path |
SQLite DB path (default: rustfox.db) |
embedding (optional) |
Vector search API config (default model: qwen/qwen3-embedding-8b) |
skills.directory |
Folder of bot skill files (default: skills/) |
mcp_servers |
List of MCP servers to connect |
general.location |
Your location string (under [general]), injected into system prompt |
RustFox supports the Model Context Protocol (MCP) — an open standard for connecting AI assistants to external tools and data sources. Any MCP-compatible server can be plugged in via config.toml.
MCP servers are usually distributed as Python packages (run via uvx) or npm packages (run via npx).
| Runtime | Install |
|---|---|
uvx (Python) |
Install uv — curl -LsSf https://astral.sh/uv/install.sh | sh |
npx (Node.js) |
Install Node.js — comes bundled with npm/npx |
Add one [[mcp_servers]] block per server in config.toml:
[[mcp_servers]]
name = "server-name" # used to namespace tools: mcp_<name>_<tool>
command = "uvx" # or "npx", or any executable on PATH
args = ["package-name", "optional-arg"]
# Optional: pass environment variables to the server process
# [mcp_servers.env]
# API_KEY = "your-key-here"| Server | Package | Runtime | Notes |
|---|---|---|---|
| Git | mcp-server-git |
uvx |
Read/search git repos |
| Filesystem | @modelcontextprotocol/server-filesystem |
npx |
File access outside the sandbox |
| Brave Search | @brave/brave-search-mcp-server |
npx |
Web search (needs Brave API key) |
| GitHub | @modelcontextprotocol/server-github |
npx |
Issues, PRs, repos |
| Fetch | mcp-server-fetch |
uvx |
HTTP fetch / web scraping |
| SQLite | mcp-server-sqlite |
uvx |
Query local SQLite databases |
| Puppeteer | @modelcontextprotocol/server-puppeteer |
npx |
Browser automation |
| Threads | threads-mcp-server |
npx |
Publish/manage Meta Threads posts (needs access token) |
Find more servers at the MCP server registry and mcp.so.
# Git — inspect repositories
[[mcp_servers]]
name = "git"
command = "uvx"
args = ["mcp-server-git"]
# Filesystem — expose an extra directory to the bot
[[mcp_servers]]
name = "filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
# Brave Search — web search (requires API key)
[[mcp_servers]]
name = "brave-search"
command = "npx"
args = ["-y", "@brave/brave-search-mcp-server"]
[mcp_servers.env]
BRAVE_API_KEY = "your-brave-api-key"
# Meta Threads — publish posts and read replies (requires long-lived access token)
# Token setup: Facebook Developers → Create App → add Threads API product →
# request threads_basic / threads_content_publish / threads_manage_replies /
# threads_read_replies → generate token under Threads API → Access Tokens
[[mcp_servers]]
name = "threads"
command = "npx"
args = ["-y", "threads-mcp-server"]
[mcp_servers.env]
THREADS_ACCESS_TOKEN = "your-long-lived-access-token"Tools from MCP servers are automatically namespaced as mcp_<server-name>_<tool-name> (e.g. mcp_git_git_log). Run /tools in the bot to see all registered tools after startup.
| Tool | Description |
|---|---|
read_file |
Read file contents within sandbox |
write_file |
Write/create files within sandbox |
list_files |
List directory contents within sandbox |
execute_command |
Run shell commands within sandbox directory |
| Tool | Description |
|---|---|
schedule_task |
Schedule a recurring (cron) or one-shot task with a message |
list_scheduled_tasks |
List all active scheduled tasks |
cancel_scheduled_task |
Cancel a scheduled task by ID |
| Command | Description |
|---|---|
/start |
Show welcome message |
/clear |
Clear conversation history |
/tools |
List all available tools |
src/
├── main.rs # Entry point, config loading, initialization
├── config.rs # TOML configuration parsing
├── llm.rs # OpenRouter API client with tool calling
├── agent.rs # Agentic loop, tool dispatch, scheduling tools
├── tools.rs # Built-in tools (file I/O, command execution)
├── mcp.rs # MCP client manager for external tool servers
├── memory/ # SQLite persistence, vector embeddings
├── scheduler/ # Cron/one-shot task scheduler with DB persistence
├── skills/ # Skill loader (auto-loads from skills/ directory)
└── platform/ # Telegram bot handler
- Telegram bot with user allowlist
- OpenRouter LLM integration with tool calling (agentic loop)
- Built-in sandboxed tools (file read/write, directory listing, command execution)
- MCP server integration for extensible tooling
- Per-user conversation history
- Persistent memory with SQLite
- Vector embedding search (
qwen/qwen3-embedding-8b) - Scheduling tools (
schedule_task,list_scheduled_tasks,cancel_scheduled_task) - Bot skills (folder-based, auto-loaded at startup)
- Setup wizard (web UI + CLI) for guided
config.tomlcreation - Agent skill writer (
write_skill_filetool — creates/updates skill files from within the agent) - Agent skill reload (
reload_skillstool — hot-reloads skill registry without restart) - Meta Threads MCP integration (setup wizard entry, config example, token setup guide)
- Image upload support
- Google integration tools (Calendar, Email, Drive)
- Event trigger framework (e.g., on email receive)
- WhatsApp support
- Webhook mode (in addition to polling)
- And more…
This project is open source under the MIT License. Contributions are very welcome! See CONTRIBUTING.md for how to open issues and submit pull requests.
If you find RustFox useful, consider supporting the project:
- teloxide — Telegram bot framework
- rmcp — Official MCP Rust SDK
- reqwest — HTTP client for OpenRouter
- tokio — Async runtime
- tokio-cron-scheduler — Task scheduling
