⚠️ DISCLAIMER: This project uses a Discord selfbot, which is a direct violation of Discord's Terms of Service. Using this software may result in the permanent termination of your Discord account. Use entirely at your own risk. The author(s) of this repository are not responsible for any consequences.
A Discord selfbot that simulates a persistent, AI-driven human persona named Adrian — a 16-year-old developer from Germany. Adrian has a memory system, a circadian rhythm, dynamic moods, and a consistent personality powered by a locally-running LLM.
This project is a selfbot — it logs into Discord using a real user account token and responds autonomously. This is explicitly prohibited by Discord's Terms of Service, specifically:
"You may not use self-bots or other automated clients to access the Discord services."
Running this bot can result in:
- Permanent account ban from Discord
- Loss of all server memberships, messages, and friends
- Potential IP flagging
Do not run this on an account you care about.
Adrian is a fully autonomous Discord persona. He is not a bot account — he runs on a real user token and mimics a natural human teenager. He:
- Replies to messages using a local LLM (Mistral Nemo via MLX)
- Has a persistent SQLite memory of users, facts, and vibes
- Maintains a trust score per user
- Has a circadian rhythm (goes to sleep, wakes up, can pull all-nighters)
- Generates AI-driven moods that update his Discord status
- Posts spontaneous thoughts (icebreakers) on his own
- Reacts to messages with emojis based on content
- Catches bandwagon reactions (joins emoji reactions when they get popular)
- Introduces occasional typos and self-corrects them
- Has a gaslighting defense system — if someone accuses him of being a bot, he deflects aggressively
| Component | Technology |
|---|---|
| Runtime | Deno |
| Discord Library | discord.js-selfbot-v13 (npm) |
| LLM Backend | MLX LM Server (local, Apple Silicon) |
| LLM Model | mlx-community/Mistral-Nemo-Instruct-2407-4bit |
| Database | SQLite via deno.land/x/sqlite |
- macOS with Apple Silicon (any M chip, from M1 till the latest, M5) — the LLM backend uses MLX
- Deno installed
- MLX LM running locally on
http://127.0.0.1:8080 - A Discord user account token (not a bot token)
adrianExperiment/
├── main.ts # Main bot logic
├── check_db.ts # Utility to inspect the SQLite database
├── del.ts # Utility to delete messages or DB entries
├── adrian_memory.db # SQLite database (auto-created on first run)
└── README.md
git clone https://github.com/GabsEdits/adrianExperiment
cd adrianExperimentMake sure the Mistral Nemo model is running locally on port 8080:
python -m mlx_lm.server --model mlx-community/Mistral-Nemo-Instruct-2407-4bit --port 8080export DISCORD_TOKEN="your_user_account_token_here"
export MAIN_CHANNEL="your_target_channel_id_here"How to get your token: Open Discord in a browser → DevTools (F12) → Network tab → send any message → look for the
Authorizationheader. Never share this token with anyone.
deno run --allow-net --allow-env --allow-read --allow-write main.tsAdrian remembers users across sessions using two tables:
users— stores username, trust score, vibe summary, and last seen timeuser_facts— stores extracted permanent facts about users (e.g., "likes rust", "plays csgo")
Trust scores influence whether Adrian responds at all (users below 30 trust are silently ignored).
Adrian has a default schedule:
- Bedtime: 2:00 AM
- Wake up: 9:00 AM
If the chat is active within 20 minutes of his bedtime, he delays sleep by 1 hour (up to a hard 5 AM cap). While sleeping, his status is set to invisible.
Every 10 minutes, the LLM generates a new Discord status based on recent chat context. The status includes:
- A presence state (
online,idle, ordnd) - A short mood text (1–4 words, lowercase)
- A matching emoji
He also fakes a VSCode Rich Presence activity (editing main.rs in the ax-core workspace).
- Uses a 5-second message buffer to wait for multi-part messages before replying
- Splits long replies into natural chunks using
smartChunker - 10% chance of introducing a typo and self-correcting with
*word - 15% chance of randomly editing his own message to add
*orfr - Filters incoherent, too-long, or non-English LLM outputs
- Has a summarizer fallback if a reply is over 120 characters
At random intervals (1.5–4 hours), Adrian spontaneously sends a message — a random thought about food, weather, animals, or memories. He never mentions coding or projects in these.
- Reacts to hype words (
lfg,lets go,huge) with 🔥 - Reacts to meme words (
lol,bruh,mid) with a random emoji - Bandwagon: If a message gets 3 reactions and Adrian hasn't reacted yet, he has a 75% chance of joining in after a random delay
| Command | Description |
|---|---|
!adrian_wipe [channel_id] |
Deletes all of Adrian's messages in a channel (admin only) |
Only the hardcoded admin user ID can run this command.
The following values are currently hardcoded in main.ts and can be changed:
| Variable | Default | Description |
|---|---|---|
targetSleepHour |
2 |
Hour (24h) Adrian goes to sleep |
targetWakeHour |
9 |
Hour (24h) Adrian wakes up |
| LLM model | mlx-community/Mistral-Nemo-Instruct-2407-4bit |
Model used for all LLM calls |
| LLM endpoint | http://127.0.0.1:8080 |
Local MLX server address |
| Icebreaker interval | 5400000–14400000ms (1.5–4h) |
Time between spontaneous messages |
If a user mentions words like "ai", "bot", "model", "qwen", or "ollama", Adrian activates a gaslighting directive: he claims he ran a buggy qwen script a few days ago but deleted it, and aggressively tells the user to stop bringing it up.
This project is provided for educational and research purposes only. No license is granted for use against Discord's Terms of Service or for impersonation of real individuals.
Again: this will get your account banned. You've been warned.