<?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: Aman Kumar</title>
    <description>The latest articles on DEV Community by Aman Kumar (@aman_k_).</description>
    <link>https://dev.to/aman_k_</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4175649%2F6f116a46-bfc8-4066-b770-1afb6af58a32.jpg</url>
      <title>DEV Community: Aman Kumar</title>
      <link>https://dev.to/aman_k_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aman_k_"/>
    <language>en</language>
    <item>
      <title> Refund Sloth 🦥: Local AI Agents That Get Your Money Back While You Nap</title>
      <dc:creator>Aman Kumar</dc:creator>
      <pubDate>Sat, 24 Oct 2026 05:05:22 +0000</pubDate>
      <link>https://dev.to/aman_k_/refund-sloth-local-ai-agents-that-get-your-money-back-while-you-nap-3ee8</link>
      <guid>https://dev.to/aman_k_/refund-sloth-local-ai-agents-that-get-your-money-back-while-you-nap-3ee8</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Somewhere between 48% and 79% of us have paid for a free trial we forgot to cancel. The average person loses &lt;strong&gt;$187–$540 a year&lt;/strong&gt; to forgotten trials, missed return windows and subscriptions they stopped using. We &lt;em&gt;think&lt;/em&gt; we spend about $86 a month on subscriptions; it's closer to $219. And 44% of people keep a subscription simply because cancelling is a chore.&lt;/p&gt;

&lt;p&gt;That's the most sloth-shaped problem I know: the money is recoverable, but only if you do boring admin before a deadline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Refund Sloth 🦥&lt;/strong&gt; does the boring part. You drop receipts, order emails and your bank statement into one folder (or let it read your mailbox) and go to sleep. At 2 AM a team of six local AI agents wakes up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔭 &lt;strong&gt;Scout&lt;/strong&gt; finds new files through the official filesystem MCP server, locked to the inbox.&lt;/li&gt;
&lt;li&gt;📖 &lt;strong&gt;Reader&lt;/strong&gt; reads receipt &lt;em&gt;photos&lt;/em&gt; with a vision model, and PDFs and emails with a text model, into strict JSON.&lt;/li&gt;
&lt;li&gt;🦅 &lt;strong&gt;Deadline Hawk&lt;/strong&gt; works out return-by, trial-end, warranty and renewal dates and creates calendar reminders.&lt;/li&gt;
&lt;li&gt;🧾 &lt;strong&gt;Auditor&lt;/strong&gt; finds recurring charges in your bank CSV and flags 🧟 zombie, 👯 duplicate and 📈 price-hiked subscriptions.&lt;/li&gt;
&lt;li&gt;👻 &lt;strong&gt;Ghostwriter&lt;/strong&gt; drafts the cancellation and return emails.&lt;/li&gt;
&lt;li&gt;🦥 &lt;strong&gt;Sloth Boss&lt;/strong&gt; reviews everything with tool calls and writes your morning brief.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the morning you get a notification:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🦥 3 deadlines this week · $86.96/mo you can cut · 10 drafts ready&lt;br&gt;
Most urgent: ⏳ Peacock Premium free trial ends 2026-10-23 ($7.99 at stake).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You open the dashboard, click &lt;strong&gt;Approve &amp;amp; copy&lt;/strong&gt;, paste, send. Or click &lt;strong&gt;Cancel now ↗&lt;/strong&gt; to jump straight to the store's cancel page. Total effort: about 30 seconds. The sloth never sends or pays anything itself: a human stays in the loop, always.&lt;/p&gt;

&lt;p&gt;Even lazier extras:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📬 &lt;strong&gt;Connect mail (optional):&lt;/strong&gt; give it a Gmail, iCloud or Outlook &lt;em&gt;app password&lt;/em&gt; and it fetches order, trial and renewal emails by itself. The mailbox is opened &lt;strong&gt;read-only&lt;/strong&gt;, and the password is stored encrypted on your machine (macOS Keychain / Windows DPAPI).&lt;/li&gt;
&lt;li&gt;🚨 &lt;strong&gt;Urgent popup:&lt;/strong&gt; anything ending in the next 2 days gets its own desktop notification and a red banner at the top of the dashboard.&lt;/li&gt;
&lt;li&gt;↗️ &lt;strong&gt;Cancel now:&lt;/strong&gt; every trial, subscription and return has a button that opens the store's cancel or return page. No more hunting for the hidden cancel link.&lt;/li&gt;
&lt;li&gt;🖥️ Runs on &lt;strong&gt;macOS and Windows&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who gets to be lazier?&lt;/strong&gt; Anyone with a stack of receipts in a drawer, a "free" trial they meant to cancel, and a gym membership they've been "about to use again" since March.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/hmQlxosJAlk" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5lck471u4hzexcn8a9a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd5lck471u4hzexcn8a9a.gif" alt="Refund Sloth demo: landing page, dashboard tabs, agent log and mail connect" width="599" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Today:&lt;/strong&gt; the urgent banner, the morning brief, and money saved vs. money at risk.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flkfysaf1ga5scqukx85x.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flkfysaf1ga5scqukx85x.png" alt="Today tab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subscriptions:&lt;/strong&gt; zombies, duplicates and price hikes, each with a Cancel link.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftkiu8eqjdbdyeis8agcd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftkiu8eqjdbdyeis8agcd.png" alt="Subscriptions tab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Action queue:&lt;/strong&gt; ready-to-send emails. Nothing leaves without your click.&lt;br&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0n741fkf833yzkuptbys.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0n741fkf833yzkuptbys.png" alt="Action queue" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All data in the demo is fake (generated fixtures). No real receipts or bank statements were harmed.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/amangithub01" rel="noopener noreferrer"&gt;
        amangithub01
      &lt;/a&gt; / &lt;a href="https://github.com/amangithub01/refund-sloth" rel="noopener noreferrer"&gt;
        refund-sloth
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🦥 Local AI agents that get your money back while you nap. Open-weight models (Ollama) + MCP, no API keys, no cloud.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🦥 Refund Sloth&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Local AI agents that get your money back while you nap.&lt;/strong&gt; Drop receipts, order emails and bank statements into a folder. Overnight, a team of open-weight models running on &lt;em&gt;your&lt;/em&gt; laptop finds forgotten free trials, closing return windows, expiring warranties and zombie subscriptions, then drafts the cancellation and return emails for you. In the morning you click &lt;strong&gt;Approve&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;No API keys. No cloud. $0 per run. Works with Wi-Fi off.&lt;/p&gt;
&lt;p&gt;🌐 &lt;strong&gt;Try the live demo:&lt;/strong&gt; &lt;a href="https://refund-sloth.vercel.app" rel="nofollow noopener noreferrer"&gt;refund-sloth.vercel.app&lt;/a&gt;. It shows the dashboard with sample data, runs entirely in your browser, and needs no install. The real agents and mail sync run only on your own machine (see &lt;a href="https://github.com/amangithub01/refund-sloth#setup" rel="noopener noreferrer"&gt;Setup&lt;/a&gt;).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/amangithub01/refund-sloth/docs/media/refund-sloth-demo.gif"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fraw.githubusercontent.com%2Famangithub01%2Frefund-sloth%2FHEAD%2Fdocs%2Fmedia%2Frefund-sloth-demo.gif" alt="Refund Sloth demo: landing page, laptop orbit, dashboard tabs, agent log, mail connect"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;▶️ Full-quality video: &lt;a href="https://github.com/amangithub01/refund-sloth/docs/media/refund-sloth-demo.mp4" rel="noopener noreferrer"&gt;docs/media/refund-sloth-demo.mp4&lt;/a&gt; (26 s, demo data, fake "today" = 2026-10-21)&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📸 Screenshots&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Landing&lt;/th&gt;
&lt;th&gt;Scroll: the laptop orbit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/amangithub01/refund-sloth/docs/screenshots/landing.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Famangithub01%2Frefund-sloth%2FHEAD%2Fdocs%2Fscreenshots%2Flanding.png" alt="Landing page"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/amangithub01/refund-sloth/docs/screenshots/landing-orbit.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Famangithub01%2Frefund-sloth%2FHEAD%2Fdocs%2Fscreenshots%2Flanding-orbit.png" alt="Everything the sloth found, orbiting the laptop"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Today: urgent banner + morning brief&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Deadlines&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/amangithub01/refund-sloth/docs/screenshots/today.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Famangithub01%2Frefund-sloth%2FHEAD%2Fdocs%2Fscreenshots%2Ftoday.png" alt="Today"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a rel="noopener noreferrer" href="https://github.com/amangithub01/refund-sloth/docs/screenshots/deadlines.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Famangithub01%2Frefund-sloth%2FHEAD%2Fdocs%2Fscreenshots%2Fdeadlines.png" alt="Deadlines"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Subscriptions: zombies, duplicates, price hikes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Action queue: drafts you approve&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/amangithub01/refund-sloth" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Every model runs locally through &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt;.&lt;/strong&gt; No API keys anywhere in the project.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Open-weight model&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;Reader (images)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen2.5vl:7b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;small, fast vision model; reads crumpled receipt photos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reader (text), Hawk, Auditor, Ghostwriter, Boss&lt;/td&gt;
&lt;td&gt;&lt;code&gt;qwen3.5:35b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;strong JSON output and tool calling; runs well on an M3 Max&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lite profile&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;qwen3:8b&lt;/code&gt; + &lt;code&gt;qwen2.5vl:3b&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;for laptops with 8–16 GB of RAM&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;MCP is the backbone.&lt;/strong&gt; I wrote five small MCP servers in TypeScript over stdio:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ledger&lt;/code&gt; (SQLite)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs&lt;/code&gt; (PDF, image, EML, MBOX and CSV parsing)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;calendar&lt;/code&gt; (&lt;code&gt;.ics&lt;/code&gt; files with alarms)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;notify&lt;/code&gt; (desktop notifications and the brief)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mail&lt;/code&gt; (read-only IMAP)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alongside them runs the official &lt;code&gt;@modelcontextprotocol/server-filesystem&lt;/code&gt;, rooted at the inbox with only its read-only tools exposed. A small harness (&lt;code&gt;McpHub&lt;/code&gt;) starts every server, turns their tools into Ollama tool definitions and runs the agent loops. The full architecture diagram is in the README.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid by design: rules for math, models for mess.&lt;/strong&gt; The biggest lesson: don't let an LLM do arithmetic on your money.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain code:&lt;/strong&gt; hashing and dedup, all deadline math (document date, then &lt;code&gt;policies.json&lt;/code&gt;, then a clearly marked AI guess), recurring-charge detection, the zombie, duplicate and price-hike flags, and every number in the brief. All unit-tested.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLMs:&lt;/strong&gt; reading messy documents, guessing return policies for unknown stores, naming bank descriptors (&lt;code&gt;APPLE.COM/BILL 866-712-7753 CA&lt;/code&gt; → "Apple Music"), writing emails, and the Boss's review.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Structured output that doesn't break.&lt;/strong&gt; Every LLM call uses a zod schema, converted to JSON Schema and passed to Ollama's &lt;code&gt;format&lt;/code&gt;, then validated. On failure it retries with the validation error. Low-confidence extractions go to a "🔎 Needs a look" list instead of being silently wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A lesson from the local models:&lt;/strong&gt; prompt-only email formatting was ignored (one-line bodies, greeting the wrong company). Moving layout into deterministic post-processing fixed all of it. Small models are great at &lt;em&gt;content&lt;/em&gt;; let code handle &lt;em&gt;form&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eval.&lt;/strong&gt; &lt;code&gt;sloth eval&lt;/code&gt; runs the full pipeline on fake fixtures: receipt photos, PDF invoices, order emails, an mbox, a 13-month bank CSV, and a meme that must be ignored.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Field accuracy (merchant / amount / date)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;96.7%&lt;/strong&gt; (29/30)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deadline accuracy (type + date ±1 day)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;100%&lt;/strong&gt; (14/14)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subscription recall / flag accuracy&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100% / 100%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;False positives&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0&lt;/strong&gt; (the meme is correctly ignored)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time&lt;/td&gt;
&lt;td&gt;~3 minutes for the whole batch, fully local (M3 Max, 48 GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; TypeScript, Node 24 (built-in &lt;code&gt;node:sqlite&lt;/code&gt;), MCP TypeScript SDK, Ollama JS, zod, imapflow, Express 5 + SSE (a live agent log), React 19 + Vite + Tailwind v4, Vitest (39 tests).&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;For &lt;em&gt;this&lt;/em&gt; project it isn't a nice-to-have. It's the only way the project can exist.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy.&lt;/strong&gt; To find a forgotten trial you need someone's bank statement, receipts and order emails: their whole financial life. With a closed API, that's a nightly upload of your bank CSV to someone else's server. With open weights it never leaves the laptop. &lt;code&gt;sloth doctor&lt;/code&gt; even fails if Ollama isn't on localhost, and the dashboard API only listens on 127.0.0.1.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Works offline.&lt;/strong&gt; Nothing in the pipeline needs the internet; try it with Wi-Fi off. A 2 AM job shouldn't depend on a connection or an API being up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$0 per run, forever.&lt;/strong&gt; It runs every night. A closed API would charge per token, every night, to save me money. Ironic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable.&lt;/strong&gt; Each agent's model is one line in a config. I switch between a 35B model and an 8B "lite" profile, and a &lt;code&gt;single&lt;/code&gt; profile uses one multimodal model for everything. No vendor lock-in, and no deprecation can break my nightly job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tunable.&lt;/strong&gt; There's a &lt;code&gt;Modelfile&lt;/code&gt; that bakes in the Reader prompt, and because the weights are open you could fine-tune Reader on your own receipts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No OAuth app for your inbox.&lt;/strong&gt; Mail sync is plain read-only IMAP to your own provider. No cloud project, no client secret, no third party reading your mail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open standards.&lt;/strong&gt; Because of MCP, the tools (ledger, docs, calendar, mail) work with any other MCP client, and the agents use the official filesystem server instead of me reinventing file access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where open worked &lt;em&gt;better&lt;/em&gt; than closed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON-schema-constrained decoding through Ollama's &lt;code&gt;format&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keep_alive&lt;/code&gt; to keep models warm across a batch.&lt;/li&gt;
&lt;li&gt;The freedom to run a tiny vision model just for photos while a bigger one does the reasoning, on hardware I already own.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I built Refund Sloth with &lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; as my pair programmer. It helped with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;planning the agent pipeline;&lt;/li&gt;
&lt;li&gt;writing the MCP servers, the tests and the eval;&lt;/li&gt;
&lt;li&gt;iterating on the UI with headless-Chrome screenshots;&lt;/li&gt;
&lt;li&gt;recording the demo video.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every non-obvious decision (why rules do the math, why read-only IMAP instead of OAuth, why "Cancel now" is a link and not auto-cancel) is logged in &lt;a href="https://github.com/amangithub01/refund-sloth/blob/main/DECISIONS.md" rel="noopener noreferrer"&gt;DECISIONS.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;On the demo data (a realistic year of transactions), Refund Sloth found:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;$2,424 at risk in the next 30 days:&lt;/strong&gt; a $1,299 laptop return closing in 4 days, $348 headphones in 6, $249 AirPods in 8, and a trial that bills in 2.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$86.96 a month (~$1,043 a year) you can cut:&lt;/strong&gt; a gym nobody visits ($24.99), an unused AI tool ($20), the most expensive of four streaming services ($17.99), and the extra music and cloud plans ($11.99 each).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10 ready-to-send emails&lt;/strong&gt; and &lt;strong&gt;15 calendar reminders&lt;/strong&gt;, none of which I had to write.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing this by hand (digging through emails, checking each store's return policy, reading a bank statement line by line, writing polite-but-firm emails) is easily 1–2 hours a month. Now it's about 30 seconds of clicking Approve. 🦥&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of GitHub Copilot:&lt;/strong&gt; built end to end with the GitHub Copilot CLI.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>BillBox: a bill-to-spreadsheet tool that runs on your laptop with an open model</title>
      <dc:creator>Aman Kumar</dc:creator>
      <pubDate>Sun, 18 Oct 2026 15:11:33 +0000</pubDate>
      <link>https://dev.to/aman_k_/billbox-a-bill-to-spreadsheet-tool-that-runs-on-your-laptop-with-an-open-model-66c</link>
      <guid>https://dev.to/aman_k_/billbox-a-bill-to-spreadsheet-tool-that-runs-on-your-laptop-with-an-open-model-66c</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Every month, small shop owners and freelancers sit down with a pile of bills and type them into a spreadsheet so their accountant can file GST. It's slow, and the bills contain GSTINs, bank details and customer names. Uploading them to a cloud OCR service is a bad trade for something this sensitive.&lt;/p&gt;

&lt;p&gt;So I built BillBox for my relative, who keeps a drawer full of paper bills and hands them to the accountant at the end of every quarter.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjvmq6ix0vk8jz3f512a9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjvmq6ix0vk8jz3f512a9.png" alt="BillBox inbox showing invoices with Approved, Needs Review and Missing GSTIN status chips" width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drop in photos or PDFs of bills. A vision model running on your own laptop reads each one and extracts the vendor, GSTIN, invoice number, date and totals. A validation layer checks the math and flags anything suspicious. You fix flagged fields next to the original image, approve, and export a CSV your accountant can open in Excel.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Demo (sample data, no model runs here): &lt;a href="https://billbox-pi.vercel.app/" rel="noopener noreferrer"&gt;https://billbox-pi.vercel.app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/amangithub01/billbox" rel="noopener noreferrer"&gt;https://github.com/amangithub01/billbox&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Real app: runs locally with Ollama (setup in the README)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/vR_1ueRiwG0" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Why open models mattered
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Privacy:&lt;/strong&gt; The bill never leaves the machine, because the model runs locally through Ollama.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost:&lt;/strong&gt; there's no per-page fee, so 500 bills cost the same as 5. That's what makes this viable for someone who earns little from it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control:&lt;/strong&gt; the model is one config line (&lt;code&gt;qwen2.5vl:3b&lt;/code&gt; via Ollama). A bigger or fine-tuned model drops in without changing the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My laptop has 8 GB RAM and no GPU, so I used the 3B model. That limits accuracy, and the next section is about what that meant in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What went wrong (and what I did about it)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The model is right-ish, not right.&lt;/strong&gt; My first test was an electricity bill. It returned valid JSON, but the date came back as &lt;code&gt;04-07-2018&lt;/code&gt; instead of &lt;code&gt;2018-07-04&lt;/code&gt;, and the total came back as a string, &lt;code&gt;"1031.00"&lt;/code&gt;, instead of a number. A spreadsheet can't use either. I added a normalization step that converts dates (day-first, the Indian format) and parses numbers like &lt;code&gt;"1,031.00"&lt;/code&gt; and &lt;code&gt;"Rs. 1031"&lt;/code&gt;, with unit tests for each case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small models make mistakes on digits, so I stopped trusting the output.&lt;/strong&gt; Instead of showing extracted values as facts, BillBox runs checks: GSTIN format and checksum, rate x quantity = amount, subtotal + taxes = total, and CGST/SGST vs IGST. A mismatch turns the field red with a plain-English message. On a bill with no GSTIN, BillBox flagged "Missing Vendor GSTIN" and sent it to Needs Review instead of guessing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context limits.&lt;/strong&gt; Sending two images in one request crashed Ollama with a "request exceeds the available context size" error. The app now sends one image per request, resizes to 1280px, and sets a larger context window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not every bill is an invoice.&lt;/strong&gt; My electricity bill has no line items and no GSTIN, so the GST checks flagged errors that weren't errors. Now the checks are skipped when those fields don't exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;Tested on 10 real bills (printed invoices, phone photos, one electricity bill), on an 8 GB Windows laptop with no GPU.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Correct&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vendor&lt;/td&gt;
&lt;td&gt;10/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invoice number&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Date&lt;/td&gt;
&lt;td&gt;6/10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;td&gt;8/10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;About 55 seconds per bill. Validation flagged 4 wrong values that I would otherwise have missed. The worst results were on blurry phone photos and bills with no GSTIN printed on them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A 3B model needs human review. Treat the output as a draft.&lt;/li&gt;
&lt;li&gt;Roughly a minute per bill without a GPU.&lt;/li&gt;
&lt;li&gt;The hosted demo is simulated. The real extraction only runs locally.&lt;/li&gt;
&lt;li&gt;The CSV is meant for an accountant to open or import. It is not a ready-made Tally import file.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Fine-tune on the corrections people make (every fix is a labeled example), add Tally-compatible export, and try a larger model on better hardware.&lt;/p&gt;

&lt;p&gt;Built with Qwen2.5-VL, Ollama, FastAPI, React and OpenCV.&lt;/p&gt;

</description>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
      <category>devchallenge</category>
    </item>
  </channel>
</rss>
