<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>AI on MangoDriod</title><link>https://md.eknath.dev/tags/ai/</link><description>Recent content in AI on MangoDriod</description><generator>Hugo -- 0.141.0</generator><language>en-us</language><lastBuildDate>Sun, 26 Apr 2026 10:25:15 +0530</lastBuildDate><atom:link href="https://md.eknath.dev/tags/ai/index.xml" rel="self" type="application/rss+xml"/><item><title>AI Command Center to manage multiple projects [Expriment]</title><link>https://md.eknath.dev/posts/software-development/ai-command-center-expriment/</link><pubDate>Sun, 26 Apr 2026 10:25:15 +0530</pubDate><guid>https://md.eknath.dev/posts/software-development/ai-command-center-expriment/</guid><description>&lt;p>a team of 20+ handed over a project to our team of 5. i ended up owning all the native clients: iOS, Android, Windows by mostly bymyself. There are multiple repos, multiple languages and the hardship of understanding thier 7 year codebase.&lt;/p>
&lt;p>initially the thought of this was pretty stressful, but being a good solutionist i proceeded with dicecting the issues one by one and presistent on finding a solition for them all.&lt;/p></description><content:encoded><![CDATA[<p>a team of 20+ handed over a project to our team of 5. i ended up owning all the native clients: iOS, Android, Windows by mostly bymyself. There are multiple repos, multiple languages and the hardship of understanding thier 7 year codebase.</p>
<p>initially the thought of this was pretty stressful, but being a good solutionist i proceeded with dicecting the issues one by one and presistent on finding a solition for them all.</p>
<p>The first thing is prioritizing platoforms, The stats were clear hence shared them with my manager, got iOS, Android prioritized in order and parked Windows for later as usage is extremly low. now the priority is set to the next thing.</p>
<p>The problem was not the workload. it was the cognitive overhead. i can barely understand my own code after a few months. here i am inheriting code from 6-7 people who clearly took shortcuts to ship fast. folder structure was a dump. files everywhere. and on top of reverse-engineering three codebases i had to track what is done, what is next, what is blocked: simultaneously, across all platforms this task alone without AI would be a real pain and would def take more than few months.</p>
<p>I opted to the $20 Claude subscription. so every session i was wasting the first chunk of context re-explaining the same codebase to Claude, re-orienting it to where i left off, re-answering questions it should already know. by lunch i was running out of tokens i had to use my colleague&rsquo;s accounts to do whole thing again (Thanks Arun!)</p>
<p>out of this mess i needed a single place. one terminal. one browser tab. one AI session that already knows everything and picks up exactly where we left off, an interface for me and claude to read/update/learn about the project im working and it has to be highly structured, organized and prioritized.</p>
<p>so i built one. i call it the <strong>Command Center</strong>. if you have any other name to suggest, my inbox is open. this post is the full breakdown of what it is, how it works, and how you can shape it for your your own structure if you ever are in that spot, a little future pridction i think by the end of 2026 we all might have to work in this kind of set-up working on multiple projects simultaniously or atleast we will be capabble of that level of productivity.</p>
<hr>
<h2 id="what-is-this-ai-command-center">What is this AI-Command Center</h2>
<p><img alt="The Command Center&rsquo;s Dashboard Home Screen — This is the primary human interface rendered in the browser tab with everything: repo status, today&rsquo;s focus, quick links, docs and more" loading="lazy" src="/img/command-center-images/cce-home.png"></p>
<p>the idea is simple. instead of having our docs, tasks, changelogs in multiple apps and your terminal tabs scattered across screens for different platforms wokfing with different stages of the tasks or even totally different task altogether: and your daily runner claude-code has no means to know about all these instead you put a single shared operational layer above all your repos. not inside them. above them hence the term command center.</p>
<pre tabindex="0"><code>MyWorkspace/
├── ios/               ← own git repo, untouched
├── ios-dataKit/       ← own git repo, untouched
├── android/           ← own git repo, untouched
├── win/               ← own git repo, untouched
└── .ops/              ← Command Center (its own git repo)
    ├── docs/          ← documentation per project
    ├── todo/          ← task files per project + daily focus
    ├── memo/          ← decisions, KT notes, research
    ├── diagrams/      ← architecture diagrams + companion notes
    ├── changelog/     ← per-project ship history
    ├── scripts/       ← automation scripts
    └── dashboard/     ← local web dashboard
</code></pre><p>Don&rsquo;t worry the project folders stay completely independent. <code>git -C ios/ status</code> never bleeds into <code>git -C android/ status</code>. you can add or remove a project folder without touching anything else, this is very important sepearation for corporate repositories where the restrictions are tight.</p>
<p>almost everything in <code>.ops/</code> is a markdown, here is where it might looks like the WiKi pattern shared by the Andrej Karpathy. it is readable by me and the AI, diffs cleanly, and has zero dependencies you can stop here is you want a bare simple command-center but if you are like me this is not enough and there are many flaws here like doc&rsquo;s going stale as we make changes so lets get to the text stage.</p>
<hr>
<h2 id="the-scripts-are-the-real-mvp">The scripts are the real MVP</h2>
<p>As i said earlier i still use the 20$ subscription so for me tokens are really valuable running out of limit means one less productive day that might gift me a day of guilt so making use of scripts to save some routine commands that im sure will be helpful for claude to not be too dependent on remote calls, it might be confusting so here is example:</p>
<p>when i ask Claude &ldquo;what is the git status across all my repos?&rdquo;  Claude tries to figure it out by calling tools one at a time burning tokens on reasoning and multiple tool calls to give me accurate and proper response</p>
<p>but if you have a script that does it:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># .ops/scripts/git_status_all.sh</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> dir in android ios ios-dataKit ios-textEditor win; <span style="color:#66d9ef">do</span>
</span></span><span style="display:flex;"><span>    branch<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>git -C <span style="color:#e6db74">&#34;</span>$ROOT<span style="color:#e6db74">/</span>$dir<span style="color:#e6db74">&#34;</span> branch --show-current 2&gt;/dev/null<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>    changes<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>git -C <span style="color:#e6db74">&#34;</span>$ROOT<span style="color:#e6db74">/</span>$dir<span style="color:#e6db74">&#34;</span> status --porcelain | wc -l | tr -d <span style="color:#e6db74">&#39; &#39;</span><span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#f92672">[</span> <span style="color:#e6db74">&#34;</span>$changes<span style="color:#e6db74">&#34;</span> -gt <span style="color:#ae81ff">0</span> <span style="color:#f92672">]</span>; <span style="color:#66d9ef">then</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;● </span>$dir<span style="color:#e6db74"> — </span>$branch<span style="color:#e6db74"> (</span>$changes<span style="color:#e6db74"> uncommitted)&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">else</span>
</span></span><span style="display:flex;"><span>        echo <span style="color:#e6db74">&#34;● </span>$dir<span style="color:#e6db74"> — </span>$branch<span style="color:#e6db74"> (clean)&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">fi</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">done</span>
</span></span></code></pre></div><p>Claude runs the script. gets the answer in one shot. no reasoning, no guessing, no tool call loop you don&rsquo;t have to write this manually you can just ask it to do, just make sure you get the code though.</p>
<p>the scripts i have accumulated up over time:</p>
<table>
  <thead>
      <tr>
          <th>Script</th>
          <th>What it does</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>briefing.sh</code></td>
          <td>morning snapshot: repo status, high-priority tasks, daily focus, doc staleness — all in one output</td>
      </tr>
      <tr>
          <td><code>session_context.sh</code></td>
          <td>generates a JSON briefing injected into Claude context at session start via a hook</td>
      </tr>
      <tr>
          <td><code>daily_reset.sh</code></td>
          <td>resets <code>daily.md</code> to today, carries over incomplete items, pulls high-priority tasks from project todos</td>
      </tr>
      <tr>
          <td><code>git_status_all.sh</code></td>
          <td>git status across all repos in one command</td>
      </tr>
      <tr>
          <td><code>git_pull_all.sh</code></td>
          <td>pull latest on all repos</td>
      </tr>
      <tr>
          <td><code>git_branch_all.sh</code></td>
          <td>current branch per repo</td>
      </tr>
      <tr>
          <td><code>doc_sync.js</code></td>
          <td>diffs each doc&rsquo;s last-verified commit against HEAD, flags stale docs</td>
      </tr>
      <tr>
          <td><code>pre-push-codecheck.sh</code></td>
          <td>pre-push validation — lint, build check, etc. per platform</td>
      </tr>
      <tr>
          <td><code>log_token_saving.py</code></td>
          <td>PostToolUse hook — logs each local MCP call with estimated tokens saved, reminds Claude to tag responses with <code>[local-command-center-mcp]</code></td>
      </tr>
  </tbody>
</table>
<p>the pattern is always same: take something that would require Claude to do many tool calls or make assumptions, turn it into one script, let Claude just run it and read the output. you get a more reliable answer and you spend a fraction of the tokens.</p>
<p>the <code>session_context.sh</code> one is worth explaining. it runs as a session-start hook and injects the project context automatically before i type anything:</p>
<pre tabindex="0"><code>=== SESSION BRIEFING (2026-04-26) ===

REPOS
  ios          dev_eganathan   clean
  android      dev_eganathan   clean
  ios-dataKit  dev_eganathan   14 uncommitted  ← needs attention

HIGH PRIORITY (ios)
  - sessionId hardcoded as &#34;&#34; (TIBConverseInteractor.swift:83)
  - Localization migration uncommitted

LAST SESSION: 2026-04-22 — ios folder restructure, Settings flatten done
DOC SYNC: 8 stale docs — run /sync
=====================================
</code></pre><p>this replaces re-explaining the codebase every session. the entire briefing is generated from actual file state and costs about 100 tokens to inject i shared only a small portion of this but it basically added more relavant contexts that im sure will help claude so compare that to the 500–1000 tokens you&rsquo;d spend manually orienting Claude each time.</p>
<hr>
<h2 id="documentation-that-doesnt-go-stale">Documentation that doesn&rsquo;t go stale</h2>
<p><img alt="Docs folder — each file has watches frontmatter so the sync script knows exactly which code changes make it stale." loading="lazy" src="/img/command-center-images/cce-doc-folder.png"></p>
<p>the biggest problem with docs is they go stale the moment you stop actively maintaining them. and the honest truth is most people stop maintaining them pretty quickly.</p>
<p>so instead of relying on discipline, i wired it into the workflow. every doc has frontmatter that declares what code it describes:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span>---
</span></span><span style="display:flex;"><span><span style="color:#f92672">project</span>: <span style="color:#ae81ff">ios</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">watches</span>: <span style="color:#ae81ff">ios/Features/Inbox/**, ios/Core/Network/**</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">lastVerified</span>: <span style="color:#ae81ff">a3f9c12</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">verifiedDate</span>: <span style="color:#e6db74">2026-04-20</span>
</span></span><span style="display:flex;"><span>---
</span></span></code></pre></div><p><code>watches</code> is a glob pattern over source paths. <code>lastVerified</code> is the git commit hash when i last checked this doc.</p>
<p><code>doc_sync.js</code> runs at session start: diffs <code>lastVerified</code> against HEAD per project, filtered by <code>watches</code>. if watched files changed, the doc is flagged stale. you get a list of exactly which docs need attention — not all of them, just the ones where the underlying code actually changed.</p>
<p>the workflow: read the diff, update the doc if needed, run <code>--mark-current</code> to stamp it with the new HEAD. stale docs are a session-start action item, not a quarterly effort.</p>
<p>one more thing worth building: a <code>doc_sync_prompt.md</code> template. when <code>doc_sync.js</code> flags a doc as stale, you need to give Claude a consistent prompt for reviewing it. the template fills in <code>{{DOC_PATH}}</code>, <code>{{GIT_DIFF_STAT}}</code>, <code>{{CHANGED_FILES}}</code>, and <code>{{DOC_CONTENT}}</code> — Claude reads the diff, decides what changed, updates only what is wrong or outdated, and preserves the frontmatter format. without a template you end up writing a different prompt every time and the quality of the review varies. one template file in <code>scripts/</code>, referenced whenever <code>/sync</code> runs.</p>
<hr>
<h2 id="task-management-across-platforms">Task management across platforms</h2>
<p><img alt="Per-platform todo files with priority buckets — high, medium, low, and completed. Daily.md pulls from these each morning." loading="lazy" src="/img/command-center-images/cce-todos.png"></p>
<p>one file per platform. <code>ios_todos.md</code>, <code>android_todos.md</code>, <code>win_todos.md</code>. same structure in all of them:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span><span style="color:#75715e">## High Priority
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">- [ ]</span> Fix session ID bug in TIBConverseInteractor.swift:83
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Medium Priority
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">- [ ]</span> Add unit test target
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Low Priority
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">- [ ]</span> Refactor legacy auth flow
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Completed
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">- [x]</span> 2026-04-20 — Migrated Localizable strings
</span></span></code></pre></div><p>there is also <code>daily.md</code> — today&rsquo;s focus, separate from the long-running backlogs. <code>daily_reset.sh</code> resets it each morning, carries over anything incomplete from yesterday, and pulls the top items from each project&rsquo;s High Priority section so you are never starting from blank. at end of day you move done items back to the project file and carry over the rest.</p>
<p>it is not rocket science but it works because everything is in one place and Claude can read all of it directly — no context switching, no &ldquo;go check Linear&rdquo;, no copy-pasting.</p>
<hr>
<h2 id="memos-kt-notes-and-changelogs">Memos, KT notes, and changelogs</h2>
<p>these three are the most underrated parts of the system. they get skipped when people think about &ldquo;what does an AI need to know&rdquo; but they are exactly what the AI is missing when it gives you advice that misses context.</p>
<p><strong>Memos (<code>memo/</code>)</strong> are for anything that does not fit in a doc or a todo. decision logs, architecture choices, research, migration plans, meeting outputs. the key thing about a memo is it captures the <em>why</em>. a doc says &ldquo;the auth middleware works like this&rdquo;. a memo says &ldquo;we rewrote the auth middleware because legal flagged the session token storage in April&rdquo;. without the memo Claude treats every piece of code as a deliberate, still-valid decision. with the memo it knows what is intentional and what is technical debt inherited from a compliance scramble.</p>
<p><strong>KT notes (<code>memo/kt/&lt;platform&gt;/YYYY-MM-DD_topic.md</code>)</strong> are specifically for inheriting a codebase. when someone does a knowledge transfer session, you write it up here. when you figure out something non-obvious about how the code works, you write it up here. these are the things that would take a new person weeks to discover by reading code — undocumented conventions, &ldquo;we don&rsquo;t touch that file because&rdquo;, quirks of the build system, context behind a weird architectural choice. writing them down once means Claude knows them forever.</p>
<p><strong>Changelogs (<code>changelog/&lt;project&gt;.md</code>)</strong> are append-only per-project ship logs:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span>| 2026-04-15 | Migrated inbox to VIPER          | PR #441 |
</span></span><span style="display:flex;"><span>| 2026-04-08 | Upgraded to AGP 8.3              | PR #438 |
</span></span><span style="display:flex;"><span>| 2026-03-22 | Added push notification handling | PR #421 |
</span></span></code></pre></div><p>one row per notable change. the practical use: &ldquo;did we ship X on all platforms yet?&rdquo; — you check the changelog instead of grepping git history across five repos. also useful at standup when someone asks what shipped last week.</p>
<hr>
<h2 id="the-local-web-dashboard">The local web dashboard</h2>
<p><img alt="Quick links panel — one-click access to docs, scripts, and frequently used paths across all projects." loading="lazy" src="/img/command-center-images/cce-home-quicklinks.png"></p>
<p><img alt="Keyboard shortcuts reference — configured per-project so you never forget the exact command flags." loading="lazy" src="/img/command-center-images/cce-shortcuts.png"></p>
<p>the dashboard is a local Node.js server. no framework, no build step, runs offline, starts in two seconds.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>node .ops/dashboard/server.js
</span></span><span style="display:flex;"><span><span style="color:#75715e"># opens at localhost:3000</span>
</span></span></code></pre></div><p><strong>File browser</strong> — tree sidebar over all docs, todos, memos. files render as Markdown. todo files have live checkboxes — clicking one calls <code>POST /api/toggle</code> and writes the change directly to disk.</p>
<p><strong>Git status panel</strong> — polls all repos in parallel. branch, last commit, time ago, dirty file count.</p>
<p><strong>Full-text search</strong> — index built at startup from every <code>.md</code>, <code>.txt</code>, <code>.sh</code> file. AND-matched with scoring. returns results with line-number snippets. useful when you remember something exists but can not remember which doc it is in.</p>
<p><strong>Doc staleness indicators</strong> — green/yellow/red dots next to each doc in the sidebar based on <code>doc_sync.js</code> output. a resync button re-runs the script and refreshes the cache.</p>
<p><strong>Task creation</strong> — a form on every page to add a todo at any priority level to any project. finds the right heading and inserts the item, updates the <code>Last updated:</code> stamp.</p>
<hr>
<h2 id="shape-it-to-your-problems--the-cmd-tabs-and-rss-feeds">Shape it to your problems — the CMD tabs and RSS feeds</h2>
<p>here is the thing: everyone&rsquo;s pain is different. the folder structure and scripts above are the common base. but the reason this actually works day-to-day is that you can add whatever else you actually need on top.</p>
<p>for me, the two things i added that made the biggest difference:</p>
<p><img alt="Embedded terminal with per-project tabs — each one opens a PTY in that project&rsquo;s directory. Quick-command buttons above run the commands you&rsquo;d otherwise forget." loading="lazy" src="/img/command-center-images/cce-terminal.png"></p>
<p><strong>CMD view</strong> — <code>xterm.js</code> + <code>node-pty</code> over WebSocket. a real terminal embedded in the browser, one tab per project. each tab opens a PTY session in that project&rsquo;s directory. per-project quick-command buttons — you configure a label and a shell command, they appear as buttons above the terminal. so <code>Build Debug</code> runs <code>./gradlew assembleDebug</code> in the Android tab. <code>Sync Pods</code> runs <code>pod install</code> in the iOS tab. i click once, watch it run. no switching windows, no remembering the exact command flags.</p>
<p>before this i was constantly switching terminal windows and losing track of which one was which. now everything is in one browser tab.</p>
<p><img alt="RSS feeds grouped by platform — no algorithm, no app, just the dev blogs and release channels you actually want to follow." loading="lazy" src="/img/command-center-images/cce-rss.png"></p>
<p><strong>RSS feeds / newsletters</strong> — each platform has its own dev newsletter and release channel. iOS dev forum, Android releases, Kotlin blog. i added an RSS tab. feed URLs live in a <code>feeds.json</code> file, keyed by platform:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;ios&#34;</span>: [
</span></span><span style="display:flex;"><span>    { <span style="color:#f92672">&#34;label&#34;</span>: <span style="color:#e6db74">&#34;iOS Dev Weekly&#34;</span>, <span style="color:#f92672">&#34;url&#34;</span>: <span style="color:#e6db74">&#34;https://iosdevweekly.com/issues.rss&#34;</span> },
</span></span><span style="display:flex;"><span>    { <span style="color:#f92672">&#34;label&#34;</span>: <span style="color:#e6db74">&#34;Swift Blog&#34;</span>, <span style="color:#f92672">&#34;url&#34;</span>: <span style="color:#e6db74">&#34;https://swift.org/atom.xml&#34;</span> }
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;android&#34;</span>: [
</span></span><span style="display:flex;"><span>    { <span style="color:#f92672">&#34;label&#34;</span>: <span style="color:#e6db74">&#34;Android Developers Blog&#34;</span>, <span style="color:#f92672">&#34;url&#34;</span>: <span style="color:#e6db74">&#34;https://feeds.feedburner.com/blogspot/hsDu&#34;</span> }
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>the server fetches them server-side (handles redirects, CDATA stripping), renders as cards per platform. i stop by when i want to catch up. no separate app, no subscriptions, no algorithm deciding what i see — just the feeds i actually want, inside the same tab i already have open.</p>
<p>neither of these exist in anyone else&rsquo;s command center because they are solving my specific workflow pain. the point is the base layer gives you the foundation. the top layer is yours to build.</p>
<p>other ideas i have seen or thought about that i haven&rsquo;t built yet: a meeting notes tab that auto-stamps today&rsquo;s date, a platform-specific analytics panel, a PR review queue for when you work with a team.</p>
<hr>
<h2 id="the-two-tier-ai-model">The two-tier AI model</h2>
<p><img alt="Local AI chat powered by Mistral 7B via Ollama — answers questions about your codebase from the RAG index, free and fully offline." loading="lazy" src="/img/command-center-images/cce-local-ai-chat.png"></p>
<p>the local web dashboard has a built-in AI chat powered by Mistral 7B via Ollama — not Claude. this is the layer that routes cheap questions away from the cloud.</p>
<p>the RAG pipeline:</p>
<pre tabindex="0"><code>question
   │
   ▼
embed ──► LanceDB vector search ──► top-k doc chunks
                                          │
                                          ▼
                             Mistral 7B ◄── context + question
                                          │
                                          ▼
                                    streamed answer
                               (with source file citations)
</code></pre><p>at startup the server walks all docs, chunks them, embeds them and stores the index in LanceDB. conversation history (last 12 turns) is passed with each request. topics can be filtered per platform.</p>
<p>but here is the part that matters more — the local model is also wired directly into Claude as an MCP tool. not just the dashboard chat, but Claude itself can call it:</p>
<pre tabindex="0"><code>search_docs(query, project?)  — semantic search over the LanceDB index
ask_local(question, project?) — full RAG query to Mistral 7B
</code></pre><p>so when you ask Claude &ldquo;where is the WebSocket manager?&rdquo; Claude does not think about it, does not run three tool calls, does not burn tokens. it calls <code>ask_local</code>, gets the answer back from the local model as a tool response, and continues. the routing decision is encoded in <code>CLAUDE.md</code> as explicit rules so it happens automatically:</p>
<pre tabindex="0"><code>You
 │
 ├── Complex reasoning ──────────────────► Claude (API tokens)
 │    debugging, architecture,
 │    multi-file refactoring, codegen
 │
 └── Lookups + summaries ──► local MCP ──► Mistral 7B (free, local)
      &#34;where is X?&#34;, todos,
      file summaries, templates
</code></pre><p>questions that go local: &ldquo;where is ClassName defined&rdquo;, &ldquo;what files are in folder X&rdquo;, &ldquo;summarise this file&rdquo;, &ldquo;what todos are open for Android&rdquo;, &ldquo;what is the VIPER template for a new scene&rdquo;, anything answerable by reading the existing docs.</p>
<p>questions that use Claude: multi-file refactoring, debugging across call chains, cross-platform analysis with real reasoning, writing new features.</p>
<p>in practice around 60–70% of session queries route to the local model. those run free on my machine. Claude gets the work that actually needs it.</p>
<h3 id="tracking-what-you-saved">Tracking what you saved</h3>
<p>there is one more hook worth adding: a PostToolUse hook on the local MCP calls. every time Claude calls <code>ask_local</code> or <code>search_docs</code>, a small Python script logs the call to a <code>token_savings.jsonl</code> file with a timestamp, the tool used, and an estimated token count saved:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{<span style="color:#f92672">&#34;ts&#34;</span>: <span style="color:#e6db74">&#34;2026-04-26T10:32:11&#34;</span>, <span style="color:#f92672">&#34;tool&#34;</span>: <span style="color:#e6db74">&#34;ask_local&#34;</span>,    <span style="color:#f92672">&#34;estTokensSaved&#34;</span>: <span style="color:#ae81ff">400</span>}
</span></span><span style="display:flex;"><span>{<span style="color:#f92672">&#34;ts&#34;</span>: <span style="color:#e6db74">&#34;2026-04-26T10:33:45&#34;</span>, <span style="color:#f92672">&#34;tool&#34;</span>: <span style="color:#e6db74">&#34;search_docs&#34;</span>,  <span style="color:#f92672">&#34;estTokensSaved&#34;</span>: <span style="color:#ae81ff">250</span>}
</span></span></code></pre></div><p>the same hook also outputs a reminder back into Claude&rsquo;s context: <em>&ldquo;you just used the local model — append <code>[tib-mcp-info]</code> to the sentence in your response that came from this result.&rdquo;</em></p>
<p>that <code>[tib-mcp-info]</code> tag in the response is how you know which parts Claude answered from local knowledge vs the local model. it is easy to skip but worth keeping — after a few weeks you can look at the JSONL and get a rough sense of how many tokens the routing saved. it also keeps you honest about whether the local model is actually being used or whether Claude is quietly doing everything itself.</p>
<hr>
<h2 id="the-session-cache--picking-up-exactly-where-you-left-off">The session cache — picking up exactly where you left off</h2>
<p>the session briefing knows &ldquo;what was worked on last session&rdquo; because <code>/callitaday</code> writes a <code>session_summary.json</code> at the end of each day. the structure:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;date&#34;</span>: <span style="color:#e6db74">&#34;2026-04-22&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;platform&#34;</span>: <span style="color:#e6db74">&#34;ios&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;done&#34;</span>: [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;Settings flatten complete — SettingsSUI/NewUI/Settings_base merged into Features/Settings&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;Helpers restructured — Contacts moved to Features/Contacts&#34;</span>
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;carriedOver&#34;</span>: [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;Android: edge to edge mandate for Play Store — not checked yet&#34;</span>
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;decisions&#34;</span>: [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;Contacts gets Features/Contacts/ not buried in Helpers&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;URLSchemeAnalyser lives in Core/DeepLinker/&#34;</span>
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;openQuestions&#34;</span>: [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;CustomContextMenu still needs to move to Features/Inbox/Actions/&#34;</span>
</span></span><span style="display:flex;"><span>  ],
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;keyFiles&#34;</span>: [
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;native/TeamInbox.xcodeproj/project.pbxproj&#34;</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;native/TeamInbox/Features/Settings/&#34;</span>
</span></span><span style="display:flex;"><span>  ]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>next morning, <code>session_context.sh</code> reads this file and includes the <code>done</code>, <code>carriedOver</code>, <code>decisions</code>, and <code>openQuestions</code> fields in the briefing. Claude starts the session knowing exactly where things were left — no re-reading git log, no &ldquo;what were we working on?&rdquo;. the <code>keyFiles</code> field is useful if you want Claude to immediately orient to the relevant parts of the code.</p>
<p><code>/callitaday</code> is the slash command that writes this. it wraps the session: moves done items from <code>daily.md</code> back to the project todo files, carries over incomplete items, writes the JSON. it is the last thing you run before closing the terminal.</p>
<hr>
<h2 id="setting-this-up-yourself">Setting this up yourself</h2>
<p>the minimum version of this is five files and an afternoon:</p>
<ol>
<li>create a parent workspace folder above all your repos</li>
<li>add a <code>.ops/</code> folder with <code>docs/</code>, <code>todo/</code>, <code>memo/</code>, <code>scripts/</code></li>
<li>write a <code>CLAUDE.md</code> at the workspace root — folder layout, git command prefixes, working conventions, routing rules</li>
<li>write <code>session_context.sh</code> or a simple briefing script that runs <code>git -C &lt;project&gt;/ status</code> across all repos and prints a summary — hook it to session start</li>
<li>write one doc per project covering the folder structure and architecture, add the <code>watches</code> frontmatter</li>
</ol>
<p>that is the base. that alone kills the &ldquo;re-explain everything every session&rdquo; problem and the &ldquo;docs live in Notion somewhere&rdquo; problem.</p>
<p>layer on top in order of payoff:</p>
<ul>
<li><code>daily_reset.sh</code> and the <code>daily.md</code> workflow — probably adds the most to day-to-day sanity</li>
<li><code>doc_sync.js</code> — if you are writing docs and want them to stay honest</li>
<li>the dashboard — once you want a visual layer over all of it</li>
<li>the CMD tabs — if you are constantly switching terminal windows for the same commands</li>
<li>the local model + MCP — when token pressure is real and your doc library is large enough to justify a RAG pipeline</li>
</ul>
<p>do not build all of it at once. start with the folder structure and the <code>CLAUDE.md</code>. add the rest as you actually feel the pain they solve.</p>
<hr>
<h2 id="what-changed">What changed</h2>
<p>before: open the right repo in Xcode, find the right Notion page, check Slack for where i left off, re-explain the codebase to Claude, watch the first 30% of my context window fill with boilerplate before writing a single line of actual code.</p>
<p>after: one terminal, one browser tab, one Claude session. the Command Center has the state of every repo, every doc, every task, every recent decision — and the cheap questions never reach the cloud.</p>
<p>the whole system is about 1,500 lines of Node.js, a handful of shell scripts, and Markdown files. no heavy dependencies, no cloud services, runs entirely offline.</p>
<p>if you are managing more than two active repos and you are constantly re-orienting your AI every session — this pattern is worth trying. you do not have to build the whole thing. start with the folder structure and a <code>CLAUDE.md</code>. that alone will change how your sessions feel.</p>
<p>the rest you will figure out as you go, shaped around whatever is actually slowing you down. that is the point.</p>
<hr>
<p><em>a note on this post — the ideas, the frustration, the architecture, the decisions are all mine. i used Claude to help structure and articulate things i already knew but was too lazy to write out properly. felt right to mention it given the whole post is about working with AI. use your tools.</em></p>
<p><em>after writing this i came across andrej karpathy&rsquo;s wiki pattern — same instinct around plain files, single source of truth, readable by humans and machines. worth looking up if this resonated.</em></p>
]]></content:encoded></item><item><title>To or not to use AI Tools - A Self Reflection</title><link>https://md.eknath.dev/posts/ai-ml/to-or-not-to-use-ai-tools/</link><pubDate>Sat, 07 Mar 2026 21:47:13 +0530</pubDate><guid>https://md.eknath.dev/posts/ai-ml/to-or-not-to-use-ai-tools/</guid><description>&lt;p>This is more of self reflection than some sort of an ai generate slop that i wish to shove it on to your face, Less than 5% of my friend circle has enough patient&amp;rsquo;s to actually read an any article let alone debate or discuss on the topics, im trying to get into that learned circle because they seems to have more clarity on topics, thankfully at work i was blessed with a friend who shared and discuess on the things he shares, i mostly defend the values/lessons/reflections shared by the articles (Thanks aditya!) One such article is the reason for this reflective thougts.&lt;/p></description><content:encoded><![CDATA[<p>This is more of self reflection than some sort of an ai generate slop that i wish to shove it on to your face, Less than 5% of my friend circle has enough patient&rsquo;s to actually read an any article let alone debate or discuss on the topics, im trying to get into that learned circle because they seems to have more clarity on topics, thankfully at work i was blessed with a friend who shared and discuess on the things he shares, i mostly defend the values/lessons/reflections shared by the articles (Thanks aditya!) One such article is the reason for this reflective thougts.</p>
<p>before we go further i humbly request you to read this article, don&rsquo;t stop reading it after the first few paragraph(Again, Thanks Aditya), keep reading till the end there are twists and turns so please try to read it and get back here on this reflection journey.</p>
<p>Recently, a colleague shared an article with me titled <a href="https://www.scottsmitelli.com/articles/you-dont-have-to/">&ldquo;You Don&rsquo;t Have To&rdquo;</a> by Scott Smitelli. I highly recommend reading it. It really makes you think about how we might slowly be losing our edge due to the heavy use of Large Language Models (LLMs), like how i stoped memorizing phone numbers coz its available on my phone book except mine ;0 and find it hard to calculate in head with large numbers continuesly like the guy in typical village shop guy does quickly.</p>
<p>With ai there are so many techniques i still experiment with and i continiously work on. It&rsquo;s great to use AI to brainstorm, validate, or debate your thoughts, but don&rsquo;t let it run the show for you. If you do, you&rsquo;ll slowly vanish into the background.</p>
<p>Reading this article—and later debating it with my manager—sent me down a rabbit hole of self-reflection. It sparked a deep, sometimes controversial, conversation between us. Is AI destroying the art of coding? Or is it simply the next step in our evolution? After stepping back to clear my thoughts, here are my reflections on where I stand with AI tools today.</p>
<h2 id="the-zero-to-one-myth">The &ldquo;Zero to One&rdquo; Myth</h2>
<p>There&rsquo;s a romanticized idea in our industry that we are still building things &ldquo;from zero.&rdquo; The truth is, that hasn&rsquo;t been true for years. We went from machine code, to assembly, to C, to Java, and Kotlin. Today, 95% of developers rely heavily on layers of abstractions like frameworks, APIs, and libraries that they didn&rsquo;t build and often don&rsquo;t fully understand under the hood.</p>
<p>AI isn&rsquo;t some alien invasion; it is merely the newest layer of abstraction in this ongoing shift.</p>
<p>Also, AI isn&rsquo;t a &ldquo;magic button.&rdquo; Unless you are simply cloning a well-documented repository, AI cannot build a full-fledged, custom solution from start to finish with a single prompt. Real engineering still needs architecture, logic, and deep orchestration—all of which must come from a human.</p>
<h2 id="value-over-the-craft">Value over &ldquo;The Craft&rdquo;</h2>
<p>Many developers treat coding as an art form. They pride themselves on writing the perfect, zero-dependency code. But let&rsquo;s be practical: in a professional setting, we aren&rsquo;t here just to write poetry in code. We are here to solve problems, deliver value to our clients, and ultimately earn a living.</p>
<p>All I care about are the humans using the tools I build. The exact ingredients or the &ldquo;purity&rdquo; of the code doesn&rsquo;t matter nearly as much as the end-user&rsquo;s experience. Getting too caught up in digging through abstractions or coding like a purist feels unnecessary if it stands in the way of delivering a working, valuable product.</p>
<h2 id="the-danger-of-ai-slop">The Danger of &ldquo;AI Slop&rdquo;</h2>
<p>That being said, my manager raised a very valid point: the sheer ease of generating content with AI easily leads to garbage. Generative AI can produce 10x more content in a single day than humans have produced in a lifetime. When people generate and publish content without any personal input, refinement, or real intent, we get what he accurately called &ldquo;AI slop.&rdquo;</p>
<p>I agree completely. Outputting anything publicly without real personal meaning—just creating for the sake of creating without adding value—is wrong. It pollutes the internet and human conversations. The tool is only as good as the intent behind it.</p>
<h2 id="the-axe-and-the-chainsaw">The Axe and the Chainsaw</h2>
<p>Think of AI as an electric chainsaw, and traditional coding as an axe (an example from the article shared above).</p>
<p>Knowing how to use an axe remains extremely important even when a chainsaw is available. The chainsaw can break or fail. More importantly, <strong>a lumberjack who has cut down trees with an axe a thousand times knows exactly how to angle the cut so the tree falls right where he wants it to</strong>.</p>
<p>Using AI tools doesn&rsquo;t turn your brain to mush, <strong>provided</strong> you actually understand the changes it makes to your creation. Let me be real here THIS IS EXTREMLU HARD! That&rsquo;s actually why I&rsquo;m thankful for Claude&rsquo;s token limitations sometimes. It forces me to stay involved. AI shifts your role from pure execution to orchestration. You cannot outsource your JUDGEMENT, EXPERIENCE, or PERSONALITY. If you rely entirely on AI without applying these human traits, the quality of your work will drop, and you will eventually become redundant.</p>
<h2 id="an-equalizer-for-communication">An Equalizer for Communication</h2>
<p>Beyond just writing code, AI is an incredible equalizer for communication. Not everyone is a natural wordsmith. For those of us who are less vocal or struggle to find the right phrasing, AI is a tool that helps us communicate our technical intent clearly. It&rsquo;s not about faking a voice; it&rsquo;s about polishing it. It helps take the raw intent inside my head and words it rightly for the world to understand, let me say its not easy to get it the way we have in mind there are limitations like token limit, it tries to end it very quickly by saying the crux of things or to draggy but never, or almost never the right proprotion.</p>
<h2 id="wielding-the-future">Wielding the Future</h2>
<p>My philosophy in this rapidly changing landscape is simple:</p>
<ul>
<li>When we only had machine code, we coded in assembly.</li>
<li>When we got high-level languages like Java and Kotlin, we used them.</li>
<li>Now we have AI, and we should use it extensively.</li>
<li>If AI becomes inaccessible or too expensive tomorrow, we simply go back to coding in Kotlin. We should be prepared for that.</li>
</ul>
<p>To make sure I&rsquo;m prepared, I&rsquo;ve actually started &ldquo;AI fasting.&rdquo; As silly as it might sound, taking a break from AI helps me make sure I can still build or think differently without these tools. I&rsquo;m not sure how every employer feels about this, but for me, spending three days coding without AI is a healthy practice. If feature demands increase, I might have to tweak this schedule, but I try not to be too rigid about it, so far looks like we are going all in this new era.</p>
<p>Recently, I was scrolling through Instagram and saw a reel where a developer made a great point. He said: &ldquo;Before AI, you delivered a project in a week. Now, even with AI, it still takes a week—why is that?&rdquo; His answer was that while AI generates code quickly, fixing the bugs or tweeking the code it creates and also reviewing it has become extremely harder.</p>
<p>That really stood out to me. I still have some lingering doubts about all of this, but what matters most is finding the right balance,keeping it away is not going to help me, im going to embrance it tight find its strenth and weekness and use it to my advantage.</p>
<p>I don&rsquo;t wish to nitpick on philosophies people have, that have no real meaning to the end user. Coding like a &ldquo;caveman&rdquo; shouldn&rsquo;t be a badge of honor. Utilizing tools like MCP, plugins, and advanced prompting is how we stay forward-thinking and effective in this day and age, especially in the phase we are moving in right now.</p>
<p>Ultimately, machines should take the drudgery out of life. AI brings that promise to our doorsteps. It&rsquo;s up to us to embrace it, orchestrate it responsibly, and ensure that we are using it to add real value, rather than just contributing to the noise of confusions around.</p>
<p>I wrote this just to clear some thoughts in my head regarding the excesive ai tool usage, i myself fell into this trap of vibe working for a short period of time, i regret it coz i lost the chance to learn what happend in that part of the code, i thought skipping that was okey but that above article opens by eyes. This is also a phase of learning but don&rsquo;t ever do that on work/personal projects that you truly care, thats a big no no, Blinde Vibecoding is okey for prototying some personal productivity tools, features and such silly thing never on any real product that you truely care.</p>
]]></content:encoded></item><item><title>Visualizing Ideas with Claude: Setting Up the Official Draw.io MCP Server</title><link>https://md.eknath.dev/posts/ai-ml/drawio-mcp-server-setup/</link><pubDate>Tue, 17 Feb 2026 12:00:00 +0530</pubDate><guid>https://md.eknath.dev/posts/ai-ml/drawio-mcp-server-setup/</guid><description>&lt;h2 id="tldr---quick-setup">TL;DR - Quick Setup&lt;/h2>
&lt;p>Want to generate diagrams directly in Claude? Here is the fast track configuration for your &lt;code>claude_desktop_config.json&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-json" data-lang="json">&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;mcpServers&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;drawio&amp;#34;&lt;/span>: {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;command&amp;#34;&lt;/span>: &lt;span style="color:#e6db74">&amp;#34;npx&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#f92672">&amp;#34;args&amp;#34;&lt;/span>: [
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;-y&amp;#34;&lt;/span>,
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#e6db74">&amp;#34;@drawio/mcp&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ]
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Restart Claude Desktop, and then ask: &lt;em>&amp;ldquo;Create a flowchart for a user login system.&amp;rdquo;&lt;/em>&lt;/p>
&lt;hr>
&lt;h2 id="why-drawio-with-claude">Why Draw.io with Claude?&lt;/h2>
&lt;p>If you are like me, explaining architecture or complex flows in text can get wordy and confusing. &amp;ldquo;Component A talks to B, which then signals C&amp;hellip;&amp;rdquo; is much harder to parse than a simple arrow connecting boxes.&lt;/p></description><content:encoded><![CDATA[<h2 id="tldr---quick-setup">TL;DR - Quick Setup</h2>
<p>Want to generate diagrams directly in Claude? Here is the fast track configuration for your <code>claude_desktop_config.json</code>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;mcpServers&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;drawio&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;npx&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;-y&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;@drawio/mcp&#34;</span>
</span></span><span style="display:flex;"><span>      ]
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Restart Claude Desktop, and then ask: <em>&ldquo;Create a flowchart for a user login system.&rdquo;</em></p>
<hr>
<h2 id="why-drawio-with-claude">Why Draw.io with Claude?</h2>
<p>If you are like me, explaining architecture or complex flows in text can get wordy and confusing. &ldquo;Component A talks to B, which then signals C&hellip;&rdquo; is much harder to parse than a simple arrow connecting boxes.</p>
<p>The <strong>Official Draw.io MCP Server</strong> (<code>@drawio/mcp</code>) bridges this gap. It allows Claude to:</p>
<ol>
<li><strong>Generate Diagrams</strong>: Create flowcharts, sequence diagrams, and system architectures from scratch.</li>
<li><strong>Edit Existing Diagrams</strong>: Update diagrams based on new requirements.</li>
<li><strong>Render Visuals</strong>: See the diagram directly in the chat interface (depending on the client support).</li>
</ol>
<p>This is a game-changer for documentation, brainstorming, and technical specs.</p>
<hr>
<h2 id="prerequisites">Prerequisites</h2>
<p>Before we start, ensure you have the following:</p>
<ul>
<li><strong>Claude Desktop App</strong>: Installed on your Mac or Linux machine.</li>
<li><strong>Node.js</strong>: Version 18 or higher.
<ul>
<li>Check your version: <code>node -v</code></li>
<li>If missing, I recommend using <code>nvm</code> (Node Version Manager) to install it.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="step-by-step-setup-guide">Step-by-Step Setup Guide</h2>
<h3 id="1-locate-configuration-file">1. Locate Configuration File</h3>
<p>You need to edit the highly specific <code>claude_desktop_config.json</code> file.</p>
<p><strong>On macOS:</strong>
Open your terminal and run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>code ~/Library/Application<span style="color:#ae81ff">\ </span>Support/Claude/claude_desktop_config.json
</span></span></code></pre></div><p><em>(Or use <code>nano</code>, <code>vim</code>, or <code>open -e</code> if you don&rsquo;t use VS Code)</em></p>
<p><strong>On Linux:</strong>
The file is typically located at:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>~/.config/Claude/claude_desktop_config.json
</span></span></code></pre></div><h3 id="2-add-the-drawio-server">2. Add the Draw.io Server</h3>
<p>Add the following entry to the <code>mcpServers</code> object in your config file. If the file is empty, wrap it in curly braces.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span>{
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;mcpServers&#34;</span>: {
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&#34;drawio&#34;</span>: {
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;npx&#34;</span>,
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&#34;args&#34;</span>: [
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;-y&#34;</span>,
</span></span><span style="display:flex;"><span>        <span style="color:#e6db74">&#34;@drawio/mcp&#34;</span>
</span></span><span style="display:flex;"><span>      ]
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p><strong>What is this doing?</strong></p>
<ul>
<li>It tells Claude to run the <code>npx</code> command.</li>
<li>The <code>-y</code> flag automatically creates the environment without prompting.</li>
<li><code>@drawio/mcp</code> is the official package containing the server logic.</li>
</ul>
<h3 id="3-restart-claude">3. Restart Claude</h3>
<p>For the changes to take effect:</p>
<ol>
<li>Close the Claude Desktop interface completely.</li>
<li>Re-open it.</li>
</ol>
<p>You should see a generic &ldquo;MCP&rdquo; icon or indicator (depending on your version) showing that tools are loaded.</p>
<hr>
<h2 id="alternative-setup-with-claude-code-cli">Alternative: Setup with Claude Code CLI</h2>
<p>If you prefer using the <strong>Claude Code CLI</strong> (command line interface) instead of the Desktop app, you can add the server directly using the <code>claude mcp add</code> command.</p>
<p>This is particularly useful if you want to scope the tool to a specific project or your user account without editing JSON files manually.</p>
<h3 id="one-line-setup">One-Line Setup</h3>
<p>Run this command in your terminal:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>claude mcp add drawio --scope user -- npx -y @drawio/mcp
</span></span></code></pre></div><p><strong>Breakdown of the command:</strong></p>
<ul>
<li><code>claude mcp add drawio</code>: Tells Claude to add a new MCP server named &ldquo;drawio&rdquo;.</li>
<li><code>--scope user</code>: Installs it globally for your user account (use <code>--scope project</code> to install for the current folder only).</li>
<li><code>--</code>: Separator indicating the start of the actual server command.</li>
<li><code>npx -y @drawio/mcp</code>: The command to run the Draw.io server.</li>
</ul>
<p>Once added, you can verify it with:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>claude mcp list
</span></span></code></pre></div><hr>
<h2 id="how-to-use-it">How to Use It</h2>
<p>Once connected, you can converse with Claude naturally about diagrams.</p>
<h3 id="creating-a-new-diagram">Creating a New Diagram</h3>
<p><strong>Prompt:</strong></p>
<blockquote>
<p>&ldquo;Create a sequence diagram for an OAuth 2.0 authentication flow involving a User, Client App, Authorization Server, and Resource Server.&rdquo;</p>
</blockquote>
<p>Claude will generate the XML or specific format required for Draw.io and often provide a link or a rendered view.</p>
<h3 id="editing-a-diagram">Editing a Diagram</h3>
<p>If you have a diagram file (e.g., XML) in your project context, you can ask Claude to modify it.</p>
<p><strong>Prompt:</strong></p>
<blockquote>
<p>&ldquo;Update the attached architecture diagram to include a Redis cache layer between the API and the Database.&rdquo;</p>
</blockquote>
<h3 id="complex-visualizations">Complex Visualizations</h3>
<p>You aren&rsquo;t limited to simple boxes. You can ask for:</p>
<ul>
<li><strong>Mind Maps</strong>: &ldquo;Create a mind map for a marketing strategy.&rdquo;</li>
<li><strong>ER Diagrams</strong>: &ldquo;Generate an Entity-Relationship diagram for an e-commerce database schema.&rdquo;</li>
<li><strong>Network Topologies</strong>: &ldquo;Draw a high-availability AWS network setup with public and private subnets.&rdquo;</li>
</ul>
<hr>
<h2 id="troubleshooting">Troubleshooting</h2>
<h3 id="command-not-found-npx">&ldquo;Command not found: npx&rdquo;</h3>
<p>If Claude complains it can&rsquo;t find <code>npx</code>, you might need to provide the absolute path.</p>
<ol>
<li>Run <code>which npx</code> in your terminal. (e.g., <code>/usr/local/bin/npx</code>)</li>
<li>Update your config:
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-json" data-lang="json"><span style="display:flex;"><span><span style="color:#e6db74">&#34;drawio&#34;</span><span style="color:#960050;background-color:#1e0010">:</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;command&#34;</span>: <span style="color:#e6db74">&#34;/usr/local/bin/npx&#34;</span>,
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&#34;args&#34;</span>: [<span style="color:#e6db74">&#34;-y&#34;</span>, <span style="color:#e6db74">&#34;@drawio/mcp&#34;</span>]
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div></li>
</ol>
<h3 id="server-error--disconnection">Server Error / Disconnection</h3>
<p>If the server crashes, check your Node.js version. The Draw.io MCP server requires a modern Node environment. Ensure <code>node -v</code> returns <code>v18.x.x</code> or newer.</p>
<hr>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://github.com/jgraph/drawio-mcp">Official Draw.io MCP GitHub Repository</a></li>
<li><a href="https://modelcontextprotocol.io">Model Context Protocol Documentation</a></li>
<li><a href="https://www.draw.io">Draw.io Website</a></li>
</ul>
]]></content:encoded></item><item><title>Supercharging Claude Code with Serena - Save 70% on Tokens</title><link>https://md.eknath.dev/posts/ai-ml/serena-claude-code-setup/</link><pubDate>Wed, 04 Feb 2026 10:00:00 +0530</pubDate><guid>https://md.eknath.dev/posts/ai-ml/serena-claude-code-setup/</guid><description>&lt;h2 id="tldr---quick-setup">TL;DR - Quick Setup&lt;/h2>
&lt;p>Already know what Serena is? Here&amp;rsquo;s the fast track:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 1. Install uv and Serena&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>curl -LsSf https://astral.sh/uv/install.sh | sh
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>source ~/.zshrc
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>uv tool install git+https://github.com/oraios/serena
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 2. Restart terminal, then connect to your project&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cd /path/to/your/project
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>claude mcp add serena -- serena-mcp-server --project &lt;span style="color:#66d9ef">$(&lt;/span>pwd&lt;span style="color:#66d9ef">)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>echo &lt;span style="color:#e6db74">&amp;#34;.serena/&amp;#34;&lt;/span> &amp;gt;&amp;gt; .gitignore
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e"># 3. Start Claude&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>claude --allowedTools &lt;span style="color:#e6db74">&amp;#34;mcp__serena*&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Then tell Claude: &lt;em>&amp;ldquo;Use Serena to onboard this project.&amp;rdquo;&lt;/em>&lt;/p>
&lt;p>Want to understand what this does and why? Read on.&lt;/p></description><content:encoded><![CDATA[<h2 id="tldr---quick-setup">TL;DR - Quick Setup</h2>
<p>Already know what Serena is? Here&rsquo;s the fast track:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># 1. Install uv and Serena</span>
</span></span><span style="display:flex;"><span>curl -LsSf https://astral.sh/uv/install.sh | sh
</span></span><span style="display:flex;"><span>source ~/.zshrc
</span></span><span style="display:flex;"><span>uv tool install git+https://github.com/oraios/serena
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 2. Restart terminal, then connect to your project</span>
</span></span><span style="display:flex;"><span>cd /path/to/your/project
</span></span><span style="display:flex;"><span>claude mcp add serena -- serena-mcp-server --project <span style="color:#66d9ef">$(</span>pwd<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;.serena/&#34;</span> &gt;&gt; .gitignore
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># 3. Start Claude</span>
</span></span><span style="display:flex;"><span>claude --allowedTools <span style="color:#e6db74">&#34;mcp__serena*&#34;</span>
</span></span></code></pre></div><p>Then tell Claude: <em>&ldquo;Use Serena to onboard this project.&rdquo;</em></p>
<p>Want to understand what this does and why? Read on.</p>
<hr>
<h2 id="a-quick-note">A Quick Note</h2>
<p>This is a continuation of my <a href="https://md.eknath.dev/posts/ai-ml/claude-code-notes/">Claude Code notes</a>. If you haven&rsquo;t read that yet, I recommend starting there for the fundamentals. This article focuses on a specific optimization that has dramatically improved my Claude Code experience.</p>
<p><strong>What you&rsquo;ll learn:</strong></p>
<ul>
<li>Why Claude Code can get expensive on large codebases</li>
<li>How Serena uses LSP to provide semantic code navigation</li>
<li>Step-by-step setup (takes ~5 minutes)</li>
<li>Practical usage patterns and prompts</li>
<li>When to use Serena vs. vanilla Claude Code</li>
</ul>
<hr>
<h2 id="the-problem-token-costs-add-up-fast">The Problem: Token Costs Add Up Fast</h2>
<p>If you&rsquo;ve been using Claude Code for a while, you&rsquo;ve probably noticed that <strong>token costs can spiral quickly</strong> - especially on large codebases. Here&rsquo;s why:</p>
<p>When you ask Claude something like <em>&ldquo;Where is the authentication logic?&rdquo;</em>, it often:</p>
<ol>
<li>Reads entire files to understand context</li>
<li>Scans through multiple modules looking for patterns</li>
<li>Sometimes re-reads files it already looked at</li>
</ol>
<p>For a medium-sized project (50k+ lines of code), a single exploration session can consume <strong>thousands of tokens</strong> just reading files. Multiply that across a day&rsquo;s work, and you&rsquo;re looking at serious costs.</p>
<p>Worse, when the context window fills up, Claude can start <strong>hallucinating</strong> - referencing functions that don&rsquo;t exist or suggesting patterns that don&rsquo;t match your codebase.</p>
<hr>
<h2 id="enter-serena-semantic-code-navigation">Enter Serena: Semantic Code Navigation</h2>
<p><strong>Serena</strong> is an open-source MCP (Model Context Protocol) server that gives Claude Code <strong>semantic understanding</strong> of your codebase. Instead of reading entire files, Claude can now:</p>
<ul>
<li><strong>Jump directly to function definitions</strong></li>
<li><strong>Find all usages of a class or method</strong></li>
<li><strong>Navigate imports and dependencies</strong></li>
<li><strong>Understand type hierarchies</strong></li>
</ul>
<p>It does this by leveraging <strong>LSP (Language Server Protocol)</strong> - the same technology that powers your IDE&rsquo;s &ldquo;Go to Definition&rdquo; and &ldquo;Find All References&rdquo; features.</p>
<h3 id="the-results">The Results?</h3>
<p>In my testing on a ~100k line Android/KMP project:</p>
<table>
  <thead>
      <tr>
          <th>Metric</th>
          <th>Without Serena</th>
          <th>With Serena</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Tokens for &ldquo;Find auth logic&rdquo;</td>
          <td>~15,000</td>
          <td>~4,500</td>
      </tr>
      <tr>
          <td>Context preservation</td>
          <td>Poor</td>
          <td>Excellent</td>
      </tr>
      <tr>
          <td>Navigation accuracy</td>
          <td>File-based guessing</td>
          <td>Semantic precision</td>
      </tr>
      <tr>
          <td>Estimated cost savings</td>
          <td>Baseline</td>
          <td><strong>~70%</strong></td>
      </tr>
  </tbody>
</table>
<p>That 70% isn&rsquo;t marketing fluff - it&rsquo;s real savings from not reading entire files when you only need specific symbols.</p>
<hr>
<h2 id="how-serena-works-under-the-hood">How Serena Works Under the Hood</h2>
<p>MCP servers extend Claude&rsquo;s capabilities through a standardized protocol (see <a href="#mcp-model-context-protocol">Glossary</a> if this is new to you). Serena specifically provides:</p>
<ol>
<li>
<p><strong>Code Indexing</strong>: When you connect Serena to Claude, it automatically builds an index of your codebase&rsquo;s symbols, types, and relationships.</p>
</li>
<li>
<p><strong>LSP Integration</strong>: Serena wraps language servers (for Kotlin, TypeScript, Python, etc.) to provide semantic navigation.</p>
</li>
<li>
<p><strong>Smart Querying</strong>: When Claude asks &ldquo;Where is <code>UserRepository</code>?&rdquo;, Serena returns the exact file and line number - not a file dump.</p>
</li>
<li>
<p><strong>Live Updates</strong>: The index updates as you modify code, staying in sync with your project.</p>
</li>
</ol>
<pre tabindex="0"><code>┌─────────────────┐      MCP Protocol      ┌─────────────────┐
│   Claude Code   │ ◄──────────────────────► │     Serena      │
│    (Client)     │                          │   (MCP Server)  │
└─────────────────┘                          └────────┬────────┘
                                                      │
                                                      │ LSP
                                                      ▼
                                             ┌─────────────────┐
                                             │  Language Server │
                                             │  (kotlin-ls,    │
                                             │   tsserver, etc) │
                                             └─────────────────┘
</code></pre><hr>
<h2 id="one-time-setup">One-Time Setup</h2>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>Claude Code CLI installed (<a href="https://md.eknath.dev/posts/ai-ml/claude-code-notes/">see my setup guide</a>)</li>
<li>A supported project (Kotlin, TypeScript, Python, Go, Rust, and more)</li>
</ul>
<h3 id="step-1-install-uv-package-manager">Step 1: Install <code>uv</code> Package Manager</h3>
<p>Serena uses <code>uv</code> for installation. If you don&rsquo;t have it:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># macOS/Linux</span>
</span></span><span style="display:flex;"><span>curl -LsSf https://astral.sh/uv/install.sh | sh
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Reload your shell</span>
</span></span><span style="display:flex;"><span>source ~/.zshrc  <span style="color:#75715e"># or ~/.bashrc</span>
</span></span></code></pre></div><p>Why <code>uv</code>? It&rsquo;s a fast Python package manager that handles Serena&rsquo;s dependencies cleanly.</p>
<h3 id="step-2-install-serena-tools">Step 2: Install Serena Tools</h3>
<p>Install the CLI tools globally:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>uv tool install git+https://github.com/oraios/serena
</span></span></code></pre></div><p>This gives you two commands:</p>
<ul>
<li><code>serena</code> - Project management CLI</li>
<li><code>serena-mcp-server</code> - The MCP server that Claude connects to</li>
</ul>
<h3 id="step-3-restart-your-terminal">Step 3: Restart Your Terminal</h3>
<blockquote>
<p><strong>Important</strong>: After installing <code>uv</code> and Serena, <strong>close all terminal windows and open a fresh one</strong>. This ensures your shell recognizes the new commands.</p>
</blockquote>
<p>I spent time debugging &ldquo;command not found&rdquo; errors only to realize a terminal restart fixed everything. Save yourself the frustration.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Close all terminals, then open a new one and verify</span>
</span></span><span style="display:flex;"><span>which serena
</span></span><span style="display:flex;"><span>which serena-mcp-server
</span></span></code></pre></div><p>Both should return valid paths. If not, try running <code>source ~/.zshrc</code> (or <code>~/.bashrc</code>).</p>
<h3 id="step-4-connect-serena-to-claude-code">Step 4: Connect Serena to Claude Code</h3>
<p>Navigate to your project root and register Serena as an MCP server:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cd /path/to/your/project
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Add the server (this also initializes the project index automatically)</span>
</span></span><span style="display:flex;"><span>claude mcp add serena -- serena-mcp-server --project <span style="color:#66d9ef">$(</span>pwd<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><p><strong>What this does:</strong></p>
<ul>
<li>Registers Serena as an MCP server for Claude</li>
<li>Auto-initializes the project index (creates <code>.serena/</code> folder)</li>
<li>Scans your codebase for symbols, types, and relationships</li>
</ul>
<p><strong>Initial indexing time</strong> depends on project size:</p>
<table>
  <thead>
      <tr>
          <th>Project Size</th>
          <th>Approximate Time</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Small (&lt; 10k lines)</td>
          <td>10-30 seconds</td>
      </tr>
      <tr>
          <td>Medium (10k-50k lines)</td>
          <td>1-3 minutes</td>
      </tr>
      <tr>
          <td>Large (50k-200k lines)</td>
          <td>3-10 minutes</td>
      </tr>
      <tr>
          <td>Very Large (200k+ lines)</td>
          <td>10-20 minutes</td>
      </tr>
  </tbody>
</table>
<p>You can monitor progress at <code>http://localhost:24282</code> during indexing.</p>
<blockquote>
<p><strong>Important</strong>: Add <code>.serena/</code> to your <code>.gitignore</code>. This folder is local cache and shouldn&rsquo;t be committed.</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>echo <span style="color:#e6db74">&#34;.serena/&#34;</span> &gt;&gt; .gitignore
</span></span></code></pre></div><p>Verify it&rsquo;s connected:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Check MCP server status</span>
</span></span><span style="display:flex;"><span>claude mcp list
</span></span></code></pre></div><p>You should see <code>serena</code> in the list with a green status.</p>
<hr>
<h2 id="handling-permission-prompts">Handling Permission Prompts</h2>
<p>When you start using Serena with Claude Code, you&rsquo;ll encounter <strong>multiple permission prompts</strong>. Claude asks for approval each time Serena wants to:</p>
<ul>
<li>Read files</li>
<li>Navigate to definitions</li>
<li>Search for symbols</li>
<li>Access the index</li>
</ul>
<p>This is good for security, but can get tedious during intensive coding sessions.</p>
<h3 id="option-1-approve-permissions-individually-recommended-for-learning">Option 1: Approve Permissions Individually (Recommended for Learning)</h3>
<p>When starting out, approve each permission manually. This helps you understand what Serena is doing and builds trust in the tool.</p>
<h3 id="option-2-auto-accept-permissions-for-serena">Option 2: Auto-Accept Permissions for Serena</h3>
<p>If you trust Serena and want a smoother experience, you can configure Claude to auto-accept its tool calls:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start Claude with auto-accept for the current session</span>
</span></span><span style="display:flex;"><span>claude --allowedTools <span style="color:#e6db74">&#34;mcp__serena*&#34;</span>
</span></span></code></pre></div><p>This allows all Serena MCP tools without prompting, while still prompting for other potentially dangerous operations.</p>
<h3 id="option-3-dangerously-skip-all-permissions-use-with-caution">Option 3: Dangerously Skip All Permissions (Use with Caution)</h3>
<p>For experienced users who understand the risks:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Skip ALL permission prompts (not just Serena)</span>
</span></span><span style="display:flex;"><span>claude --dangerously-skip-permissions
</span></span></code></pre></div><blockquote>
<p><strong>Warning</strong>: This flag bypasses ALL safety prompts - file writes, shell commands, everything. Only use this if:</p>
<ul>
<li>You&rsquo;re on a development machine (not production)</li>
<li>You understand Claude can modify/delete files without asking</li>
<li>You&rsquo;re working in a git-tracked project (easy to revert mistakes)</li>
<li>You trust your judgment to review changes before committing</li>
</ul>
</blockquote>
<p>For most users, Option 2 (<code>--allowedTools &quot;mcp__serena*&quot;</code>) is the sweet spot - smooth Serena experience while keeping other safeguards in place.</p>
<hr>
<h2 id="using-serena-with-claude-code">Using Serena with Claude Code</h2>
<h3 id="starting-a-session">Starting a Session</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Navigate to your project</span>
</span></span><span style="display:flex;"><span>cd /path/to/your/project
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Start Claude with Serena connected</span>
</span></span><span style="display:flex;"><span>claude
</span></span></code></pre></div><h3 id="onboarding-claude-to-your-project">Onboarding Claude to Your Project</h3>
<p>The first time you use Serena on a project, run this prompt:</p>
<pre tabindex="0"><code>Use Serena to onboard this project. Understand the architecture,
main modules, and key entry points.
</code></pre><p>Claude will use Serena&rsquo;s semantic capabilities to build a mental model of your codebase - without reading every file.</p>
<h3 id="practical-examples">Practical Examples</h3>
<p><strong>Finding specific implementations:</strong></p>
<pre tabindex="0"><code>Where is the UserRepository interface implemented?
</code></pre><p>Without Serena: Claude reads multiple files guessing where implementations might be.
With Serena: Claude jumps directly to the concrete class.</p>
<p><strong>Understanding call hierarchies:</strong></p>
<pre tabindex="0"><code>What functions call the `syncUserData()` method?
</code></pre><p>Serena traces all callers semantically, giving Claude precise context.</p>
<p><strong>Navigating multi-module projects:</strong></p>
<pre tabindex="0"><code>How does the :feature:auth module communicate with :core:network?
</code></pre><p>Serena understands module boundaries and can trace cross-module dependencies.</p>
<hr>
<h2 id="monitoring-and-debugging">Monitoring and Debugging</h2>
<h3 id="live-dashboard">Live Dashboard</h3>
<p>Serena provides a local web dashboard for monitoring and debugging:</p>
<pre tabindex="0"><code>http://localhost:24282
</code></pre><p>Open this URL in your browser while Serena is running. You&rsquo;ll see:</p>
<p><strong>Index Status Panel</strong></p>
<ul>
<li>Total symbols indexed (classes, functions, variables)</li>
<li>Indexing progress percentage</li>
<li>Last index update timestamp</li>
<li>Any indexing errors or warnings</li>
</ul>
<p><strong>Query Logs</strong></p>
<ul>
<li>Real-time log of Claude&rsquo;s queries to Serena</li>
<li>Which symbols were requested</li>
<li>Response times for each query</li>
<li>Helps you understand what Claude is &ldquo;thinking&rdquo;</li>
</ul>
<p><strong>Language Server Status</strong></p>
<ul>
<li>Connected language servers (kotlin-ls, tsserver, etc.)</li>
<li>Server health and memory usage</li>
<li>Restart buttons if a server becomes unresponsive</li>
</ul>
<p><strong>Cache Statistics</strong></p>
<ul>
<li>Hit/miss ratios</li>
<li>Memory usage</li>
<li>Option to clear cache if things get stale</li>
</ul>
<blockquote>
<p><strong>Tip</strong>: Keep the dashboard open in a browser tab during intensive coding sessions. If Claude seems confused or slow, check the dashboard - you might spot a language server that crashed or an indexing error.</p>
</blockquote>
<h3 id="serena-tools-available-to-claude">Serena Tools Available to Claude</h3>
<p>When connected, Claude gains access to these MCP tools (you can see these with <code>claude mcp list</code>):</p>
<table>
  <thead>
      <tr>
          <th>Tool</th>
          <th>Purpose</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>serena_get_definition</code></td>
          <td>Jump to where a symbol is defined</td>
      </tr>
      <tr>
          <td><code>serena_get_references</code></td>
          <td>Find all usages of a symbol</td>
      </tr>
      <tr>
          <td><code>serena_get_symbols</code></td>
          <td>List all symbols in a file</td>
      </tr>
      <tr>
          <td><code>serena_search_symbols</code></td>
          <td>Search for symbols by name pattern</td>
      </tr>
      <tr>
          <td><code>serena_get_hover</code></td>
          <td>Get type info and documentation</td>
      </tr>
      <tr>
          <td><code>serena_get_diagnostics</code></td>
          <td>Get compiler errors/warnings</td>
      </tr>
  </tbody>
</table>
<p>Claude automatically chooses the right tool based on your question.</p>
<h3 id="troubleshooting-common-issues">Troubleshooting Common Issues</h3>
<p><strong>&ldquo;command not found: serena&rdquo; after installation:</strong></p>
<p>This is the most common issue. Your terminal doesn&rsquo;t know about the new commands yet.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Option 1: Reload shell config</span>
</span></span><span style="display:flex;"><span>source ~/.zshrc  <span style="color:#75715e"># or ~/.bashrc</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Option 2 (recommended): Close ALL terminal windows and open a fresh one</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># This ensures a clean shell environment</span>
</span></span></code></pre></div><p><strong>&ldquo;1 MCP server failed&rdquo; error:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Remove and re-add the server</span>
</span></span><span style="display:flex;"><span>claude mcp remove serena
</span></span><span style="display:flex;"><span>claude mcp add serena -- serena-mcp-server --project <span style="color:#66d9ef">$(</span>pwd<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><p><strong>Index out of sync:</strong></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Rebuild the index</span>
</span></span><span style="display:flex;"><span>serena project update --name &lt;your-project-name&gt;
</span></span></code></pre></div><p><strong>Server not starting:</strong></p>
<p>Make sure you&rsquo;re in the correct project root where you ran the <code>claude mcp add</code> command.</p>
<p><strong>Language not supported:</strong></p>
<p>Check <a href="https://github.com/oraios/serena#supported-languages">Serena&rsquo;s supported languages</a>. For Android/KMP projects, Kotlin support works out of the box.</p>
<hr>
<h2 id="tip-simplify-with-aliases">Tip: Simplify with Aliases</h2>
<p>These Serena commands are verbose. If you find yourself typing them often, consider setting up shell aliases or using a tool like <a href="https://github.com/Eganathan/aliasly">Aliasly</a> to manage shortcuts across projects.</p>
<hr>
<h2 id="best-practices">Best Practices</h2>
<h3 id="1-keep-your-index-updated">1. Keep Your Index Updated</h3>
<p>After major refactors or pulling new changes:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>serena project update --name &lt;your-project-name&gt;
</span></span></code></pre></div><h3 id="2-use-specific-queries">2. Use Specific Queries</h3>
<p>Instead of:</p>
<pre tabindex="0"><code>How does authentication work?
</code></pre><p>Try:</p>
<pre tabindex="0"><code>Show me the AuthViewModel and its dependencies using Serena.
</code></pre><p>The more specific your query, the better Serena can target the exact symbols.</p>
<h3 id="3-combine-with-claudemd">3. Combine with CLAUDE.md</h3>
<p>Your <code>CLAUDE.md</code> file complements Serena perfectly. Use CLAUDE.md for:</p>
<ul>
<li>Project conventions and coding standards</li>
<li>Build commands and configuration</li>
<li>Architecture overview</li>
</ul>
<p>Use Serena for:</p>
<ul>
<li>Navigating actual code</li>
<li>Finding implementations</li>
<li>Tracing dependencies</li>
</ul>
<h3 id="4-monitor-your-savings">4. Monitor Your Savings</h3>
<p>Use <code>/cost</code> in Claude Code to track your token usage. Compare sessions before and after Serena to see the actual savings.</p>
<hr>
<h2 id="comparison-claude-code-vs-claude-code--serena">Comparison: Claude Code vs. Claude Code + Serena</h2>
<table>
  <thead>
      <tr>
          <th>Feature</th>
          <th>Without Serena</th>
          <th>With Serena</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Search Method</strong></td>
          <td>Text-based / Full file reads</td>
          <td>Symbolic / LSP-powered</td>
      </tr>
      <tr>
          <td><strong>Code Retrieval</strong></td>
          <td>Reads entire files</td>
          <td>Extracts specific symbols/blocks</td>
      </tr>
      <tr>
          <td><strong>Token Usage</strong></td>
          <td>High (linear to file size)</td>
          <td>Low (targeted retrieval)</td>
      </tr>
      <tr>
          <td><strong>Memory</strong></td>
          <td>Session-based only</td>
          <td>Persistent project indexing</td>
      </tr>
      <tr>
          <td><strong>Navigation</strong></td>
          <td>File path guessing</td>
          <td>Precise &ldquo;Go to Definition&rdquo;</td>
      </tr>
      <tr>
          <td><strong>Cross-references</strong></td>
          <td>Manual grep patterns</td>
          <td>Semantic &ldquo;Find All References&rdquo;</td>
      </tr>
      <tr>
          <td><strong>Type Understanding</strong></td>
          <td>Inferred from context</td>
          <td>Actual type hierarchy from LSP</td>
      </tr>
      <tr>
          <td><strong>Multi-module Support</strong></td>
          <td>Reads each module separately</td>
          <td>Understands module relationships</td>
      </tr>
      <tr>
          <td><strong>Context Preservation</strong></td>
          <td>Fills up quickly</td>
          <td>Stays efficient longer</td>
      </tr>
      <tr>
          <td><strong>Setup Required</strong></td>
          <td>None</td>
          <td>One-time (~5 min)</td>
      </tr>
      <tr>
          <td><strong>Token Efficiency</strong></td>
          <td>Baseline</td>
          <td><strong>~70% reduction</strong></td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="supported-languages">Supported Languages</h2>
<p>Serena works with any language that has LSP support. Here&rsquo;s the current status:</p>
<table>
  <thead>
      <tr>
          <th>Language</th>
          <th>Support Level</th>
          <th>Language Server</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Kotlin</strong></td>
          <td>Excellent</td>
          <td>kotlin-language-server</td>
      </tr>
      <tr>
          <td><strong>TypeScript/JavaScript</strong></td>
          <td>Excellent</td>
          <td>tsserver</td>
      </tr>
      <tr>
          <td><strong>Python</strong></td>
          <td>Excellent</td>
          <td>pylsp / pyright</td>
      </tr>
      <tr>
          <td><strong>Go</strong></td>
          <td>Excellent</td>
          <td>gopls</td>
      </tr>
      <tr>
          <td><strong>Rust</strong></td>
          <td>Excellent</td>
          <td>rust-analyzer</td>
      </tr>
      <tr>
          <td><strong>Java</strong></td>
          <td>Good</td>
          <td>eclipse.jdt.ls</td>
      </tr>
      <tr>
          <td><strong>C/C++</strong></td>
          <td>Good</td>
          <td>clangd</td>
      </tr>
      <tr>
          <td><strong>Swift</strong></td>
          <td>Experimental</td>
          <td>sourcekit-lsp</td>
      </tr>
  </tbody>
</table>
<p>For <strong>Android/KMP projects</strong>, Kotlin support is what matters most - and it works great.</p>
<blockquote>
<p><strong>Note</strong>: Serena auto-detects your project&rsquo;s languages and starts the appropriate language servers. You don&rsquo;t need to configure this manually.</p>
</blockquote>
<hr>
<h2 id="updating-and-managing-serena">Updating and Managing Serena</h2>
<h3 id="update-serena-to-latest-version">Update Serena to Latest Version</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>uv tool upgrade serena
</span></span></code></pre></div><h3 id="rebuild-project-index">Rebuild Project Index</h3>
<p>After major refactors, dependency updates, or pulling large changes:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>serena project update --name &lt;your-project-name&gt;
</span></span></code></pre></div><h3 id="remove-serena-from-a-project">Remove Serena from a Project</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Remove MCP server from Claude</span>
</span></span><span style="display:flex;"><span>claude mcp remove serena
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Delete the local index (optional)</span>
</span></span><span style="display:flex;"><span>rm -rf .serena/
</span></span></code></pre></div><h3 id="working-with-multiple-projects">Working with Multiple Projects</h3>
<p>Serena indexes are project-specific. To switch between projects:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Project A</span>
</span></span><span style="display:flex;"><span>cd /path/to/project-a
</span></span><span style="display:flex;"><span>claude mcp add serena -- serena-mcp-server --project <span style="color:#66d9ef">$(</span>pwd<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Project B (in a different terminal/session)</span>
</span></span><span style="display:flex;"><span>cd /path/to/project-b
</span></span><span style="display:flex;"><span>claude mcp add serena -- serena-mcp-server --project <span style="color:#66d9ef">$(</span>pwd<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><p>Each project maintains its own <code>.serena/</code> index.</p>
<hr>
<h2 id="when-not-to-use-serena">When NOT to Use Serena</h2>
<p>Serena isn&rsquo;t always the best choice:</p>
<ul>
<li><strong>Small scripts or single-file projects</strong>: The overhead of indexing doesn&rsquo;t pay off</li>
<li><strong>Heavily dynamic languages</strong>: LSP works best with typed languages</li>
<li><strong>Quick one-off questions</strong>: Sometimes just asking Claude directly is faster</li>
<li><strong>Non-code tasks</strong>: Documentation, git operations, etc. don&rsquo;t benefit from Serena</li>
</ul>
<p>Use judgment - Serena is a tool for <strong>navigating complex codebases</strong>, not a universal solution.</p>
<hr>
<h2 id="integration-with-my-workflow">Integration with My Workflow</h2>
<p>Here&rsquo;s how Serena fits into my daily Claude Code usage:</p>
<ol>
<li>
<p><strong>Morning context building</strong>: &ldquo;Use Serena to show me what I worked on yesterday in the :feature:dashboard module&rdquo;</p>
</li>
<li>
<p><strong>Feature development</strong>: &ldquo;Using Serena, find all places where we handle network errors and show me the patterns&rdquo;</p>
</li>
<li>
<p><strong>Code review</strong>: &ldquo;Navigate to the UserService implementation and review it for potential issues&rdquo;</p>
</li>
<li>
<p><strong>Debugging</strong>: &ldquo;Trace all callers of <code>processPayment()</code> and identify where the null check might be failing&rdquo;</p>
</li>
<li>
<p><strong>Onboarding teammates</strong>: &ldquo;Use Serena to explain the data flow from API response to UI state&rdquo;</p>
</li>
</ol>
<hr>
<h2 id="cost-analysis">Cost Analysis</h2>
<p>Let&rsquo;s break down the real savings. With Claude Sonnet at ~$3/1M input tokens:</p>
<table>
  <thead>
      <tr>
          <th>Session Type</th>
          <th>Without Serena</th>
          <th>With Serena</th>
          <th>Savings</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Quick exploration</td>
          <td>10k tokens</td>
          <td>3k tokens</td>
          <td>$0.02</td>
      </tr>
      <tr>
          <td>Feature implementation</td>
          <td>50k tokens</td>
          <td>15k tokens</td>
          <td>$0.10</td>
      </tr>
      <tr>
          <td>Full-day coding</td>
          <td>200k tokens</td>
          <td>60k tokens</td>
          <td>$0.42</td>
      </tr>
      <tr>
          <td>Monthly usage (20 days)</td>
          <td>4M tokens</td>
          <td>1.2M tokens</td>
          <td><strong>$8.40</strong></td>
      </tr>
  </tbody>
</table>
<p>These are conservative estimates. For larger codebases or Opus usage, savings multiply significantly.</p>
<hr>
<h2 id="setup-checklist">Setup Checklist</h2>
<p>Quick reference for new projects:</p>
<ul>
<li><input disabled="" type="checkbox"> Install <code>uv</code>: <code>curl -LsSf https://astral.sh/uv/install.sh | sh</code></li>
<li><input disabled="" type="checkbox"> Install Serena: <code>uv tool install git+https://github.com/oraios/serena</code></li>
<li><input disabled="" type="checkbox"> <strong>Restart terminal</strong> (close all windows, open fresh)</li>
<li><input disabled="" type="checkbox"> Verify install: <code>which serena &amp;&amp; which serena-mcp-server</code></li>
<li><input disabled="" type="checkbox"> Connect to Claude (auto-creates index): <code>claude mcp add serena -- serena-mcp-server --project $(pwd)</code></li>
<li><input disabled="" type="checkbox"> Add to .gitignore: <code>echo &quot;.serena/&quot; &gt;&gt; .gitignore</code></li>
<li><input disabled="" type="checkbox"> Test connection: <code>claude mcp list</code></li>
<li><input disabled="" type="checkbox"> Start Claude: <code>claude</code> (or <code>claude --allowedTools &quot;mcp__serena*&quot;</code> to auto-accept Serena permissions)</li>
<li><input disabled="" type="checkbox"> Onboard Claude: &ldquo;Use Serena to onboard this project&rdquo;</li>
</ul>
<hr>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://github.com/oraios/serena">Serena GitHub Repository</a></li>
<li><a href="https://modelcontextprotocol.io/">Model Context Protocol Documentation</a></li>
<li><a href="https://md.eknath.dev/posts/ai-ml/claude-code-notes/">My Claude Code Notes</a></li>
<li><a href="https://microsoft.github.io/language-server-protocol/">LSP Specification</a></li>
</ul>
<hr>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Serena has become an essential part of my Claude Code setup. The token savings are nice, but the real value is <strong>better context preservation</strong>. Claude makes fewer mistakes when it has precise semantic information instead of guessing from partial file reads.</p>
<p>If you&rsquo;re working on any non-trivial codebase - especially multi-module Android/KMP projects - give Serena a try. The 10-minute setup pays for itself within the first session.</p>
<p>As always, remember: <strong>AI is a copilot, not a pilot</strong>. Serena makes the copilot more efficient, but you&rsquo;re still in control.</p>
<hr>
<p><em>This article is a living document. Last updated: February 2026</em></p>
<hr>
<h2 id="glossary">Glossary</h2>
<p>New to some of these terms? Here&rsquo;s a quick reference:</p>
<h3 id="mcp-model-context-protocol">MCP (Model Context Protocol)</h3>
<p><strong>Model Context Protocol</strong> is an open standard created by Anthropic that allows AI assistants (like Claude) to connect to external tools and data sources. Think of it as a &ldquo;USB port&rdquo; for AI - any tool that implements MCP can plug into Claude and extend its capabilities.</p>
<p><strong>Example</strong>: Serena is an MCP server. When you run <code>claude mcp add serena</code>, you&rsquo;re telling Claude &ldquo;hey, there&rsquo;s a new tool you can use.&rdquo;</p>
<p><a href="https://modelcontextprotocol.io/">Learn more</a></p>
<hr>
<h3 id="lsp-language-server-protocol">LSP (Language Server Protocol)</h3>
<p><strong>Language Server Protocol</strong> is a standard created by Microsoft that powers IDE features like:</p>
<ul>
<li>&ldquo;Go to Definition&rdquo; (Ctrl/Cmd + Click)</li>
<li>&ldquo;Find All References&rdquo;</li>
<li>Auto-completion</li>
<li>Syntax errors and warnings</li>
</ul>
<p>Instead of each IDE implementing these features separately for every language, LSP provides a common interface. Your IDE talks to a &ldquo;language server&rdquo; that understands the specific language.</p>
<p><strong>Example</strong>: When you Ctrl+Click a function in VS Code and it jumps to the definition - that&rsquo;s LSP in action. Serena uses this same technology to give Claude semantic code navigation.</p>
<p><a href="https://microsoft.github.io/language-server-protocol/">Learn more</a></p>
<hr>
<h3 id="uv">uv</h3>
<p><strong>uv</strong> is a fast Python package and project manager created by <a href="https://astral.sh/">Astral</a>. It&rsquo;s like npm for Python, but significantly faster (written in Rust).</p>
<p><strong>Why Serena uses it</strong>: Serena is a Python project. <code>uv tool install</code> installs CLI tools globally, similar to <code>npm install -g</code>.</p>
<p><strong>Key commands</strong>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Install a tool globally</span>
</span></span><span style="display:flex;"><span>uv tool install package-name
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Install from git repository</span>
</span></span><span style="display:flex;"><span>uv tool install git+https://github.com/user/repo
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Update a tool</span>
</span></span><span style="display:flex;"><span>uv tool upgrade package-name
</span></span></code></pre></div><p><a href="https://docs.astral.sh/uv/">Learn more</a></p>
<hr>
<h3 id="tokens">Tokens</h3>
<p><strong>Tokens</strong> are the fundamental units that AI models process. Roughly:</p>
<ul>
<li>1 token ≈ 4 characters in English</li>
<li>1 token ≈ 0.75 words</li>
<li>100 tokens ≈ 75 words</li>
</ul>
<p>When you send a prompt to Claude, it counts tokens. When Claude responds, it generates tokens. Both cost money with the API.</p>
<p><strong>Why this matters</strong>: If Claude reads a 1000-line file to answer a simple question, that&rsquo;s a lot of tokens wasted. Serena helps Claude read only what it needs.</p>
<hr>
<h3 id="context-window">Context Window</h3>
<p>The <strong>context window</strong> is the maximum amount of text (in tokens) that an AI model can &ldquo;remember&rdquo; during a conversation. Think of it as the AI&rsquo;s working memory.</p>
<table>
  <thead>
      <tr>
          <th>Model</th>
          <th>Context Window</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Claude Sonnet</td>
          <td>200k tokens</td>
      </tr>
      <tr>
          <td>Claude Sonnet 4.5</td>
          <td>500k tokens</td>
      </tr>
      <tr>
          <td>GPT-4</td>
          <td>128k tokens</td>
      </tr>
  </tbody>
</table>
<p><strong>Why this matters</strong>: When the context window fills up, older information gets &ldquo;forgotten&rdquo; or summarized. With large codebases, this can cause Claude to lose track of important details. Serena&rsquo;s efficient queries help preserve context.</p>
<hr>
<h3 id="semantic-vs-syntactic">Semantic vs. Syntactic</h3>
<ul>
<li><strong>Syntactic</strong>: Understanding code as text/patterns (like grep searching for &ldquo;function&rdquo;)</li>
<li><strong>Semantic</strong>: Understanding code&rsquo;s meaning and relationships (knowing that <code>UserRepository implements Repository&lt;User&gt;</code>)</li>
</ul>
<p>Serena provides <strong>semantic</strong> navigation - it understands your code&rsquo;s structure, not just the text.</p>
<hr>
<h3 id="index--indexing">Index / Indexing</h3>
<p>When Serena &ldquo;indexes&rdquo; your project, it&rsquo;s building a searchable database of your code&rsquo;s structure:</p>
<ul>
<li>All classes, functions, and variables</li>
<li>Their locations (file + line number)</li>
<li>Their relationships (what calls what, what implements what)</li>
</ul>
<p>This is similar to how search engines index websites - they pre-process content so searches are fast.</p>
<hr>
<h3 id="cli-command-line-interface">CLI (Command Line Interface)</h3>
<p>A <strong>CLI</strong> is a text-based interface for interacting with software. Instead of clicking buttons in a GUI, you type commands.</p>
<p><strong>Examples</strong>:</p>
<ul>
<li><code>git</code> - Version control CLI</li>
<li><code>npm</code> - Node.js package manager CLI</li>
<li><code>claude</code> - Claude Code&rsquo;s CLI</li>
</ul>
<hr>
<h3 id="mcp-server-vs-client">MCP Server vs. Client</h3>
<p>In the MCP architecture:</p>
<ul>
<li><strong>Client</strong>: The AI assistant (Claude Code) that uses tools</li>
<li><strong>Server</strong>: The tool that provides capabilities (Serena, file system access, etc.)</li>
</ul>
<p>When you run <code>claude mcp add serena</code>, you&rsquo;re registering Serena as a server that Claude (the client) can connect to.</p>
<hr>
<p>Questions or feedback? Reach out:</p>
<ul>
<li><a href="mailto:mail@eknath.dev">Email</a></li>
<li><a href="https://eknath.dev">Website</a></li>
</ul>
]]></content:encoded></item><item><title>Staying Relevant with Claude Code - A Self-Note for Android &amp; KMP Developers</title><link>https://md.eknath.dev/posts/ai-ml/claude-code-notes/</link><pubDate>Fri, 09 Jan 2026 21:47:13 +0530</pubDate><guid>https://md.eknath.dev/posts/ai-ml/claude-code-notes/</guid><description>&lt;h2 id="a-quick-disclaimer">A Quick Disclaimer&lt;/h2>
&lt;p>This article is primarily a &lt;strong>self-note&lt;/strong> that I keep updating as I learn more about Claude Code. The AI tooling landscape evolves rapidly, so some information might be outdated by the time you read this. If you find something that needs updating, feel free to reach out!&lt;/p>
&lt;p>Whether you&amp;rsquo;re a &lt;strong>junior developer&lt;/strong> just getting started or a &lt;strong>senior developer&lt;/strong> looking to boost your workflow, Claude Code has something for everyone.&lt;/p></description><content:encoded><![CDATA[<h2 id="a-quick-disclaimer">A Quick Disclaimer</h2>
<p>This article is primarily a <strong>self-note</strong> that I keep updating as I learn more about Claude Code. The AI tooling landscape evolves rapidly, so some information might be outdated by the time you read this. If you find something that needs updating, feel free to reach out!</p>
<p>Whether you&rsquo;re a <strong>junior developer</strong> just getting started or a <strong>senior developer</strong> looking to boost your workflow, Claude Code has something for everyone.</p>
<hr>
<h2 id="why-should-you-care">Why Should You Care?</h2>
<p>If you&rsquo;ve read my <a href="https://md.eknath.dev/posts/software-development/devfest2025-solutionist-mindset-talk/">Solutionist Mindset talk</a>, you know I believe in <strong>using AI as a copilot, not a pilot</strong>. Claude Code embodies this philosophy perfectly—it&rsquo;s a CLI tool that sits alongside your existing workflow, helping you move faster while keeping you in control.</p>
<p>For Android and <strong>Compose Multiplatform (KMP)</strong> developers like us, having a tool that understands our codebase context is game-changing. Gradle configurations, multi-module architectures, platform-specific implementations—Claude Code can navigate all of this.</p>
<hr>
<h2 id="what-is-claude-code">What is Claude Code?</h2>
<p>Claude Code is Anthropic&rsquo;s <strong>official CLI tool</strong> that brings Claude directly into your terminal. Unlike the web interface, it:</p>
<ul>
<li><strong>Has full access to your codebase</strong> (with your permission)</li>
<li><strong>Can read, write, and edit files</strong> directly</li>
<li><strong>Runs shell commands</strong> for you</li>
<li><strong>Understands project context</strong> across multiple files</li>
<li><strong>Integrates with Git</strong> for version control operations</li>
</ul>
<p>Think of it as having a senior developer sitting next to you who can:</p>
<ul>
<li>Explore your codebase instantly</li>
<li>Write and refactor code</li>
<li>Debug issues by reading logs and stack traces</li>
<li>Create commits and PRs</li>
<li>Explain complex code sections</li>
</ul>
<hr>
<h2 id="latest-updates-january-2026">Latest Updates (January 2026)</h2>
<p><strong>Update available for Claude Code users (v: 2.1.2)!</strong></p>
<h3 id="model-selection">Model Selection</h3>
<p>Opus 4.5 is now available in model selection. While <strong>Sonnet is superior for general coding tasks</strong>, <strong>Opus is amazing for complex features and crazy bugs</strong>. You can use <code>-m</code> flag for selecting a specific model for particular task sessions.</p>
<table>
  <thead>
      <tr>
          <th>Model ID</th>
          <th>Description</th>
          <th>Context Window</th>
          <th>Relative Cost</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>claude-sonnet-4-20250514</code></td>
          <td>Sonnet 4 (default, most balanced)</td>
          <td>200K</td>
          <td>$$ (Moderate)</td>
      </tr>
      <tr>
          <td><code>claude-opus-4-20250514</code></td>
          <td>Opus 4 (most capable, slower)</td>
          <td>200K</td>
          <td>$$$$ (Very High)</td>
      </tr>
      <tr>
          <td><code>claude-sonnet-4-5-20250929</code></td>
          <td>Sonnet 4.5 (smartest, efficient)</td>
          <td>500K</td>
          <td>$$$ (High)</td>
      </tr>
      <tr>
          <td><code>claude-haiku-4-5-20251001</code></td>
          <td>Haiku 4.5 (fastest, most economical)</td>
          <td>200K</td>
          <td>$ (Low)</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>[!WARNING]
<strong>Token Usage Warning</strong>: Continuous usage of <strong>Opus</strong> models will consume your rate limits and quota significantly faster (approx. 5-10x) than Sonnet. Use Opus only for complex debugging or architectural tasks.</p>
</blockquote>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Run with a specific model</span>
</span></span><span style="display:flex;"><span>claude -m claude-opus-4-20250514
</span></span></code></pre></div><h3 id="official-plugins">Official Plugins</h3>
<p>Check out the official plugins:</p>
<ul>
<li><a href="https://github.com/anthropics/claude-code/tree/main/plugins">All Plugins</a></li>
<li><a href="https://github.com/anthropics/claude-code/tree/main/plugins/code-review">Code Review Plugin</a></li>
</ul>
<hr>
<h2 id="getting-started">Getting Started</h2>
<h3 id="installation">Installation</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Using npm</span>
</span></span><span style="display:flex;"><span>npm install -g @anthropic-ai/claude-code
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Using Homebrew (macOS)</span>
</span></span><span style="display:flex;"><span>brew install claude-code
</span></span></code></pre></div><p>After installation, run <code>claude</code> in your terminal to start an interactive session. You&rsquo;ll need to authenticate with your Anthropic API key or use the <code>claude --login</code> command to login via the browser.</p>
<h3 id="basic-usage">Basic Usage</h3>
<p>Navigate to your project directory and simply run:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>claude
</span></span></code></pre></div><p>This starts an interactive session where you can ask questions, request code changes, or explore your codebase.</p>
<hr>
<h2 id="essential-commands-every-developer-should-know">Essential Commands Every Developer Should Know</h2>
<h3 id="1-slash-commands">1️⃣ Slash Commands</h3>
<p>Claude Code has built-in slash commands that trigger specific workflows:</p>
<table>
  <thead>
      <tr>
          <th>Command</th>
          <th>What It Does</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>/help</code></td>
          <td>Shows available commands and usage tips</td>
      </tr>
      <tr>
          <td><code>/clear</code></td>
          <td>Clears conversation history (starts fresh)</td>
      </tr>
      <tr>
          <td><code>/compact</code></td>
          <td>Compresses the conversation to save context</td>
      </tr>
      <tr>
          <td><code>/cost</code></td>
          <td>Shows token usage and estimated costs</td>
      </tr>
      <tr>
          <td><code>/doctor</code></td>
          <td>Diagnoses installation and configuration issues</td>
      </tr>
      <tr>
          <td><code>/init</code></td>
          <td>Creates a CLAUDE.md file with project context</td>
      </tr>
      <tr>
          <td><code>/review</code></td>
          <td>Triggers code review for recent changes</td>
      </tr>
      <tr>
          <td><code>/commit</code></td>
          <td>Creates a git commit with meaningful message</td>
      </tr>
  </tbody>
</table>
<h3 id="2-the-claudemd-file">2️⃣ The CLAUDE.md File</h3>
<p>One of the most powerful features for <strong>multi-module Android/KMP projects</strong> is the <code>CLAUDE.md</code> file. Create this at your project root:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-markdown" data-lang="markdown"><span style="display:flex;"><span># Project: MyKMPApp
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Architecture
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">-</span> Multi-module KMP project
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> Shared module: commonMain, androidMain, iosMain
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> Android app module with Jetpack Compose UI
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> iOS app using SwiftUI
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Key Conventions
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">-</span> Use Koin for dependency injection
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> Room for local database (Android), SQLDelight for shared
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> Ktor for networking
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> Kotlin Coroutines + Flow for async operations
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Build Commands
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">-</span> <span style="color:#e6db74">`./gradlew assembleDebug`</span> - Build Android debug
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> <span style="color:#e6db74">`./gradlew :shared:build`</span> - Build shared module only
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> <span style="color:#e6db74">`./gradlew connectedAndroidTest`</span> - Run instrumented tests
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">## Module Structure
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">-</span> :app - Android application entry point
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> :shared - KMP shared code
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> :feature:home - Home feature module
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> :feature:settings - Settings feature module
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> :core:network - Networking utilities
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">-</span> :core:database - Database layer
</span></span></code></pre></div><p>Claude reads this file and uses it as <strong>persistent context</strong> for every conversation. This is incredibly useful for:</p>
<ul>
<li><strong>Multi-module navigation</strong> - Claude knows your module structure</li>
<li><strong>Consistent coding patterns</strong> - Follows your conventions</li>
<li><strong>Faster builds</strong> - Knows the right Gradle commands</li>
</ul>
<h3 id="3-vim-style-keybindings">3️⃣ Vim-Style Keybindings</h3>
<p>For terminal enthusiasts, Claude Code supports vim keybindings:</p>
<table>
  <thead>
      <tr>
          <th>Key</th>
          <th>Action</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>Escape</code></td>
          <td>Enter command mode</td>
      </tr>
      <tr>
          <td><code>i</code></td>
          <td>Return to insert mode</td>
      </tr>
      <tr>
          <td><code>Ctrl+C</code></td>
          <td>Cancel current operation</td>
      </tr>
      <tr>
          <td><code>Ctrl+D</code></td>
          <td>Exit Claude Code</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="practical-use-cases-for-androidkmp-developers">Practical Use Cases for Android/KMP Developers</h2>
<h3 id="use-case-1-exploring-unfamiliar-codebases">Use Case 1: Exploring Unfamiliar Codebases</h3>
<p>When you join a new project or inherit legacy code:</p>
<pre tabindex="0"><code>You: How is the authentication flow implemented in this app?
     Show me the key files involved.
</code></pre><p>Claude will search through your codebase, identify relevant files (ViewModels, Repositories, API services), and explain the flow.</p>
<h3 id="use-case-2-writing-compose-ui-components">Use Case 2: Writing Compose UI Components</h3>
<pre tabindex="0"><code>You: Create a bottom sheet component for filtering products.
     It should have checkboxes for categories and a price range slider.
     Follow our existing design system in :core:designsystem module.
</code></pre><p>Claude will:</p>
<ol>
<li>Look at your existing design system</li>
<li>Match the patterns and naming conventions</li>
<li>Create the component following your architecture</li>
</ol>
<h3 id="use-case-3-debugging-build-issues">Use Case 3: Debugging Build Issues</h3>
<pre tabindex="0"><code>You: I&#39;m getting this Gradle error when building the shared module:
     [paste error here]

     Help me understand and fix it.
</code></pre><p>Claude can read your <code>build.gradle.kts</code> files, understand the dependency graph, and suggest fixes.</p>
<h3 id="use-case-4-writing-platform-specific-implementations">Use Case 4: Writing Platform-Specific Implementations</h3>
<pre tabindex="0"><code>You: I need to implement biometric authentication.
     Create the expect/actual declarations for Android and iOS
     in the :core:auth module.
</code></pre><p>Claude understands KMP&rsquo;s expect/actual mechanism and generates appropriate platform-specific code.</p>
<h3 id="use-case-5-creating-git-commits">Use Case 5: Creating Git Commits</h3>
<pre tabindex="0"><code>You: /commit
</code></pre><p>Claude will:</p>
<ol>
<li>Analyze your staged changes</li>
<li>Understand the context of modifications</li>
<li>Generate a meaningful commit message</li>
<li>Create the commit</li>
</ol>
<h3 id="use-case-6-room-database-migrations">Use Case 6: Room Database Migrations</h3>
<pre tabindex="0"><code>You: I need to add a &#39;lastSyncedAt&#39; column to the UserEntity.
     Create the migration and update the entity.
</code></pre><p>Claude handles the boilerplate of Room migrations, which can be error-prone manually.</p>
<hr>
<h2 id="best-practices-for-effective-usage">Best Practices for Effective Usage</h2>
<h3 id="-do">✅ DO</h3>
<ol>
<li>
<p><strong>Be specific with context</strong> - Instead of &ldquo;fix this bug&rdquo;, say &ldquo;fix the crash in <code>UserRepository.kt</code> when the token expires&rdquo; make sure you add the file and line-number of the function or scope.</p>
</li>
<li>
<p><strong>Review generated code</strong> - Always understand what Claude writes. Don&rsquo;t blindly accept suggestions.</p>
</li>
<li>
<p><strong>Use it for exploration</strong> - Ask Claude to explain complex parts of your codebase or third-party libraries</p>
</li>
<li>
<p><strong>Leverage for boilerplate</strong> - Let Claude handle repetitive tasks like:</p>
<ul>
<li>Creating data classes from API responses</li>
<li>Writing Room entities and DAOs</li>
<li>Setting up Hilt/Koin modules</li>
<li>Creating navigation graphs</li>
<li>Writing unit test boilerplate</li>
</ul>
</li>
<li>
<p><strong>Maintain your CLAUDE.md</strong> - Keep it updated as your project evolves</p>
</li>
<li>
<p><strong>Use the right model for the task</strong> - Haiku for quick questions, Sonnet for general coding, Opus for complex debugging</p>
</li>
</ol>
<h3 id="-dont">❌ DON&rsquo;T</h3>
<ol>
<li>
<p><strong>Don&rsquo;t share sensitive data</strong> - Avoid passing API keys, secrets, or user data through Claude</p>
</li>
<li>
<p><strong>Don&rsquo;t skip the review</strong> - Especially for security-critical code (authentication, payment processing, encryption etc)</p>
</li>
<li>
<p><strong>Don&rsquo;t use it as a crutch</strong> - You should still understand the fundamentals. AI is a multiplier, not a replacement.</p>
</li>
<li>
<p><strong>Don&rsquo;t expect perfection</strong> - Claude can make mistakes. Treat its output as a starting point.</p>
</li>
<li>
<p><strong>Don&rsquo;t ignore Gradle sync</strong> - After Claude modifies <code>build.gradle.kts</code>, sync manually in Android Studio</p>
</li>
</ol>
<hr>
<h2 id="cost-management-tips">Cost Management Tips</h2>
<p>Claude Code uses API tokens, which cost money. Here&rsquo;s how to optimize:</p>
<h3 id="1-choose-the-right-model">1️⃣ Choose the Right Model</h3>
<table>
  <thead>
      <tr>
          <th>Task Type</th>
          <th>Recommended Model</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Quick questions, simple edits</td>
          <td>Haiku 4.5</td>
      </tr>
      <tr>
          <td>General development</td>
          <td>Sonnet 4/4.5</td>
      </tr>
      <tr>
          <td>Complex debugging, architecture</td>
          <td>Opus 4/4.5</td>
      </tr>
  </tbody>
</table>
<h3 id="2-use-compact-regularly">2️⃣ Use <code>/compact</code> Regularly</h3>
<p>Long conversations consume more tokens. Use <code>/compact</code> to summarize and reduce context.</p>
<h3 id="3-start-fresh-for-new-tasks">3️⃣ Start Fresh for New Tasks</h3>
<p>Use <code>/clear</code> when switching to unrelated tasks. No need to carry previous context.</p>
<h3 id="4-be-concise">4️⃣ Be Concise</h3>
<p>Instead of:</p>
<pre tabindex="0"><code>&#34;Hey Claude, I was wondering if you could maybe help me
understand how the user authentication works in this app,
like when someone logs in, what happens step by step?&#34;
</code></pre><p>Try:</p>
<pre tabindex="0"><code>&#34;Explain the login flow. Start from LoginViewModel.&#34;
</code></pre><h3 id="6-offload-tasks-to-other-modelstools-save-those-tokens">6️⃣ Offload Tasks to Other Models/Tools (Save those Tokens!)</h3>
<p>Not everything requires Claude Code&rsquo;s deep context awareness. Save your tokens by routing tasks to the right tool:</p>
<ul>
<li><strong>Use Gemini for Quick Concepts</strong>: Need to understand &ldquo;How <code>LruCache</code> works internally&rdquo; or &ldquo;Explain the Builder pattern&rdquo;? Use <strong>Gemini</strong>. It&rsquo;s fast, free/cheap, and great for general knowledge that doesn&rsquo;t need your private codebase context.</li>
<li><strong>Use ChatGPT for High-Level Project Questions</strong>: If you need advice on &ldquo;Best practices for modularizing a KMP project&rdquo; or architecture discussions where providing full code access isn&rsquo;t necessary, <strong>ChatGPT</strong> is a great option.</li>
<li><strong>Use CLI Tools for Quick Answers</strong>: If you&rsquo;re a terminal power user (using <code>tmux</code>, <code>dia</code>, etc.), tools like <strong>ddgr</strong> (DuckDuckGo from terminal) or <strong>Ollama</strong> (local models) are fantastic for quick lookups without leaving your flow.</li>
</ul>
<blockquote>
<p>[!TIP]
<strong>Pro Tip</strong>: Reserve Claude Code for tasks that <em>specifically</em> need to read your files, understand your project structure, or perform edits. For everything else, cheaper (or free) alternatives often work just as well!</p>
</blockquote>
<h3 id="7-check-costs-with-cost">7️⃣ Check Costs with <code>/cost</code></h3>
<p>Regularly run <code>/cost</code> to monitor your usage.</p>
<hr>
<h2 id="integration-with-development-workflow">Integration with Development Workflow</h2>
<h3 id="ide-integration">IDE Integration</h3>
<p>Claude Code works alongside your IDE, not inside it. A typical workflow:</p>
<ol>
<li><strong>Have your IDE open</strong> (Android Studio / Fleet / IntelliJ)</li>
<li><strong>Run Claude in a terminal</strong> (split screen works great)</li>
<li><strong>Ask Claude to make changes</strong></li>
<li><strong>Review changes in IDE</strong> (they appear instantly)</li>
<li><strong>Test and iterate</strong></li>
</ol>
<h3 id="git-workflow-integration">Git Workflow Integration</h3>
<p>Claude Code integrates nicely with Git:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start a session</span>
</span></span><span style="display:flex;"><span>claude
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Create meaningful commits</span>
</span></span><span style="display:flex;"><span>You: /commit
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Create a pull request</span>
</span></span><span style="display:flex;"><span>You: Create a PR <span style="color:#66d9ef">for</span> these changes. The target branch is develop.
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Review code before pushing</span>
</span></span><span style="display:flex;"><span>You: Review the changes in the last commit <span style="color:#66d9ef">for</span> any issues.
</span></span></code></pre></div><hr>
<h2 id="common-gotchas-for-androidkmp-projects">Common Gotchas for Android/KMP Projects</h2>
<h3 id="1-gradle-sync-after-changes">1️⃣ Gradle Sync After Changes</h3>
<p>When Claude modifies <code>build.gradle.kts</code> files, you&rsquo;ll need to sync in Android Studio manually. Claude can&rsquo;t trigger this for you.</p>
<h3 id="2-resource-files">2️⃣ Resource Files</h3>
<p>Claude can create/modify XML resources (layouts, strings, drawables), but be careful with:</p>
<ul>
<li><strong>Generated resources</strong> (R class) - These regenerate on build</li>
<li><strong>Vector drawables</strong> - Complex paths might need manual tweaking</li>
</ul>
<h3 id="3-compose-preview">3️⃣ Compose Preview</h3>
<p>Claude-generated Compose components might need <code>@Preview</code> annotations added for visibility in Android Studio&rsquo;s preview pane.</p>
<h3 id="4-ios-specific-code">4️⃣ iOS-Specific Code</h3>
<p>For KMP projects, Claude can write Swift/Objective-C code for iOS implementations, but:</p>
<ul>
<li>You&rsquo;ll need Xcode to verify it compiles</li>
<li>Swift interop with Kotlin can be tricky</li>
</ul>
<h3 id="5-version-catalog">5️⃣ Version Catalog</h3>
<p>If you use <code>libs.versions.toml</code>, make sure Claude knows about it in your <code>CLAUDE.md</code>. Otherwise, it might use hardcoded versions.</p>
<hr>
<h2 id="my-personal-workflow">My Personal Workflow</h2>
<p>Here&rsquo;s how I typically use Claude Code for Android development:</p>
<ol>
<li>
<p><strong>Morning exploration</strong> - &ldquo;What did I work on yesterday? Show me recent changes.&rdquo;</p>
</li>
<li>
<p><strong>Feature development</strong> - Start with asking Claude to explore existing patterns, then implement following those patterns</p>
</li>
<li>
<p><strong>Code review helper</strong> - &ldquo;Review this ViewModel for potential memory leaks or coroutine issues&rdquo;</p>
</li>
<li>
<p><strong>Documentation</strong> - &ldquo;Generate KDoc comments for the public methods in NetworkClient.kt&rdquo;</p>
</li>
<li>
<p><strong>Refactoring</strong> - &ldquo;Migrate this callback-based API to use Kotlin Coroutines with Flow&rdquo;</p>
</li>
<li>
<p><strong>Test writing</strong> - &ldquo;Write unit tests for UserRepository using MockK&rdquo;</p>
</li>
</ol>
<hr>
<h2 id="advanced-mcp-servers">Advanced: MCP Servers</h2>
<p>Claude Code supports <strong>Model Context Protocol (MCP)</strong> servers, which extend its capabilities. For Android developers, interesting MCPs include:</p>
<ul>
<li><strong>File system access</strong> - Already built-in</li>
<li><strong>Git operations</strong> - Built-in</li>
<li><strong>Web search</strong> - For documentation lookups</li>
<li><strong>Custom tools</strong> - You can create your own MCP servers</li>
</ul>
<p>Check out the <a href="https://modelcontextprotocol.io/">MCP Documentation</a> for more details.</p>
<hr>
<h2 id="useful-one-liners">Useful One-Liners</h2>
<p>Quick commands I use frequently:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Start with a specific model for complex tasks</span>
</span></span><span style="display:flex;"><span>claude -m claude-opus-4-20250514
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Resume last conversation</span>
</span></span><span style="display:flex;"><span>claude --resume
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Check installation health</span>
</span></span><span style="display:flex;"><span>claude /doctor
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Quick code review</span>
</span></span><span style="display:flex;"><span>claude <span style="color:#e6db74">&#34;Review my staged changes for issues&#34;</span>
</span></span></code></pre></div><hr>
<h2 id="whats-next">What&rsquo;s Next?</h2>
<p>This article covers the fundamentals, but Claude Code is constantly evolving. I plan to update this note as I discover:</p>
<ul>
<li>New features and capabilities</li>
<li>Better workflows for KMP development</li>
<li>Integration patterns with CI/CD</li>
<li>Team collaboration strategies</li>
</ul>
<hr>
<h2 id="final-thoughts">Final Thoughts</h2>
<p>Claude Code is a <strong>powerful addition to the Android/KMP developer toolkit</strong>. It&rsquo;s not about replacing your skills—it&rsquo;s about <strong>amplifying</strong> them. Use it to handle boilerplate, explore unfamiliar code, and move faster on repetitive tasks.</p>
<p>But remember: <strong>You are still the pilot</strong>. Claude is your copilot. Understand what it generates, review its suggestions, and keep learning the fundamentals.</p>
<p>The developers who thrive in the AI age won&rsquo;t be those who code the fastest—they&rsquo;ll be the ones who <strong>solve problems thoughtfully</strong> while leveraging every tool at their disposal.</p>
<hr>
<h2 id="resources">Resources</h2>
<ul>
<li><a href="https://docs.anthropic.com/claude-code">Official Claude Code Documentation</a></li>
<li><a href="https://github.com/anthropics/claude-code">Claude Code GitHub</a></li>
<li><a href="https://github.com/anthropics/claude-code/tree/main/plugins">Official Plugins</a></li>
<li><a href="https://modelcontextprotocol.io/">Model Context Protocol</a></li>
<li><a href="https://md.eknath.dev/posts/software-development/devfest2025-solutionist-mindset-talk/">My Solutionist Mindset Talk</a></li>
</ul>
<hr>
<p>Feel free to connect with me on:
📩 <strong><a href="mailto:mail@eknath.dev">Email</a></strong>
🌍 <strong><a href="https://eknath.dev">Website</a></strong></p>
<p><em>I wish to keep this article as a living document. Last updated: January 2026</em></p>
]]></content:encoded></item><item><title>Solutionist Mindset: Reclaiming Purpose in the Age of AI - My DevFest2025 Talk</title><link>https://md.eknath.dev/posts/software-development/devfest2025-solutionist-mindset-talk/</link><pubDate>Sun, 09 Nov 2025 00:00:00 +0000</pubDate><guid>https://md.eknath.dev/posts/software-development/devfest2025-solutionist-mindset-talk/</guid><description>&lt;p>&lt;em>This is an elaborated version of my talk at Google Developer Group Chennai&amp;rsquo;s DevFest2025, where I shared my journey from rock bottom to becoming an Android Developer at Zoho and how the &amp;ldquo;Solutionist Mindset&amp;rdquo; can help us thrive in the age of AI.&lt;/em>&lt;/p>
&lt;p>&lt;img alt="Speaking at the Platform" loading="lazy" src="https://md.eknath.dev/img/devfest_2025/speaking-at-the-platform-01.JPG">
&lt;em>Presenting the Solutionist Mindset on stage&lt;/em>&lt;/p>
&lt;script defer class="speakerdeck-embed" data-id="ae22be07dca842408af4c8ec3fd4b234" data-ratio="1.7777777777777777" src="//speakerdeck.com/assets/embed.js">&lt;/script>
&lt;p>Standing on that stage at DevFest2025 in Chennai, looking out to you all, I asked a simple question: &lt;strong>&amp;ldquo;How many of you are worried about AI taking over your job?&amp;rdquo;&lt;/strong>&lt;/p></description><content:encoded><![CDATA[<p><em>This is an elaborated version of my talk at Google Developer Group Chennai&rsquo;s DevFest2025, where I shared my journey from rock bottom to becoming an Android Developer at Zoho and how the &ldquo;Solutionist Mindset&rdquo; can help us thrive in the age of AI.</em></p>
<p><img alt="Speaking at the Platform" loading="lazy" src="/img/devfest_2025/speaking-at-the-platform-01.JPG">
<em>Presenting the Solutionist Mindset on stage</em></p>
<script defer class="speakerdeck-embed" data-id="ae22be07dca842408af4c8ec3fd4b234" data-ratio="1.7777777777777777" src="//speakerdeck.com/assets/embed.js"></script>
<p>Standing on that stage at DevFest2025 in Chennai, looking out to you all, I asked a simple question: <strong>&ldquo;How many of you are worried about AI taking over your job?&rdquo;</strong></p>
<p>The show of hands was overwhelming (some shared why they are confident too, I wish I was them). The anxiety in the room was palpable.</p>
<p>I get it. I&rsquo;ve been there. In fact, I&rsquo;m still navigating these waters myself. As an Android Developer at Zoho, I&rsquo;ve watched AI tools evolve from curiosities to formidable coding partners. They&rsquo;re impressive—spitting out code 10 to 100 times faster than we can. It&rsquo;s almost unsettling, watching something produce in minutes what would take us hours or days.</p>
<p>The predictions are scary. The layoff numbers are even scarier. Tech Twitter is full of doom-scrolling material about how AI will replace developers, how junior positions are vanishing, how the barrier to entry is impossibly high now.</p>
<p>So I did what any rational person would do—I took a step back and contemplated this deeper.</p>
<p><strong>What&rsquo;s the worst thing that can happen to me?</strong></p>
<p>And then I realized something profound: I&rsquo;ve been through worse.</p>
<hr>
<h2 id="rock-bottom-varanasi-december-2017">Rock Bottom: Varanasi, December 2017</h2>
<p>Let me share something deeply personal with you. Something I don&rsquo;t talk about often, but something that fundamentally changed how I approach adversity.</p>
<p>In December 2017, my life fell apart.</p>
<p>Not in the dramatic, movie-like way—but in the quiet, suffocating way that creeps up on you. Emotionally stuck, I watched as friends I believed would be with me forever just&hellip; disappeared. The community I had built my identity around crumbled. My entire belief system, everything I thought I knew about life and relationships, shattered.</p>
<p>Losing all hope, I set out on what I genuinely thought would be my final journey: to Varanasi.</p>
<h3 id="the-ghats-of-varanasi">The Ghats of Varanasi</h3>
<p>I spent weeks alone at the ghats with almost nothing. It was the coldest winter I&rsquo;ve ever experienced, and I wasn&rsquo;t prepared—not physically, not mentally, not emotionally.</p>
<p>Surviving on just one meal a day at a nearby temple, I would spend my days sitting by the river, gazing into the Ganges in silence. The helplessness, the solitude—it was unlike anything I had ever known before. Even now, years later, I struggle to put that experience into words.</p>
<p>Imagine this: You&rsquo;re standing at the crossroads of chaos. Motion swirls all around you—boats on the river, pilgrims performing rituals, the constant murmur of life and death existing side by side. Yet despite all this movement, you&rsquo;re paralyzed. You can&rsquo;t decide where to step next. Your mind feels numb. The whole experience is so overwhelming that language itself becomes inadequate.</p>
<p>But here&rsquo;s what that experience taught me: <strong>Clarity doesn&rsquo;t come from escaping pain. It comes from sitting with it, accepting it, and taking it in as a lesson from the universe.</strong></p>
<p>When you&rsquo;ve sat at the ghats of Varanasi, contemplating the impermanence of everything while watching funeral pyres burn and pilgrims bathe, the fear of losing a job to AI becomes&hellip; manageable. Not trivial—but definitely manageable.</p>
<hr>
<h2 id="fast-forward-finding-auroville">Fast Forward: Finding Auroville</h2>
<p>After a few more reality checks and life lessons (because apparently, Varanasi wasn&rsquo;t enough), I came across Auroville and its unique philosophy around money and community living.</p>
<p>For those unfamiliar, Auroville is an experimental township in Tamil Nadu, founded on the principles of human unity, sustainable living, and spiritual evolution. Their approach to money and work fascinated me—the idea that work should be about contribution, not just compensation.</p>
<p>I felt drawn to it. It seemed like a place that resonated with what I was searching for—a new way of living, a new framework for understanding my place in the world.</p>
<h3 id="reality-meets-philosophy">Reality Meets Philosophy</h3>
<p>When I arrived, I realized that while the philosophy was inspiring, it was still very much a work in progress—an idea in the process of becoming real. The gap between the ideal and the reality was significant. But you know what? That&rsquo;s okay. That&rsquo;s how all great experiments work.</p>
<p>Yet, amidst that gap, I found something invaluable: a warm, accepting community and my very first job at a busy guest house.</p>
<p>I started as a <strong>waiter</strong>. Then I worked my way up—biller, receptionist, whatever was needed. Each role taught me something new about human interaction, problem-solving, and the simple dignity of work.</p>
<p>It was genuinely educative in ways a classroom never could be. I learned about hospitality, about managing stress during rush hours, about the intricate dance of keeping customers happy while maintaining operational efficiency.</p>
<p>But there was one problem that bugged me daily, especially at the billing counter.</p>
<hr>
<h2 id="my-first-solution-the-python-calculator">My First Solution: The Python Calculator</h2>
<p>Restaurants in Auroville had unique discount structures that reflected their community-oriented values:</p>
<ul>
<li>10% off for volunteers</li>
<li>20% off for Auroville residents</li>
<li>Plus 5% GST for regular guests</li>
</ul>
<p>Simple enough, right? Except during rush hours, when we had to calculate all this <strong>manually using a calculator</strong>.</p>
<p>Picture this: It&rsquo;s lunch rush. The kitchen is yelling that orders are backing up. Customers are waiting, getting increasingly impatient. You&rsquo;re trying to calculate percentages on a basic calculator while keeping track of multiple bills, and someone changes their mind about their order halfway through.</p>
<p>It was absolute chaos.</p>
<p>So, I did something I had never done before—I wrote a <strong>simple Python Tkinter app</strong> to simplify this process.</p>
<h3 id="the-joy-of-building-your-first-solution">The Joy of Building Your First Solution</h3>
<p>Now, to any experienced developer reading this, a Python Tkinter calculator probably sounds laughably simple. And it is. But back then, for someone with minimal programming experience, it was <strong>transformative</strong>.</p>
<p>It took me a couple of days and several iterations. The first version was buggy. The UI was ugly. But it worked. And during the next busy lunch rush, it saved my sanity.</p>
<p>This was my first real solution. Not a tutorial project. Not a homework assignment. A real problem, solved with real code, that helped real people.</p>
<p>Looking back now, it&rsquo;s not sparkly or impressive. I wouldn&rsquo;t put it in my portfolio. But it was a <strong>huge milestone</strong> in my journey. It empowered me to believe that I could build tools to solve problems.</p>
<h3 id="the-ai-comparison">The AI Comparison</h3>
<p>Here&rsquo;s the kicker: If I faced the same problem today, with access to Claude, GPT-4, or Copilot, it would take me <strong>5 minutes or less</strong> to build the same thing. Probably better, with proper error handling and a cleaner UI.</p>
<p>That&rsquo;s both amazing and terrifying. Amazing because of the productivity boost. Terrifying because if I were starting my journey today, would I have learned the same lessons? Would I have struggled enough to truly understand the fundamentals?</p>
<p>This is the paradox we&rsquo;re living in.</p>
<hr>
<h2 id="the-bootcamp-zoho-schools-of-graduate-studies">The Bootcamp: Zoho Schools of Graduate Studies</h2>
<p>After a while working at the restaurant, things were getting repetitive. I could do the job in my sleep. The initial learning curve had flattened out completely.</p>
<p>Then, I was given an opportunity to participate in the <strong>Zoho Schools of Graduate Studies (ZSGS)</strong>—a pilot 3-month fast-track program into software development.</p>
<p>There were interviews. There were coding tests. There were problem-solving assessments.</p>
<p>But you know what stood out during my interview? <strong>That custom calculator project I built to solve the billing problem.</strong></p>
<p>It wasn&rsquo;t the fanciest project. It wasn&rsquo;t built with the latest framework or deploying cutting-edge architecture. But it demonstrated something crucial: <strong>I could identify a problem and build a solution.</strong></p>
<h3 id="the-underdog-journey">The Underdog Journey</h3>
<p>With a few more rounds of interviews and small projects, I was accepted into the program. But here&rsquo;s the thing—acceptance didn&rsquo;t guarantee employment at Zoho. It just meant you&rsquo;d get direct interviews if there were openings afterward.</p>
<p>And I wasn&rsquo;t under any illusion about my chances.</p>
<p>I was the <strong>only individual with just an SSLC (10th grade) certificate</strong> among some incredibly bright minds with degrees in Computer Science, Electronics, Mathematics, and various other technical streams. On paper, I was the least qualified person in that room.</p>
<p>But I knew one thing: I could give my absolute best and absorb everything like a sponge.</p>
<p>I was like a thirsty man stumbling upon an oasis—desperate to quench my thirst by learning everything I possibly could.</p>
<h3 id="the-learning-environment">The Learning Environment</h3>
<p>The program was intense. We learned data structures, algorithms, software design principles, databases, and practical software development. But more than the technical content, it was the <strong>mindset shift</strong> that mattered.</p>
<p>My mentors didn&rsquo;t just teach me how to code—they taught me how to <strong>think</strong>. How to break down complex problems. How to ask the right questions. How to learn independently.</p>
<p>The other students, despite their impressive credentials, were incredibly supportive. We learned from each other, challenged each other, and grew together.</p>
<p>Thanks to my mentors and the collaborative environment, I managed to not just survive, but thrive.</p>
<h3 id="the-interview">The Interview</h3>
<p>And the first team that interviewed me at the end of the program? <strong>They took me in.</strong></p>
<p>Not because of my credentials (I had none). Not because of my degree (I had none). But because I demonstrated the ability to learn, adapt, and build solutions.</p>
<p>That&rsquo;s how I became part of this wonderful tech world. Not through traditional credentials, but through small projects, relentless learning, and incredible mentors who saw potential where others might have seen only limitations.</p>
<hr>
<h2 id="a-glimpse-of-tech-life">A Glimpse of Tech Life</h2>
<p>After joining a team at Zoho, I slowly started getting accustomed to this new life—realizing how incredibly fortunate I was to be on an <strong>autodidactic journey</strong> that felt like a dream.</p>
<p>Learning, growing, and getting paid for it? It seemed almost too good to be true.</p>
<h3 id="the-difference-from-previous-jobs">The Difference from Previous Jobs</h3>
<p>Unlike any job I&rsquo;d had before—waiter, receptionist, biller—this one was fundamentally different. Everything I learned for work actually <strong>empowered me personally</strong>. It felt like one of those rare systems where the more you give, the more you grow.</p>
<p>It was like tending a bonsai tree—carefully shaped by external constraints and guidance, yet every bit of effort you put in feeds your own roots, strengthens your own foundation.</p>
<p>I was getting paid to:</p>
<ul>
<li>Learn new technologies</li>
<li>Experiment with different approaches</li>
<li>Build features that many would use</li>
<li>Solve genuinely interesting problems</li>
</ul>
<p>It felt unreal. It felt like the job I had dreamed about during those cold nights in Varanasi.</p>
<h3 id="the-honeymoon-phase">The Honeymoon Phase</h3>
<p>For a couple of years, it was blissful. The learning curve was steep but manageable. Android development was evolving rapidly—Kotlin was gaining traction, Jetpack Compose was being introduced, and the ecosystem was thriving.</p>
<p>I threw myself into it. I learned Kotlin inside and out. I became proficient in Android architecture patterns. I contributed to significant features in our products.</p>
<p>For a while, I felt secure. I had carved out expertise. I had value.</p>
<p>And then… <strong>the AI wave hit.</strong></p>
<hr>
<h2 id="then-ai-happened">Then AI Happened</h2>
<p>ChatGPT launched in November 2022. At first, it was a curiosity. We played with it, asked it silly questions, marveled at its responses.</p>
<p>Then GitHub Copilot became mainstream. Then GPT-4 arrived. Then Claude. Then specialized coding models like Codex and Replit Ghostwriter.</p>
<p>Watching AI get better at coding, debugging, and doing things that used to be uniquely ours—suddenly, that old fear came back.</p>
<p>Not the fear of losing everything (I&rsquo;d survived that in Varanasi). But the <strong>fear of becoming irrelevant</strong> was just as scary in a different way.</p>
<h3 id="the-existential-questions">The Existential Questions</h3>
<p>What happens when the skills we&rsquo;ve painstakingly built over years suddenly don&rsquo;t matter anymore?</p>
<p>What happens when a fresh graduate with AI assistance can be as productive as a senior developer?</p>
<p>What happens when companies realize they can maintain codebases with fewer people because AI handles the routine work?</p>
<p>These weren&rsquo;t hypothetical questions anymore. They were becoming reality. The layoff announcements from major tech companies included explicit mentions of &ldquo;productivity improvements through AI&rdquo; as justification.</p>
<h3 id="the-essay-that-changed-my-perspective">The Essay That Changed My Perspective</h3>
<p>Around that time, in one of our team discussions about the future of software development, my manager shared an essay from <strong>1932</strong> by Bertrand Russell called <strong>&ldquo;In Praise of Idleness.&rdquo;</strong></p>
<p>Has anyone here read it? If not, I highly recommend it.</p>
<p>Russell wrote this during the <strong>Great Depression</strong>, when millions were unemployed and the world was in economic turmoil. Yet his argument wasn&rsquo;t about working harder to save the economy—it was about working <strong>smarter</strong> and questioning the entire premise of constant labor.</p>
<h3 id="russells-radical-idea">Russell&rsquo;s Radical Idea</h3>
<p>Russell argued that modern civilization had created a <strong>moral trap</strong> where we measure human worth by hours worked, not by problems solved or lives improved.</p>
<p>He believed that if machines could handle labor, we shouldn&rsquo;t artificially create more meaningless work just to keep people busy. Instead, we should use that freedom for:</p>
<ul>
<li>Creativity</li>
<li>Learning</li>
<li>Art</li>
<li>Philosophy</li>
<li>Solving problems that actually matter</li>
</ul>
<p>Think about that. Written in <strong>1932</strong>, before:</p>
<ul>
<li>Computers</li>
<li>The Internet</li>
<li>Mobile phones</li>
<li>Artificial Intelligence</li>
</ul>
<p>Yet it feels like it was written specifically for us, right now, in 2025.</p>
<h3 id="the-question-reframed">The Question Reframed</h3>
<p>Russell&rsquo;s essay helped me reframe the question entirely.</p>
<p>It&rsquo;s not &ldquo;Will AI replace us?&rdquo;</p>
<p>It&rsquo;s <strong>&ldquo;What will we do with the freedom AI creates?&rdquo;</strong></p>
<p>Tasks that used to take weeks or months of research, development, and iteration now take hours or days thanks to AI assistance.</p>
<p>Yes, there will be side effects:</p>
<ul>
<li>Layoffs</li>
<li>Reduced entry-level positions</li>
<li>Increased pressure on individual productivity</li>
<li>Market corrections</li>
</ul>
<p>But these aren&rsquo;t permanent states—they&rsquo;re transition periods. And the question for each of us is: <strong>How do we position ourselves to thrive in this transition?</strong></p>
<hr>
<h2 id="breaking-out-of-the-box">Breaking Out of the Box</h2>
<p>For years, I had confined myself to what I call a <strong>&ldquo;boxed developer&rdquo; mindset</strong>.</p>
<p>Everything revolved around:</p>
<ul>
<li>Kotlin</li>
<li>Android</li>
<li>Jetpack Compose</li>
</ul>
<p>I was good at it. I was comfortable. I could solve most Android problems thrown my way.</p>
<p>But I realized that comfort was becoming a <strong>cage</strong>.</p>
<h3 id="the-title-trap">The Title Trap</h3>
<p>We do this to ourselves, don&rsquo;t we? We accept titles and roles that become our entire identity:</p>
<ul>
<li>&ldquo;I&rsquo;m an Android Developer&rdquo;</li>
<li>&ldquo;I&rsquo;m a Frontend Engineer&rdquo;</li>
<li>&ldquo;I&rsquo;m a Backend Specialist&rdquo;</li>
</ul>
<p>These titles are useful for resumes and LinkedIn profiles. They help us find jobs. They give us a sense of expertise.</p>
<p>But they also <strong>limit our view</strong>. They keep us from looking beyond what our immediate work needs us to see.</p>
<h3 id="developer-vs-solutionist">Developer vs. Solutionist</h3>
<p>Here&rsquo;s the crucial distinction I&rsquo;ve discovered:</p>
<p>A <strong>developer</strong> writes code to win bread. They learn what they need to stay employed. They specialize to remain valuable. It&rsquo;s transactional.</p>
<p>A <strong>solutionist</strong> goes much deeper. They enjoy and learn every bit they can, like a magnet drawn to new knowledge. They&rsquo;re driven by curiosity and the joy of solving problems, not just by paychecks.</p>
<p>The developer asks: &ldquo;What do I need to know for my job?&rdquo;</p>
<p>The solutionist asks: &ldquo;What do I need to know to solve this problem effectively?&rdquo;</p>
<p>See the difference?</p>
<hr>
<h2 id="staying-relevant-build-continuously">Staying Relevant: Build Continuously</h2>
<p>This distinction matters immensely because once the AI tsunami completes its first wave, <strong>the next one is already forming</strong>.</p>
<p>Quantum computing advancements. More sophisticated AI models. New paradigms we haven&rsquo;t even conceived of yet.</p>
<p>Staying relevant through all of these requires constant adaptation and learning.</p>
<p>My proposition for navigating this? <strong>BUILD CONTINUOUSLY.</strong></p>
<h3 id="why-build-more">Why Build More?</h3>
<p>Because what better way to learn than building projects?</p>
<p>Not theoretical knowledge. Not tutorial hell. Not certifications that gather dust.</p>
<p><strong>Actual projects</strong> that solve real problems faced by real humans (even if that human is just you).</p>
<h3 id="the-compounding-effect-of-small-projects">The Compounding Effect of Small Projects</h3>
<p>Just like that simple billing calculator I mentioned earlier—you never know where a small project might lead.</p>
<p>After experiencing the joy of building that first solution, I built many more:</p>
<ul>
<li>A personal expense tracker (because existing ones didn&rsquo;t fit my mental model)</li>
<li>A community link-sharing platform (to solve coordination problems in my friend group)</li>
<li>A personal task management system (because I needed something simpler than Notion but more structured than notes)</li>
<li>Various automation scripts for repetitive tasks</li>
</ul>
<p>All of these are available on my website. Are they perfect? Absolutely not. Do they have bugs? Definitely. Are they going to change the world? Probably not.</p>
<p>But they&rsquo;ve changed <strong>my world</strong>.</p>
<h3 id="what-building-teaches-you">What Building Teaches You</h3>
<p>Building small things consistently <strong>transforms you</strong>:</p>
<ol>
<li>
<p><strong>You see problems differently</strong> - Instead of complaining about inefficiencies, you see opportunities to build solutions.</p>
</li>
<li>
<p><strong>You stop feeling stuck</strong> - There&rsquo;s always something you can build, always some small improvement you can make.</p>
</li>
<li>
<p><strong>You develop taste</strong> - You understand what makes software feel good to use because you&rsquo;re both the builder and the user.</p>
</li>
<li>
<p><strong>You become resilient</strong> - When things break (and they will), you learn to fix them. When approaches don&rsquo;t work, you pivot.</p>
</li>
<li>
<p><strong>You evolve unexpectedly</strong> - You slowly become someone you didn&rsquo;t know you could become. Skills compound. Confidence grows.</p>
</li>
</ol>
<hr>
<h2 id="so-what-is-a-solutionist">So, What Is a Solutionist?</h2>
<p>After all these stories and reflections, let me give you a concrete definition:</p>
<p><strong>A Solutionist isn&rsquo;t defined by tools, but by problems solved.</strong></p>
<p>They are:</p>
<ul>
<li>Language-agnostic</li>
<li>Framework-flexible</li>
<li>System-aware</li>
<li>Problem-focused</li>
</ul>
<h3 id="the-four-traits-of-a-solutionist">The Four Traits of a Solutionist</h3>
<p>Through my journey and observation of people I admire, I&rsquo;ve identified four core traits:</p>
<h4 id="1-empathy--understanding-people-not-just-specs">1. Empathy — Understanding People, Not Just Specs</h4>
<p>The best solutions come from understanding the <strong>human problem</strong>, not just the technical specification.</p>
<p>This means:</p>
<ul>
<li>Putting yourself in the user&rsquo;s shoes</li>
<li>Understanding their frustrations, not just their feature requests</li>
<li>Recognizing that &ldquo;make it faster&rdquo; often means &ldquo;I feel frustrated waiting&rdquo;</li>
<li>Seeing the emotional journey, not just the user journey</li>
</ul>
<p>When I built that billing calculator, I wasn&rsquo;t solving a math problem. I was solving the <strong>stress and anxiety</strong> of my colleagues during rush hours.</p>
<h4 id="2-systems-thinking--seeing-ripple-effects">2. Systems Thinking — Seeing Ripple Effects</h4>
<p>Nothing exists in isolation. One change ripples through everything.</p>
<p>Systems thinking means:</p>
<ul>
<li>Understanding dependencies and consequences</li>
<li>Recognizing that &ldquo;fixing&rdquo; one thing might break another</li>
<li>Seeing the whole forest, not just the tree you&rsquo;re debugging</li>
<li>Appreciating long-term implications of short-term decisions</li>
</ul>
<p>In Android development, this might mean understanding how a seemingly innocent change in a shared ViewModel might affect multiple screens, or how a database migration could impact app startup time.</p>
<h4 id="3-lifelong-learning--venturing-into-the-unknown-without-fear">3. Lifelong Learning — Venturing Into the Unknown Without Fear</h4>
<p>The moment you stop learning, you start becoming obsolete.</p>
<p>Lifelong learning means:</p>
<ul>
<li>Being comfortable with being a beginner again and again</li>
<li>Exploring technologies outside your comfort zone</li>
<li>Reading papers, essays, and documentation for things you don&rsquo;t &ldquo;need&rdquo; yet</li>
<li>Understanding that every new skill multiplies with every previous skill you&rsquo;ve learned</li>
</ul>
<p>From SSLC certificate to Android Developer to exploring AI/ML, backend systems, DevOps—each layer adds new dimensions to how you solve problems.</p>
<h4 id="4-communication--bridging-technical-and-non-technical-minds">4. Communication — Bridging Technical and Non-Technical Minds</h4>
<p>The best solution is useless if no one understands it.</p>
<p>Communication means:</p>
<ul>
<li>Explaining complex technical concepts to non-technical stakeholders</li>
<li>Writing documentation that actually helps</li>
<li>Listening actively to understand requirements beneath the surface</li>
<li>Collaborating effectively across disciplines—design, product, business</li>
</ul>
<p>I&rsquo;ve seen brilliant solutions fail because they were explained poorly. And I&rsquo;ve seen simple solutions succeed because they were communicated effectively.</p>
<hr>
<h2 id="ai-as-freedom-russells-prophecy-coming-true">AI as Freedom: Russell&rsquo;s Prophecy Coming True</h2>
<p>When AI arrived, many feared job loss. And yes, that&rsquo;s happening in some sectors.</p>
<p>But what if Russell was right all along?</p>
<h3 id="what-ai-actually-removes">What AI Actually Removes</h3>
<p>AI removes:</p>
<ul>
<li>Repetitive, mechanical work</li>
<li>Boilerplate that makes our days feel routine</li>
<li>The cognitive load of remembering syntax</li>
<li>The tedium of debugging simple logic errors</li>
</ul>
<p>It gives time back for:</p>
<ul>
<li>Creativity</li>
<li>Empathy</li>
<li>Real problem-solving</li>
<li>Strategic thinking</li>
<li>Learning deeply instead of superficially</li>
</ul>
<h3 id="vibe-coding-thanks-to-andrej-karpathy">Vibe Coding: Thanks to Andrej Karpathy</h3>
<p>This is where <strong>&lsquo;vibe coding&rsquo;</strong> comes in—a term popularized by Andrej Karpathy.</p>
<p>Let AI help you move faster. Let it handle the repetition, the boilerplate, the syntax you can never quite remember.</p>
<p>But—and this is crucial—<strong>understand what it&rsquo;s changing</strong>.</p>
<p>Know the patterns. Understand the tweaks. Grasp the reasoning behind every line it suggests.</p>
<h3 id="the-danger-of-blind-coding">The Danger of Blind Coding</h3>
<p>If you code blindly, just accepting whatever AI suggests without understanding:</p>
<ul>
<li>You lose the joy of building</li>
<li>You become oblivious to your own vision</li>
<li>You can&rsquo;t debug effectively when things inevitably break</li>
<li>You stop learning and start copy-pasting</li>
</ul>
<p>AI should be your <strong>copilot</strong>, not your pilot. You&rsquo;re still flying the plane.</p>
<hr>
<h2 id="how-to-actually-start-practical-steps">How to Actually Start: Practical Steps</h2>
<p>Enough philosophy. Let&rsquo;s talk practically.</p>
<p>Want to build something? Here&rsquo;s what I&rsquo;ve learned through building multiple projects with AI assistance:</p>
<h3 id="step-1-start-with-the-problem">Step 1: Start with the Problem</h3>
<p>Write it down. Not the solution—<strong>the problem</strong>.</p>
<p>Ask yourself:</p>
<ul>
<li>What are you trying to solve?</li>
<li>Who are you solving it for?</li>
<li>Why does this problem matter?</li>
<li>What does success look like?</li>
</ul>
<p>Be specific. &ldquo;I want to build a todo app&rdquo; is not a problem. &ldquo;I keep forgetting to follow up on important emails, and existing todo apps don&rsquo;t integrate well with my email workflow&rdquo; is a problem.</p>
<h3 id="step-2-document-your-vision-first">Step 2: Document Your Vision First</h3>
<p>Before you write a single line of code, create a <strong>clear vision</strong> of what you&rsquo;re building and why.</p>
<p>Your first commit should be your vision, not your code.</p>
<p>This document becomes your North Star. When AI suggests clever solutions that drift from your vision, you can catch it. When scope creep tempts you, you can resist it.</p>
<h3 id="step-3-use-ai-to-move-fast-but-understand-everything">Step 3: Use AI to Move Fast, But Understand Everything</h3>
<p>This is the balance:</p>
<ul>
<li>Let AI generate boilerplate → But understand the structure it creates</li>
<li>Let AI suggest solutions → But understand why those solutions work</li>
<li>Let AI write tests → But understand what they&rsquo;re testing and why</li>
</ul>
<p>Know the patterns. Understand the tweaks. Grasp the reasoning behind every line.</p>
<p>If you find yourself accepting suggestions without understanding them, <strong>stop</strong>. Research. Learn. Only then proceed.</p>
<h3 id="step-4-iterate-deliberately">Step 4: Iterate Deliberately</h3>
<p>Add features <strong>one at a time</strong>.</p>
<p>Track changes with Git. See what&rsquo;s happening at each step.</p>
<p>This isn&rsquo;t just about version control—it&rsquo;s about <strong>understanding the evolution</strong> of your project. Each commit is a story. Each feature is a chapter.</p>
<p>Deliberate iteration means:</p>
<ul>
<li>Build one thing</li>
<li>Test it thoroughly</li>
<li>Document what you learned</li>
<li>Commit it</li>
<li>Move to the next thing</li>
</ul>
<h3 id="step-5-the-tools-dont-matter-the-mindset-does">Step 5: The Tools Don&rsquo;t Matter. The Mindset Does.</h3>
<p>I cannot stress this enough.</p>
<p>The language doesn&rsquo;t matter. The framework doesn&rsquo;t matter. The cloud provider doesn&rsquo;t matter.</p>
<p>What matters is:</p>
<ul>
<li>Do you understand the problem?</li>
<li>Does your solution solve it effectively?</li>
<li>Can you explain why you made the choices you made?</li>
<li>Did you learn something building it?</li>
</ul>
<p>That&rsquo;s all that matters.</p>
<hr>
<h2 id="the-real-power-wearing-all-the-hats">The Real Power: Wearing All the Hats</h2>
<p>When you build your own projects, you&rsquo;re not just a developer.</p>
<p>You&rsquo;re everything:</p>
<ul>
<li><strong>Visionary</strong> — Defining what should exist</li>
<li><strong>Product Manager</strong> — Prioritizing features</li>
<li><strong>Designer</strong> — Crafting the experience</li>
<li><strong>Developer</strong> — Building the solution</li>
<li><strong>QA</strong> — Testing and breaking things</li>
<li><strong>DevOps</strong> — Deploying and maintaining</li>
<li><strong>Support</strong> — Handling bugs and feedback</li>
</ul>
<h3 id="the-freedom-this-gives-you">The Freedom This Gives You</h3>
<p>Maybe you&rsquo;ll build something the world uses. Maybe not.</p>
<p>Either way, <strong>it&rsquo;s yours</strong>. It&rsquo;s your journey.</p>
<p>In a typical software job, you might not get to wear all these hats due to company policies and defined roles. You&rsquo;re the &ldquo;backend developer&rdquo; or the &ldquo;mobile engineer&rdquo; or the &ldquo;frontend specialist.&rdquo;</p>
<p>But here, on your own project, you are the <strong>boss</strong>. The founder. The everything.</p>
<p>This level of ownership is both daunting and incredibly empowering.</p>
<h3 id="the-career-impact">The Career Impact</h3>
<p>I&rsquo;m certain that this experience—building complete projects from vision to deployment—will help you solve day-to-day professional problems much faster.</p>
<p>Because you&rsquo;ve seen the whole picture. You understand how the pieces fit together. You&rsquo;ve debugged across the stack. You&rsquo;ve made tradeoffs and lived with the consequences.</p>
<p>That holistic understanding is <strong>invaluable</strong> and increasingly rare in our specialized world.</p>
<hr>
<h2 id="start-today-your-action-items">Start Today: Your Action Items</h2>
<p>Don&rsquo;t wait. Don&rsquo;t prepare. Don&rsquo;t plan endlessly.</p>
<p><strong>Start small. Start now.</strong></p>
<h3 id="pick-one-frustrating-problem">Pick One Frustrating Problem</h3>
<p>Look at your daily life. What frustrates you repeatedly?</p>
<ul>
<li>Tracking expenses?</li>
<li>Managing reading lists?</li>
<li>Coordinating with friends?</li>
<li>Remembering to water plants?</li>
<li>Finding recipes based on ingredients you have?</li>
</ul>
<p>Pick <strong>one</strong>. Just one.</p>
<h3 id="dont-chase-perfection-chase-progress">Don&rsquo;t Chase Perfection. Chase Progress.</h3>
<p>Your first version will be ugly. It will have bugs. It will be embarrassing to show others.</p>
<p><strong>Build it anyway.</strong></p>
<p>Because version 0.1 is infinitely better than the perfect app that exists only in your imagination.</p>
<h3 id="use-every-project-as-a-playground">Use Every Project as a Playground</h3>
<p>Want to learn a new framework? Use it for your next project.</p>
<p>Curious about a new database? Try it.</p>
<p>Interested in a new deployment strategy? Experiment.</p>
<p>Every project is an opportunity to <strong>play</strong>, to <strong>experiment</strong>, to <strong>learn</strong>.</p>
<h3 id="every-problem-solved-is-progress">Every Problem Solved Is Progress</h3>
<p>Each problem solved is one step closer to being a Solutionist.</p>
<p>Not because you&rsquo;re accumulating credentials or certificates, but because you&rsquo;re <strong>training yourself to see opportunities where others see obstacles</strong>.</p>
<hr>
<h2 id="closing-reclaiming-purpose">Closing: Reclaiming Purpose</h2>
<p>When my manager first sent me &ldquo;In Praise of Idleness,&rdquo; I thought it was ironic. Here we are, working in tech, and he&rsquo;s sending me an essay about working less?</p>
<p>Now I see the wisdom.</p>
<p>It&rsquo;s not about doing less. It&rsquo;s about <strong>doing better</strong>.</p>
<p>It&rsquo;s about focusing on work that matters, that challenges us, that makes us grow.</p>
<h3 id="what-ai-cant-replace">What AI Can&rsquo;t Replace</h3>
<p>We&rsquo;ve built technology powerful enough to automate tasks, but not powerful enough to replace people who bring <strong>meaning</strong> to them.</p>
<p>AI can:</p>
<ul>
<li>Write code</li>
<li>Debug programs</li>
<li>Architect systems</li>
<li>Generate tests</li>
<li>Refactor codebases</li>
</ul>
<p>But it can&rsquo;t:</p>
<ul>
<li>Understand <strong>why</strong> we build</li>
<li>Feel <strong>empathy</strong> for users</li>
<li>Ask deeper questions about <strong>impact</strong></li>
<li>Navigate the <strong>human</strong> complexities of real projects</li>
<li>Find <strong>purpose</strong> in the work</li>
</ul>
<p>That&rsquo;s still our job. <strong>Always will be.</strong></p>
<h3 id="the-world-needs-solutionists">The World Needs Solutionists</h3>
<p>The world doesn&rsquo;t just need coders. We have enough people who can write syntactically correct code.</p>
<p>The world needs people who:</p>
<ul>
<li>See problems and craft thoughtful solutions</li>
<li>Combine empathy with engineering</li>
<li>Explore fearlessly and learn relentlessly</li>
<li>Ask &ldquo;why&rdquo; as often as they ask &ldquo;how&rdquo;</li>
<li>Reclaim purpose in a world obsessed with productivity</li>
</ul>
<h3 id="dont-confine-yourself-to-a-box">Don&rsquo;t Confine Yourself to a Box</h3>
<p>So don&rsquo;t confine yourself to a box labeled &ldquo;Android Developer&rdquo; or &ldquo;Frontend Engineer&rdquo; or &ldquo;Data Scientist.&rdquo;</p>
<p><strong>Explore.</strong> Venture into the unknown.</p>
<p><strong>Build.</strong> Create things that matter to you.</p>
<p><strong>Reflect.</strong> Learn from what works and what doesn&rsquo;t.</p>
<p><strong>Be a Solutionist.</strong></p>
<p>Because the world doesn&rsquo;t just need more developers.</p>
<p><strong>It needs you.</strong></p>
<hr>
<h2 id="thank-you">Thank You</h2>
<p>First and foremost, a huge thank you to <strong>Google Developer Group Chennai</strong> for organizing DevFest2025 and giving me this incredible platform to share my journey and thoughts with the community.</p>
<p>To all the <strong>volunteers</strong> who worked tirelessly behind the scenes—setting up the venue, managing logistics, helping attendees, and ensuring everything ran smoothly—you are the unsung heroes who make events like this possible. Your dedication and energy created the welcoming atmosphere that made DevFest2025 special.</p>
<p>A special thanks to all the <strong>sponsors</strong> who believed in this event and invested in our developer community. Your support makes it possible for us to gather, learn, share, and grow together.</p>
<p>To the <strong>GDG Chennai organizers and core team members</strong>—thank you for building and nurturing this vibrant tech community in Chennai. Your consistent efforts to bring developers together, facilitate learning, and create opportunities for knowledge sharing are truly invaluable.</p>
<p>To everyone who <strong>attended the talk</strong> and engaged with these ideas—your questions, your reflections, your nodding heads, and even your skeptical looks made this talk so much more meaningful. The conversations we had afterward were some of the most enriching parts of the entire experience.</p>
<p>And to you, reading this now—whether you attended DevFest2025 or are discovering this for the first time—I hope something here resonates. I hope it sparks something in you.</p>
<h2 id="now-lets-build-something"><strong>Now let&rsquo;s build something.</strong></h2>
<h2 id="sone-of-the-feedbacks-from-participants">Sone of the feedbacks from Participants</h2>
<p><img alt="Feedbacks from participants" loading="lazy" src="/img/devfest_2025/updated-feedbacks-10-11-2025.png">
<em>Heartwarming feedback from the DevFest2025 participants</em></p>
<hr>
<h2 id="event-highlights">Event Highlights</h2>
<p>Here are some moments from DevFest2025:</p>
<p><img alt="Speaker Announcement" loading="lazy" src="/img/devfest_2025/speeker-annoncement-screenshot.png">
<em>The announcement that started it all</em></p>
<p><img alt="Speaking at DevFest2025" loading="lazy" src="/img/devfest_2025/talking-at-the-event.jpeg">
<em>Sharing the Solutionist Mindset with the DevFest2025 community</em></p>
<p><img alt="Speaking at the Platform" loading="lazy" src="/img/devfest_2025/speaking-at-the-platform-01.JPG">
<em>Presenting the Solutionist Mindset on stage</em></p>
<p><img alt="Speaking at the Stage" loading="lazy" src="/img/devfest_2025/speaking-at-the-stage.JPG">
<em>Engaging with the audience during the talk</em></p>
<p><img alt="DevFest 2025 Moment" loading="lazy" src="/img/devfest_2025/DevFest%2025%20(1).JPG">
<em>A memorable moment from DevFest2025</em></p>
<p><img alt="All the Volunteers" loading="lazy" src="/img/devfest_2025/DevFest%2025%20SEP%200461.-all-the%20voluntters-who-made-it-possible.JPG">
<em>All the amazing volunteers who made DevFest2025 possible - couldn&rsquo;t have done it without you!</em></p>
<p><img alt="Speaker Goodies" loading="lazy" src="/img/devfest_2025/speaker-goddies.jpeg">
<em>The speaker goodies bag - thanks GDG Chennai! For everyone who asked what&rsquo;s inside: GDG swag, stickers, and some awesome tech goodies!</em></p>
<hr>
<p><em>If you want to discuss any of these ideas further, or if you&rsquo;re building something and want to share your journey, feel free to reach out. I&rsquo;m always excited to connect with fellow solutionists.</em></p>
<p><em>All my projects are available on my website. They&rsquo;re not perfect, but they&rsquo;re mine, and they&rsquo;re continuously evolving. Just like me. Just like you.</em></p>
]]></content:encoded></item><item><title>Ollama &amp; Goose cli - Offline Agent setup</title><link>https://md.eknath.dev/posts/ai-ml/local-coding-agents/</link><pubDate>Fri, 20 Jun 2025 19:47:13 +0530</pubDate><guid>https://md.eknath.dev/posts/ai-ml/local-coding-agents/</guid><description>&lt;h2 id="fair-warning">Fair Warning&lt;/h2>
&lt;p>Make sure you are using a capable system — ideally with a powerful CPU, GPU, and adequate cooling — before running large language models locally. LLMs can consume significant resources, generate substantial heat, and may cause system instability or damage if your hardware isn’t up to the task. Please proceed with caution!&lt;/p>
&lt;p>This guide walks you through setting up Ollama (with deepseek-r1-goose) and Goose CLI.&lt;/p>
&lt;h2 id="step-1-download--install-ollama">Step 1: Download &amp;amp; Install Ollama&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>curl -fsSL https://ollama.com/install.sh | sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Or, if you prefer to download manually then checkout:&lt;a href="https://ollama.com/download">https://ollama.com/download&lt;/a>
&lt;a href="https://md.eknath.dev/posts/shell/command-line-tools/#ollama---local-and-opensource-llms">Ollama-SetUpGuide&lt;/a>&lt;/p></description><content:encoded><![CDATA[<h2 id="fair-warning">Fair Warning</h2>
<p>Make sure you are using a capable system — ideally with a powerful CPU, GPU, and adequate cooling — before running large language models locally. LLMs can consume significant resources, generate substantial heat, and may cause system instability or damage if your hardware isn’t up to the task. Please proceed with caution!</p>
<p>This guide walks you through setting up Ollama (with deepseek-r1-goose) and Goose CLI.</p>
<h2 id="step-1-download--install-ollama">Step 1: Download &amp; Install Ollama</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl -fsSL https://ollama.com/install.sh | sh
</span></span></code></pre></div><p>Or, if you prefer to download manually then checkout:<a href="https://ollama.com/download">https://ollama.com/download</a>
<a href="https://md.eknath.dev/posts/shell/command-line-tools/#ollama---local-and-opensource-llms">Ollama-SetUpGuide</a></p>
<h2 id="step-2pull-and-run-the-model">Step 2:Pull and Run the model</h2>
<p>The following model is optimized for the agent we are going to install next so lets pull and run the model:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>ollama run michaelneale/deepseek-r1-goose
</span></span></code></pre></div><p>more info about the model is available here <a href="https://www.ollama.com/michaelneale/deepseek-r1-goose">https://www.ollama.com/michaelneale/deepseek-r1-goose</a></p>
<h2 id="step-3-download-and-configure-goose-cli">Step 3: Download And configure Goose-cli</h2>
<p>Download the goose via HomeBrew if you don&rsquo;t have it installed please check this article <a href="https://md.eknath.dev/posts/shell/command-line-tools/#homebrew">HomeBrew-SetUpGuide</a></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>brew install block-goose-cli
</span></span></code></pre></div><p>now you can run the goose</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>goose 
</span></span></code></pre></div><p>Running after the first installation, the configure menu will be shown, make sure you select <code>Ollama</code> as the model provider, you can navigate by up and down arrow and hit return/enter to select the option.</p>
<p>After the model provider, next comes the model selection option, just type <code>michaelneale/deepseek-r1-goose</code> and hit return/enter.</p>
<p>Later if you want to change the model you can always run <code>bash goose configure</code>, i would recommend you use this model others are not working as expected this is already slow.</p>
<p>You can stop goose by given <code>/exit</code> command.</p>
<h2 id="where-offline-agents-work-best">Where Offline Agents Work Best</h2>
<ul>
<li>The task is narrow, well-defined, and focused.</li>
<li>You want fast, private processing without sending data to the cloud.</li>
<li>You are working with small to moderate inputs and outputs, as local models may struggle with large contexts or long conversations on limited hardware.</li>
<li>Context limit required is less than 32K tokens</li>
</ul>
<p>Again, always monitor your system’s health, and don’t hesitate to stop the model if things heat up!</p>
]]></content:encoded></item><item><title>Understanding Recurrent Neural Network</title><link>https://md.eknath.dev/posts/ai-ml/what-is-an-rnn/</link><pubDate>Wed, 19 Feb 2025 19:47:13 +0530</pubDate><guid>https://md.eknath.dev/posts/ai-ml/what-is-an-rnn/</guid><description>&lt;p>When diving into AI/ML, we constantly hear about &lt;strong>transformers&lt;/strong> and their revolutionary impact. But how did we get here? The journey started from &lt;code>Traditional Neural Networks&lt;/code> ➡ &lt;code>Recurrent Neural Networks (RNNs)&lt;/code> ➡ &lt;code>Attention Mechanisms&lt;/code> and finally to &lt;code>Transformers&lt;/code>.&lt;/p>
&lt;p>RNNs were a &lt;strong>significant milestone&lt;/strong> because they addressed sequential data processing but had major limitations. These limitations led to the birth of attention mechanisms and transformers. Interestingly, before &lt;strong>GPT&lt;/strong> became a household name, &lt;strong>Google extensively used RNNs&lt;/strong> in their products, including predictive text, speech recognition, and early recommendation systems.&lt;/p></description><content:encoded><![CDATA[<p>When diving into AI/ML, we constantly hear about <strong>transformers</strong> and their revolutionary impact. But how did we get here? The journey started from <code>Traditional Neural Networks</code> ➡ <code>Recurrent Neural Networks (RNNs)</code> ➡ <code>Attention Mechanisms</code> and finally to <code>Transformers</code>.</p>
<p>RNNs were a <strong>significant milestone</strong> because they addressed sequential data processing but had major limitations. These limitations led to the birth of attention mechanisms and transformers. Interestingly, before <strong>GPT</strong> became a household name, <strong>Google extensively used RNNs</strong> in their products, including predictive text, speech recognition, and early recommendation systems.</p>
<h2 id="what-is-a-recurrent-neural-network-rnn">What is a Recurrent Neural Network (RNN)?</h2>
<p>Have you ever wondered how your keyboard <strong>predicts the next word</strong> while typing? Before transformers took over, <strong>RNNs were the secret behind word suggestions</strong> and other sequential tasks.</p>
<h3 id="definition"><strong>Definition:</strong></h3>
<p>An <strong>RNN (Recurrent Neural Network)</strong> is a type of artificial neural network designed specifically for <strong>processing sequential data</strong>. Unlike traditional feed-forward networks, RNNs have <strong>loops that allow information to persist</strong>, making them well-suited for tasks where <strong>context and order matter</strong>.</p>
<h3 id="common-use-cases-of-rnns"><strong>Common Use Cases of RNNs:</strong></h3>
<p>👉 <strong>Natural Language Processing (NLP)</strong> (e.g., speech recognition, text generation, machine translation)<br>
👉 <strong>Time Series Prediction</strong> (e.g., stock price forecasting, weather prediction)<br>
👉 <strong>Sequence Modeling</strong> (e.g., handwriting recognition, music composition)</p>
<h2 id="how-does-an-rnn-work">How Does an RNN Work?</h2>
<p>Let’s use the <strong>word prediction</strong> example to understand the key stages of an RNN. When you type a sentence, the RNN processes it in three key stages:</p>
<h3 id="1-input-processing-stage"><strong>1️⃣ Input Processing Stage</strong></h3>
<p>This is the <strong>data collection stage</strong>, where the model gathers input to make predictions.</p>
<p>🔹 When you <strong>first start using a social media app</strong>, its recommendations may seem random or inaccurate. Over time, as you interact more, the app starts to understand your preferences. This happens because it continuously <strong>collects data from you</strong> to make better predictions.</p>
<p>🔹 In the <strong>keyboard analogy</strong>, as you type more, the model <strong>stores your words</strong> in memory, helping it predict what you might type next.</p>
<h3 id="2-hidden-state-update-memory-stage"><strong>2️⃣ Hidden State Update (Memory Stage)</strong></h3>
<p>At this stage, the RNN <strong>updates its hidden state</strong> based on the new input and previous memory.</p>
<p>🔹 In <strong>social media</strong>, the model remembers what you’ve previously engaged with and <strong>adjusts recommendations</strong> accordingly. If you keep watching <strong>travel vlogs</strong>, it will prioritize showing more similar content.</p>
<p>🔹 In <strong>keyboard predictions</strong>, the model updates its memory with each word you type, continuously refining its <strong>contextual understanding</strong>.</p>
<h3 id="3-output-generation-stage"><strong>3️⃣ Output Generation Stage</strong></h3>
<p>Now, the model <strong>makes a decision</strong> and produces an output based on its learning.</p>
<p>🔹 In <strong>social media</strong>, this means recommending the <strong>next video or post</strong> that best matches your interests.<br>
🔹 In <strong>typing</strong>, this means predicting and suggesting the <strong>next word</strong> in your sentence.</p>
<h3 id="4-backpropagation-through-time-bptt--training-stage"><strong>4️⃣ Backpropagation Through Time (BPTT) – Training Stage</strong></h3>
<p>This is where the model <strong>learns from past mistakes</strong> and improves over time. Think of it like a <strong>student reviewing mistakes from past exams</strong> to perform better in the next test.</p>
<p>🔹 In <strong>social media</strong>, if you suddenly stop engaging with travel vlogs and switch to fitness videos, the model realizes its past predictions were wrong and <strong>adjusts itself</strong> to reflect your new interests.</p>
<p>🔹 In <strong>keyboard predictions</strong>, if you frequently <strong>delete a suggested word and type something else</strong>, the model <strong>adapts</strong> to improve its future suggestions.</p>
<h3 id="how-does-bptt-work"><strong>How Does BPTT Work?</strong></h3>
<p>1️⃣ The model <strong>compares its predictions</strong> to actual user behavior.<br>
2️⃣ If there’s an <strong>error</strong>, it <strong>adjusts its internal weights</strong> to improve accuracy.<br>
3️⃣ This process repeats across <strong>multiple iterations</strong>, constantly fine-tuning the model.</p>
<p>This stage is <strong>crucial</strong> because it ensures that the model <strong>evolves and adapts</strong> based on real-world interactions.</p>
<hr>
<h2 id="final-thoughts"><strong>Final Thoughts</strong></h2>
<p>RNNs played a critical role in AI’s evolution, <strong>powering early NLP applications, recommendations, and predictive text systems</strong>. However, due to <strong>limitations like vanishing gradients and slow processing</strong>, they were eventually replaced by <strong>transformers</strong> and <strong>attention-based models</strong>.</p>
<p>Yet, understanding RNNs is essential because they paved the way for <strong>modern AI breakthroughs</strong>. Without RNNs, we wouldn’t have reached <strong>the transformer era of GPT</strong>! 🚀</p>
<hr>
<p>Your feedbacks are welcome, Thanks for Reading.</p>
]]></content:encoded></item></channel></rss>