<?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: Rahul Patel</title>
    <description>The latest articles on DEV Community by Rahul Patel (@foodlbs).</description>
    <link>https://dev.to/foodlbs</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%2F3806534%2F97497af3-0bb9-41d1-9b42-4cee6031a21a.jpg</url>
      <title>DEV Community: Rahul Patel</title>
      <link>https://dev.to/foodlbs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/foodlbs"/>
    <language>en</language>
    <item>
      <title>Openclad: A 24/7 Personal AI Agent That Actually Does Things</title>
      <dc:creator>Rahul Patel</dc:creator>
      <pubDate>Wed, 04 Mar 2026 20:46:38 +0000</pubDate>
      <link>https://dev.to/foodlbs/openclad-a-247-personal-ai-agent-that-actually-does-things-4amc</link>
      <guid>https://dev.to/foodlbs/openclad-a-247-personal-ai-agent-that-actually-does-things-4amc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Full visual version&lt;/strong&gt; : &lt;a href="https://foodlbs.github.io/openclad/" rel="noopener noreferrer"&gt;foodlbs.github.io/openclad&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's a gap between what AI chatbots &lt;em&gt;can&lt;/em&gt; do and what they &lt;em&gt;actually&lt;/em&gt; do for you day-to-day. ChatGPT can write a poem, but it can't turn off your living room lights when you're already in bed. Claude can analyze a document, but it won't proactively send you a news briefing at 9 AM.&lt;/p&gt;

&lt;p&gt;I wanted something different: an AI agent that runs &lt;strong&gt;continuously&lt;/strong&gt;, has access to my real tools and services, makes decisions autonomously for low-risk tasks, and asks permission before doing anything destructive. Something I could message from my phone and get things &lt;em&gt;done&lt;/em&gt; — not just get answers.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Jarvis&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Jarvis Can Do
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9:00 AM&lt;/td&gt;
&lt;td&gt;Jarvis sends a news briefing to Telegram — top headlines, tech, markets. No prompt needed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10:30 AM&lt;/td&gt;
&lt;td&gt;"What's the status of my job applications?" → queries SQLite tracker, returns summary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2:00 PM&lt;/td&gt;
&lt;td&gt;Send a PDF → Jarvis summarizes, stores in vector memory, saves markdown to Documents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11:00 PM&lt;/td&gt;
&lt;td&gt;"Turn off all the lights." → Approval button on Telegram → tap Approve → lights off&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key insight: Jarvis doesn't just respond to questions. It &lt;strong&gt;executes tasks&lt;/strong&gt;, &lt;strong&gt;remembers context&lt;/strong&gt;, and &lt;strong&gt;operates on a schedule&lt;/strong&gt; — all while respecting a risk classification system that keeps me in control of anything with real-world side effects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;The system breaks down into four layers:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffiyys9uk9ey2cunp473h.png" alt="Architecture Diagram" width="800" height="552"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Language&lt;/td&gt;
&lt;td&gt;Python 3.12 + uv workspace&lt;/td&gt;
&lt;td&gt;Fast deps, monorepo support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;Claude Agent SDK (subprocess)&lt;/td&gt;
&lt;td&gt;Process isolation, crash recovery&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Chat&lt;/td&gt;
&lt;td&gt;aiogram 3.x&lt;/td&gt;
&lt;td&gt;Async Telegram, inline keyboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State&lt;/td&gt;
&lt;td&gt;Redis&lt;/td&gt;
&lt;td&gt;Task state, buffers, retry queue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vector Memory&lt;/td&gt;
&lt;td&gt;ChromaDB (local)&lt;/td&gt;
&lt;td&gt;Free, no cloud dependency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embeddings&lt;/td&gt;
&lt;td&gt;OpenAI text-embedding-3-small&lt;/td&gt;
&lt;td&gt;Cost-effective semantic search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP Framework&lt;/td&gt;
&lt;td&gt;FastMCP&lt;/td&gt;
&lt;td&gt;Simple Python MCP server creation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Config&lt;/td&gt;
&lt;td&gt;pydantic-settings + YAML&lt;/td&gt;
&lt;td&gt;Type-safe + env var overrides&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logging&lt;/td&gt;
&lt;td&gt;structlog&lt;/td&gt;
&lt;td&gt;Structured JSON logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daemon&lt;/td&gt;
&lt;td&gt;macOS LaunchAgent&lt;/td&gt;
&lt;td&gt;Auto-start, background execution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Deep Dive: How Each Piece Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The Conversation Flow
&lt;/h3&gt;

&lt;p&gt;When you send a message on Telegram:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbn6pycj94szv6wubml2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpbn6pycj94szv6wubml2.png" alt="Workflow Diagram" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Smart model selection&lt;/strong&gt; — Short, simple messages (&amp;lt;100 chars, no complex keywords) auto-route to Haiku instead of Sonnet. Saves cost and cuts latency for quick tasks while preserving Sonnet's reasoning for demanding work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conversation buffer&lt;/strong&gt; — Last 10 turns stored in Redis with a 1-hour TTL. Follow-ups like "What about the bedroom lights?" work because Jarvis remembers the context.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. The Risk System
&lt;/h3&gt;

&lt;p&gt;The most important piece. Two-tier classification:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ AUTONOMOUS — No approval needed&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File reads, web search, memory queries&lt;/li&gt;
&lt;li&gt;Code sandbox, browser navigation&lt;/li&gt;
&lt;li&gt;Job tracker reads, calendar reads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🔒 REQUIRE APPROVAL — Inline Telegram button&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File writes / deletes&lt;/li&gt;
&lt;li&gt;Email sends, calendar edits&lt;/li&gt;
&lt;li&gt;Smart home control, phone calls, purchases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Classification isn't just by tool name — it examines &lt;strong&gt;input parameters&lt;/strong&gt; too. Reading &lt;code&gt;~/Documents&lt;/code&gt; is autonomous. Writing to &lt;code&gt;/etc/&lt;/code&gt; always requires approval. Checking a lock status is autonomous. &lt;em&gt;Unlocking&lt;/em&gt; it requires approval regardless of context.&lt;/p&gt;

&lt;p&gt;Configured via &lt;code&gt;risk_policy.yaml&lt;/code&gt; — no code changes needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;risk_overrides&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mcp__filesystem__write_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;autonomous&lt;/span&gt;       &lt;span class="c1"&gt;# Trust local file writes&lt;/span&gt;
  &lt;span class="na"&gt;mcp__smart_home__call_service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;require_approval&lt;/span&gt;  &lt;span class="c1"&gt;# Always ask&lt;/span&gt;

&lt;span class="na"&gt;context_escalation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dangerous_paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/system&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/etc&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/usr/bin&lt;/span&gt;
  &lt;span class="na"&gt;sensitive_entities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;lock&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;alarm&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;security&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. The Memory System
&lt;/h3&gt;

&lt;p&gt;Two layers, each optimized for different retrieval patterns:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Short-term: Markdown files injected into the system prompt&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;preferences.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Learned preferences ("prefers TypeScript over JavaScript")&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;projects.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Active project status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chat_history.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recent session summaries — auto-trims at 30 sessions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;journal.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agent reflections and observations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;ContextLoader&lt;/code&gt; stitches these into every agent invocation. When &lt;code&gt;chat_history.md&lt;/code&gt; exceeds 30 sessions, older entries compress into bullet-point summaries to keep the prompt under control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long-term: ChromaDB vector store with semantic search&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After completing significant tasks, Jarvis stores a 2-3 sentence summary with metadata. Before tackling complex work, it searches: "Have I solved something like this before?"&lt;/p&gt;

&lt;p&gt;The combination gives Jarvis both &lt;em&gt;working memory&lt;/em&gt; (always loaded) and &lt;em&gt;recall&lt;/em&gt; (searchable when needed).&lt;/p&gt;




&lt;h3&gt;
  
  
  4. The Skill Framework
&lt;/h3&gt;

&lt;p&gt;Skills are Markdown files defining triggers, steps, and required tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Daily News Briefing&lt;/span&gt;
&lt;span class="gs"&gt;**Trigger:**&lt;/span&gt; "news update", "daily news", "morning briefing"
&lt;span class="gs"&gt;**Schedule:**&lt;/span&gt; Every day at 9:00 AM EST

&lt;span class="gu"&gt;### Steps&lt;/span&gt;
&lt;span class="p"&gt;1.&lt;/span&gt; Search for current top headlines
&lt;span class="p"&gt;2.&lt;/span&gt; Search for tech industry news
&lt;span class="p"&gt;3.&lt;/span&gt; Search for business/markets news
&lt;span class="p"&gt;4.&lt;/span&gt; Format into clean briefing with sections
&lt;span class="p"&gt;5.&lt;/span&gt; Output ONLY the briefing — no meta-commentary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The skill manager routes incoming messages by matching keywords and context. If a request matches multiple skills, it chains them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The interesting part:&lt;/strong&gt; when Jarvis notices a repeatable pattern (3+ similar tool call sequences), it &lt;em&gt;suggests creating a new skill&lt;/em&gt;. The system grows organically based on actual usage.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. The Scheduler
&lt;/h3&gt;

&lt;p&gt;Parses a human-readable &lt;code&gt;schedules.md&lt;/code&gt; into cron-like entries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Daily News Briefing&lt;/span&gt;
&lt;span class="gs"&gt;**Schedule:**&lt;/span&gt; Every day at 9:00 AM EST
&lt;span class="gs"&gt;**Action:**&lt;/span&gt; Execute daily-news-briefing skill
&lt;span class="gs"&gt;**Output:**&lt;/span&gt; Send formatted news briefing via Telegram
&lt;span class="gs"&gt;**Status:**&lt;/span&gt; Active
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each job runs as an async task with max turns capped at 15 to enforce conciseness and suppress the model's meta-commentary tendency.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Resilience &amp;amp; Fallback
&lt;/h3&gt;

&lt;p&gt;Running 24/7 means things will break. Three mechanisms handle it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retry queue&lt;/strong&gt; — Failed tasks enter a Redis sorted set with exponential backoff (30s → 60s → 120s). After 3 retries, abandoned with a failure notification. On retry, model downgrades to Haiku to reduce cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API fallback&lt;/strong&gt; — If the Claude API is rate-limited, Jarvis detects error keywords (&lt;code&gt;"rate_limit"&lt;/code&gt;, &lt;code&gt;"529"&lt;/code&gt;, &lt;code&gt;"overloaded"&lt;/code&gt;) and falls back to the Claude Code CLI with a cached OAuth token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Circuit breaker&lt;/strong&gt; — Standard closed → open → half-open pattern. After 5 consecutive failures, circuit opens and rejects calls for 60 seconds before allowing a probe request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;personal-ai-agent/
├── main.py                    # Entry point &amp;amp; orchestrator
├── pyproject.toml             # uv workspace root
├── compose.yaml               # Docker Compose (Redis)
├── packages/
│   ├── core/                  # Agent, config, state, risk, retry, scheduler
│   ├── interfaces/            # Telegram bot, handlers, approval flow
│   └── mcp_servers/           # Job tracker, smart home, memory
├── data/
│   ├── agent_context/         # personality.md, skills/, schedules.md
│   ├── memory/chroma/         # Vector store persistence
│   └── secrets/               # OAuth credentials (gitignored)
├── configs/
│   ├── agent.yaml             # Runtime config
│   └── risk_policy.yaml       # Risk classification overrides
└── tests/                     # 20+ unit tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The monorepo keeps things modular — &lt;code&gt;core&lt;/code&gt; has no Telegram dependency, &lt;code&gt;interfaces&lt;/code&gt; has no MCP dependency, and &lt;code&gt;mcp_servers&lt;/code&gt; are standalone FastMCP processes. Want Discord instead of Telegram? Replace &lt;code&gt;interfaces&lt;/code&gt; without touching &lt;code&gt;core&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Design Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why local ChromaDB over Pinecone?&lt;/strong&gt; No cloud dependency. The vector store lives at &lt;code&gt;data/memory/chroma/&lt;/code&gt; — just files on disk. Zero cost, zero round-trip latency, git-backupable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why the subprocess model?&lt;/strong&gt; Each agent invocation is isolated. If it crashes, nothing leaks. SDK upgrade? Restart the process. Simplest possible isolation boundary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Telegram over a custom UI?&lt;/strong&gt; Already on my phone, laptop, and watch. Inline keyboards, file attachments, voice messages, rich formatting — all built-in. A custom UI would have taken weeks for a worse experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Markdown for schedules and skills?&lt;/strong&gt; Editable with any text editor, version-controlled with git, readable by the agent itself. When Jarvis creates a new skill, it writes a &lt;code&gt;.md&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Redis for everything stateful?&lt;/strong&gt; One dependency, in-memory speed, TTL for auto-cleanup, pub/sub for future real-time features.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the starter&lt;/span&gt;
git clone https://github.com/yourusername/jarvis-starter.git
&lt;span class="nb"&gt;cd &lt;/span&gt;jarvis-starter

&lt;span class="c"&gt;# Configure&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env   &lt;span class="c"&gt;# Add your API keys&lt;/span&gt;

&lt;span class="c"&gt;# Install&lt;/span&gt;
uv &lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="nt"&gt;--all-packages&lt;/span&gt;

&lt;span class="c"&gt;# Start Redis&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; redis

&lt;span class="c"&gt;# Run&lt;/span&gt;
uv run python main.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You'll need:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anthropic API key (Claude)&lt;/li&gt;
&lt;li&gt;Telegram bot token (from &lt;code&gt;@BotFather&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Your Telegram chat ID&lt;/li&gt;
&lt;li&gt;Optional: OpenAI key (embeddings), Google OAuth (Calendar/Gmail), Home Assistant URL + token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The starter ships with the full structure, a working Telegram bot, the risk system, two MCP servers (filesystem + memory), and one example skill (daily news briefing). Everything else added incrementally.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Voice pipeline&lt;/strong&gt; — Telegram voice transcription works but is clunky. A dedicated streaming voice pipeline would transform the experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parameterized skills&lt;/strong&gt; — Skills as templates: &lt;code&gt;Research {topic} with depth {shallow|deep}&lt;/code&gt; instead of flat instruction sets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-agent orchestration&lt;/strong&gt; — Some tasks need parallel sub-agents (researcher + writer). The single-agent model hits turn limits on complex workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability dashboard&lt;/strong&gt; — Task history, tool usage, cost tracking, memory growth. The event stream is there but underutilized.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Jarvis has been running 24/7 on my Mac for about two weeks — delivering morning news, tracking job applications, helping with research, and controlling my apartment — all through Telegram.&lt;/p&gt;

&lt;p&gt;The total codebase is ~2,000 lines of Python across three packages, plus Markdown files for personality, skills, and schedules. The agent framework (Claude SDK + MCP servers) does the heavy lifting; the surrounding infrastructure — risk classification, retry logic, conversation persistence, skill routing — is what transforms a chatbot into an actual assistant.&lt;/p&gt;

&lt;p&gt;Check out the starter repo and if you build something cool with it, I'd love to hear about it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Claude Agent SDK · aiogram · Redis · ChromaDB · FastMCP · Running on a Mac Mini as a LaunchAgent&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>claude</category>
      <category>mac</category>
    </item>
  </channel>
</rss>
