https://github.com/garudust-org/garudust-agent
๐ฆ
Open-source AI agent runtime in Rust โ Self-hostable with persistent memory, self-improving skills, MCP support, built-in cron, multi-platform messaging & production gateway.
https://github.com/garudust-org/garudust-agent
ai-agent anthropic cli discord-bot llm mcp ollama openrouter rag rust self-hosted self-improvement self-learning telegram-bot tui
Last synced: 19 days ago
JSON representation
๐ฆ Open-source AI agent runtime in Rust โ Self-hostable with persistent memory, self-improving skills, MCP support, built-in cron, multi-platform messaging & production gateway.
- Host: GitHub
- URL: https://github.com/garudust-org/garudust-agent
- Owner: garudust-org
- License: mit
- Created: 2026-04-26T15:47:17.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-06-03T07:56:38.000Z (22 days ago)
- Last Synced: 2026-06-03T09:26:08.304Z (22 days ago)
- Topics: ai-agent, anthropic, cli, discord-bot, llm, mcp, ollama, openrouter, rag, rust, self-hosted, self-improvement, self-learning, telegram-bot, tui
- Language: Rust
- Homepage: https://garudust-org.github.io/garudust-agent/
- Size: 8.44 MB
- Stars: 22
- Watchers: 1
- Forks: 6
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README
# Garudust Agent
[](https://github.com/garudust-org/garudust-agent/actions/workflows/ci.yml)
[](https://crates.io/crates/garudust-agent)
[](https://crates.io/crates/garudust-agent)
[](https://github.com/garudust-org/garudust-agent/releases/latest)
[](LICENSE)

[](https://discord.com/channels/1501414298449088745/1501414298893942877)
**Your AI agent. Your server. Your rules.**
A self-improving AI agent runtime written in Rust โ ~10 MB binary, no runtime dependencies. Chat in the terminal, reply across 7 platforms, open the web dashboard, run the desktop app, or expose a REST + WebSocket API. Connect any MCP server, swap LLM providers with one env var. No telemetry. No lock-in.
---
## Quick Start
**01 โ Install**
```bash
curl -fsSL https://raw.githubusercontent.com/garudust-org/garudust-agent/main/scripts/install.sh | sh
```
macOS & Linux, any arch (ARM, Raspberry Pi, WSL). Windows: `irm .../scripts/install.ps1 | iex`. Override with `GARUDUST_VERSION` / `GARUDUST_BIN_DIR`.
Manual download or build from source
Grab a pre-built binary from [GitHub Releases](https://github.com/garudust-org/garudust-agent/releases/latest):
| OS | Architecture | Binary |
|----|-------------|--------|
| macOS | Apple Silicon (M1/M2/M3/M4) | `garudust-*-aarch64-apple-darwin.tar.gz` |
| macOS | Intel | `garudust-*-x86_64-apple-darwin.tar.gz` |
| Linux | x86_64 | `garudust-*-x86_64-unknown-linux-musl.tar.gz` |
| Linux | ARM64 (Raspberry Pi 4/5, Jetson) | `garudust-*-aarch64-unknown-linux-musl.tar.gz` |
| Windows | x86_64 | `garudust-*-x86_64-pc-windows-msvc.zip` |
Or build from source (Rust 1.87+): `git clone https://github.com/garudust-org/garudust-agent && cargo build --release`
---
**02 โ Configure**
```bash
garudust setup # interactive wizard โ picks provider, writes config.yaml + .env
```
Or set your key directly in `~/.garudust/.env` (e.g. `ANTHROPIC_API_KEY=sk-ant-...`). See [LLM Providers](#llm-providers) for all supported keys.
---
**03 โ Run**
```bash
garudust # interactive TUI
garudust "summarise git log" # one-shot task
garudust --hint fast "check this" # route to a cheaper model
garudust-server --port 3000 # headless REST + WebSocket server (+ web dashboard, see below)
docker compose up -d
# Management subcommands
garudust setup # interactive first-time setup wizard
garudust doctor # check environment and configuration
garudust config show # view current configuration
garudust config set # set a configuration value
garudust model [] # get or switch the active model
# Script tools
garudust tool list # list installed + available hub tools
garudust tool install # install a tool from the hub
garudust tool uninstall # remove an installed tool
garudust tool update [] # update one tool (omit to update all)
# Skills
garudust skill list # list installed + available hub skills
garudust skill install # install from hub / GitHub / URL / well-known
garudust skill uninstall # remove an installed skill
garudust skill update [] # update one skill (omit to update all)
garudust skill validate [] # validate SKILL.md frontmatter
```
---
## Desktop app & web dashboard
The recommended way to use Garudust with a UI is the **native desktop app** โ a
pure-Rust ([egui](https://github.com/emilk/egui)) app with the agent embedded
in-process (no webview, no separate server). Just download and run.
### โฌ Download Garudust Desktop
[**๐ macOS**](https://github.com/garudust-org/garudust-agent/releases/latest/download/Garudust-macOS-universal.dmg) ย ยทย
[**๐ช Windows**](https://github.com/garudust-org/garudust-agent/releases/latest/download/Garudust-Windows-x64-setup.exe) ย ยทย
[**๐ง Linux (AppImage)**](https://github.com/garudust-org/garudust-agent/releases/latest/download/Garudust-Linux-x86_64.AppImage) ย ยทย
[**๐ฆ Debian/Ubuntu (.deb)**](https://github.com/garudust-org/garudust-agent/releases/latest/download/Garudust-Linux-x86_64.deb)
macOS is a universal build (Intel + Apple Silicon). Other archs / versions: [all releases](https://github.com/garudust-org/garudust-agent/releases/latest)

| OS | Install |
|----|---------|
| macOS | open the `.dmg`, drag **Garudust** to Applications |
| Windows 10/11 | run the `.exe` installer |
| Linux | `chmod +x Garudust_*.AppImage && ./Garudust_*.AppImage` |
| Debian / Ubuntu | `sudo dpkg -i Garudust_*.deb` |
> Builds are not yet code-signed, so on first launch macOS Gatekeeper
> (right-click โ **Open**) and Windows SmartScreen (**More info โ Run anyway**)
> will warn โ expected for unsigned apps.
On first run, set your LLM key on the **Secrets** page (or in `~/.garudust/.env`).
The Secrets page is masked + write-only; the agent runs inside the app itself.
Build from source: `cargo run -p garudust-desktop-native --release` (see
[`apps/desktop-native/README.md`](apps/desktop-native/README.md)).
**Prefer the browser?** The same UI (Rust/[Leptos](https://leptos.dev) โ WASM) is
served by the server with the `web-ui` feature:
```bash
cd web && trunk build --release # one-time: cargo install trunk + rustup target add wasm32-unknown-unknown
cargo run -p garudust-server --features web-ui --port 3000 # โ open http://localhost:3000
```
---
## Features
๐ชถ **Tiny footprint** โ ~10 MB statically linked binary, < 20 ms cold start, zero runtime dependencies. Runs on a Raspberry Pi without Docker.
๐ง **Self-improving** โ remembers your preferences and facts across every session. Automatically writes reusable skills after complex multi-step workflows. Cross-session goals stay injected until you mark them done โ you never repeat yourself.
๐ **24 LLM providers, one config line** โ Anthropic, OpenAI, Gemini, Groq, Mistral, DeepSeek, Ollama, AWS Bedrock, vLLM, and 15 more. Route tasks to cheaper models with `--hint`, rotate fallback keys automatically on auth failure.
๐ก **7 platforms in one process** โ Telegram, Discord, Slack, Matrix, LINE, WhatsApp, Webhook. Per-platform RBAC, mention gate, per-user session isolation โ each adapter activates the moment its token is in `.env`.
โก **Parallel tool execution** โ independent tool calls run concurrently; conflict-prone calls serialized by key. 15+ built-in tools: web search, file I/O, browser automation (CDP), terminal, RAG, sub-agent delegation. Connect any MCP server or drop a custom script tool in any language.
๐ **Secure by design** โ three sandbox modes for the terminal tool: direct host, Docker container, or SSH remote host. Hardline blocks on the most destructive commands regardless of sandbox. Approval modes (`auto` / `smart` / `deny`) gate destructive operations. Secrets are redacted from all tool output before the model sees them.
๐ **Headless API** โ `garudust-server` exposes `/chat`, `/stream`, and a WebSocket endpoint โ embed in any app or script. Cron-scheduled autonomous tasks run without a user present.
๐ฅ๏ธ **Web dashboard & native desktop app** โ a Rust/Leptos (WASM) dashboard served straight from the binary (`web-ui` feature) for the browser, plus a pure-Rust native [egui](https://github.com/emilk/egui) desktop app with the agent embedded in-process (DMG / EXE / AppImage / deb). No JS/TS; secrets stay masked and server-side.
---
## Platforms
All adapters run in the same `garudust-server` process. Set the token in `~/.garudust/.env` and the adapter activates automatically.
---
## LLM Providers
Set `providers.default.name` in `config.yaml` and the corresponding key in `~/.garudust/.env`:
| Provider | `name` | `.env` key |
|----------|--------|------------|
| Anthropic | `anthropic` | `ANTHROPIC_API_KEY` |
| OpenAI | `openai` | `OPENAI_API_KEY` |
| Google Gemini | `gemini` | `GEMINI_API_KEY` |
| Groq | `groq` | `GROQ_API_KEY` |
| Mistral | `mistral` | `MISTRAL_API_KEY` |
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` |
| xAI (Grok) | `xai` | `XAI_API_KEY` |
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` |
| AWS Bedrock | `bedrock` | `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` |
| Ollama | `ollama` | *(none โ add `url:` for custom endpoint)* |
| vLLM | `vllm` | `VLLM_API_KEY` |
| ThaiLLM | `thaillm` | `THAILLM_API_KEY` |
| Together AI | `together` | `TOGETHER_API_KEY` |
| Fireworks AI | `fireworks` | `FIREWORKS_API_KEY` |
| Cerebras | `cerebras` | `CEREBRAS_API_KEY` |
| Perplexity | `perplexity` | `PERPLEXITY_API_KEY` |
| Cohere | `cohere` | `COHERE_API_KEY` |
| NVIDIA NIM | `nvidia` | `NVIDIA_API_KEY` |
| Alibaba DashScope | `alibaba` | `DASHSCOPE_API_KEY` |
| ByteDance Doubao | `doubao` | `ARK_API_KEY` |
| Zhipu AI (GLM) | `zhipu` | `ZHIPU_API_KEY` |
| Moonshot (Kimi) | `moonshot` | `MOONSHOT_API_KEY` |
| Baidu ERNIE | `baidu` | `QIANFAN_API_KEY` |
| Any OpenAI-compat | *(omit `name:`, set `url:` in profile)* | relevant key |
Fallback keys: set `LLM_FALLBACK_API_KEYS=key2,key3` in `.env` โ rotated automatically on auth failure.
---
## Architecture
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ bin/garudust (CLI) bin/garudust-server (Daemon) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โ โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ garudust-gateway (server-only) โ
โ โ POST /chat ยท POST /stream ยท GET /ws โ
โ โ RBAC ยท /join ยท /invite ยท Metrics โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ garudust-platforms (server-only) โ
โ โ Telegram ยท Discord ยท Slack โ
โ โ LINE ยท Matrix ยท WhatsApp ยท Webhook โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ garudust-cron (server-only) โ
โ โ cron-scheduled autonomous tasks โ
โ โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ garudust-agent (run-loop) โ
โ load memory โ build prompt โ LLM call โ tool dispatch โ repeat โ
โโโโโโโโฌโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โผ โผ โผ
garudust- garudust- garudust-
transport tools memory
(24 LLMs + (built-in + (memory.md +
key rotation) hub + MCP) SQLite + RAG)
garudust-core โ shared types ยท config ยท traits (used by every crate above)
```
---
## Configuration
Secrets โ `~/.garudust/.env`. Everything else โ `~/.garudust/config.yaml`.
### `~/.garudust/.env`
```bash
# LLM provider โ set one (auto-detected from env when no config.yaml)
ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# GEMINI_API_KEY=AIza...
# GROQ_API_KEY=gsk_...
# Fallback keys โ rotated automatically on auth failure
# LLM_FALLBACK_API_KEYS=sk-ant-backup1,sk-ant-backup2
# Platform adapters โ set only what you use
TELEGRAM_TOKEN=123456789:AAFxxx
DISCORD_TOKEN=
SLACK_BOT_TOKEN=xoxb-...
SLACK_APP_TOKEN=xapp-...
LINE_CHANNEL_TOKEN=
LINE_CHANNEL_SECRET=<32-char-hex>
WHATSAPP_ACCESS_TOKEN=EAAxxxxx
WHATSAPP_PHONE_NUMBER_ID=123456789012345
WHATSAPP_VERIFY_TOKEN=my_verify_token
# Search (optional โ falls back to DuckDuckGo)
BRAVE_SEARCH_API_KEY=BSA...
SERPER_API_KEY=...
# Gateway auth
GARUDUST_API_KEY=my-gateway-secret
```
### `~/.garudust/config.yaml`
```yaml
providers:
default:
name: anthropic # see LLM Providers table above for all 24 options
key: ${ANTHROPIC_API_KEY}
model: claude-sonnet-4-6
security:
approval_mode: smart # auto | smart | deny
terminal_sandbox: none # none | docker | ssh
rate_limit_rpm: ~ # per-IP limit (~ = unlimited)
rate_limit_rpm_per_user: ~ # per-(platform, user_id) limit
# โโ SSH sandbox (terminal_sandbox: ssh) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# ssh_host: "192.168.1.50" # required
# ssh_user: "pi" # optional โ defaults to current OS user
# ssh_port: 22 # optional โ default 22
# ssh_key_path: ~/.ssh/garudust_pi # optional โ uses ~/.ssh/id_* if unset
# ssh_jump_host: "bastion.example.com" # optional โ ProxyJump for hosts behind NAT
# ssh_remote_cwd: "/home/pi/scripts" # optional โ cd here before every command
# ssh_options: ["IdentitiesOnly=yes"] # optional โ extra -o flags (escape hatch)
# Route a single task to a different model without changing the default:
routing:
fast: groq-fast/llama-3.1-8b-instant
# then: garudust --hint fast "quick question"
# Use a cheap model for background skill-reflection (defaults to main model):
reflection_model: groq/llama-3.1-8b-instant
# Conversation window per session โ pairs of (user, assistant) turns (default 20):
max_history_pairs: 20
```
For the full config reference (cron, MCP, RBAC, compression, etc.) see [CONTRIBUTING.md](CONTRIBUTING.md).
---
## Tools
Built-in, no configuration needed:
`web_fetch` ยท `web_search` ยท `http_request` ยท `browser` (CDP) ยท `read_file` ยท `write_file` ยท `list_directory` ยท `terminal` ยท `memory` ยท `session_search` ยท `delegate_task` ยท `skill_view` ยท `write_skill` ยท `doc_ingest` ยท `doc_search`
**Hub** โ community tools and skills from [garudust-hub](https://github.com/garudust-org/garudust-hub):
```bash
garudust tool install hash_text # script tool โ ~/.garudust/tools/hash_text/
garudust tool install read_qr
garudust skill install weather # Markdown instruction, no subprocess
garudust skill install fetch-title
```
**MCP** โ connect any [Model Context Protocol](https://modelcontextprotocol.io) server:
```yaml
mcp_servers:
- name: filesystem
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
```
**Custom tools** โ drop a `tool.yaml` + script in `~/.garudust/tools//`. Any language. See [garudust-hub](https://github.com/garudust-org/garudust-hub) for examples.
---
## Access Control
Role-based access via `roles:` in `config.yaml`. The first person to DM the bot is auto-promoted to `admin` when no users are assigned yet.
```yaml
roles:
default_role: member
definitions:
admin: { approval_mode: auto }
member: { approval_mode: smart, allowed_toolsets: [web, files, memory], denied_tools: [bash] }
readonly: { approval_mode: deny }
users:
telegram:
"123456789": admin
```
Runtime commands: `/whoami` ยท `/join [code]` ยท `/invite [max_uses]` ยท `/role list|add|approve|remove`
> **Production:** set `terminal_sandbox: docker` (local container) or `terminal_sandbox: ssh` (remote host) to sandbox shell execution, and `max_delegation_depth: 0` to prevent sub-agent chains.
> **Note:** setting `platform.session_per_user: false` causes all users to share one conversation context. The server logs a `WARN` at startup as a reminder. Only safe for single-user deployments.
---
## Terminal Sandbox
The `terminal` tool supports three execution backends:
| Mode | `terminal_sandbox` | Runs on | Requires |
|---|---|---|---|
| Direct host | `none` | Local machine | Nothing |
| Docker container | `docker` | Isolated container | Docker daemon |
| Remote SSH host | `ssh` | Any host with sshd | SSH key auth |
All modes share the same hardline blocks (fork bomb, `rm -rf /`, `mkfs`, etc.) and the same approval gate โ the sandbox only controls *where* the command runs.
### SSH Sandbox
Commands are forwarded via the system `ssh` binary to a remote host. Useful for managing a remote server, Raspberry Pi, or build machine without exposing any port to the internet โ the agent SSHes *out*, the remote host just needs port 22 open.
**Config fields** (all under `security:` in `config.yaml`):
| Field | Type | Default | Description |
|---|---|---|---|
| `ssh_host` | string | โ | **Required.** Remote hostname or IP |
| `ssh_user` | string | current OS user | Login username |
| `ssh_port` | integer | `22` | SSH port |
| `ssh_key_path` | path | `~/.ssh/id_*` | Private key file |
| `ssh_jump_host` | string | โ | ProxyJump bastion (`user@host:port`) for hosts behind NAT |
| `ssh_remote_cwd` | string | โ | `cd &&` prepended to every command; must be an absolute path with no shell metacharacters (e.g. `/home/pi/scripts`) |
| `ssh_options` | list | `[]` | Extra `-o key=value` flags (appended after hardened defaults) |
**Environment variable overrides** โ no config.yaml required:
```bash
GARUDUST_TERMINAL_SANDBOX=ssh
GARUDUST_SSH_HOST=192.168.1.50
GARUDUST_SSH_USER=pi
GARUDUST_SSH_PORT=22
GARUDUST_SSH_KEY_PATH=/home/user/.ssh/garudust_pi
```
**Minimal working example** โ Raspberry Pi behind a home router:
```yaml
security:
terminal_sandbox: ssh
ssh_host: "192.168.1.50"
ssh_user: "pi"
ssh_key_path: ~/.ssh/garudust_pi
```
**With a bastion** โ Pi is reachable only through a public jump server:
```yaml
security:
terminal_sandbox: ssh
ssh_host: "pi.internal"
ssh_user: "pi"
ssh_key_path: ~/.ssh/garudust_pi
ssh_jump_host: "bastion.example.com"
```
**Security properties applied automatically:**
- `BatchMode=yes` โ no interactive prompts; fails immediately if key auth is rejected
- `StrictHostKeyChecking=accept-new` โ auto-trusts first contact, rejects changed host keys (MITM protection)
- `ConnectTimeout` capped at 30 s โ no indefinite TCP hangs
- `ServerAliveInterval=10 ServerAliveCountMax=3` โ detects dead connections in ~30 s rather than hanging until the command timeout fires
- `--` before the command โ prevents a command starting with `-` from being misread as an SSH flag
- `env_clear()` before spawning `ssh` โ API keys and secrets never reach the remote host
- `ssh_remote_cwd` is validated as a safe absolute path before use โ values containing shell metacharacters (`;` `&` `|` `` ` `` `$` `>` `<` quotes, whitespace, etc.) are rejected at command time, not silently forwarded to the remote shell
- `ssh_options` are appended *after* hardened defaults โ `BatchMode` and `StrictHostKeyChecking` cannot be overridden by caller config
---
## Memory & Skills
The agent saves everything it learns to `~/.garudust/memory/` and loads it at the start of every session โ you never need to repeat yourself. Repeating workflows are automatically written as reusable skills in `~/.garudust/skills/` after `auto_skill_threshold` iterations. Set `reflection_model` in `config.yaml` to use a cheaper model for this background pass and keep costs down.
---
## Contributing
Garudust is Rust and designed to be extended. Pick your area:
| Area | Where | Effort |
|------|-------|--------|
| Hub tool or skill | [garudust-hub](https://github.com/garudust-org/garudust-hub) โ `tool.yaml` + script | Low โ no Rust needed |
| Bug reports / docs | [Issues](https://github.com/garudust-org/garudust-agent/issues) | Minimal |
| New LLM provider | `crates/garudust-transport/src/` โ impl `ProviderTransport` (2 methods) | Medium |
| New platform adapter | `crates/garudust-platforms/src/` โ impl `PlatformAdapter` (2 methods) | Medium |
| Built-in tool | `crates/garudust-tools/src/toolsets/` โ impl `Tool`, register in `ToolRegistry::new()` | Medium (~100 lines) |
| Core features | Agent loop, memory, compression, gateway | High |
```bash
git clone https://github.com/garudust-org/garudust-agent
cd garudust-agent
git config core.hooksPath .githooks # enable pre-push checks (fmt + tests)
cargo build && cargo test --workspace && cargo clippy --workspace
```
Step-by-step guides for each area: [CONTRIBUTING.md](CONTRIBUTING.md)
**Community:** [Discord](https://discord.com/channels/1501414298449088745/1501414298893942877) ยท [Issues](https://github.com/garudust-org/garudust-agent/issues) ยท [Discussions](https://github.com/garudust-org/garudust-agent/discussions) ยท [dev.to/garudust](https://dev.to/garudust)
---
## License
MIT โ see [LICENSE](LICENSE).
---
## Contributors
[](https://github.com/garudust-org/garudust-agent/graphs/contributors)
---
## Star History
[](https://star-history.com/#garudust-org/garudust-agent&Date)
---