<?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-Tools on MangoDriod</title><link>https://md.eknath.dev/categories/ai-tools/</link><description>Recent content in AI-Tools on MangoDriod</description><generator>Hugo -- 0.141.0</generator><language>en-us</language><lastBuildDate>Tue, 17 Feb 2026 12:00:00 +0530</lastBuildDate><atom:link href="https://md.eknath.dev/categories/ai-tools/index.xml" rel="self" type="application/rss+xml"/><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></channel></rss>