<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michal Kraus</title>
    <description>The latest articles on DEV Community by Michal Kraus (@michal_kraus_151c2a53e667).</description>
    <link>https://dev.to/michal_kraus_151c2a53e667</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3837469%2Fe14974e7-0144-4a94-88c3-04e452c34751.png</url>
      <title>DEV Community: Michal Kraus</title>
      <link>https://dev.to/michal_kraus_151c2a53e667</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michal_kraus_151c2a53e667"/>
    <language>en</language>
    <item>
      <title>I built an open-source AI assistant that actually runs my day — here's the architecture</title>
      <dc:creator>Michal Kraus</dc:creator>
      <pubDate>Sat, 21 Mar 2026 18:39:21 +0000</pubDate>
      <link>https://dev.to/michal_kraus_151c2a53e667/i-built-an-open-source-ai-assistant-that-actually-runs-my-day-heres-the-architecture-24b3</link>
      <guid>https://dev.to/michal_kraus_151c2a53e667/i-built-an-open-source-ai-assistant-that-actually-runs-my-day-heres-the-architecture-24b3</guid>
      <description>&lt;p&gt;For the past few months, I've been running a personal AI assistant on a $5 VPS. Not a chatbot — an actual assistant that manages my calendar, triages my email, controls my Spotify, sends me proactive reminders, and remembers my preferences over time.&lt;/p&gt;

&lt;p&gt;Today I'm open-sourcing it. It's called &lt;strong&gt;Rook&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/barman1985/Rook" rel="noopener noreferrer"&gt;github.com/barman1985/Rook&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;Every AI assistant I tried fell into one of two categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Chatbots&lt;/strong&gt; — they answer questions but don't &lt;em&gt;do&lt;/em&gt; anything&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overengineered platforms&lt;/strong&gt; — they need Kubernetes, five microservices, and a PhD to deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I wanted something in between. An AI that lives in Telegram (zero onboarding — no new app to install), actually executes tasks via tool use, and runs on a single VPS I already had lying around.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Rook does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📅 &lt;strong&gt;Google Calendar&lt;/strong&gt; — create, edit, delete, search events&lt;/li&gt;
&lt;li&gt;📧 &lt;strong&gt;Gmail&lt;/strong&gt; — read, search, send emails&lt;/li&gt;
&lt;li&gt;🎵 &lt;strong&gt;Spotify&lt;/strong&gt; — play, search, playlists, device management&lt;/li&gt;
&lt;li&gt;📺 &lt;strong&gt;TV/Chromecast&lt;/strong&gt; — power, apps, volume control via ADB&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Memory&lt;/strong&gt; — remembers preferences using ACT-R cognitive architecture&lt;/li&gt;
&lt;li&gt;🔔 &lt;strong&gt;Proactive&lt;/strong&gt; — morning briefing at 7am, calendar reminders every 15 min, evening summary&lt;/li&gt;
&lt;li&gt;🎙️ &lt;strong&gt;Voice&lt;/strong&gt; — local STT (faster-whisper) + TTS (Piper) — completely free and private&lt;/li&gt;
&lt;li&gt;🔌 &lt;strong&gt;MCP Server&lt;/strong&gt; — expose all tools to Claude Desktop or Cursor&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Plugins&lt;/strong&gt; — drop a Python file, restart, new skill is live&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The architecture (the part I'm most proud of)
&lt;/h2&gt;

&lt;p&gt;Rook has 5 layers with strict dependency direction — each layer only depends on the layer below it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────┐
│       Transport layer           │  Telegram, MCP, CLI
├─────────────────────────────────┤
│       Router / Orchestrator     │  Intent → model → agentic loop
├─────────────────────────────────┤
│       Skill layer (pluggable)   │  Calendar, Email, Spotify, ...
│  ┌──────┐ ┌──────┐ ┌───────-─┐  │
│  │built │ │built │ │community│  │  Drop a .py, done.
│  │ -in  │ │ -in  │ │ plugin  │  │
│  └──────┘ └──────┘ └──────-──┘  │
├─────────────────────────────────┤
│           Event bus             │  on "calendar.reminder"→notify
├─────────────────────────────────┤
│         Core services           │  Config, DB, Memory, LLM client
└─────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;** Why this matters: **&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skills never import from Transport.&lt;/strong&gt; Calendar doesn't know it's being called from Telegram. Tomorrow it could be WhatsApp or a CLI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event bus decouples everything.&lt;/strong&gt; The scheduler emits &lt;code&gt;calendar.reminder&lt;/code&gt; — it doesn't know or care who's listening. The notification service picks it up and sends a Telegram message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One config, one DB, one LLM client.&lt;/strong&gt; No module reads &lt;code&gt;.env&lt;/code&gt; directly. No module opens its own SQLite connection. Everything flows through Core.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The plugin system
&lt;/h2&gt;

&lt;p&gt;This is what I think makes Rook actually useful for others. Adding a new integration is one Python file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# rook/skills/community/weather.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rook.skills.base&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Skill&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Skill&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get weather forecasts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nd"&gt;@tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get current weather for a city&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://wttr.in/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;?format=3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;

&lt;span class="n"&gt;skill&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;WeatherSkill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. The &lt;code&gt;@tool&lt;/code&gt; decorator registers it with the LLM. Type hints are auto-inferred into JSON schema. Drop the file in &lt;code&gt;skills/community/&lt;/code&gt;, restart Rook, and the LLM can now call &lt;code&gt;get_weather&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No core changes. No PR needed. No registration boilerplate.&lt;/p&gt;




&lt;h2&gt;
  
  
  ACT-R memory (not just another key-value store)
&lt;/h2&gt;

&lt;p&gt;Most AI assistants either forget everything between sessions or dump everything into a flat database. Rook's memory is inspired by the ACT-R cognitive architecture from psychology.&lt;/p&gt;

&lt;p&gt;Every memory has an &lt;strong&gt;activation score&lt;/strong&gt; based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Recency&lt;/strong&gt; — when was it last accessed? (power law decay)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frequency&lt;/strong&gt; — how often is it accessed? (logarithmic boost)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence&lt;/strong&gt; — how reliable is this fact?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the LLM needs context, only the most activated memories get injected into the system prompt. Frequently used memories stay sharp. Unused ones naturally fade. Just like your brain.&lt;/p&gt;




&lt;h2&gt;
  
  
  Local voice (zero API costs)
&lt;/h2&gt;

&lt;p&gt;Rook processes voice messages locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STT:&lt;/strong&gt; faster-whisper (base model, CPU int8) — transcribes voice messages from Telegram&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TTS:&lt;/strong&gt; Piper (Czech voice, 61MB ONNX model) — Rook speaks back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both run on the VPS. No cloud API calls, no per-minute billing, completely private.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setup takes 2 minutes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/barman1985/Rook.git
&lt;span class="nb"&gt;cd &lt;/span&gt;Rook &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
python &lt;span class="nt"&gt;-m&lt;/span&gt; rook.setup  &lt;span class="c"&gt;# interactive wizard guides you through everything&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; rook.main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup wizard asks for your API keys step by step, auto-detects available integrations, and generates &lt;code&gt;.env&lt;/code&gt;. Docker is also supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you need:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any VPS or home server (runs fine on 1GB RAM)&lt;/li&gt;
&lt;li&gt;Python 3.11+&lt;/li&gt;
&lt;li&gt;Anthropic API key (~$5-10/month for personal use)&lt;/li&gt;
&lt;li&gt;Telegram (as the interface)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3,100 lines&lt;/strong&gt; of Python&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10 skills&lt;/strong&gt;, &lt;strong&gt;32 tools&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;65 tests&lt;/strong&gt; (62 pass, 3 skip for optional dependencies)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MIT license&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Runs on a $5 VPS alongside other projects&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More community skills (weather, Notion, Todoist, Home Assistant)&lt;/li&gt;
&lt;li&gt;Bluesky integration for social posting&lt;/li&gt;
&lt;li&gt;Ollama support for local LLM fallback&lt;/li&gt;
&lt;li&gt;GitHub Actions CI pipeline&lt;/li&gt;
&lt;li&gt;Skill marketplace&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you've ever wanted an AI assistant that actually does things instead of just chatting, give Rook a try. Star the repo if it looks useful, and I'd love feedback on the architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/barman1985/Rook" rel="noopener noreferrer"&gt;github.com/barman1985/Rook&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Support:&lt;/strong&gt; &lt;a href="https://buymeacoffee.com/rook_ai" rel="noopener noreferrer"&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;♜ Rook — your strategic advantage.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>ai</category>
      <category>python</category>
      <category>selfhosted</category>
    </item>
  </channel>
</rss>
