<?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>MCP on MangoDriod</title><link>https://md.eknath.dev/tags/mcp/</link><description>Recent content in MCP 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/tags/mcp/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></channel></rss>