Your AI co-pilot, living inside Discord.
RYO is a multi-agent Discord bot powered by Claude that keeps you informed, remembers what matters, plans your trips, and pings you before things slip β all through plain conversation in your server.
π¬ Just talk naturally. No slash commands, no syntax. Ask in plain English β RYO figures out what you need.
π§ Remembers you. Every user gets their own isolated memory. Tell RYO something once and it uses it forever.
β° Chases you. Reminders come to you β in DMs or your channel β on a schedule you define.
π Tracks its own cost. Live credit dashboard so you always know what's being spent.
RYO routes conversations by channel β each one has a focused purpose.
| Channel | Purpose |
|---|---|
#ryo-general |
News, web search, weather, memory, reminders β everything |
#ryo-travel |
Trip itineraries and travel planning only |
#ryo-stats |
Live cost and credit dashboard |
Off-topic messages in a specialised channel are automatically redirected and answered in #ryo-general.
In #ryo-general:
- π° News β "What's in the news?" β fetches live headlines
- π Web search β "Look up X" / "Find info on Y"
- π€οΈ Weather β "What's the weather in Tokyo?" β always in Celsius
- π§ Remember β "Remember I'm a VP at JPMorgan"
- ποΈ Forget β "Forget my address"
- β° Reminders β "Remind me at 3pm" / "Remind me 3 times every 10 minutes" / "Keep reminding me until I say stop"
- πΈ Images & PDFs β attach a file and ask a question β Ryo can analyse it
In #ryo-travel:
- πΊοΈ Full day-by-day itineraries with hotels, food, and budget breakdown
- π Personalised to your travel profile (card type, cuisine, driving, budget style)
- π Creates Discord Scheduled Events for each day of the trip
- β° Automatically sets pre-trip reminders (7 days, 2 days, 1 day before departure)
- πΈ Images & PDFs β attach a file and ask a question β Ryo can analyse it
| Command | What it does |
|---|---|
π !clear |
Delete all RYO messages in this channel (owner only) |
| Command | What it does |
|---|---|
!travel-preferences |
View or set up your travel profile |
!travel-preferences update |
Update your saved travel preferences |
!plan-trip <destination> <start YYYY-MM-DD> <end YYYY-MM-DD> |
Generate full itinerary + Discord events + reminders |
π !clear |
Delete all messages in this channel (owner only) |
| Command | What it does |
|---|---|
!refresh |
Force-refresh the credits dashboard |
π !setcredits <amount> |
Set your current credit balance (owner only) |
π !clear |
Delete all messages in this channel (owner only) |
Commands are channel-scoped β
!setcreditsonly works in#ryo-stats, travel commands only in#ryo-travel, etc.
#ryo-stats shows a live embed that updates after every message:
- Credit bar with % remaining (green β yellow β red as balance drops)
- Remaining vs. consumed breakdown
- Direct link to billing page
- Low-credit DM alert when balance drops below $5
flowchart TD
A([Discord Message]) --> B[channel router\nmain.py]
B -->|ryo-stats| C[commands only\n!setcredits Β· !refresh Β· !clear]
B -->|ryo-travel| D[travel CEO\ntravel_prompt.txt]
B -->|ryo-general or other| E[general CEO\nceo_prompt.txt]
D -->|off-topic| E
D -->|!travel-preferences reply| F[travel_preferences_save prompt\nβ memory-supervisor skill]
D -->|!plan-trip| G[trip planner\nβ itinerary + Discord events + reminders]
E --> H{claude-agent-sdk\nclaude-sonnet-4-6}
H -->|news| I[news-agent skill]
H -->|search / weather| J[search-agent skill]
H -->|remember / remind / forget| K[memory-supervisor skill]
K --> L[(ryo.db Β· SQLite)]
H --> M[Response]
M --> N[sanitize + chunk]
N --> O([Discord reply])
flowchart LR
T([Every 60 seconds]) --> Q[query reminders\nWHERE window <= now]
Q --> R{repeat_count?}
R -->|once| S[send DM β delete row]
R -->|N times| U[send DM β decrement\nreschedule window]
R -->|infinite| V[send DM β reschedule\nuntil user says stop]
S & U & V --> W([DM or channel ping])
erDiagram
users {
TEXT discord_id PK
TEXT username
TEXT display_name
TEXT registered_at
}
permanent_memories {
INTEGER id PK
TEXT discord_id FK
TEXT index_title
TEXT context
TEXT remember_window
TEXT date_logged
}
reminders {
INTEGER id PK
TEXT discord_id FK
TEXT index_title
TEXT context
TEXT remember_window
INTEGER repeat_count
INTEGER snooze_interval_mins
TEXT date_logged
}
cost_tracking {
INTEGER id PK
REAL total_cost_usd
REAL credit_balance_usd
INTEGER total_messages
INTEGER low_credit_alerted
}
users ||--o{ permanent_memories : has
users ||--o{ reminders : has
Built on the Claude Agent SDK with filesystem-based skills loaded on-demand.
.claude/skills/
βββ news-agent/SKILL.md
βββ search-agent/SKILL.md
βββ memory-supervisor/SKILL.md
βββ memory-store/
β βββ SKILL.md
β βββ scripts/store_memory.py
βββ memory-delete/
βββ SKILL.md
βββ scripts/delete_memory.py
conda activate llm_env
pip install -r requirements.txtANTHROPIC_API_KEY="" # console.anthropic.com
OPENWEATHERMAP_API_KEY="" # openweathermap.org
DISCORD_TOKEN="" # discord.com/developers
OWNER_DISCORD_ID="" # your Discord user ID
python memory/setup_db.pySafe to re-run β creates tables if missing, migrates existing CSV data.
python main.pyRYO auto-creates #ryo-stats, #ryo-travel, and #ryo-general channels on first start if they don't exist.
RYO runs 24/7 on Oracle Cloud (Ubuntu). Deploy scripts in deploy/:
deploy/
βββ setup.sh β one-shot provisioning
βββ ryo.service β systemd unit (auto-start on reboot)
βββ requirements-server.txt
Fresh instance:
bash deploy/setup.shPush an update:
git push
ssh ubuntu@<ip> "cd /home/ubuntu/Ryo && git pull && sudo systemctl restart ryo"Logs:
sudo journalctl -u ryo -f