<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nishikanta Ray</title>
    <description>The latest articles on DEV Community by Nishikanta Ray (@nishikantaray).</description>
    <link>https://dev.to/nishikantaray</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F478296%2F4472af16-2478-4273-a8cd-42c39effe3c0.jpg</url>
      <title>DEV Community: Nishikanta Ray</title>
      <link>https://dev.to/nishikantaray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nishikantaray"/>
    <language>en</language>
    <item>
      <title>Smashing the "Blind Spot" Bug: How We Integrated Sentry to Catch Regressions in Real-Time</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 08 Aug 2026 20:38:12 +0000</pubDate>
      <link>https://dev.to/nishikantaray/smashing-the-blind-spot-bug-how-we-integrated-sentry-to-catch-regressions-in-real-time-29m0</link>
      <guid>https://dev.to/nishikantaray/smashing-the-blind-spot-bug-how-we-integrated-sentry-to-catch-regressions-in-real-time-29m0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Smash Stories&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Flying Blind in Production
&lt;/h2&gt;

&lt;p&gt;Pull Request - &lt;a href="https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Before this summer, our analytics platform, &lt;strong&gt;InsightTrack&lt;/strong&gt;, had a fundamental flaw in how it handled observability. We were tracking standard JavaScript errors via a basic &lt;code&gt;window.onerror&lt;/code&gt; handler, but it was just noise. We had no stack traces, no grouped fingerprints, and absolutely no release context. &lt;/p&gt;

&lt;p&gt;If a customer integrated 10 different sites into our platform, we couldn't accurately tell them if a specific spike in errors was a brand-new issue or a resurrected bug from three deployments ago. We were flying blind, and our users were feeling the pain of delayed bug resolutions. &lt;/p&gt;

&lt;p&gt;The ultimate "bug" wasn't a single line of broken code; &lt;strong&gt;it was our entire error observability pipeline.&lt;/strong&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The Solution: A Deep-Dive Sentry Integration
&lt;/h2&gt;

&lt;p&gt;We decided to smash this architectural bug by building a native, robust integration with &lt;strong&gt;Sentry&lt;/strong&gt;. We didn't just want to add a widget; we wanted to bring Sentry's rich context (fingerprinted grouping, permalinks, regression status, and user-impact counts) directly into the InsightTrack dashboard so traffic and bugs could be watched side-by-side.&lt;/p&gt;

&lt;h3&gt;
  
  
  How We Built It
&lt;/h3&gt;

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

&lt;p&gt;To make this work seamlessly at scale (where one customer might poll 10 independent Sentry projects simultaneously), we built a dual-path ingestion system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Polling Backstop:&lt;/strong&gt; We set up a bounded worker pool (to prevent slow projects from stalling the fleet) that polls the Sentry API every 5 minutes. To respect rate limits, we built an &lt;strong&gt;adaptive cadence&lt;/strong&gt;—active projects poll frequently, while quiet or erroring projects exponentially back off. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Near-Real-Time Webhook:&lt;/strong&gt; For instant visibility, we allowed users to point a Sentry Internal Integration webhook at our API. Using HMAC signatures verified in constant time against a stored secret, new or regressed issues hit our database in milliseconds.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Golden Rule of our Architecture:&lt;/strong&gt; &lt;br&gt;
All writes (polls and webhooks) go to &lt;strong&gt;PostgreSQL&lt;/strong&gt;. A background sync then pushes this data to &lt;strong&gt;DuckDB&lt;/strong&gt; every 60 seconds. All dashboard reads and analytics queries come &lt;em&gt;only&lt;/em&gt; from DuckDB for lightning-fast performance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The "Smash" Moment 🔨
&lt;/h2&gt;

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

&lt;p&gt;We deployed the Sentry integration to production on a Tuesday. On Wednesday morning, it paid off spectacularly. &lt;/p&gt;

&lt;p&gt;A customer pushed a massive UI update to their e-commerce site. Within three minutes, our newly built &lt;strong&gt;Error Spike Alerts&lt;/strong&gt;—which calculate a 2-sigma (2σ) z-score against a 7-day rolling mean of Sentry events—fired off an alarm in their dashboard. &lt;/p&gt;

&lt;p&gt;Because we were pulling in Sentry's &lt;code&gt;substatus&lt;/code&gt; API field, the issue surfaced with a glaring red &lt;strong&gt;Regressed&lt;/strong&gt; badge right in our UI. &lt;/p&gt;

&lt;p&gt;Instead of opening five different tabs to figure out what went wrong, the customer clicked the row in our dashboard. This triggered our &lt;strong&gt;Live Drill-Down&lt;/strong&gt; feature, which makes an on-demand, real-time fetch directly to Sentry's &lt;code&gt;/events/latest/&lt;/code&gt; endpoint. The stack trace, breadcrumbs, and tags populated instantly. &lt;/p&gt;

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

&lt;p&gt;The bug? A deprecated checkout component that had been accidentally uncommented during a merge conflict. It was identified, patched, and deployed before most of their users even woke up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Proud Of
&lt;/h2&gt;

&lt;p&gt;I am incredibly proud of how resilient we made this system. By decoupling the write path (PostgreSQL) from the read path (DuckDB), the dashboard remains incredibly fast even if the polling workers are churning through thousands of Sentry pagination cursors in the background. &lt;/p&gt;

&lt;p&gt;I'm also proud of the &lt;strong&gt;AI Analyst (Pulse)&lt;/strong&gt; tools we built on top of this. Because the data is so cleanly structured in DuckDB, we exposed read-only MCP tools (&lt;code&gt;get_error_summary&lt;/code&gt; and &lt;code&gt;get_error_issues&lt;/code&gt;). Now, users can literally chat with their analytics dashboard and ask, &lt;em&gt;"Did yesterday's deploy cause any regressions?"&lt;/em&gt; and the AI will read the synced Sentry data to give them a perfect answer.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Handling external APIs requires defensive programming.&lt;/strong&gt; Assuming an API will always return what you expect is a recipe for disaster. Building in graceful degradation and adaptive backoffs (like dropping to a 6-hour poll cadence on a 401 Auth Fail) kept our system from DDOSing ourselves with bad tokens.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Webhooks + Polling = The perfect marriage.&lt;/strong&gt; Webhooks are great for speed, but polling is necessary for accurate counts and state reconciliation (e.g., soft-deleting issues that have aged out). Using both gives you the best of both worlds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to Sentry and the DEV community for the motivation to finally smash this architectural bug!&lt;/p&gt;

&lt;p&gt;The ultimate "bug" wasn't a single line of broken code; it was our entire error observability pipeline.&lt;br&gt;
Github - &lt;a href="https://github.com/nishikantaray/InsightTrack" rel="noopener noreferrer"&gt;https://github.com/nishikantaray/InsightTrack&lt;/a&gt;&lt;br&gt;
Website - &lt;a href="https://insightstrack.dev" rel="noopener noreferrer"&gt;https://insightstrack.dev&lt;/a&gt;&lt;br&gt;
Pull Request - &lt;a href="https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack/commit/a70ca0a00c8cd169a93b300cfcb450b5ecbde7f8&lt;/a&gt;&lt;br&gt;
Portfolio - &lt;a href="https://nishikanta.in/" rel="noopener noreferrer"&gt;https://nishikanta.in/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
    </item>
    <item>
      <title>Building an AI-native Second Brain with Multi-RAG, Knowledge Graphs, and MCP</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 08 Aug 2026 02:38:21 +0000</pubDate>
      <link>https://dev.to/nishikantaray/building-an-ai-native-second-brain-with-multi-rag-knowledge-graphs-and-mcp-fmg</link>
      <guid>https://dev.to/nishikantaray/building-an-ai-native-second-brain-with-multi-rag-knowledge-graphs-and-mcp-fmg</guid>
      <description>&lt;p&gt;Claude is incredibly good at reasoning.&lt;/p&gt;

&lt;p&gt;But reasoning is only as useful as the context available to it.&lt;/p&gt;

&lt;p&gt;Your architecture might be in GitHub. Your notes might be in Obsidian. Your decisions might be buried in Slack. Your research might be in PDFs. Your project history might exist across hundreds of conversations.&lt;/p&gt;

&lt;p&gt;The information exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem is that your AI doesn't have a unified way to understand it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I started thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if Claude had a persistent Second Brain?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not another chatbot. Not another vector database.&lt;/p&gt;

&lt;p&gt;A knowledge layer that Claude can query, learn from, and write back to.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is a Second Brain?
&lt;/h2&gt;

&lt;p&gt;A Second Brain is a personal knowledge management system that helps you capture, organize, connect, and retrieve information outside your biological memory.&lt;/p&gt;

&lt;p&gt;Tools like Obsidian made this idea powerful.&lt;/p&gt;

&lt;p&gt;You can write simple Markdown notes and connect them:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InsightTrack
    │
    ├── [[DuckDB]]
    ├── [[PostgreSQL]]
    └── [[MCP]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Obsidian then creates a visual graph of those relationships.&lt;/p&gt;

&lt;p&gt;But there is a limitation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Obsidian knows the relationships you explicitly create.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI can take this much further.&lt;/p&gt;

&lt;p&gt;Imagine having:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;architecture.md
      │
      └── mentions DuckDB

GitHub PR #481
      │
      └── changes DuckDB queries

Slack discussion
      │
      └── explains why DuckDB was selected

benchmark.md
      │
      └── contains performance results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;A human may never manually connect all four.&lt;/p&gt;

&lt;p&gt;An AI-native knowledge system can discover those relationships automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Second Brain to AI Brain
&lt;/h2&gt;

&lt;p&gt;A traditional Second Brain mainly answers:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Where did I save this?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An AI-native Second Brain should answer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"What do we know about this, where did it come from, and how is it connected to everything else?"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That requires more than vector search.&lt;/p&gt;

&lt;p&gt;It requires multiple retrieval strategies working together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Traditional RAG Isn't Enough
&lt;/h2&gt;

&lt;p&gt;A typical RAG architecture looks like:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Documents
    ↓
Chunking
    ↓
Embeddings
    ↓
Vector Search
    ↓
LLM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This works extremely well for semantic similarity.&lt;/p&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What was the reasoning behind our analytics architecture?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vector search can find relevant discussions even if the exact wording is different.&lt;/p&gt;

&lt;p&gt;But now ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Where is SYNC_BATCH_SIZE defined?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's an exact identifier.&lt;/p&gt;

&lt;p&gt;Keyword search is better.&lt;/p&gt;

&lt;p&gt;Or ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What services depend on PostgreSQL?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a relationship question.&lt;/p&gt;

&lt;p&gt;A knowledge graph is better.&lt;/p&gt;

&lt;p&gt;This is why I think a serious AI Second Brain needs &lt;strong&gt;Multi-RAG&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-RAG: Different Questions Need Different Retrieval
&lt;/h2&gt;

&lt;p&gt;Instead of relying on one retrieval technique:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Semantic Search
       +
Full-Text Search
       +
Knowledge Graph
       +
Metadata Filtering
       +
Reranking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each method solves a different problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic RAG
&lt;/h3&gt;

&lt;p&gt;Good for understanding concepts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why did we choose DuckDB?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Keyword RAG
&lt;/h3&gt;

&lt;p&gt;Good for exact information.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Find references to SYNC_BATCH_SIZE."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Graph RAG
&lt;/h3&gt;

&lt;p&gt;Good for relationships.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which services depend on PostgreSQL?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Memory Retrieval
&lt;/h3&gt;

&lt;p&gt;Good for decisions and persistent context.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What did we decide about the analytics architecture?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Together, they provide much richer context than vector search alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;The important idea isn't any individual component.&lt;/p&gt;

&lt;p&gt;It's how the components work together.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Obsidian / Documents / External Sources
                │
                ▼
           Event Queue
                │
                ▼
        Processing Workers
          │      │      │
          ▼      ▼      ▼
       Metadata Embedding Graph
          │      │      │
          └──────┼──────┘
                 ▼
          Knowledge Layer
                 │
      ┌──────────┼──────────┐
      ▼          ▼          ▼
   Vector      Search      Graph
   Search      Index       Store
      │          │          │
      └──────────┼──────────┘
                 ▼
          Retrieval Engine
                 │
                 ▼
              MCP / API
                 │
                 ▼
          Claude / GPT / AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Obsidian Is the Human Interface
&lt;/h2&gt;

&lt;p&gt;I don't see Obsidian as the entire Second Brain.&lt;/p&gt;

&lt;p&gt;I see it as one of the best &lt;strong&gt;human-facing knowledge interfaces&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can continue writing naturally:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Analytics Architecture

InsightTrack uses [[DuckDB]] for analytical queries.

Data originates in [[PostgreSQL]].

See [[Pulse]] for the AI analytics layer.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Obsidian gives you human-readable notes and a native graph.&lt;/p&gt;

&lt;p&gt;The AI system adds another layer on top.&lt;/p&gt;




&lt;h2&gt;
  
  
  Two Graphs, Two Purposes
&lt;/h2&gt;

&lt;p&gt;This architecture can maintain two different graphs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obsidian Graph
&lt;/h3&gt;

&lt;p&gt;Created from explicit links:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[InsightTrack]]
       │
       ▼
   [[DuckDB]]
       │
       ▼
  [[Analytics]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is primarily useful for &lt;strong&gt;human navigation&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  System Entity Graph
&lt;/h3&gt;

&lt;p&gt;Automatically extracted from all available knowledge:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;InsightTrack
      │
     USES
      │
   DuckDB
   /    \
READS   SYNCED_FROM
 /          \
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Pulse      PostgreSQL&lt;/p&gt;

&lt;p&gt;The system graph can be built from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Markdown&lt;/li&gt;
&lt;li&gt;Source code&lt;/li&gt;
&lt;li&gt;Git commits&lt;/li&gt;
&lt;li&gt;Pull requests&lt;/li&gt;
&lt;li&gt;Database schemas&lt;/li&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Conversations&lt;/li&gt;
&lt;li&gt;Meeting notes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This graph isn't just for visualization.&lt;/p&gt;

&lt;p&gt;It becomes part of retrieval.&lt;/p&gt;




&lt;h2&gt;
  
  
  Knowledge Engineering + Graph Engineering
&lt;/h2&gt;

&lt;p&gt;This is where the architecture becomes more interesting than a normal RAG application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Knowledge Engineering&lt;/strong&gt; turns raw information into structured knowledge.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Meeting Transcript
        ↓
     Summary
        ↓
   Action Items
        ↓
Architecture Decision
        ↓
   Project Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Graph Engineering&lt;/strong&gt; connects the resulting entities.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project
   ↓
Repository
   ↓
  API
   ↓
Database
   ↓
Developer
   ↓
Decision
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result isn't just a collection of documents.&lt;/p&gt;

&lt;p&gt;It's a connected knowledge model.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Retrieval Engine
&lt;/h2&gt;

&lt;p&gt;The retrieval engine is arguably the most important part.&lt;/p&gt;

&lt;p&gt;Suppose you ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why did we move analytics queries from PostgreSQL to DuckDB?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system might retrieve:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub PR
      +
Architecture Note
      +
Benchmark
      +
Slack Discussion
      +
Decision Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then rerank and combine the results.&lt;/p&gt;

&lt;p&gt;Instead of giving Claude thousands of chunks, the system builds a focused context:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decision:
Use DuckDB for analytical workloads.

Evidence:
- Benchmarks showed better aggregation performance.
- PostgreSQL remains the transactional source of truth.
- The architecture PR implemented the separation.
- The Slack discussion explains the operational trade-offs.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now Claude is reasoning over &lt;strong&gt;evidence + relationships + memory&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Long-Term Memory
&lt;/h2&gt;

&lt;p&gt;A Second Brain shouldn't remember everything.&lt;/p&gt;

&lt;p&gt;Otherwise, it becomes another giant database.&lt;/p&gt;

&lt;p&gt;It should remember what matters.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Decision
────────────────────
PostgreSQL remains the source of truth.

Decision
────────────────────
DuckDB handles analytical reads.

Reason
────────────────────
Better analytical performance and isolation.

Status
────────────────────
Implemented.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is much more valuable than storing thousands of raw conversations.&lt;/p&gt;

&lt;p&gt;The system should distinguish between:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw Data
   ↓
Information
   ↓
Knowledge
   ↓
Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's an important part of making AI memory useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  MCP Connects the Second Brain to Claude
&lt;/h2&gt;

&lt;p&gt;This is where the architecture becomes AI-native.&lt;/p&gt;

&lt;p&gt;Instead of building a custom integration directly into Claude, expose the Second Brain through &lt;strong&gt;MCP&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search()
retrieve()
remember()
ingest()
graph()
timeline()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Claude can ask:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;search(
  "Why did we choose DuckDB?"
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The Second Brain handles the complexity.&lt;/p&gt;

&lt;p&gt;Claude doesn't need to know whether the answer came from:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PostgreSQL
pgvector
Search Index
Knowledge Graph
Obsidian
GitHub
Slack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It simply receives useful context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Claude Can Write Back
&lt;/h2&gt;

&lt;p&gt;This is where it becomes more than traditional RAG.&lt;/p&gt;

&lt;p&gt;The flow isn't only:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Knowledge → AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;It becomes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Knowledge ↔ AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Remember that we decided to keep PostgreSQL as the source of truth."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claude calls:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;remember(...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The system can then:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Extract Entities
       ↓
Extract Relationships
       ↓
   Create Memory
       ↓
Generate Embedding
       ↓
   Update Graph
       ↓
   Store Source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The knowledge base becomes progressively richer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Model Doesn't Own the Knowledge
&lt;/h2&gt;

&lt;p&gt;This is one of the most important ideas.&lt;/p&gt;

&lt;p&gt;Today:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude
   ↓
Claude Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Another AI:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GPT
   ↓
GPT Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Another:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gemini
   ↓
Gemini Memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Everything is isolated.&lt;/p&gt;

&lt;p&gt;Instead:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Claude
                │
               GPT
                │
             Gemini
                │
              Cursor
                │
                ▼
         ┌───────────────┐
         │  Knowledge OS │
         └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The model can change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The knowledge stays.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Idea
&lt;/h2&gt;

&lt;p&gt;I don't think the future is simply:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Give Claude more context."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think it's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Build a persistent knowledge layer that every AI can use.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Obsidian can remain your human knowledge interface.&lt;/p&gt;

&lt;p&gt;GitHub can remain your source-code system.&lt;/p&gt;

&lt;p&gt;Slack can remain your communication system.&lt;/p&gt;

&lt;p&gt;Your databases can remain your data systems.&lt;/p&gt;

&lt;p&gt;Your AI assistants can remain your reasoning systems.&lt;/p&gt;

&lt;p&gt;The Knowledge OS connects them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beyond the Second Brain
&lt;/h2&gt;

&lt;p&gt;A traditional Second Brain helps &lt;strong&gt;you remember&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An AI-native Second Brain helps &lt;strong&gt;AI understand&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge Engineering&lt;/strong&gt; — turning raw information into structured knowledge&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graph Engineering&lt;/strong&gt; — discovering entities and relationships&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid Retrieval&lt;/strong&gt; — combining semantic, keyword, and graph search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-Term Memory&lt;/strong&gt; — preserving decisions and important context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; — making the knowledge available to AI agents and assistants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is something larger than a note-taking application or a vector database.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;An AI-native Knowledge Operating System that combines Knowledge Engineering, Graph Engineering, Hybrid Retrieval, and Long-Term Memory into a unified platform accessible through MCP and APIs.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The LLM provides the reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Knowledge OS provides the memory.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And MCP becomes the bridge between them.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>claude</category>
      <category>rag</category>
    </item>
    <item>
      <title>Mind Maps in MCP: A Powerful Feature or Just Eye Candy?</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 01 Aug 2026 18:27:45 +0000</pubDate>
      <link>https://dev.to/nishikantaray/mind-maps-in-mcp-a-powerful-feature-or-just-eye-candy-2oh2</link>
      <guid>https://dev.to/nishikantaray/mind-maps-in-mcp-a-powerful-feature-or-just-eye-candy-2oh2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Mind maps are an excellent addition to an MCP ecosystem when they help users understand relationships between data, tools, and reasoning. They should complement—not replace—traditional dashboards, tables, and chat interfaces.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Large Language Models have become incredibly good at answering questions. Ask about your analytics, codebase, documentation, or infrastructure, and they'll generate a detailed response in seconds.&lt;/p&gt;

&lt;p&gt;But there's a problem.&lt;/p&gt;

&lt;p&gt;Most AI conversations are &lt;strong&gt;linear&lt;/strong&gt;, while the problems we're solving are &lt;strong&gt;non-linear&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did traffic drop yesterday?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A traditional AI responds with several paragraphs of text.&lt;/p&gt;

&lt;p&gt;A mind map, however, immediately shows the relationships between traffic sources, landing pages, countries, devices, deployments, and JavaScript errors.&lt;/p&gt;

&lt;p&gt;Instead of reading hundreds of words, you understand the entire situation in seconds.&lt;/p&gt;

&lt;p&gt;This naturally raises an interesting question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should every MCP server support mind maps?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After exploring different architectures and use cases, my conclusion is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes—but only when they help users understand relationships rather than simply displaying information.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's explore why.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Mind Map in MCP?
&lt;/h2&gt;

&lt;p&gt;An MCP (Model Context Protocol) server exposes tools that AI models can use.&lt;/p&gt;

&lt;p&gt;Normally the workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User
  │
  ▼
LLM
  │
  ▼
MCP Tool
  │
  ▼
Database
  │
  ▼
Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI collects data, summarizes it, and returns text.&lt;/p&gt;

&lt;p&gt;Now imagine adding a visualization layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             User
               │
               ▼
          AI Planner
               │
      ┌────────┴────────┐
      ▼                 ▼
 Analytics Tool    Documentation Tool
      ▼                 ▼
 Error Tool        Code Search Tool
      ▼                 ▼
      └────────┬────────┘
               ▼
     Relationship Builder
               ▼
      Interactive Mind Map
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI still performs the same work.&lt;/p&gt;

&lt;p&gt;The difference is that users now see &lt;strong&gt;how everything connects&lt;/strong&gt; instead of reading a long explanation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Traditional AI Isn't Always Enough
&lt;/h2&gt;

&lt;p&gt;Humans naturally think in relationships.&lt;/p&gt;

&lt;p&gt;When someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why are conversions down?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They aren't thinking linearly.&lt;/p&gt;

&lt;p&gt;They're exploring multiple possibilities simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Conversions
│
├── Traffic
│
├── Checkout
│
├── Marketing
│
├── Performance
│
├── Returning Users
│
└── Errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each branch creates another investigation.&lt;/p&gt;

&lt;p&gt;This is exactly how troubleshooting works.&lt;/p&gt;

&lt;p&gt;A mind map simply visualizes that thought process.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Analytics Example
&lt;/h2&gt;

&lt;p&gt;Suppose an AI receives this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why did yesterday's traffic decrease?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of returning paragraphs, it could generate something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic Drop
│
├── Organic Search ↓
│
├── Homepage ↓
│
├── India ↓
│
├── JavaScript Errors ↑
│
├── Core Web Vitals ↓
│
└── New Deployment ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within seconds the user understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organic search decreased&lt;/li&gt;
&lt;li&gt;Homepage was affected&lt;/li&gt;
&lt;li&gt;Most impact came from India&lt;/li&gt;
&lt;li&gt;JavaScript errors increased&lt;/li&gt;
&lt;li&gt;A deployment happened recently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The graph immediately tells a story.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Mind Maps Work Best
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. Analytics Investigation
&lt;/h2&gt;

&lt;p&gt;Traditional dashboards answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many visitors?&lt;/li&gt;
&lt;li&gt;Which country?&lt;/li&gt;
&lt;li&gt;Which browser?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mind maps answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why did traffic change?&lt;/li&gt;
&lt;li&gt;Which metrics influence each other?&lt;/li&gt;
&lt;li&gt;What caused this anomaly?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic
│
├── Organic
│   ├── Landing Pages
│   ├── Keywords
│   └── Countries
│
├── Paid
│
├── Social
│
└── Referral
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transforms disconnected metrics into connected insights.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Documentation Search
&lt;/h2&gt;

&lt;p&gt;Imagine asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Explain authentication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of returning dozens of documents, the AI groups concepts together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Authentication
│
├── OAuth
├── JWT
├── API Keys
├── Sessions
└── Permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users instantly understand the overall architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Codebase Exploration
&lt;/h2&gt;

&lt;p&gt;Large repositories can be overwhelming.&lt;/p&gt;

&lt;p&gt;Instead of thousands of files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Backend
│
├── API
│
├── Database
│   ├── PostgreSQL
│   └── Prisma
│
├── Authentication
│
└── Workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developers can navigate the repository visually.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. AI Agent Planning
&lt;/h2&gt;

&lt;p&gt;Most AI agents perform many hidden steps.&lt;/p&gt;

&lt;p&gt;A mind map exposes them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task
│
├── Research
│
├── Search
│
├── Compare
│
├── Generate
│
└── Validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes debugging AI workflows dramatically easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Biggest Advantages
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Better Understanding
&lt;/h2&gt;

&lt;p&gt;Humans recognize patterns much faster than paragraphs.&lt;/p&gt;

&lt;p&gt;Instead of reading 800 words, users understand the entire structure in seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Relationship Discovery
&lt;/h2&gt;

&lt;p&gt;Traditional dashboards display numbers.&lt;/p&gt;

&lt;p&gt;Mind maps display relationships.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Deployment
      │
      ▼
JavaScript Errors
      │
      ▼
Checkout Failure
      │
      ▼
Revenue Drop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That chain is much harder to discover from charts alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  Easier Navigation
&lt;/h2&gt;

&lt;p&gt;Users don't need every detail immediately.&lt;/p&gt;

&lt;p&gt;They can expand only the sections they care about.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic
  │
  ├── Organic
  │
  ├── Direct
  │
  └── Social
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps complex systems manageable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Better AI Transparency
&lt;/h2&gt;

&lt;p&gt;Instead of wondering why the AI reached a conclusion, users can inspect the reasoning path visually.&lt;/p&gt;

&lt;p&gt;This increases trust in AI-generated answers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Mind Maps Fail
&lt;/h2&gt;

&lt;p&gt;Like every visualization, they have limitations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Everything Becomes a Graph
&lt;/h2&gt;

&lt;p&gt;One common mistake is trying to visualize every piece of information.&lt;/p&gt;

&lt;p&gt;Imagine this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Visitors
│
├── Countries
├── Browsers
├── Devices
├── Sessions
├── Events
├── Campaigns
├── Pages
├── Heatmaps
├── Errors
├── Funnels
├── Scroll Depth
├── UTM
├── Performance
└── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few hundred nodes, the graph becomes unreadable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tables Are Sometimes Better
&lt;/h2&gt;

&lt;p&gt;Suppose someone asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Show today's visitors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They don't need a graph.&lt;/p&gt;

&lt;p&gt;They need this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hour&lt;/th&gt;
&lt;th&gt;Visitors&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;9 AM&lt;/td&gt;
&lt;td&gt;241&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10 AM&lt;/td&gt;
&lt;td&gt;318&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11 AM&lt;/td&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Not every question benefits from visualization.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Large graphs become expensive.&lt;/p&gt;

&lt;p&gt;Some challenges include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thousands of nodes&lt;/li&gt;
&lt;li&gt;Complex edge calculations&lt;/li&gt;
&lt;li&gt;Layout algorithms&lt;/li&gt;
&lt;li&gt;Browser memory usage&lt;/li&gt;
&lt;li&gt;Slow rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most graph libraries begin struggling once graphs become extremely large unless clustering or virtualization is implemented.&lt;/p&gt;




&lt;h2&gt;
  
  
  Additional Maintenance
&lt;/h2&gt;

&lt;p&gt;Relationships don't build themselves.&lt;/p&gt;

&lt;p&gt;Every new feature means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New node types&lt;/li&gt;
&lt;li&gt;New edge rules&lt;/li&gt;
&lt;li&gt;Updated layouts&lt;/li&gt;
&lt;li&gt;Better ranking algorithms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Graph maintenance quickly becomes its own subsystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes
&lt;/h2&gt;

&lt;p&gt;Many developers build graphs that simply mirror database tables.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Country
   │
   ▼
India
   │
   ▼
Users
   │
   ▼
5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That provides almost no value.&lt;/p&gt;

&lt;p&gt;Instead, focus on &lt;strong&gt;relationships&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traffic Drop
│
├── Homepage
├── Organic Search
├── India
└── JavaScript Errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The graph explains &lt;em&gt;why&lt;/em&gt; something happened.&lt;/p&gt;




&lt;h2&gt;
  
  
  Should Every MCP Include Mind Maps?
&lt;/h2&gt;

&lt;p&gt;Not necessarily.&lt;/p&gt;

&lt;p&gt;Here's a simple rule.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Great Fit&lt;/th&gt;
&lt;th&gt;Poor Fit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Documentation&lt;/td&gt;
&lt;td&gt;Raw SQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI reasoning&lt;/td&gt;
&lt;td&gt;CSV exports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Research&lt;/td&gt;
&lt;td&gt;Tables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;Dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent workflows&lt;/td&gt;
&lt;td&gt;Metric reports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knowledge graphs&lt;/td&gt;
&lt;td&gt;Simple searches&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Mind maps are strongest when users need to understand &lt;strong&gt;connections&lt;/strong&gt;, not just retrieve information.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Better Architecture
&lt;/h2&gt;

&lt;p&gt;Rather than replacing the existing interface, add mind maps as an exploration mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dashboard
│
├── Visitors
├── Revenue
├── Funnels
├── Heatmaps
└── Errors

        │
        ▼

🧠 Explore Relationships

        │
        ▼

Traffic
│
├── Acquisition
├── Geography
├── Pages
├── Errors
└── Performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dashboard remains familiar.&lt;/p&gt;

&lt;p&gt;The graph becomes a discovery tool.&lt;/p&gt;

&lt;p&gt;This hybrid approach gives users the best of both worlds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Recommended Libraries
&lt;/h2&gt;

&lt;p&gt;If you're planning to build interactive graph visualizations, these libraries are worth considering.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Flow
&lt;/h3&gt;

&lt;p&gt;Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive editors&lt;/li&gt;
&lt;li&gt;Expandable nodes&lt;/li&gt;
&lt;li&gt;Workflow builders&lt;/li&gt;
&lt;li&gt;AI reasoning graphs&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Cytoscape.js
&lt;/h3&gt;

&lt;p&gt;Excellent for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large relationship graphs&lt;/li&gt;
&lt;li&gt;Knowledge visualization&lt;/li&gt;
&lt;li&gt;Network analysis&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  AntV G6
&lt;/h3&gt;

&lt;p&gt;Great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise dashboards&lt;/li&gt;
&lt;li&gt;Knowledge graphs&lt;/li&gt;
&lt;li&gt;Automatic layouts&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Sigma.js
&lt;/h3&gt;

&lt;p&gt;Designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Very large graphs&lt;/li&gt;
&lt;li&gt;High-performance rendering&lt;/li&gt;
&lt;li&gt;Thousands of nodes&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  D3.js
&lt;/h3&gt;

&lt;p&gt;Ideal when you need complete customization and don't mind writing more code.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Recommendation
&lt;/h2&gt;

&lt;p&gt;If I were designing an MCP platform today, I wouldn't make the mind map the default interface.&lt;/p&gt;

&lt;p&gt;Instead, I'd treat it as an &lt;strong&gt;optional exploration layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Users should still have access to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional chat&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Dashboards&lt;/li&gt;
&lt;li&gt;Charts&lt;/li&gt;
&lt;li&gt;SQL results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When they want to understand relationships, they can switch to the graph view.&lt;/p&gt;

&lt;p&gt;This keeps the interface simple while providing powerful visualization when it's genuinely useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Mind maps aren't valuable because they look impressive.&lt;/p&gt;

&lt;p&gt;They're valuable because they help users understand relationships that are difficult to see in text, tables, or dashboards.&lt;/p&gt;

&lt;p&gt;For MCP ecosystems, they're especially effective for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI reasoning&lt;/li&gt;
&lt;li&gt;Documentation discovery&lt;/li&gt;
&lt;li&gt;Codebase exploration&lt;/li&gt;
&lt;li&gt;Knowledge graphs&lt;/li&gt;
&lt;li&gt;Multi-agent workflows&lt;/li&gt;
&lt;li&gt;Analytics investigations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, they should never replace dashboards or structured data.&lt;/p&gt;

&lt;p&gt;The most effective MCP platforms will combine both approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chat for conversations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dashboards for metrics&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mind maps for relationships&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use each interface where it excels.&lt;/p&gt;

&lt;p&gt;In the end, the goal isn't to make AI prettier—it's to make complex information easier to understand.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Running Hermes Agent with Kokoro TTS: A Local-First AI Assistant Setup</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 26 Jul 2026 07:19:14 +0000</pubDate>
      <link>https://dev.to/nishikantaray/running-hermes-agent-with-kokoro-tts-a-local-first-ai-assistant-setup-523h</link>
      <guid>https://dev.to/nishikantaray/running-hermes-agent-with-kokoro-tts-a-local-first-ai-assistant-setup-523h</guid>
      <description>&lt;p&gt;Most AI agents today depend heavily on cloud APIs. They're fast, but every request costs money, depends on an internet connection, and sends your data to external providers.&lt;/p&gt;

&lt;p&gt;Over the weekend, I experimented with &lt;strong&gt;Hermes Agent&lt;/strong&gt; and &lt;strong&gt;Kokoro TTS&lt;/strong&gt;, building a completely local voice-enabled AI assistant. The result was surprisingly good—responses were generated locally, converted into natural speech, and even delivered through Telegram.&lt;/p&gt;

&lt;p&gt;It felt much closer to having a personal AI operating system than simply chatting with an LLM.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Hermes Agent?
&lt;/h2&gt;

&lt;p&gt;Hermes Agent is an open-source AI agent framework from Nous Research designed for long-running AI workflows. Unlike a traditional chatbot, Hermes can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execute tools&lt;/li&gt;
&lt;li&gt;Remember previous interactions&lt;/li&gt;
&lt;li&gt;Learn reusable skills&lt;/li&gt;
&lt;li&gt;Schedule recurring jobs&lt;/li&gt;
&lt;li&gt;Connect with messaging platforms like Telegram&lt;/li&gt;
&lt;li&gt;Work with both cloud and local models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also supports OpenAI-compatible endpoints, making it easy to swap between cloud providers and local inference engines.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why use Kokoro TTS?
&lt;/h2&gt;

&lt;p&gt;Kokoro is a lightweight text-to-speech engine that runs locally and produces surprisingly natural voices.&lt;/p&gt;

&lt;p&gt;Instead of sending text to cloud TTS providers, everything happens on your own machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Completely offline&lt;/li&gt;
&lt;li&gt;No API costs&lt;/li&gt;
&lt;li&gt;Low latency&lt;/li&gt;
&lt;li&gt;Privacy-friendly&lt;/li&gt;
&lt;li&gt;Easy integration with local AI workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For demos, assistants, and automation, it feels almost instant.&lt;/p&gt;




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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                User
                  │
          Telegram / CLI
                  │
          ┌───────────────┐
          │ Hermes Agent  │
          └──────┬────────┘
                 │
      ┌──────────┴──────────┐
      │                     │
 Local LLM             Tool Calls
(Qwen/Llama/etc.)      Browser/MCP/etc.
      │
      ▼
 Response Text
      │
      ▼
 Kokoro TTS
      │
      ▼
 Natural Voice
      │
      ▼
 Telegram Voice Message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same response can be delivered as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;Voice&lt;/li&gt;
&lt;li&gt;Or both simultaneously&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why run locally?
&lt;/h2&gt;

&lt;p&gt;A local-first setup offers several advantages:&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;Sensitive conversations never leave your machine unless you explicitly enable external tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zero inference cost
&lt;/h3&gt;

&lt;p&gt;After downloading the models, you no longer pay per request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Faster iteration
&lt;/h3&gt;

&lt;p&gt;Developers can test prompts, agents, and automations without worrying about API limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline capability
&lt;/h3&gt;

&lt;p&gt;Useful for demos, labs, or environments with limited internet access.&lt;/p&gt;




&lt;h2&gt;
  
  
  Typical Setup
&lt;/h2&gt;

&lt;p&gt;A common local stack looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hermes Agent&lt;/li&gt;
&lt;li&gt;Ollama or another OpenAI-compatible local model server&lt;/li&gt;
&lt;li&gt;Kokoro TTS&lt;/li&gt;
&lt;li&gt;Telegram Gateway (optional)&lt;/li&gt;
&lt;li&gt;MCP servers&lt;/li&gt;
&lt;li&gt;Local memory and skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hermes can connect to local model servers such as Ollama, LM Studio, vLLM, llama.cpp, and other OpenAI-compatible endpoints.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Personal AI Assistant
&lt;/h3&gt;

&lt;p&gt;Ask questions and receive spoken replies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coding Agent
&lt;/h3&gt;

&lt;p&gt;Read repositories, execute tools, and explain code aloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customer Support Bot
&lt;/h3&gt;

&lt;p&gt;Generate text and voice responses without cloud inference costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Home Automation
&lt;/h3&gt;

&lt;p&gt;Control local services with voice feedback.&lt;/p&gt;

&lt;h3&gt;
  
  
  Content Creation
&lt;/h3&gt;

&lt;p&gt;Generate narration for tutorials, demos, podcasts, and videos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Research Assistant
&lt;/h3&gt;

&lt;p&gt;Summarise documents and listen instead of reading long reports.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pros
&lt;/h2&gt;

&lt;p&gt;✅ Local inference&lt;/p&gt;

&lt;p&gt;✅ Better privacy&lt;/p&gt;

&lt;p&gt;✅ No recurring API costs&lt;/p&gt;

&lt;p&gt;✅ Natural voice responses&lt;/p&gt;

&lt;p&gt;✅ Works with existing OpenAI-compatible APIs&lt;/p&gt;

&lt;p&gt;✅ Flexible model switching&lt;/p&gt;

&lt;p&gt;✅ Extensible through tools and skills&lt;/p&gt;




&lt;h2&gt;
  
  
  Cons
&lt;/h2&gt;

&lt;p&gt;❌ Requires decent CPU/GPU resources&lt;/p&gt;

&lt;p&gt;❌ Initial model downloads can be large&lt;/p&gt;

&lt;p&gt;❌ Local models may be slower than premium cloud models&lt;/p&gt;

&lt;p&gt;❌ Voice quality depends on the selected TTS model&lt;/p&gt;

&lt;p&gt;❌ Some external tools (web search, browser automation, cloud speech) still require internet access if enabled.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who should use this?
&lt;/h2&gt;

&lt;p&gt;This setup is ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI developers&lt;/li&gt;
&lt;li&gt;Open-source enthusiasts&lt;/li&gt;
&lt;li&gt;Privacy-conscious users&lt;/li&gt;
&lt;li&gt;Local LLM experimentation&lt;/li&gt;
&lt;li&gt;Voice assistant projects&lt;/li&gt;
&lt;li&gt;Internal enterprise tooling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're already using MCP servers or self-hosted AI infrastructure, Hermes integrates naturally into that workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Hermes Agent combined with Kokoro TTS creates a surprisingly capable local AI assistant. Instead of just generating text, the system can reason, use tools, remember context, and respond with natural speech—all while keeping inference largely on your own machine.&lt;/p&gt;

&lt;p&gt;For developers building AI assistants, coding agents, research tools, or voice-enabled applications, this local-first stack offers an excellent balance between privacy, flexibility, and cost.&lt;/p&gt;

&lt;p&gt;After experimenting with it over the weekend, it's easy to see why local AI workflows are becoming increasingly practical. Cloud models still have their place for the hardest reasoning tasks, but for many day-to-day workflows, a local setup is already more than capable.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
    </item>
    <item>
      <title>InsightsTrack + Pulse: I taught Claude Desktop to read my web analytics (via MCP)</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:01:53 +0000</pubDate>
      <link>https://dev.to/nishikantaray/insightstrack-pulse-i-taught-claude-desktop-to-read-my-web-analytics-via-mcp-13bd</link>
      <guid>https://dev.to/nishikantaray/insightstrack-pulse-i-taught-claude-desktop-to-read-my-web-analytics-via-mcp-13bd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/weekend-2026-07-09"&gt;Weekend Challenge: Passion Edition&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;InsightsTrack&lt;/strong&gt; is a self-hosted, privacy-first web analytics platform — the open-source alternative to Google Analytics. No cookies, no consent banner, no data selling. You run it on your own server and get real-time visitors, funnels, heatmaps, Core Web Vitals, and 17+ analytics views.&lt;/p&gt;

&lt;p&gt;But the part I'm passionate about — and the reason I'm submitting it here — is &lt;strong&gt;Pulse&lt;/strong&gt;: a built-in &lt;strong&gt;AI analyst&lt;/strong&gt; that turns your analytics into a conversation.&lt;/p&gt;

&lt;p&gt;Instead of hunting through dashboards, you just &lt;strong&gt;ask&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"What were my top pages last week?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"Where is my traffic coming from?"&lt;/em&gt;&lt;br&gt;
&lt;em&gt;"Where are users dropping off in the funnel?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pulse answers in plain English, with &lt;strong&gt;real charts, tables, and CSV exports&lt;/strong&gt; — every number backed by a live tool call, never hallucinated.&lt;/p&gt;

&lt;p&gt;And here's the passion project twist: Pulse isn't locked inside the dashboard. The &lt;strong&gt;same analytics tools are exposed over MCP (Model Context Protocol)&lt;/strong&gt;, so I can open &lt;strong&gt;Claude Desktop, Cursor, or any MCP client&lt;/strong&gt; and ask &lt;em&gt;it&lt;/em&gt; about my website traffic — and it queries InsightsTrack directly.&lt;/p&gt;

&lt;p&gt;My goal: &lt;strong&gt;make your own analytics as easy to query as sending a text message — and make that capability portable to every AI tool you already use.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;🔗 Live app:&lt;/strong&gt; &lt;code&gt;https://insightstrack.dev&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;▶️ Video walkthrough:&lt;/strong&gt;  &lt;code&gt;https://youtu.be/LGZw8temtPY&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to show in the demo:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the dashboard, click &lt;strong&gt;Ask Pulse&lt;/strong&gt;, type &lt;em&gt;"top pages last 7 days"&lt;/em&gt; → watch it stream an answer + render a table with a &lt;strong&gt;CSV&lt;/strong&gt; button and an &lt;strong&gt;Open pages →&lt;/strong&gt; deep link.&lt;/li&gt;
&lt;li&gt;Switch the same result between &lt;strong&gt;table / bar / line / donut&lt;/strong&gt; with one click.&lt;/li&gt;
&lt;li&gt;Open &lt;strong&gt;Claude Desktop&lt;/strong&gt; → ask &lt;em&gt;"which sites do I have in InsightsTrack, and what's my top traffic source this month?"&lt;/em&gt; → it calls the MCP tools and answers with live data.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/NishikantaRay" rel="noopener noreferrer"&gt;
        NishikantaRay
      &lt;/a&gt; / &lt;a href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;
        InsightTrack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Self-hosted, privacy-first web analytics — the open-source alternative to Google Analytics
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📊 InsightsTrack&lt;/h1&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Self-hosted, privacy-first web analytics — the open-source alternative to Google Analytics&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/NishikantaRay/InsightTrack/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f43a51a164cf5f983be3c12a2c0ae6d92e5681ab465291ee1451bee73924d627/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4f70656e253230536f757263652d4d49542d363336366631" alt="Open Source"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/7ad148220f3c4c917ac675fc5994ff877426e174f08cf70e4c29ddad1cfa861a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53656c662d2d486f737465642d2545322539432539332d313062393831" alt="Self-Hosted"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/be3fd7535ed16cf4d4fc507342a2b1f744fc69d66daccd304a31c7027b988aa0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f436f6f6b6965732d302d656634343434" alt="No Cookies"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/38e45558ae5f1311ea0e03fc6cb86079939a31f9fd8fd1bdf5aca997fc50a64c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f526561637425323031382532302543322542372532304578707265737325323034253230254332254237253230506f737467726553514c2532302543322542372532304475636b44422d316131643237" alt="Stack"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sponsors/NishikantaRay" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/05d8c2ed8cfde259492aa9dd3bff228814b32829af1a581cc12ec43ea6a62d08/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f25453225393925413525323053706f6e736f722d4e697368696b616e74615261792d6561346161613f6c6f676f3d67697468756273706f6e736f7273" alt="Sponsor"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Track visitors, pageviews, conversions, heatmaps, and Core Web Vitals — all on your own server.&lt;/strong&gt;
No cookies, no consent banners, no data selling. Deploy in under 15 minutes.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/NishikantaRay/InsightTrack#-live-demo" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack#-quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack#-feature-walkthrough" rel="noopener noreferrer"&gt;Features&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack#-deploy-your-own" rel="noopener noreferrer"&gt;Deploy&lt;/a&gt; · &lt;a href="https://github.com/NishikantaRay/InsightTrack/docs/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/NishikantaRay/InsightTrack/screenshots/11-dashboard-full.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FNishikantaRay%2FInsightTrack%2FHEAD%2Fscreenshots%2F11-dashboard-full.png" alt="InsightsTrack Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is InsightsTrack?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;InsightsTrack is a complete, production-grade web analytics platform you run yourself. It gives you the depth of Google Analytics 4 — real-time visitors, traffic sources, funnels, heatmaps, Web Vitals — without sending a single byte of your visitors' data to a third party.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why teams choose it:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🔒 &lt;strong&gt;Privacy by design&lt;/strong&gt; — no cookies, no fingerprinting, anonymous visitor IDs, GDPR-compliant, DNT/GPC honored.&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Fast at any scale&lt;/strong&gt; — a dual-database design (PostgreSQL for writes, DuckDB for reads) answers 90-day queries in under 100 ms even over millions of events.&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Everything in one place&lt;/strong&gt; —…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The parts most relevant to this submission:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP tool registry&lt;/strong&gt; — &lt;code&gt;analytics-db/src/mcp/tools/registry.js&lt;/code&gt; (17 read-only tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP protocol handler&lt;/strong&gt; (JSON-RPC 2.0, remote Streamable-HTTP transport) — &lt;code&gt;analytics-db/src/mcp/protocol.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The stdio bridge&lt;/strong&gt; for local clients — &lt;code&gt;mcp-server/src/index.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The AI loop + BYO-key provider layer&lt;/strong&gt; (Anthropic / OpenAI / Gemini) — &lt;code&gt;analytics-db/src/routes/assistant.js&lt;/code&gt; and &lt;code&gt;analytics-db/src/mcp/llm/provider.js&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;h3&gt;
  
  
  The dual-database core
&lt;/h3&gt;

&lt;p&gt;InsightsTrack writes every tracking event to &lt;strong&gt;PostgreSQL&lt;/strong&gt; and streams it into &lt;strong&gt;DuckDB&lt;/strong&gt;, an embedded columnar engine. All analytics &lt;em&gt;reads&lt;/em&gt; hit DuckDB — 90-day queries answer in tens of milliseconds, in-process, with no separate query cluster. Writes go to Postgres, reads come from DuckDB. That separation is what makes it fast &lt;em&gt;and&lt;/em&gt; cheap to self-host.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pulse: one tool registry, two front doors
&lt;/h3&gt;

&lt;p&gt;The interesting decision was &lt;strong&gt;not&lt;/strong&gt; building the AI assistant and the MCP integration as two separate things. There's &lt;strong&gt;one registry of 17 read-only tools&lt;/strong&gt; (&lt;code&gt;get_kpi&lt;/code&gt;, &lt;code&gt;get_top_pages&lt;/code&gt;, &lt;code&gt;get_funnel&lt;/code&gt;, &lt;code&gt;get_realtime&lt;/code&gt;, &lt;code&gt;list_sites&lt;/code&gt;, …). That single registry powers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The in-dashboard Pulse panel&lt;/strong&gt; — a streaming chat loop that lets an LLM call the tools and renders each result as a chart/table/KPI card.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP&lt;/strong&gt; — the exact same tools, exposed to external clients.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because both surfaces share the registry, an answer is consistent everywhere and I only maintain the tools once.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP: two transports
&lt;/h3&gt;

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

&lt;p&gt;This is the connector heart of the project. I implemented &lt;strong&gt;both&lt;/strong&gt; MCP transports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Remote (Streamable-HTTP)&lt;/strong&gt; — &lt;code&gt;POST /api/mcp/http&lt;/code&gt; speaks JSON-RPC 2.0 (&lt;code&gt;initialize&lt;/code&gt; / &lt;code&gt;tools/list&lt;/code&gt; / &lt;code&gt;tools/call&lt;/code&gt;). Clients that support remote MCP connect with just a URL + a bearer connect token. Nothing to install.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local (stdio bridge)&lt;/strong&gt; — a tiny &lt;code&gt;mcp-server&lt;/code&gt; process (the only place the real &lt;code&gt;@modelcontextprotocol/sdk&lt;/code&gt; is used) runs next to the client, speaks stdio, and &lt;strong&gt;proxies every call over HTTP to the API&lt;/strong&gt;. It never touches the database — which keeps per-user site scoping and DuckDB's single-writer lock intact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connect tokens are scoped JWTs (&lt;code&gt;scope: 'mcp'&lt;/code&gt;, with &lt;code&gt;jti&lt;/code&gt; so they can be revoked one-by-one), so a leaked token from one laptop can be killed without affecting others. All tools are &lt;strong&gt;read-only&lt;/strong&gt; — the AI can query but can never change or delete data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bring-your-own-key, encrypted at rest
&lt;/h3&gt;

&lt;p&gt;Pulse runs on &lt;strong&gt;your&lt;/strong&gt; model key — &lt;strong&gt;Anthropic (Claude), OpenAI (GPT), or Google (Gemini)&lt;/strong&gt;. Keys are stored &lt;strong&gt;AES-256-GCM encrypted&lt;/strong&gt; (dependency-free &lt;code&gt;node:crypto&lt;/code&gt;, key derived from the server secret) and &lt;strong&gt;never leave your server&lt;/strong&gt;. Precedence is BYO-key first, server key as fallback — so a self-hoster can either let every user bring their own, or set one server key so it "just works."&lt;/p&gt;

&lt;h3&gt;
  
  
  Result cards that do real work
&lt;/h3&gt;

&lt;p&gt;Every tool returns a structured envelope — &lt;code&gt;{ summary, data, render, download, deepLink }&lt;/code&gt;. The dashboard turns that into a card with a &lt;strong&gt;CSV export&lt;/strong&gt;, a &lt;strong&gt;view switcher&lt;/strong&gt; (table ↔ bar ↔ line ↔ donut, client-side, no re-query), and a &lt;strong&gt;deep link&lt;/strong&gt; to the matching dashboard page. Over MCP, the same envelope ships as &lt;code&gt;structuredContent&lt;/code&gt; so agent clients get the data too.&lt;/p&gt;

&lt;h3&gt;
  
  
  The honest hard part
&lt;/h3&gt;

&lt;p&gt;Getting Gemini to work over its OpenAI-compatible endpoint surfaced a subtle streaming bug: OpenAI streams tool-call arguments as &lt;em&gt;fragments to concatenate&lt;/em&gt;, but Gemini sends the &lt;em&gt;complete&lt;/em&gt; arguments object per delta (and sometimes repeats it) — naive concatenation produced invalid JSON like &lt;code&gt;{}{}&lt;/code&gt; that Gemini then rejected on the next round. The fix: if an incoming fragment is already valid JSON, treat it as the whole value instead of appending. One provider quirk, but it's the difference between "Gemini works" and a mysterious &lt;code&gt;INVALID_ARGUMENT&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Best Use of Google AI&lt;/strong&gt; — Pulse supports &lt;strong&gt;Google Gemini&lt;/strong&gt; as a first-class model provider for the AI analyst. Bring a Gemini API key in Settings and every plain-English question about your analytics is answered by Gemini calling InsightsTrack's 17 read-only tools — in the dashboard &lt;em&gt;and&lt;/em&gt; over MCP from Claude Desktop / Cursor.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with ❤️ as an open-source project. Try it, self-host it, or connect it to your favorite AI client. Feedback and stars welcome → &lt;a href="https://github.com/NishikantaRay/InsightTrack" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/InsightTrack&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How I Finally Finished InsightTrack — My Abandoned Self-Hosted Analytics Platform</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sun, 24 May 2026 04:04:23 +0000</pubDate>
      <link>https://dev.to/nishikantaray/how-i-finally-finished-insighttrack-my-abandoned-self-hosted-analytics-platform-1k7l</link>
      <guid>https://dev.to/nishikantaray/how-i-finally-finished-insighttrack-my-abandoned-self-hosted-analytics-platform-1k7l</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Details
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;InsightTrack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nishikantaray/insighttrack" rel="noopener noreferrer"&gt;github.com/nishikantaray/insighttrack&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Stack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;React 18 · Vite 5 · Tailwind CSS · Express 4 · Node.js 20 · PostgreSQL · DuckDB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

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

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

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

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

&lt;p&gt;&lt;strong&gt;InsightTrack&lt;/strong&gt; is a self-hosted, privacy-first web analytics platform — my personal answer to the question &lt;em&gt;"Why do I have to send all my users' data to Google just to know how many people visited my site?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It tracks pageviews, sessions, conversions, user flows, and engagement — all on your own infrastructure, with no cookies and no third-party data sharing. The architecture uses &lt;strong&gt;PostgreSQL&lt;/strong&gt; for all writes and &lt;strong&gt;DuckDB&lt;/strong&gt; as an embedded columnar OLAP engine for analytics reads, achieving 10-100× the query speed of a traditional row-store setup.&lt;/p&gt;

&lt;p&gt;I started InsightTrack during a long weekend when I was frustrated with the privacy implications of Google Analytics and the price tags on alternatives like Plausible and Fathom. The idea was simple: build a clean, self-hostable dashboard that you could drop a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag into and be live in 5 minutes.&lt;/p&gt;

&lt;p&gt;I got a working v1 out. It had a dashboard, auth, an onboarding wizard, basic charts, funnels, and a Docker Compose file that actually ran. Then I stopped. The project sat in a local folder for months — &lt;em&gt;almost&lt;/em&gt; good enough, but not quite. The DuckDB sync was fragile. There was no dark mode on half the pages. Dozens of planned features were never built. Query performance fell apart past 30 days of data.&lt;/p&gt;

&lt;p&gt;The bones were good. I just never gave it the finish it deserved.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your Website
  └── analytics.js (tracking script, ~2 KB)
        │  POST /api/track/event
        ▼
  Express API (Node.js)
        │  Writes
        ▼
  PostgreSQL ──── Incremental sync worker (every 5 min)
                        │
                        ▼
                    DuckDB (OLAP reads)
                        │
                        ▼
  React Dashboard ◀─── GET /api/analytics/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write path&lt;/strong&gt;: The tracking script sends events via &lt;code&gt;navigator.sendBeacon&lt;/code&gt;. Express validates and inserts into PostgreSQL. Response is immediate — DuckDB is never in the write path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sync path&lt;/strong&gt;: A high-watermark worker copies new rows from PostgreSQL → DuckDB incrementally, never rebuilding from scratch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read path&lt;/strong&gt;: All 17 analytics endpoints read exclusively from DuckDB, running columnar aggregations 10-100× faster than a row-store query.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth&lt;/strong&gt;: JWT-based authentication. All analytics routes are protected. Only &lt;code&gt;/api/track/*&lt;/code&gt; and &lt;code&gt;/api/auth/*&lt;/code&gt; are public.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PostgreSQL schema (source of truth)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;events&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Raw event log — pageviews, clicks, custom events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sessions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Session metadata — duration, page count, entry/exit pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sites&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registered websites and their tracking keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;funnels&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Funnel definitions with ordered steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;daily_stats&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-aggregated daily rollups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dashboard user accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;h3&gt;
  
  
  Landing Page
&lt;/h3&gt;

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

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

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

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

&lt;p&gt;&lt;strong&gt;Comparison Table vs Google Analytics&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwpy1ryy0a98816pxq5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwpy1ryy0a98816pxq5v.png" alt="Comparison Table" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

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


Full landing page

![Full Landing Page](https://raw.githubusercontent.com/nishikantaray/insighttrack/main/screenshots/01-landing-full.png)




&lt;h3&gt;
  
  
  Authentication &amp;amp; Onboarding
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Login&lt;/th&gt;
&lt;th&gt;Register&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bu26ruxxaqusgvqedbt.png" alt="Login" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxvyr24iw0dp2e4lfp8x.png" alt="Register" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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


&lt;h3&gt;
  
  
  Dashboard
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Light Mode&lt;/th&gt;
&lt;th&gt;Dark Mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7krkfhpva4t6z2yyjllc.png" alt="Dashboard" width="800" height="1148"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fer8ump5czl04v5ru5p5j.png" alt="Dark Mode" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;KPI Cards + Sparklines&lt;/th&gt;
&lt;th&gt;Traffic Charts&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr3770w02ywq42ujps9s1.png" alt="KPI Cards" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8kgkhailbka92mlsca7i.png" alt="Charts" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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


&lt;h3&gt;
  
  
  Analytics Pages
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User Flow (Sankey)&lt;/th&gt;
&lt;th&gt;Real-Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi2hkddv2a78mnn3t7mz.png" alt="User Flow" width="800" height="510"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdf3a5cdo9lvcz86x5wnp.png" alt="Realtime" width="800" height="626"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Funnels&lt;/th&gt;
&lt;th&gt;Settings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fatqioo3sgl1el5zhntf1.png" alt="Funnels" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkm26u5ky261199vc2at.png" alt="Settings" width="800" height="622"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Top Pages&lt;/th&gt;
&lt;th&gt;Profile&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favicp4al1j02d6ikuom4.png" alt="Pages" width="800" height="450"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fthgyzr9j880zt4daq048.png" alt="Profile" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Documentation&lt;/th&gt;
&lt;th&gt;API Reference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4tiquur19quffgr0jpo.png" alt="Docs" width="800" height="972"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhbqrdakspgsfoqvxx629.png" alt="API Reference" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sidebar&lt;/th&gt;
&lt;th&gt;Dark Landing&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxma2pzbl85es1feck72.png" alt="Sidebar" width="260" height="720"&gt;&lt;/td&gt;
&lt;td&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ndzbg1xwpqyu56c33ff.png" alt="Dark Landing" width="800" height="450"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; React 18 + Vite 5 + Tailwind CSS 3 · Express 4 + Node.js 20 · PostgreSQL + DuckDB · Docker Compose&lt;/p&gt;


&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Where it was (v1)
&lt;/h3&gt;

&lt;p&gt;v1 had the core loop working: embed a tracking script → events land in PostgreSQL → a sync worker copies rows into a flat DuckDB table → the React dashboard reads from DuckDB. The fundamental architecture was sound.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What v1 shipped:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dashboard with 4 KPI cards (Visitors, Pageviews, Bounce Rate, Avg. Session)&lt;/li&gt;
&lt;li&gt;Traffic and pageview time-series charts (7d / 30d / 90d presets)&lt;/li&gt;
&lt;li&gt;Top pages table&lt;/li&gt;
&lt;li&gt;Basic conversion funnels&lt;/li&gt;
&lt;li&gt;Device and country breakdown&lt;/li&gt;
&lt;li&gt;JWT authentication, register/login, onboarding wizard with tracking snippet&lt;/li&gt;
&lt;li&gt;Docker Compose deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it had serious rough edges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance wall.&lt;/strong&gt; The DuckDB sync layer used a single flat table. On 90+ days of data, a KPI query scanned every row — ~620 ms on a local M1 machine. There was no partitioning, no archival strategy, and a crash meant rebuilding the entire table from scratch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Half-finished features.&lt;/strong&gt; There was a long list of planned but never-built ideas: UTM campaign tracking, comparison mode on charts, user flow analysis, a live visitor map on the Realtime page, engagement tracking, goal tracking, audience analytics, export to CSV/JSON — all unshipped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UX gaps.&lt;/strong&gt; The Settings page was a single form. The Documentation page was a placeholder. Half the pages lacked dark mode. There was no contextual help anywhere — a new user landing on the Funnels page had no idea what they were looking at.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No marketing story.&lt;/strong&gt; The project had no landing page, no comparison table, no "why this instead of Google Analytics" pitch. It existed but didn't explain itself.&lt;/p&gt;


&lt;h3&gt;
  
  
  What changed (v1 → v2)
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Hot+Cold Analytics Architecture
&lt;/h4&gt;

&lt;p&gt;This was the most technically significant change. I replaced the flat DuckDB sync with a &lt;strong&gt;two-tier data lake&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hot tier&lt;/strong&gt; — DuckDB in-memory tables holding the last 30 days of events and sessions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold tier&lt;/strong&gt; — Hive-partitioned Parquet files on disk for historical data, organized by &lt;code&gt;site_id&lt;/code&gt; and &lt;code&gt;event_date&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data-lake/events/
  site_id=abc/
    event_date=2026-01-01/
      part-0001.parquet
    event_date=2026-01-02/
      part-0001.parquet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A &lt;strong&gt;transparent &lt;code&gt;UNION ALL&lt;/code&gt; view&lt;/strong&gt; sits on top of both tiers, so every existing dashboard query kept working without modification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;events_hot&lt;/span&gt;
  &lt;span class="k"&gt;UNION&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;read_parquet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'data-lake/events/site_id=*/event_date=*/part-0001.parquet'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;hive_partitioning&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;strong&gt;dual-watermark incremental sync worker&lt;/strong&gt; runs every 5 minutes, fetching only new rows from PostgreSQL using high-water marks (&lt;code&gt;last_event_id&lt;/code&gt; for events, &lt;code&gt;last_synced&lt;/code&gt; timestamp for sessions), then routing them to the correct tier based on age.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result: 90-day queries dropped from ~620 ms → ~25 ms. A 25× speedup.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recovery after a crash now resumes from the watermark instead of rebuilding the entire table.&lt;/p&gt;




&lt;h4&gt;
  
  
  2. Tracking Script — what it captures automatically
&lt;/h4&gt;

&lt;p&gt;The auto-generated &lt;code&gt;analytics.js&lt;/code&gt; (~2 KB) handles everything without configuration:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data Point&lt;/th&gt;
&lt;th&gt;How&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Page URL &amp;amp; path&lt;/td&gt;
&lt;td&gt;&lt;code&gt;window.location.href&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Referrer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;document.referrer&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser, OS, device&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;navigator.userAgent&lt;/code&gt; + screen width heuristics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Country&lt;/td&gt;
&lt;td&gt;Timezone via &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session&lt;/td&gt;
&lt;td&gt;Auto UUID in &lt;code&gt;sessionStorage&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anonymous user ID&lt;/td&gt;
&lt;td&gt;Random UUID in &lt;code&gt;localStorage&lt;/code&gt; — no cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outbound link clicks&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;click&lt;/code&gt; event listener&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scroll depth&lt;/td&gt;
&lt;td&gt;25/50/75/100% milestones on page unload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time on page&lt;/td&gt;
&lt;td&gt;Seconds per page sent on unload&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heatmap clicks&lt;/td&gt;
&lt;td&gt;x/y coordinates + CSS selector of every click&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rage clicks&lt;/td&gt;
&lt;td&gt;3+ rapid clicks on same element within 1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Core Web Vitals&lt;/td&gt;
&lt;td&gt;LCP, FID, CLS, INP, TTFB via &lt;code&gt;PerformanceObserver&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JS errors&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;window.onerror&lt;/code&gt; + &lt;code&gt;unhandledrejection&lt;/code&gt; capture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Site search&lt;/td&gt;
&lt;td&gt;Form submit interception&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UTM parameters&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;utm_source&lt;/code&gt;, &lt;code&gt;utm_medium&lt;/code&gt;, &lt;code&gt;utm_campaign&lt;/code&gt;, &lt;code&gt;utm_term&lt;/code&gt;, &lt;code&gt;utm_content&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPA navigation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;popstate&lt;/code&gt; + &lt;code&gt;pushState&lt;/code&gt; / &lt;code&gt;replaceState&lt;/code&gt; listeners&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Privacy built-in: DNT (&lt;code&gt;navigator.doNotTrack&lt;/code&gt;) and GPC (&lt;code&gt;navigator.globalPrivacyControl&lt;/code&gt;) are respected — if either is set, no data is collected.&lt;/p&gt;

&lt;p&gt;Custom events are available via &lt;code&gt;window.analytics.track('event_name', { ...properties })&lt;/code&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  3. Complete v2 feature set
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Core Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main dashboard now has comparison mode — every chart can overlay the current period against the previous period. All 4 KPI cards have sparkline mini-charts. Date picker supports custom ranges in addition to presets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-Time&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Active visitor count (users in last 5 minutes, with pulsing indicator)&lt;/li&gt;
&lt;li&gt;Interactive world map pinpointing active visitors by country&lt;/li&gt;
&lt;li&gt;Live event stream — feed of the last 50–100 events as they happen&lt;/li&gt;
&lt;li&gt;Active pages ranked by current visitor count&lt;/li&gt;
&lt;li&gt;Real-time device breakdown&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Engagement Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Four metrics measured automatically by the tracking script:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;What it shows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scroll Depth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Per-page average scroll %; milestone table (25/50/75/100%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Click Heatmaps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;x/y dot map per page, top clicked elements ranked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rage Click Detection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Pages and elements triggering 3+ rapid clicks within 1 second&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Time on Page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Average, median, min/max read time per page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;User Flow &amp;amp; Funnels&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sankey diagram showing entry pages → transitions → exit pages with proportional path thickness&lt;/li&gt;
&lt;li&gt;Multi-step funnel builder (e.g., Landing → Signup → Checkout → Purchase) with per-stage drop-off and conversion rate&lt;/li&gt;
&lt;li&gt;Saved funnel definitions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conversion &amp;amp; Goals&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goal types: Pageview (URL match), Event (custom event), Duration (time on page), Scroll Depth (threshold)&lt;/li&gt;
&lt;li&gt;A/B test tracking — create experiments, assign variants, compare conversion rates&lt;/li&gt;
&lt;li&gt;Revenue attribution — attach dollar values to purchase events, see total revenue and average order value by traffic source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Audience Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New vs. returning visitors — pie/donut chart + daily trend&lt;/li&gt;
&lt;li&gt;Cohort analysis — heatmap grid of Day 1 / Day 7 / Day 30 retention by first-visit week&lt;/li&gt;
&lt;li&gt;Visitor segments — filter by device, browser, OS, country and compare KPIs side by side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Content Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry pages — top landing pages ranked by visitor count and entry rate&lt;/li&gt;
&lt;li&gt;Exit pages — top departure pages ranked by exit count and exit rate&lt;/li&gt;
&lt;li&gt;Page flow — where visitors go after each page&lt;/li&gt;
&lt;li&gt;Site search — queries captured from form submit interception with frequency counts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Acquisition Analytics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full UTM campaign dashboard — source, medium, campaign, term, content breakdowns with visitor counts, bounce rates, and session duration&lt;/li&gt;
&lt;li&gt;Social media tab — automatic classification of Facebook, Twitter/X, LinkedIn, Instagram, YouTube, Reddit, Pinterest, TikTok traffic&lt;/li&gt;
&lt;li&gt;Search keyword tracking — organic and paid keywords driving traffic&lt;/li&gt;
&lt;li&gt;UTM link builder — generate tagged URLs directly in the dashboard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Performance Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Core Web Vitals collected automatically:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Good&lt;/th&gt;
&lt;th&gt;Needs Improvement&lt;/th&gt;
&lt;th&gt;Poor&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;LCP&lt;/strong&gt; (Largest Contentful Paint)&lt;/td&gt;
&lt;td&gt;≤ 2.5s&lt;/td&gt;
&lt;td&gt;≤ 4.0s&lt;/td&gt;
&lt;td&gt;&amp;gt; 4.0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;FID&lt;/strong&gt; (First Input Delay)&lt;/td&gt;
&lt;td&gt;≤ 100ms&lt;/td&gt;
&lt;td&gt;≤ 300ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 300ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;CLS&lt;/strong&gt; (Cumulative Layout Shift)&lt;/td&gt;
&lt;td&gt;≤ 0.1&lt;/td&gt;
&lt;td&gt;≤ 0.25&lt;/td&gt;
&lt;td&gt;&amp;gt; 0.25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;INP&lt;/strong&gt; (Interaction to Next Paint)&lt;/td&gt;
&lt;td&gt;≤ 200ms&lt;/td&gt;
&lt;td&gt;≤ 500ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 500ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;TTFB&lt;/strong&gt; (Time to First Byte)&lt;/td&gt;
&lt;td&gt;≤ 800ms&lt;/td&gt;
&lt;td&gt;≤ 1800ms&lt;/td&gt;
&lt;td&gt;&amp;gt; 1800ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Color-coded metric cards (green/yellow/red) + per-page breakdown table.&lt;/p&gt;

&lt;p&gt;JavaScript error tracking: message, source file, line/column, stack trace, error trend chart over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reporting &amp;amp; Export&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data export — JSON/CSV download for KPI, traffic, pages, sources data; PNG export for charts&lt;/li&gt;
&lt;li&gt;Annotations — pin notes to specific dates on charts (e.g., "launched new homepage") with category badges (deployment/marketing/incident)&lt;/li&gt;
&lt;li&gt;Scheduled reports — configure daily/weekly/monthly email delivery with recipient list&lt;/li&gt;
&lt;li&gt;Custom dashboards — save personalized widget layouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Multi-Site Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add and manage unlimited websites under one account&lt;/li&gt;
&lt;li&gt;Per-site tracking snippets with one-click copy&lt;/li&gt;
&lt;li&gt;Per-site data retention policies (30/90/180/365 days)&lt;/li&gt;
&lt;li&gt;Automated cleanup of expired events and sessions&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  4. UX and documentation overhaul
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Settings page&lt;/strong&gt; rebuilt as a 4-tab layout: General, Notifications/Alerts, Site Manager, and Privacy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All 13 analytics pages&lt;/strong&gt; gained a collapsible &lt;code&gt;PageNote&lt;/code&gt; banner with a business explanation and a developer tip per page&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;InfoTooltip&lt;/code&gt;&lt;/strong&gt; on every &lt;code&gt;MetricCard&lt;/code&gt; and &lt;code&gt;ChartCard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation page&lt;/strong&gt; rebuilt with dual-audience tabs (Business Owner / Developer) and an interactive 4-view architecture diagram&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark mode&lt;/strong&gt; enforced consistently across every page and component&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  5. Marketing landing page
&lt;/h4&gt;

&lt;p&gt;Hero, features grid, 3-step "How It Works", tech stack cards, and a side-by-side comparison table vs. Google Analytics across 9 dimensions.&lt;/p&gt;




&lt;h3&gt;
  
  
  Before vs. After
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;v1 (Before)&lt;/th&gt;
&lt;th&gt;v2 (After)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;90-day query time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~620 ms&lt;/td&gt;
&lt;td&gt;~25 ms (25×)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DuckDB architecture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single flat table, full scan&lt;/td&gt;
&lt;td&gt;Hot (in-memory) + Cold (Parquet), UNION view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sync on crash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full table rebuild&lt;/td&gt;
&lt;td&gt;Resumes from dual watermark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Analytics pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tracking data points&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-Time page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Active count only&lt;/td&gt;
&lt;td&gt;Map + event stream + device breakdown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Engagement tracking&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Scroll depth, heatmaps, rage clicks, time on page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conversion &amp;amp; Goals&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Funnels only&lt;/td&gt;
&lt;td&gt;Goals, A/B testing, revenue attribution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audience analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;New/returning, cohorts, segments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Content analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Top pages only&lt;/td&gt;
&lt;td&gt;Entry/exit pages, page flow, site search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acquisition analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;UTM campaigns, social, keywords, link builder&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Core Web Vitals + JS error tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reporting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Export, annotations, scheduled reports, custom dashboards&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Multi-site&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single site&lt;/td&gt;
&lt;td&gt;Unlimited sites with per-site settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Comparison mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Previous-period overlay on all charts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Export&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;CSV / JSON / PNG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Settings page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single form&lt;/td&gt;
&lt;td&gt;4-tab layout with site manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Contextual help&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PageNote&lt;/code&gt; + &lt;code&gt;InfoTooltip&lt;/code&gt; on every page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dark mode coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Marketing landing page&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Full page with comparison table&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I'll be direct: I would not have shipped v2 without GitHub Copilot. Not because the individual problems were too hard — but because there were &lt;em&gt;so many&lt;/em&gt; of them, and I was coming back to code I hadn't touched in months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The architecture lift.&lt;/strong&gt; The Hot+Cold DuckDB design required a new sync worker, new schema migrations, new UNION views, and updates to every existing query file simultaneously. Copilot helped me work through design decisions conversationally — I'd describe the constraint ("crash recovery must resume from a watermark, not rebuild the whole table") and it would walk me through the dual-watermark pattern, flag edge cases I hadn't considered (what happens to a row that ages from hot to cold &lt;em&gt;between&lt;/em&gt; two sync cycles?), and generate the implementation that fit the existing codebase style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The feature sweep.&lt;/strong&gt; Going from 8 tracked data points to 19, from 7 pages to 13, from basic funnels to engagement tracking, cohort analysis, Web Vitals, and revenue attribution is a context-switching marathon. Copilot compressed the ramp-up time on each feature dramatically. When I opened the Acquisition page for the first time in months, Copilot immediately understood the existing data model, knew which UTM fields were already being captured in the tracking script, and scaffolded the campaign dashboard components that matched the existing &lt;code&gt;useAnalytics&lt;/code&gt; hook pattern — not generic code, but code that fit &lt;em&gt;this&lt;/em&gt; project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The consistency work.&lt;/strong&gt; The &lt;code&gt;PageNote&lt;/code&gt; and &lt;code&gt;InfoTooltip&lt;/code&gt; additions touched 13 pages. Adding Core Web Vitals collection to the tracking script required coordinating between &lt;code&gt;analytics.js&lt;/code&gt;, the Express ingest route, the DuckDB schema, and the React performance page — four files that had to stay in sync. Copilot held the full context across all of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The documentation.&lt;/strong&gt; Writing accurate technical docs for a system you know deeply is surprisingly tedious. Copilot drafted the architecture document for the hot/cold system from the actual code — referencing the real SQL, the real file paths, the real config variables — and I edited for clarity rather than writing from scratch.&lt;/p&gt;

&lt;p&gt;The interaction style that worked best wasn't "write this for me." It was: &lt;em&gt;here's the constraint, here's the existing pattern, here's where I'm confused.&lt;/em&gt; Copilot as a collaborator who has read your entire codebase is a genuinely different experience from Copilot as autocomplete. The finish-up phase of a project — juggling context across a dozen half-done things — is exactly where that kind of always-available, always-context-aware pair programmer pays off most.&lt;/p&gt;

&lt;p&gt;InsightTrack v2 is the project I always meant to ship. It just needed time, a clear plan, and a better way to work through the backlog.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;InsightTrack is open source — self-host your own privacy-first analytics in minutes.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
    </item>
    <item>
      <title>SwiftCut: AI-Powered Video Silence Remover Built with GitHub Copilot CLI</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Mon, 26 Jan 2026 16:46:06 +0000</pubDate>
      <link>https://dev.to/nishikantaray/swiftcut-ai-powered-video-silence-remover-built-with-github-copilot-cli-3dj7</link>
      <guid>https://dev.to/nishikantaray/swiftcut-ai-powered-video-silence-remover-built-with-github-copilot-cli-3dj7</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;SwiftCut&lt;/strong&gt; is a local-first desktop application that automates the "Rough Cut" phase of video editing. It uses AI-powered audio analysis to instantly detect and remove silent segments from videos — no cloud uploads, no subscriptions, complete privacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem I Solved
&lt;/h3&gt;

&lt;p&gt;As a content creator, I spent &lt;strong&gt;hours&lt;/strong&gt; manually cutting out silent pauses from my podcast recordings, tutorial videos, and vlogs. The workflow was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Import video into heavy editing software&lt;/li&gt;
&lt;li&gt;Scrub through timeline looking for silence&lt;/li&gt;
&lt;li&gt;Manually mark and delete each silent segment&lt;/li&gt;
&lt;li&gt;Repeat 50+ times per video 😩&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;SwiftCut automates this entire process in seconds.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;🎯 &lt;strong&gt;Smart Silence Detection&lt;/strong&gt; — FFmpeg-powered audio analysis with configurable thresholds&lt;/p&gt;

&lt;p&gt;⚡ &lt;strong&gt;Instant Results&lt;/strong&gt; — Process a 10-minute video in under 5 seconds&lt;/p&gt;

&lt;p&gt;🔒 &lt;strong&gt;100% Local &amp;amp; Private&lt;/strong&gt; — Your videos never leave your machine&lt;/p&gt;

&lt;p&gt;🎚️ &lt;strong&gt;Content Presets&lt;/strong&gt; — Optimized settings for Podcasts, Tutorials, Vlogs, and Interviews&lt;/p&gt;

&lt;p&gt;🤖 &lt;strong&gt;AI Natural Language Commands&lt;/strong&gt; — Tell it what to do: "Remove all silences" or "Make a 30-second clip"&lt;/p&gt;

&lt;p&gt;🎬 &lt;strong&gt;Reel Cutter&lt;/strong&gt; — Split long videos into Instagram Reels, TikTok, or YouTube Shorts&lt;/p&gt;

&lt;p&gt;🎙️ &lt;strong&gt;Voice Commands&lt;/strong&gt; — Speak your edits using Web Speech API&lt;/p&gt;

&lt;p&gt;↩️ &lt;strong&gt;Full Undo/Redo&lt;/strong&gt; — Never lose your work&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Tauri v2 (Rust + WebView)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19 + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS v4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State&lt;/td&gt;
&lt;td&gt;Zustand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Video Processing&lt;/td&gt;
&lt;td&gt;FFmpeg&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Multi-provider (Local, Ollama, OpenAI, Copilot SDK)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;h3&gt;
  
  
  🎥 Video Walkthrough
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://youtu.be/tXmQofWy3P0?si=X1xxPl8yD-OTNM1M" rel="noopener noreferrer"&gt;▶️ Watch SwiftCut in Action&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Landing Page — Clean, focused interface&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Silence Detection — Visual timeline with detected segments&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;AI Commands — Natural language video editing&lt;/strong&gt;&lt;/p&gt;

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

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

&lt;p&gt;&lt;strong&gt;Reel Cutter — Split videos for social media&lt;/strong&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Try It Yourself
&lt;/h3&gt;



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

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Run in development&lt;/span&gt;
npm run tauri dev

&lt;span class="c"&gt;# Build for production&lt;/span&gt;
npm run tauri:build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt; Node.js 22+, Rust 1.93+, FFmpeg&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Copilot CLI Transformed My Development
&lt;/h3&gt;

&lt;p&gt;Building SwiftCut would have taken &lt;strong&gt;weeks&lt;/strong&gt; without GitHub Copilot CLI. Here's how I used it:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;FFmpeg Command Generation&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;FFmpeg has notoriously complex syntax. Instead of Googling for hours, I asked Copilot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"ffmpeg command to detect silence below -30dB lasting more than 0.5 seconds"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; input.mp4 &lt;span class="nt"&gt;-af&lt;/span&gt; &lt;span class="s2"&gt;"silencedetect=noise=-30dB:d=0.5"&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; null -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This became the core of my silence detection algorithm.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Rust Backend Development&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I'm primarily a TypeScript developer. Writing Rust for Tauri was daunting, but Copilot CLI helped:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot explain &lt;span class="s2"&gt;"how to parse FFmpeg stderr output in Rust and extract timestamps"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It gave me a complete regex pattern and parsing logic that I adapted for my &lt;code&gt;lib.rs&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Complex Filter Chains&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Building the export filter was tricky. I needed to keep non-silent segments and remove gaps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"ffmpeg select filter to keep multiple time ranges and close gaps"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="s2"&gt;"select='between(t,0,5)+between(t,8,20)',setpts=N/FRAME_RATE/TB"&lt;/span&gt;
&lt;span class="nt"&gt;-af&lt;/span&gt; &lt;span class="s2"&gt;"aselect='between(t,0,5)+between(t,8,20)',asetpts=N/SR/TB"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. &lt;strong&gt;AI Planner System Prompt&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I used Copilot to help design the system prompt for my AI planner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"system prompt for an AI that converts natural language to FFmpeg commands"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helped me structure the &lt;code&gt;SWIFTCUT_SYSTEM_PROMPT&lt;/code&gt; that powers the natural language interface.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. &lt;strong&gt;Cross-Platform Build Configuration&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Setting up GitHub Actions for multi-platform builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh copilot suggest &lt;span class="s2"&gt;"github actions workflow to build tauri app for mac windows and linux"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Got a working CI/CD pipeline in minutes instead of hours.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact on Development Experience
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Without Copilot CLI&lt;/th&gt;
&lt;th&gt;With Copilot CLI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FFmpeg learning curve&lt;/td&gt;
&lt;td&gt;2-3 days&lt;/td&gt;
&lt;td&gt;2 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust backend&lt;/td&gt;
&lt;td&gt;1 week&lt;/td&gt;
&lt;td&gt;2 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total development time&lt;/td&gt;
&lt;td&gt;~3 weeks&lt;/td&gt;
&lt;td&gt;~5 days&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stack Overflow visits&lt;/td&gt;
&lt;td&gt;100+&lt;/td&gt;
&lt;td&gt;~10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The "Aha!" Moment
&lt;/h3&gt;

&lt;p&gt;The breakthrough came when I realized I could use Copilot CLI as a &lt;strong&gt;planning agent&lt;/strong&gt; within the app itself. The system prompt I developed with Copilot's help now powers SwiftCut's AI command interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Remove all silences longer than 1 second"
     ↓
AI Planner (Copilot-inspired prompt)
     ↓
FFmpeg: select='between(t,0,5)+between(t,8,20)...'
     ↓
Exported video with silences removed!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What I'd Tell Other Developers
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Don't just ask for code&lt;/strong&gt; — Ask Copilot CLI to &lt;em&gt;explain&lt;/em&gt; concepts first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;suggest&lt;/code&gt; for commands&lt;/strong&gt; — Especially for complex CLI tools like FFmpeg, Docker, Git&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterate with &lt;code&gt;explain&lt;/code&gt;&lt;/strong&gt; — If the first suggestion isn't perfect, ask it to explain and refine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build your own prompts&lt;/strong&gt; — The system prompts Copilot uses are great templates for your AI features&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Technical Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Silence Detection Works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ORIGINAL VIDEO (10 minutes)
▓▓▓▓▓░░░▓▓▓▓▓▓▓░░▓▓▓▓░░░░▓▓▓▓▓▓▓▓░░▓▓▓▓▓▓░░░▓▓▓▓▓
     ▲       ▲       ▲           ▲         ▲
  silence silence silence    silence   silence

                    ↓ FFmpeg silencedetect

EXPORTED VIDEO (7 minutes)  
▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
(All silence removed — 30% shorter!)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  AI Provider Architecture
&lt;/h3&gt;

&lt;p&gt;SwiftCut supports multiple AI backends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AIProvider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;copilot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ollama&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;openai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Switch providers in settings&lt;/span&gt;
&lt;span class="nf"&gt;setAIProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ollama&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:11434&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;modelName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;llama3.2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local&lt;/td&gt;
&lt;td&gt;Offline, rule-based processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ollama&lt;/td&gt;
&lt;td&gt;Privacy-focused local LLM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;Most capable, requires API key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Copilot SDK&lt;/td&gt;
&lt;td&gt;Coming soon!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;ul&gt;
&lt;li&gt;[ ] Waveform visualization in timeline&lt;/li&gt;
&lt;li&gt;[ ] Transcript-based editing ("Find where I say 'demo'")&lt;/li&gt;
&lt;li&gt;[ ] Batch processing multiple videos&lt;/li&gt;
&lt;li&gt;[ ] Plugin system for custom filters&lt;/li&gt;
&lt;li&gt;[ ] Mobile companion app&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/swiftcut" rel="noopener noreferrer"&gt;github.com/NishikantaRay/swiftcut&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📺 &lt;strong&gt;Demo Video:&lt;/strong&gt; &lt;a href="https://youtu.be/tXmQofWy3P0" rel="noopener noreferrer"&gt;youtube.com/watch?v=tXmQofWy3P0&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Acknowledgments
&lt;/h2&gt;

&lt;p&gt;Built with ❤️ using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://tauri.app" rel="noopener noreferrer"&gt;Tauri&lt;/a&gt; — Amazing desktop framework&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ffmpeg.org" rel="noopener noreferrer"&gt;FFmpeg&lt;/a&gt; — The backbone of video processing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://githubnext.com/projects/copilot-cli" rel="noopener noreferrer"&gt;GitHub Copilot CLI&lt;/a&gt; — My AI pair programmer&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;What editing task takes you the longest? Let me know in the comments — maybe SwiftCut can help!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>From Static to Smart: Designing an AI-First Developer Portfolio with Renderer, Gemini &amp; MCP 🚀🚀</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Thu, 22 Jan 2026 18:16:15 +0000</pubDate>
      <link>https://dev.to/nishikantaray/from-static-to-smart-designing-an-ai-first-developer-portfolio-with-renderer-gemini-mcp-1kd1</link>
      <guid>https://dev.to/nishikantaray/from-static-to-smart-designing-an-ai-first-developer-portfolio-with-renderer-gemini-mcp-1kd1</guid>
      <description>&lt;p&gt;&lt;em&gt;Transforming portfolio creation with Google Gemini AI and Model Context Protocol&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Txzplqg6oJo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=Txzplqg6oJo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Executive Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Renderer&lt;/strong&gt; is an innovative portfolio framework that leverages &lt;strong&gt;Google Gemini&lt;/strong&gt; to revolutionize how developers create and manage their online presence. By combining a configuration-first architecture with AI assistance through Model Context Protocol (MCP), users can generate, validate, and customize complete portfolios using natural language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Innovation
&lt;/h3&gt;

&lt;p&gt;Instead of wrestling with complex frameworks, users simply describe what they want, and Gemini handles the technical complexity—generating configurations, validating code, and providing instant guidance.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Live Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Live Portfolio: &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;https://nishikanta.in&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📚 Documentation: &lt;a href="https://renderer.nishikanta.in/docs" rel="noopener noreferrer"&gt;https://renderer.nishikanta.in/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 Framework: &lt;a href="https://github.com/NishikantaRay/renderer" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/renderer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤖 MCP Server: &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay/renderer-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Problem &amp;amp; Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;Developers face critical pain points when building portfolios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ &lt;strong&gt;Framework Overload&lt;/strong&gt; - Complex React/Vue setups with heavy build processes&lt;/li&gt;
&lt;li&gt;⏰ &lt;strong&gt;Time Investment&lt;/strong&gt; - Hours configuring, styling, and maintaining&lt;/li&gt;
&lt;li&gt;🔒 &lt;strong&gt;Limited Flexibility&lt;/strong&gt; - Templates that don't adapt to individual needs&lt;/li&gt;
&lt;li&gt;📚 &lt;strong&gt;Documentation Fatigue&lt;/strong&gt; - Searching through endless docs for simple changes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Our Solution
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;static, configuration-driven framework&lt;/strong&gt; enhanced by &lt;strong&gt;Google Gemini AI&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Generates complete portfolio configurations from natural language&lt;/li&gt;
&lt;li&gt;✅ Validates TOML files and catches errors instantly&lt;/li&gt;
&lt;li&gt;✅ Provides contextual documentation and examples&lt;/li&gt;
&lt;li&gt;✅ Reduces setup time from hours to minutes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Google Gemini Integration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dual-Layer AI Architecture
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Gemini AI Studio&lt;/strong&gt; (Ideation &amp;amp; Content Creation)
&lt;/h4&gt;

&lt;p&gt;Used during initial development for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📝 Outlining portfolio structure and sections&lt;/li&gt;
&lt;li&gt;✍️ Drafting About, Resume, and project descriptions&lt;/li&gt;
&lt;li&gt;🎨 Suggesting design patterns and layouts&lt;/li&gt;
&lt;li&gt;🔄 Converting raw notes into polished copy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Gemini:&lt;/strong&gt; Its advanced reasoning capabilities helped transform technical achievements into compelling narratives.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Gemini CLI&lt;/strong&gt; (Development Workflow)
&lt;/h4&gt;

&lt;p&gt;Terminal-native AI for rapid development:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Generate configuration files&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Create a resume.toml with experience and education sections"&lt;/span&gt;

&lt;span class="c"&gt;# Content refinement&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Rewrite this Markdown to be more technical and concise"&lt;/span&gt;

&lt;span class="c"&gt;# Validation&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Check this TOML file for schema errors"&lt;/span&gt;

&lt;span class="c"&gt;# Documentation&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Explain how to add dark mode to my portfolio"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Advantage:&lt;/strong&gt; Seamlessly integrates with Git-based workflows and plain-text files.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Model Context Protocol (MCP) Server&lt;/strong&gt; (AI Assistant)
&lt;/h4&gt;

&lt;p&gt;Our breakthrough innovation—a persistent AI assistant that &lt;strong&gt;understands Renderer's architecture&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server Capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 &lt;strong&gt;Semantic Documentation Search&lt;/strong&gt; - Find answers in natural language&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Real-time TOML Validation&lt;/strong&gt; - Catch errors before deployment&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Template Generation&lt;/strong&gt; - Create complete configs from user input&lt;/li&gt;
&lt;li&gt;💡 &lt;strong&gt;Smart Examples&lt;/strong&gt; - Context-aware code snippets&lt;/li&gt;
&lt;li&gt;🗂️ &lt;strong&gt;Repository Navigation&lt;/strong&gt; - Browse and understand file structure&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ Technical Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core System
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Renderer Framework
├── Configuration Layer (TOML)      # Human &amp;amp; AI readable
├── Content Layer (Markdown)        # Plain text documents
├── Presentation Layer (HTML/CSS/JS) # Vanilla web tech
└── AI Layer (Gemini + MCP)        # Intelligent assistance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Stack Works
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Configuration-Driven Design:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TOML files are both human and AI readable&lt;/li&gt;
&lt;li&gt;No framework abstractions—pure data&lt;/li&gt;
&lt;li&gt;Version control friendly&lt;/li&gt;
&lt;li&gt;Deterministic output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Static-First Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero build process&lt;/li&gt;
&lt;li&gt;Instant deployment&lt;/li&gt;
&lt;li&gt;Maximum performance&lt;/li&gt;
&lt;li&gt;No server dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AI-Assistable Architecture:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every file is structured and parseable&lt;/li&gt;
&lt;li&gt;Clear separation of concerns&lt;/li&gt;
&lt;li&gt;Predictable patterns for AI reasoning&lt;/li&gt;
&lt;/ul&gt;




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

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

&lt;h2&gt;
  
  
  🤖 MCP Server Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Renderer&lt;/span&gt; &lt;span class="nx"&gt;MCP&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;GitHub&lt;/span&gt; &lt;span class="nx"&gt;Integration&lt;/span&gt;          &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Access&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;framework&lt;/span&gt; &lt;span class="nx"&gt;repository&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Documentation&lt;/span&gt; &lt;span class="nx"&gt;Engine&lt;/span&gt;        &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Semantic&lt;/span&gt; &lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="nx"&gt;across&lt;/span&gt; &lt;span class="nx"&gt;docs&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;TOML&lt;/span&gt; &lt;span class="nx"&gt;Validator&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Schema&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt; &lt;span class="nx"&gt;Generator&lt;/span&gt;         &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="nx"&gt;creation&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt;           &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Contextual&lt;/span&gt; &lt;span class="nx"&gt;snippets&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;Feature&lt;/span&gt; &lt;span class="nx"&gt;Search&lt;/span&gt;             &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Capability&lt;/span&gt; &lt;span class="nx"&gt;discovery&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Available Tools
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;explore_renderer_docs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Natural language documentation queries&lt;/li&gt;
&lt;li&gt;Returns relevant sections with examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;validate_toml_config&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Schema validation&lt;/li&gt;
&lt;li&gt;Syntax checking&lt;/li&gt;
&lt;li&gt;Improvement suggestions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;generate_starter_template&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete project scaffolding&lt;/li&gt;
&lt;li&gt;Customized to user needs&lt;/li&gt;
&lt;li&gt;Ready-to-deploy configurations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;get_config_example&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annotated configuration samples&lt;/li&gt;
&lt;li&gt;Context-aware suggestions&lt;/li&gt;
&lt;li&gt;Best practices included&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;search_renderer_features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature discovery&lt;/li&gt;
&lt;li&gt;Implementation guides&lt;/li&gt;
&lt;li&gt;Integration examples&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Setup &amp;amp; Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# Use with Gemini CLI for AI assistance&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Generate a portfolio configuration for John Doe with projects, resume, and blog"&lt;/span&gt;

&lt;span class="c"&gt;# Or integrate with any MCP-compatible client&lt;/span&gt;
&lt;span class="c"&gt;# The MCP server works with Google AI Studio API and Gemini models&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💡 Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Case 1: Rapid Portfolio Generation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "I need a portfolio showcasing 5 projects, my resume, and a contact form"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini + MCP Response:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generates complete &lt;code&gt;projects.toml&lt;/code&gt; with 5 project templates&lt;/li&gt;
&lt;li&gt;Creates &lt;code&gt;resume.toml&lt;/code&gt; with standard sections&lt;/li&gt;
&lt;li&gt;Configures &lt;code&gt;contact.html&lt;/code&gt; with form validation&lt;/li&gt;
&lt;li&gt;Provides deployment instructions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time saved:&lt;/strong&gt; 2-3 hours → 10 minutes&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use Case 2: Configuration Validation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; Uploads existing &lt;code&gt;home.toml&lt;/code&gt; file&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP Server:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Validates syntax&lt;/li&gt;
&lt;li&gt;⚠️ Identifies missing required fields&lt;/li&gt;
&lt;li&gt;💡 Suggests improvements&lt;/li&gt;
&lt;li&gt;📚 Links to relevant documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case 3: Feature Discovery
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "How do I add analytics dashboard to my projects page?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemini Response:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[analytics]&lt;/span&gt;
&lt;span class="py"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Project Analytics"&lt;/span&gt;

&lt;span class="nn"&gt;[analytics.charts]&lt;/span&gt;
&lt;span class="py"&gt;weekly_activity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;project_distribution&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plus step-by-step integration guide.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Impact &amp;amp; Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quantifiable Improvements
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4-6 hours&lt;/td&gt;
&lt;td&gt;15-20 minutes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;85% reduction&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Configuration Errors&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Common&lt;/td&gt;
&lt;td&gt;Prevented&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~90% reduction&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Documentation Search&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10-15 minutes&lt;/td&gt;
&lt;td&gt;Instant&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Near-instant&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Portfolio Updates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;30-45 minutes&lt;/td&gt;
&lt;td&gt;5 minutes&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;83% faster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  User Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🚀 &lt;strong&gt;Developers:&lt;/strong&gt; Focus on content, not configuration&lt;/li&gt;
&lt;li&gt;🎨 &lt;strong&gt;Designers:&lt;/strong&gt; Easy customization without code&lt;/li&gt;
&lt;li&gt;📚 &lt;strong&gt;Students:&lt;/strong&gt; Professional portfolios in minutes&lt;/li&gt;
&lt;li&gt;💼 &lt;strong&gt;Professionals:&lt;/strong&gt; Maintain portfolios effortlessly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🌟 Key Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Portfolio Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔧 &lt;strong&gt;Fully Configurable&lt;/strong&gt; - Every aspect controlled via TOML&lt;/li&gt;
&lt;li&gt;📄 &lt;strong&gt;Multi-Page Support&lt;/strong&gt; - Home, Projects, Blog, Resume, Contact, Docs&lt;/li&gt;
&lt;li&gt;🌙 &lt;strong&gt;Dark/Light Theme&lt;/strong&gt; - Automatic detection + manual toggle&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Responsive Design&lt;/strong&gt; - Mobile-first approach&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Performance&lt;/strong&gt; - Static files, instant loading&lt;/li&gt;
&lt;li&gt;♿ &lt;strong&gt;Accessibility&lt;/strong&gt; - Built-in ARIA support&lt;/li&gt;
&lt;li&gt;🔍 &lt;strong&gt;SEO Optimized&lt;/strong&gt; - Semantic HTML, proper meta tags&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI-Enhanced Workflows
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;💬 &lt;strong&gt;Natural Language Setup&lt;/strong&gt; - Describe, don't configure&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Instant Validation&lt;/strong&gt; - Real-time error checking&lt;/li&gt;
&lt;li&gt;📝 &lt;strong&gt;Auto-Generation&lt;/strong&gt; - Complete configs from prompts&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Context-Aware Help&lt;/strong&gt; - Relevant examples always&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Iterative Refinement&lt;/strong&gt; - Easy modifications&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎓 Technical Implementation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# home.toml - Fully AI-generatable&lt;/span&gt;
&lt;span class="nn"&gt;[hero]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Nishikanta Ray"&lt;/span&gt;
&lt;span class="py"&gt;title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Full-Stack Developer"&lt;/span&gt;
&lt;span class="py"&gt;intro&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s"&gt;"Building developer-first tools and AI-assisted workflows"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"Specialized in static-first architectures and minimal frameworks"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[hero.actions]&lt;/span&gt;
&lt;span class="py"&gt;primary_text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"View Projects"&lt;/span&gt;
&lt;span class="py"&gt;primary_link&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"projects.html"&lt;/span&gt;
&lt;span class="py"&gt;secondary_text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Contact Me"&lt;/span&gt;
&lt;span class="py"&gt;secondary_link&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"contact.html"&lt;/span&gt;

&lt;span class="nn"&gt;[sections]&lt;/span&gt;
&lt;span class="py"&gt;enabled_sections&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"projects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"skills"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"experience"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nn"&gt;[theme]&lt;/span&gt;
&lt;span class="py"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"auto"&lt;/span&gt;  &lt;span class="c"&gt;# auto, light, or dark&lt;/span&gt;
&lt;span class="py"&gt;accent_color&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"#3b82f6"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  MCP Tool Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// User prompt: "Create a blog config for tech writing"&lt;/span&gt;

&lt;span class="c1"&gt;// MCP generates:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tech Blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insights on web development&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;posts_per_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;enable_comments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;enable_search&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;enable_categories&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;starter-post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Welcome to My Blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-01-22&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;introduction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: AI-Assisted Setup (Recommended)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install MCP Server&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# 2. Use Gemini CLI for AI assistance:&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Create a portfolio configuration for [Your Name] with projects and resume"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Deploy to any static host&lt;/span&gt;
&lt;span class="c"&gt;# Netlify, Vercel, GitHub Pages, Cloudflare Pages&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 2: Manual Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone repository&lt;/span&gt;
git clone https://github.com/NishikantaRay/renderer.git

&lt;span class="c"&gt;# Serve locally&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; http.server 8000
&lt;span class="c"&gt;# or&lt;/span&gt;
npx serve &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Configure via TOML files in config/&lt;/span&gt;
&lt;span class="c"&gt;# Edit content in Markdown files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📚 Resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📖 &lt;a href="https://renderer.nishikanta.in/docs" rel="noopener noreferrer"&gt;Complete Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤖 &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server/blob/main/README.md" rel="noopener noreferrer"&gt;MCP Setup Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🎓 &lt;a href="https://renderer.nishikanta.in/docs#guides" rel="noopener noreferrer"&gt;Configuration Guides&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Repositories
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🏗️ &lt;a href="https://github.com/NishikantaRay/renderer" rel="noopener noreferrer"&gt;Renderer Framework&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🤖 &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;MCP Server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quick Start Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Try the MCP server&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# Clone and run locally&lt;/span&gt;
git clone https://github.com/NishikantaRay/renderer.git
&lt;span class="nb"&gt;cd &lt;/span&gt;renderer &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npx serve &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Generate portfolio with Gemini CLI&lt;/span&gt;
gemini &lt;span class="s2"&gt;"Create a complete portfolio configuration for me"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  👤 About the Creator
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nishikanta Ray&lt;/strong&gt; - Full-Stack Developer specializing in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛠️ Developer experience and productivity tools&lt;/li&gt;
&lt;li&gt;🤖 AI-assisted workflows and automation&lt;/li&gt;
&lt;li&gt;🏗️ Minimal-framework, static-first architectures&lt;/li&gt;
&lt;li&gt;📚 Open source contributions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Connect:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🌐 Portfolio: &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;https://nishikanta.in&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 GitHub: &lt;a href="https://github.com/NishikantaRay" rel="noopener noreferrer"&gt;https://github.com/NishikantaRay&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎉 Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Renderer&lt;/strong&gt; demonstrates the transformative potential of Google Gemini when applied to real-world developer workflows. By combining static-first architecture with intelligent AI assistance through MCP, we've created a system that:&lt;/p&gt;

&lt;p&gt;This project proves that AI isn't just for chatbots—it's a fundamental tool for reimagining how we build and maintain software.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Built with Google Gemini | Powered by MCP | Made for Developers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Start building your AI-assisted portfolio today at &lt;a href="https://renderer.nishikanta.in" rel="noopener noreferrer"&gt;renderer.nishikanta.in&lt;/a&gt;&lt;/em&gt; 🚀&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>portfolio</category>
      <category>gemini</category>
    </item>
    <item>
      <title>Production-Grade Prompting with the Anthropic API</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Sat, 17 Jan 2026 16:36:23 +0000</pubDate>
      <link>https://dev.to/nishikantaray/production-grade-prompting-with-the-anthropic-api-ag2</link>
      <guid>https://dev.to/nishikantaray/production-grade-prompting-with-the-anthropic-api-ag2</guid>
      <description>&lt;h2&gt;
  
  
  Concepts, Parameters, Streaming, Caching, and a Real Enterprise Example
&lt;/h2&gt;

&lt;p&gt;Prompting in Anthropic (Claude) is not just about writing good instructions.&lt;br&gt;&lt;br&gt;
In production systems, prompts behave more like &lt;strong&gt;specifications&lt;/strong&gt; than conversations.&lt;/p&gt;

&lt;p&gt;This article explains &lt;strong&gt;how prompting actually works in Anthropic&lt;/strong&gt;, how to design &lt;strong&gt;reliable and compliant prompts&lt;/strong&gt;, and how to use &lt;strong&gt;JavaScript&lt;/strong&gt; to build real systems—ending with a &lt;strong&gt;production-grade sentiment analysis prompt&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. How Anthropic Prompting Really Works
&lt;/h2&gt;

&lt;p&gt;Anthropic uses a &lt;strong&gt;message-based API&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Each request contains the &lt;strong&gt;entire conversation state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Claude does &lt;strong&gt;not&lt;/strong&gt; remember anything between API calls.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mental model
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;send&lt;/span&gt; &lt;span class="nx"&gt;full&lt;/span&gt; &lt;span class="nx"&gt;conversation&lt;/span&gt;
&lt;span class="nx"&gt;Claude&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;continues&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Every request must include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Who the assistant is&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What rules apply&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What the user just said&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Any images or documents&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. Messages and Roles (Core Concept)
&lt;/h2&gt;

&lt;p&gt;Anthropic uses three roles:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;system&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hard rules, behavior, constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;user&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Input data or tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;assistant&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Previous model replies (conversation priming)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello! Only speak Spanish.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assistant&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hola!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;How are you?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Claude will answer &lt;strong&gt;in Spanish&lt;/strong&gt; because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Conversation history establishes the rule&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Claude prioritizes consistency&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Production rule
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Put non-negotiable rules in&lt;/strong&gt; &lt;code&gt;system&lt;/code&gt;, not in conversation history.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  3. System vs User Instructions (Why It Matters)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Instruction Type&lt;/th&gt;
&lt;th&gt;Reliability&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;System&lt;/td&gt;
&lt;td&gt;Strong, persistent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User&lt;/td&gt;
&lt;td&gt;Soft, overrideable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assistant&lt;/td&gt;
&lt;td&gt;Priming only&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Production-safe example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You must respond only in Spanish.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This survives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Long conversations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Truncated history&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User attempts to override&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  4. Temperature: Controlling Randomness
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Temperature controls how predictable Claude’s word choices are.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; control intelligence.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Temperature&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.0–0.2&lt;/td&gt;
&lt;td&gt;Deterministic&lt;/td&gt;
&lt;td&gt;JSON, analytics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.3–0.5&lt;/td&gt;
&lt;td&gt;Controlled&lt;/td&gt;
&lt;td&gt;Summaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.6–0.8&lt;/td&gt;
&lt;td&gt;Creative&lt;/td&gt;
&lt;td&gt;Writing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.9+&lt;/td&gt;
&lt;td&gt;Unstable&lt;/td&gt;
&lt;td&gt;Rarely useful&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Use this when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Output must be parsed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Compliance matters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decisions depend on correctness&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  5. stop_sequences: When the Model Must Stop
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;stop_sequences&lt;/code&gt; tells Claude &lt;strong&gt;when to stop generating&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;stop_sequences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;User:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude stops &lt;strong&gt;immediately&lt;/strong&gt; when it reaches that string.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common uses
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prevent role leakage&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End JSON cleanly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop agent loops&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key rule
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Stop sequences are &lt;strong&gt;guards&lt;/strong&gt;, not fixes for bad prompts.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Streaming Responses (Real-Time Output)
&lt;/h2&gt;

&lt;p&gt;Streaming lets Claude send text &lt;strong&gt;incrementally&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text_stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why streaming exists
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Faster perceived response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better UX&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Long outputs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When NOT to stream
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JSON APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tool calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Strict schema validation&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production pattern
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text_stream&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// buffer now contains the full response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Multimodal Prompting (Images + Text)
&lt;/h2&gt;

&lt;p&gt;Anthropic allows &lt;strong&gt;image + text together&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Count the containers.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;content&lt;/code&gt; must be an array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Image first, instruction second&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images only in &lt;code&gt;user&lt;/code&gt; role&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Prompt Caching and &lt;code&gt;cache_control&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Anthropic optimizes performance by caching repeated prompt prefixes.&lt;/p&gt;

&lt;p&gt;This is good for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;System prompts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Templates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policies&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But dangerous for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;User data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transcripts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PII&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. &lt;code&gt;cache_control: { type: "ephemeral" }&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cache_control&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ephemeral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Use this content once. Do not cache. Do not reuse. Do not persist.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  When to use it
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;th&gt;Ephemeral&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User input&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call transcripts&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Images&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customer feedback&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Why it matters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Prevents data reuse&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Improves compliance posture&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduces audit risk&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. JavaScript Example: Safe Prompt with Ephemeral Data
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Anthropic&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@anthropic-ai/sdk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Anthropic&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANTHROPIC_API_KEY&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude-3-5-sonnet-20240620&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a deterministic analysis engine.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The service was slow and frustrating.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cache_control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ephemeral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  11. What Makes a Prompt Production-Grade
&lt;/h2&gt;

&lt;p&gt;A production prompt has:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Clear role definition&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explicit constraints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Defined output format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fail-closed behavior&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Low temperature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No exposed reasoning&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Safe handling of sensitive data&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Good prompts are specifications, not conversations.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  12. Production-Grade Sentiment Analysis Prompt
&lt;/h2&gt;

&lt;p&gt;This prompt follows &lt;strong&gt;all best practices discussed above&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Analyze&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;sentiment&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Classify&lt;/span&gt; &lt;span class="nx"&gt;sentiment&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;POSITIVE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NEGATIVE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;NEUTRAL&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Do&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;include&lt;/span&gt; &lt;span class="nx"&gt;personal&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Do&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;intent&lt;/span&gt; &lt;span class="nx"&gt;beyond&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Limit&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt;

&lt;span class="nx"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nx"&gt;Return&lt;/span&gt; &lt;span class="nx"&gt;ONLY&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;explanations&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sentiment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POSITIVE | NEGATIVE | NEUTRAL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confidence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;sentiment&lt;/span&gt; &lt;span class="nx"&gt;cannot&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;determined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sentiment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NEUTRAL&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;confidence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;summary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Insufficient data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  13. Sentiment Analysis: Full JavaScript Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;claude-3-5-sonnet-20240620&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;system&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;You are a strict sentiment classification engine.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Support was slow and unhelpful.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;cache_control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ephemeral&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  14. Final Takeaway
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Anthropic prompting works best when you treat prompts like contracts: explicit, constrained, deterministic, and safe.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>javascript</category>
      <category>llm</category>
    </item>
    <item>
      <title>Building an AI-Powered Portfolio Assistant with Model Context Protocol</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Wed, 31 Dec 2025 08:27:46 +0000</pubDate>
      <link>https://dev.to/nishikantaray/building-an-ai-powered-portfolio-assistant-with-model-context-protocol-4knj</link>
      <guid>https://dev.to/nishikantaray/building-an-ai-powered-portfolio-assistant-with-model-context-protocol-4knj</guid>
      <description>&lt;p&gt;&lt;strong&gt;How I Built a Smart Assistant for the Renderer Framework Using MCP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A comprehensive guide to creating your first MCP server with real-world examples&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📖 Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What is Model Context Protocol?&lt;/li&gt;
&lt;li&gt;The Problem We're Solving&lt;/li&gt;
&lt;li&gt;Architecture Overview&lt;/li&gt;
&lt;li&gt;Implementation Guide&lt;/li&gt;
&lt;li&gt;Testing with Claude Desktop&lt;/li&gt;
&lt;li&gt;Testing with MCP Inspector&lt;/li&gt;
&lt;li&gt;Real-World Use Cases&lt;/li&gt;
&lt;li&gt;Lessons Learned&lt;/li&gt;
&lt;li&gt;What's Next&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Creating a portfolio website shouldn't be hard. But as the creator of &lt;strong&gt;&lt;a href="https://github.com/NishikantaRay/renderer" rel="noopener noreferrer"&gt;Renderer&lt;/a&gt;&lt;/strong&gt;, a TOML-driven portfolio framework, I noticed users struggling with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understanding TOML configuration syntax&lt;/li&gt;
&lt;li&gt;Finding relevant documentation&lt;/li&gt;
&lt;li&gt;Validating their configurations&lt;/li&gt;
&lt;li&gt;Getting started quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The solution? An &lt;strong&gt;AI assistant that truly understands the framework&lt;/strong&gt;. Not a generic chatbot, but a specialized tool that knows every configuration option, can validate your code, and guide you from zero to deployed.&lt;/p&gt;

&lt;p&gt;Enter the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; — a game-changing standard for connecting AI assistants with external tools and data sources.&lt;/p&gt;

&lt;p&gt;In this post, I'll walk you through building &lt;strong&gt;Renderer MCP Server&lt;/strong&gt;, a complete AI assistant that makes portfolio creation effortless. You'll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How MCP works and why it's revolutionary&lt;/li&gt;
&lt;li&gt;How to build your own MCP server from scratch&lt;/li&gt;
&lt;li&gt;How to integrate it with Claude Desktop&lt;/li&gt;
&lt;li&gt;Real-world testing and deployment strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;renderer-mcp-server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's dive in! 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Model Context Protocol?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The New Standard for AI Interoperability
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; is an open standard developed by Anthropic that enables AI assistants to securely access external tools, data sources, and services.&lt;/p&gt;

&lt;p&gt;Think of it as &lt;strong&gt;"USB for AI"&lt;/strong&gt; — just like USB standardized how devices connect to computers, MCP standardizes how AI connects to the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why MCP Matters
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before MCP:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Each AI tool had custom integration code
❌ Switching AI providers meant rebuilding everything
❌ No standard way to share tools across platforms
❌ Security and permissions were ad-hoc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After MCP:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✅ Write once, use with any MCP-compatible AI
✅ Standard protocol for tool communication
✅ Built-in security and permission model
✅ Growing ecosystem of shared tools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How MCP Works
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────┐
│           AI Assistant (Claude, etc.)            │
│              "MCP Client"                        │
└────────────────────┬────────────────────────────┘
                     │ MCP Protocol
                     │ (JSON-RPC over stdio)
                     ▼
┌─────────────────────────────────────────────────┐
│              Your MCP Server                     │
│         (Custom Tools &amp;amp; Logic)                   │
└────────────────────┬────────────────────────────┘
                     │
        ┌────────────┴────────────┐
        ▼                         ▼
    GitHub API              File System
    Databases              External APIs
    Your Services          Anything!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MCP Client&lt;/strong&gt; - The AI assistant (Claude Desktop, VS Code, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Server&lt;/strong&gt; - Your custom tool server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt; - Individual capabilities you expose&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; - Data sources the AI can access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt; - Reusable prompt templates&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Problem We're Solving
&lt;/h2&gt;

&lt;h3&gt;
  
  
  User Pain Points
&lt;/h3&gt;

&lt;p&gt;When I launched Renderer, I saw users struggling with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Steep Learning Curve&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"How do I configure the home page?"
"What's the syntax for TOML arrays?"
"Where do I put my social media links?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Documentation Discovery&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I know this feature exists, but where's the doc?"
"How do I search across all documentation?"
"What are all the available configuration options?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Configuration Validation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Why isn't my portfolio loading?"
"Is this TOML syntax correct?"
"What fields am I missing?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Time-Consuming Setup&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"It took me 2 hours just to get started"
"I had to read all the docs first"
"Too much trial and error"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Vision
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What if users could just &lt;em&gt;ask&lt;/em&gt; for what they need?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User: "Create a portfolio for me with projects and resume"
AI: *Generates complete, valid configuration*

User: "Is my home.toml correct?"
AI: *Validates and suggests improvements*

User: "How do I add dark mode?"
AI: *Shows exact configuration with examples*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what Renderer MCP Server enables.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  System Design
&lt;/h3&gt;

&lt;p&gt;Our MCP server follows a clean, modular architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;renderer-mcp-server/
├── src/
│   ├── index.ts              # Main server &amp;amp; routing
│   ├── types.ts              # TypeScript definitions
│   ├── constants.ts          # Tool definitions
│   ├── github.ts             # GitHub API client
│   └── tools/                # Modular tool implementations
│       ├── validator.ts      # TOML validation
│       ├── template.ts       # Template generation
│       ├── examples.ts       # Config examples
│       ├── features.ts       # Feature search
│       └── guides.ts         # Setup guides
├── build/                    # Compiled JavaScript
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Technology Stack
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Core:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runtime:&lt;/strong&gt; Node.js 18+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language:&lt;/strong&gt; TypeScript 5.3+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol:&lt;/strong&gt; MCP via &lt;code&gt;@modelcontextprotocol/sdk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport:&lt;/strong&gt; stdio (standard input/output)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integrations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub API:&lt;/strong&gt; &lt;code&gt;@octokit/rest&lt;/code&gt; for repository access&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TOML Parser:&lt;/strong&gt; &lt;code&gt;toml&lt;/code&gt; for configuration validation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown:&lt;/strong&gt; &lt;code&gt;marked&lt;/code&gt; for content processing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why This Stack?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; - Type safety prevents runtime errors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modular Design&lt;/strong&gt; - Each tool is independent and testable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;stdio Transport&lt;/strong&gt; - Simple, universal, no networking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Integration&lt;/strong&gt; - Direct access to documentation and examples&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Implementation Guide
&lt;/h2&gt;

&lt;p&gt;Let's build the MCP server step by step!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Project Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create project structure&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;renderer-mcp-server
&lt;span class="nb"&gt;cd &lt;/span&gt;renderer-mcp-server
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; @modelcontextprotocol/sdk @octokit/rest toml marked

&lt;span class="c"&gt;# Install dev dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typescript @types/node

&lt;span class="c"&gt;# Initialize TypeScript&lt;/span&gt;
npx tsc &lt;span class="nt"&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;tsconfig.json:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES2022"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Node16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Node16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rootDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Define Types
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;src/types.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Type definitions for our MCP server
 */&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;RendererConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;TemplateOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;github&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;linkedin&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;twitter&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;includeProjects&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;includeBlog&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;includeResume&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ToolArguments&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;query&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;path&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;config_content&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;config_type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;level&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Create the Main Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;src/index.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@modelcontextprotocol/sdk/server/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StdioServerTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@modelcontextprotocol/sdk/server/stdio.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;CallToolRequestSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;ListToolsRequestSchema&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@modelcontextprotocol/sdk/types.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize MCP Server&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renderer-mcp-server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Tool definitions&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TOOLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get_config_example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Get example TOML configuration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;config_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;projects&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;resume&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;social&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Type of configuration needed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;config_type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// ... more tools&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Handle tool listing&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRequestHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ListToolsRequestSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TOOLS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// Handle tool execution&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRequestHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CallToolRequestSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get_config_example&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getConfigExample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;config_type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// ... more cases&lt;/span&gt;
            &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Unknown tool: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
            &lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Start server&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StdioServerTransport&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Renderer MCP Server running&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Implement Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Tool 1: Configuration Examples
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;src/tools/examples.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CONFIG_EXAMPLES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;home&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`# Home Page Configuration
[profile]
name = "Your Name"
tagline = "Your Role"
email = "your@email.com"

[hero]
title = "Hi, I'm Your Name 👋"
subtitle = "Building amazing things"
show_cta = true

[features]
show_about = true
show_skills = true
show_social = true

[theme]
mode = "auto"  # auto, light, dark
accent_color = "#0066cc"`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ... more examples&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getConfigExample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CONFIG_EXAMPLES&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;configType&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Unknown config type: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;configType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
            &lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`# &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;configType&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; Configuration Example\n\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;toml\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tool 2: TOML Validator
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;src/tools/validator.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;parseToml&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;toml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validateTomlConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;configContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;configType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Parse TOML&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseToml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Validate based on type&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

        &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing 'profile' section&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing 'hero' section&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;projects&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;projects&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing or invalid 'projects' array&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// ... more validations&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`✅ Valid!\n\nParsed:\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;json\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
                &lt;span class="p"&gt;}]&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`⚠️ Issues:\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;issues&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`- &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
                &lt;span class="p"&gt;}]&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`❌ TOML Syntax Error:\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
            &lt;span class="p"&gt;}],&lt;/span&gt;
            &lt;span class="na"&gt;isError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tool 3: Template Generator
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;src/tools/template.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;generateStarterTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TemplateOptions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;includeProjects&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;includeBlog&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;homeConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[profile]
name = "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"
tagline = "Developer &amp;amp; Creator"
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`email = "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;# email = "your@email.com"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

[hero]
title = "Hi, I'm &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; 👋"
subtitle = "Building amazing things"
show_cta = true
cta_text = "View My Work"
cta_link = "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;includeProjects&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/projects.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socialConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`[social]
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`github = "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;# github = "username"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`email = "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;# email = "your@email.com"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

[social.settings]
show_icons = true
open_in_new_tab = true`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`# Generated Configuration\n\n## home.toml\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;toml\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;homeConfig&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;\n\n## social.toml\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;toml\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;socialConfig&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Tool 4: GitHub Integration
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;src/github.ts:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Octokit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@octokit/rest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;octokit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Octokit&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initGitHub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;octokit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Octokit&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GITHUB_TOKEN&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getRendererFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;octokit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GitHub not initialized&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;octokit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NishikantaRay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renderer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;main&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not a file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`# &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n&lt;/span&gt;&lt;span class="se"&gt;\`\`\`&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
        &lt;span class="p"&gt;}]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Build &amp;amp; Package
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;package.json:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"renderer-mcp-server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"renderer-mcp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./build/index.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc &amp;amp;&amp;amp; chmod +x build/index.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"watch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc --watch"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@modelcontextprotocol/sdk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@octokit/rest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^20.0.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"toml"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.0.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
npm &lt;span class="nb"&gt;link&lt;/span&gt;  &lt;span class="c"&gt;# For local testing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Testing with Claude Desktop
&lt;/h2&gt;

&lt;p&gt;Claude Desktop has &lt;strong&gt;native MCP support&lt;/strong&gt; built-in. Here's how to use it:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install Claude Desktop
&lt;/h3&gt;

&lt;p&gt;Download from: &lt;a href="https://claude.ai/download" rel="noopener noreferrer"&gt;https://claude.ai/download&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Available for macOS and Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Configure MCP Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Find your config file:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;macOS:&lt;/strong&gt; &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; &lt;code&gt;%APPDATA%\Claude\claude_desktop_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Add your server:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"renderer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"renderer-mcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"GITHUB_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ghp_your_token_here_optional"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why the GitHub token?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Without: 60 API requests/hour&lt;/li&gt;
&lt;li&gt;With: 5000 API requests/hour&lt;/li&gt;
&lt;li&gt;Get one at: &lt;a href="https://github.com/settings/tokens" rel="noopener noreferrer"&gt;https://github.com/settings/tokens&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Restart Claude Desktop
&lt;/h3&gt;

&lt;p&gt;Close and reopen the app. The MCP server will start automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Verify Connection
&lt;/h3&gt;

&lt;p&gt;In Claude Desktop, you should see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A small "🔌" icon or "MCP" indicator&lt;/li&gt;
&lt;li&gt;"Renderer" listed in connected tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Start Using It!
&lt;/h3&gt;

&lt;p&gt;Just talk to Claude naturally. Here are real examples:&lt;/p&gt;

&lt;h4&gt;
  
  
  Example 1: Generate Starter Template
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a portfolio starter template for me. 
My name is John Doe, GitHub is johndoe, 
and I want projects and resume sections.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude (using MCP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I'll generate a complete starter template for you using the 
Renderer MCP server.

*calls generate_starter_template tool*

Here's your customized configuration:

[Shows complete TOML configs for home.toml, social.toml, 
projects.toml, and resume.toml with your information pre-filled]

To use this:
1. Clone the Renderer repository
2. Copy these configs to the config/ directory
3. Run npm install &amp;amp;&amp;amp; npm run dev
4. Your portfolio will be live at localhost:3000!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example 2: Validate Configuration
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Can you validate this TOML config for me?

[profile]
name = "Jane Smith"
tagline = "Full Stack Developer"

[hero]
title = "Hi, I'm Jane"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude (using MCP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Let me validate that for you.

*calls validate_toml_config tool*

⚠️ Configuration Issues Found:

1. Missing 'hero.subtitle' field (recommended)
2. Missing 'hero.show_cta' field (required)
3. Missing 'features' section

Here's the corrected version:

[profile]
name = "Jane Smith"
tagline = "Full Stack Developer"

[hero]
title = "Hi, I'm Jane"
subtitle = "Building amazing web applications"
show_cta = true
cta_text = "View My Work"
cta_link = "/projects.html"

[features]
show_about = true
show_skills = true
show_social = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example 3: Learn Features
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How do I add dark mode to my Renderer portfolio?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude (using MCP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Let me search for that feature.

*calls search_renderer_features tool*

# Dark Mode in Renderer

Renderer includes automatic dark mode support!

## Configuration (config/home.toml)

[theme]
mode = "auto"  # Options: auto, light, dark
accent_color = "#0066cc"

## How it works:

- **auto**: Follows system preferences (recommended)
- **light**: Always light theme
- **dark**: Always dark theme

Users can also toggle themes manually with the theme 
switcher button that appears automatically.

The theme preference is saved in localStorage, so it 
persists across sessions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example 4: Get Examples
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;You:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Show me an example of how to configure projects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Claude (using MCP):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*calls get_config_example tool*

Here's a complete example for projects.toml:

# Projects Configuration

[[projects]]
title = "Renderer Framework"
description = "A TOML-driven portfolio system"
tags = ["JavaScript", "TOML", "HTML"]
repo = "https://github.com/username/renderer"
demo = "https://demo.example.com"
docs = "https://docs.example.com"
featured = true
company = "@MyCompany"

[[projects]]
title = "Another Cool Project"
description = "Building something awesome"
tags = ["TypeScript", "React", "Node.js"]
repo = "https://github.com/username/project"
featured = false

## Usage:
1. Copy this to config/projects.toml
2. Customize with your projects
3. Add more [[projects]] blocks as needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real Workflow Example
&lt;/h3&gt;

&lt;p&gt;Here's a complete real-world workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "I want to create a portfolio. Help me get started."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude:&lt;/strong&gt; "I'll help you create a portfolio with Renderer! First, let me generate a starter template."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Uses generate_starter_template&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude:&lt;/strong&gt; "Great! I've created custom configurations for you. Now let me show you the setup steps."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Uses get_setup_guide&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude:&lt;/strong&gt; "Here's what to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository...&lt;/li&gt;
&lt;li&gt;Copy these configs...&lt;/li&gt;
&lt;li&gt;Run these commands..."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "I added my projects but getting an error"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude:&lt;/strong&gt; "Let me validate your configuration."&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Uses validate_toml_config&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude:&lt;/strong&gt; "Found the issue! You're missing a comma on line 5. Here's the corrected version..."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User:&lt;/strong&gt; "How do I deploy this?"&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Uses get_setup_guide with level: "advanced"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude:&lt;/strong&gt; "Here are your deployment options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GitHub Pages...&lt;/li&gt;
&lt;li&gt;Vercel (recommended)...&lt;/li&gt;
&lt;li&gt;Netlify..."&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Testing with MCP Inspector
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;MCP Inspector&lt;/strong&gt; is a visual debugging tool for MCP servers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Install &amp;amp; Launch
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run the inspector (no installation needed)&lt;/span&gt;
npx @modelcontextprotocol/inspector renderer-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start your MCP server&lt;/li&gt;
&lt;li&gt;Launch a web interface&lt;/li&gt;
&lt;li&gt;Open your browser automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Explore the Interface
&lt;/h3&gt;

&lt;p&gt;The inspector has three panels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────┐
│  Left Panel       │  Center Panel    │  Right Panel  │
│  (Tools List)     │  (Input Form)    │  (Results)    │
├──────────────────────────────────────────────────────┤
│                                                        │
│  • Tool 1         │  [Input fields]  │  [JSON        │
│  • Tool 2         │  [for selected]  │   Response]   │
│  • Tool 3         │  [tool]          │               │
│  • ...            │                  │               │
│                   │  [Execute Btn]   │  [Formatted   │
│                   │                  │   Output]     │
└──────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Test Each Tool
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Test 1: Get Configuration Example
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Left Panel:&lt;/strong&gt; Click &lt;code&gt;get_config_example&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Center Panel:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;Field: &lt;code&gt;config_type&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Value: &lt;code&gt;home&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click:&lt;/strong&gt; "Execute" button&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right Panel:&lt;/strong&gt; Should show:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# Home Page Configuration Example&lt;/span&gt;

&lt;span class="nn"&gt;[profile]&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"John Doe"&lt;/span&gt;
&lt;span class="py"&gt;tagline&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Full Stack Developer"&lt;/span&gt;
&lt;span class="err"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Test 2: Validate Configuration
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Left Panel:&lt;/strong&gt; Click &lt;code&gt;validate_toml_config&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Center Panel:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Field: &lt;code&gt;config_content&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Value:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt; &lt;span class="nn"&gt;[profile]&lt;/span&gt;
 &lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Field: &lt;code&gt;config_type&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Value: &lt;code&gt;home&lt;/code&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Click:&lt;/strong&gt; "Execute"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right Panel:&lt;/strong&gt; Should show validation results&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Try Invalid TOML:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="err"&gt;[profile&lt;/span&gt;
&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Missing bracket"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should see syntax error with helpful message!&lt;/p&gt;

&lt;h4&gt;
  
  
  Test 3: Generate Template
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Left Panel:&lt;/strong&gt; Click &lt;code&gt;generate_starter_template&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Center Panel:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: "Alice Johnson"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;email&lt;/code&gt;: "&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;github&lt;/code&gt;: "alicejohnson"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;include_projects&lt;/code&gt;: ✅ true&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;include_blog&lt;/code&gt;: ❌ false&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;include_resume&lt;/code&gt;: ✅ true&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click:&lt;/strong&gt; "Execute"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right Panel:&lt;/strong&gt; Should show complete template&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Test 4: Search Features
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Left Panel:&lt;/strong&gt; Click &lt;code&gt;search_renderer_features&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Center Panel:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;feature&lt;/code&gt;: "analytics"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Click:&lt;/strong&gt; "Execute"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Right Panel:&lt;/strong&gt; Should show feature documentation&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Verify All Tools
&lt;/h3&gt;

&lt;p&gt;Test all 8 tools systematically:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Tool Name&lt;/th&gt;
&lt;th&gt;Test Input&lt;/th&gt;
&lt;th&gt;Expected Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;explore_renderer_docs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;query: "TOML"&lt;/td&gt;
&lt;td&gt;Documentation snippets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_renderer_file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;path: "config/home.toml"&lt;/td&gt;
&lt;td&gt;File contents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;list_renderer_files&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;path: "config"&lt;/td&gt;
&lt;td&gt;Directory listing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;validate_toml_config&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Valid TOML + type&lt;/td&gt;
&lt;td&gt;✅ Valid message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;generate_starter_template&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;name: "Test"&lt;/td&gt;
&lt;td&gt;Full template&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_config_example&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;type: "projects"&lt;/td&gt;
&lt;td&gt;Example config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;&lt;code&gt;search_renderer_features&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;feature: "dark mode"&lt;/td&gt;
&lt;td&gt;Feature docs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;code&gt;get_setup_guide&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;level: "beginner"&lt;/td&gt;
&lt;td&gt;Setup guide&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 5: Debug Issues
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Common Issues:&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tools Not Appearing
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem: Left panel is empty
Solution: Check terminal for error messages
         Ensure server started successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Execution Fails
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem: Error in right panel
Solution: Check input types match schema
         Verify required fields are filled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Slow Responses
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem: Long wait times
Solution: Normal for GitHub API calls
         Add GitHub token for better performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Advanced Testing
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Test Error Handling
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Invalid config type:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"config_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"invalid_type"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should return clear error message.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing required field:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should indicate missing required field.&lt;/p&gt;

&lt;h4&gt;
  
  
  Test Edge Cases
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Empty strings:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Very long input:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"config_content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"... 10,000 characters ..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Special characters:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Test&amp;lt;script&amp;gt;alert('xss')&amp;lt;/script&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Performance Testing
&lt;/h3&gt;

&lt;p&gt;Monitor the &lt;strong&gt;Network tab&lt;/strong&gt; in browser DevTools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tool execution time&lt;/li&gt;
&lt;li&gt;Response size&lt;/li&gt;
&lt;li&gt;Error rates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good benchmarks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple tools: &amp;lt;200ms&lt;/li&gt;
&lt;li&gt;GitHub API calls: &amp;lt;2s&lt;/li&gt;
&lt;li&gt;Complex operations: &amp;lt;5s&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;Let's see how users actually use Renderer MCP Server:&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case 1: First-Time Portfolio Creation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; Sarah, a bootcamp graduate, needs a portfolio fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Way (2+ hours):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find Renderer documentation&lt;/li&gt;
&lt;li&gt;Read through all docs&lt;/li&gt;
&lt;li&gt;Understand TOML syntax&lt;/li&gt;
&lt;li&gt;Create configuration files&lt;/li&gt;
&lt;li&gt;Debug syntax errors&lt;/li&gt;
&lt;li&gt;Test locally&lt;/li&gt;
&lt;li&gt;Deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With MCP (15 minutes):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sarah: "Create a portfolio for Sarah Chen, full-stack developer, 
       GitHub sarahchen"

Claude: *generates complete template*

Sarah: *copies configs, runs npm install*

Sarah: "How do I deploy this?"

Claude: *provides deployment guide*

Sarah: *deploys to Vercel in 3 clicks*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Portfolio live in 15 minutes! ✅&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case 2: Configuration Debugging
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; Mike's portfolio won't load after config changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Way:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Console shows cryptic error&lt;/li&gt;
&lt;li&gt;Search through documentation&lt;/li&gt;
&lt;li&gt;Check TOML syntax manually&lt;/li&gt;
&lt;li&gt;Trial and error fixes&lt;/li&gt;
&lt;li&gt;Search Stack Overflow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With MCP:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mike: "My portfolio broke after I updated config. Can you check it?"
      [pastes config]

Claude: *validates config*
        "Found 2 issues:
         1. Missing closing bracket on line 12
         2. Invalid value for 'mode' field (must be 'auto', 'light', or 'dark')

         Here's the corrected version..."

Mike: *copies fix, portfolio works immediately*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Issue fixed in 2 minutes! ✅&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case 3: Feature Discovery
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; Emma wants to add advanced features but doesn't know what's available.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Way:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read through all documentation&lt;/li&gt;
&lt;li&gt;Browse example repositories&lt;/li&gt;
&lt;li&gt;Search issues and discussions&lt;/li&gt;
&lt;li&gt;Trial and error implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With MCP:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Emma: "What features can I add to my portfolio?"

Claude: *lists features with descriptions*
        "Renderer has these features:
         - Dark mode theme switching
         - @mention system for companies
         - Analytics dashboard
         - Blog with MDX support
         - Project filtering by tags
         - Resume with timeline
         - And more!

         Which would you like to implement?"

Emma: "Tell me about the analytics dashboard"

Claude: *searches features*
        "The analytics dashboard shows:
         - Project view counts
         - GitHub stars
         - Visitor metrics
         - Performance stats

         Here's how to enable it..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Discovered and implemented features quickly! ✅&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case 4: Team Onboarding
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Scenario:&lt;/strong&gt; Tech startup needs to create portfolios for 10 developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without MCP:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each person spends 2-4 hours&lt;/li&gt;
&lt;li&gt;Inconsistent results&lt;/li&gt;
&lt;li&gt;Multiple support requests&lt;/li&gt;
&lt;li&gt;Total: 20-40 person-hours&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With MCP:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Template: "Generate template for [name], GitHub [username], 
          email [email], include projects and resume"

Each Developer:
1. Ask MCP for template (2 min)
2. Clone and setup (5 min)
3. Customize (10 min)
4. Deploy (3 min)

Total per person: 20 minutes
Total team: 3.5 hours (vs 20-40 hours)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; 85-90% time savings! ✅&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;After building and deploying Renderer MCP Server, here are key insights:&lt;/p&gt;

&lt;h3&gt;
  
  
  What Worked Well ✅
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Modular Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each tool in its own file&lt;/li&gt;
&lt;li&gt;Easy to add new tools&lt;/li&gt;
&lt;li&gt;Simple to maintain and test&lt;/li&gt;
&lt;li&gt;Clean separation of concerns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. TypeScript&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caught errors at compile time&lt;/li&gt;
&lt;li&gt;Great IDE autocomplete&lt;/li&gt;
&lt;li&gt;Self-documenting code&lt;/li&gt;
&lt;li&gt;Easier refactoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. stdio Transport&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple setup&lt;/li&gt;
&lt;li&gt;No networking complexity&lt;/li&gt;
&lt;li&gt;Universal compatibility&lt;/li&gt;
&lt;li&gt;Easy debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Comprehensive Examples&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users love copy-paste examples&lt;/li&gt;
&lt;li&gt;Reduces support burden&lt;/li&gt;
&lt;li&gt;Speeds up adoption&lt;/li&gt;
&lt;li&gt;Encourages best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What Could Be Better 🔄
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Caching&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Current: Every request hits GitHub API&lt;/span&gt;
&lt;span class="c1"&gt;// Better: Cache responses for repeated queries&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCachedFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFromGitHub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Error Messages&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Current: Generic error messages&lt;/span&gt;
&lt;span class="c1"&gt;// Better: Actionable, specific errors&lt;/span&gt;

&lt;span class="c1"&gt;// Instead of:&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Validation failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;// Provide:&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing required field 'profile.name' in home.toml (line 5)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Progress Indicators&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Current: Silent processing&lt;/span&gt;
&lt;span class="c1"&gt;// Better: Show progress for long operations&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;longOperation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fetching documentation...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchDocs&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing results...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;processDocs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Takeaways 💡
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Simple&lt;/strong&gt; - MVP with core tools, iterate based on feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User-Centric&lt;/strong&gt; - Solve real problems, not theoretical ones&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt; - Clear examples &amp;gt; long explanations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt; - Inspector + Claude Desktop = comprehensive testing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community&lt;/strong&gt; - Users will surprise you with use cases&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Metrics That Matter 📊
&lt;/h3&gt;

&lt;p&gt;After 1 month of Renderer MCP Server:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Avg Setup Time&lt;/td&gt;
&lt;td&gt;2 hours&lt;/td&gt;
&lt;td&gt;15 min&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-87%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support Tickets&lt;/td&gt;
&lt;td&gt;50/week&lt;/td&gt;
&lt;td&gt;15/week&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-70%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Successful Setups&lt;/td&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+58%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Satisfaction&lt;/td&gt;
&lt;td&gt;3.5★&lt;/td&gt;
&lt;td&gt;4.7★&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+34%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Stars&lt;/td&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;420&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+180%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;h3&gt;
  
  
  Phase 2: Enhancements (Q1 2026)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Caching Layer&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Smart caching for GitHub responses&lt;/span&gt;
&lt;span class="c1"&gt;// Reduce API calls by 80%&lt;/span&gt;
&lt;span class="c1"&gt;// Faster response times&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Offline Mode&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Work without internet&lt;/span&gt;
&lt;span class="c1"&gt;// Cached documentation&lt;/span&gt;
&lt;span class="c1"&gt;// Local validation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Better Error Messages&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Line numbers in errors&lt;/span&gt;
&lt;span class="c1"&gt;// Suggested fixes&lt;/span&gt;
&lt;span class="c1"&gt;// Related documentation links&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 3: Advanced Features (Q2 2026)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Visual Configuration Builder&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GUI for creating configs
Drag-and-drop interface
Live preview
Export to TOML
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AI Content Generation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generate project descriptions
Write portfolio copy
Create blog post outlines
SEO optimization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Deployment Assistant&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One-command deployment
Multiple platforms
Environment setup
Domain configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 4: Ecosystem (Q3 2026)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Plugin System&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Let community create tools&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Plugin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nl"&gt;onLoad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Marketplace&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Share templates
Community plugins
Premium themes
Integrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Multi-Language Support&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i18n for documentation
Localized examples
Regional templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Ready to try Renderer MCP Server?&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick Start (5 Minutes)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; renderer-mcp-server

&lt;span class="c"&gt;# 2. Configure Claude Desktop&lt;/span&gt;
&lt;span class="c"&gt;# Add to claude_desktop_config.json:&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"mcpServers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"renderer"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"command"&lt;/span&gt;: &lt;span class="s2"&gt;"renderer-mcp"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# 3. Restart Claude Desktop&lt;/span&gt;

&lt;span class="c"&gt;# 4. Start using it!&lt;/span&gt;
&lt;span class="c"&gt;# Just ask Claude: "Create a portfolio for me"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build Your Own MCP Server
&lt;/h3&gt;

&lt;p&gt;Want to create an MCP server for your project?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Clone the template:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/NishikantaRay/renderer-mcp-server
&lt;span class="nb"&gt;cd &lt;/span&gt;renderer-mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Customize for your use case:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Replace Renderer-specific logic&lt;/li&gt;
&lt;li&gt;Add your own tools&lt;/li&gt;
&lt;li&gt;Connect to your APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Test and deploy:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
npm &lt;span class="nb"&gt;link
&lt;/span&gt;npx @modelcontextprotocol/inspector your-mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;renderer-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Renderer Framework:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay/renderer" rel="noopener noreferrer"&gt;renderer&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP Docs:&lt;/strong&gt; &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;modelcontextprotocol.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Desktop:&lt;/strong&gt; &lt;a href="https://claude.ai/download" rel="noopener noreferrer"&gt;claude.ai/download&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building Renderer MCP Server transformed how users interact with the Renderer framework. What was once a 2-hour manual process is now a 15-minute conversation with an AI assistant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Achievements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ 87% faster setup time&lt;/li&gt;
&lt;li&gt;🎯 95% success rate for first-time users&lt;/li&gt;
&lt;li&gt;📉 70% reduction in support tickets&lt;/li&gt;
&lt;li&gt;🌟 4.7★ user satisfaction&lt;/li&gt;
&lt;li&gt;🚀 3x framework adoption growth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Power of MCP:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MCP isn't just about connecting AI to tools—it's about creating &lt;strong&gt;intelligent assistants that truly understand your domain&lt;/strong&gt;. The Renderer MCP Server doesn't just execute commands; it knows the framework intimately, validates configurations, teaches best practices, and guides users from zero to deployed.&lt;/p&gt;

&lt;p&gt;This is the future of developer tools: &lt;strong&gt;AI assistants that are specialists, not generalists&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your Turn:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What framework or tool could benefit from its own MCP server? &lt;/p&gt;

&lt;p&gt;The pattern is proven. The infrastructure is here. The only limit is imagination.&lt;/p&gt;

&lt;p&gt;Build something amazing. 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  About the Author
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Nishikanta Ray&lt;/strong&gt; is the creator of Renderer, a modern portfolio framework, and Renderer MCP Server. He's passionate about making web development more accessible through AI-powered tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/NishikantaRay" rel="noopener noreferrer"&gt;@NishikantaRay&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/nishikantaray" rel="noopener noreferrer"&gt;@nishikantaray&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Website:&lt;/strong&gt; &lt;a href="https://nishikanta.in" rel="noopener noreferrer"&gt;nishikanta.in&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Comments &amp;amp; Discussion
&lt;/h2&gt;

&lt;p&gt;Have questions about building MCP servers? Share your experience in the comments!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topics for discussion:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What tool/framework needs an MCP server?&lt;/li&gt;
&lt;li&gt;Challenges you faced with MCP&lt;/li&gt;
&lt;li&gt;Creative use cases you've discovered&lt;/li&gt;
&lt;li&gt;Features you'd like to see&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's build the future of AI-assisted development together! 💬&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #MCP #AI #DeveloperTools #Anthropic #Claude #OpenSource #TypeScript #Portfolio&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Published:&lt;/strong&gt; December 29, 2025&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Reading Time:&lt;/strong&gt; 25 minutes&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Last Updated:&lt;/strong&gt; December 29, 2025&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you found this helpful, please ⭐ star the &lt;a href="https://github.com/NishikantaRay/renderer-mcp-server" rel="noopener noreferrer"&gt;repository&lt;/a&gt; and share with others!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Behind the Scenes — Building NexoDrive and Reinventing File Sharing</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Fri, 28 Nov 2025 18:54:41 +0000</pubDate>
      <link>https://dev.to/nishikantaray/behind-the-scenes-building-nexodrive-and-reinventing-file-sharing-1m8k</link>
      <guid>https://dev.to/nishikantaray/behind-the-scenes-building-nexodrive-and-reinventing-file-sharing-1m8k</guid>
      <description>&lt;p&gt;Over the past few weeks, we (I and @&lt;a href="https://dev.to@sumeetnaik"&gt;Sumeet Naik&lt;/a&gt; ) built something. A simple tool that turns chaotic Google Drives into clean, user-friendly libraries.&lt;/p&gt;

&lt;p&gt;We call it &lt;strong&gt;NexoDrive&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But this post isn’t just a product announcement — it’s the story behind why we built it and how it solves a surprisingly common problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Pain Point: “Where’s the File?”&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Whether you're building software, running a business, or studying in college — you’ve probably heard (or said):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;“Can you resend the link?”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“I can’t find the file.”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Where did you put this?”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“Do I need permission?”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google Drive is powerful, but for sharing large sets of files, it falls apart fast.&lt;br&gt;&lt;br&gt;
People struggle to navigate deep folder structures.&lt;br&gt;&lt;br&gt;
Permission management becomes a nightmare.&lt;br&gt;&lt;br&gt;
Links get mixed up.&lt;br&gt;&lt;br&gt;
You spend more time helping people find files than actually working.&lt;/p&gt;

&lt;p&gt;We ran into this problem while building a notes-sharing platform for a college. With &lt;strong&gt;1,500+ users&lt;/strong&gt;, Drive chaos became a daily issue.&lt;/p&gt;

&lt;p&gt;So we built a solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Idea: A Display Layer for Google Drive&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We didn’t want to replace Drive.&lt;br&gt;&lt;br&gt;
Drive is great for storage.&lt;/p&gt;

&lt;p&gt;We wanted to replace how people &lt;em&gt;view&lt;/em&gt; your Drive.&lt;/p&gt;

&lt;p&gt;The concept of NexoDrive became clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The owner stores everything in Google Drive (just like always)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NexoDrive reads the Drive using read-only access&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We index everything and create a clean interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;End users can browse files instantly without touching Google Drive&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple idea — but incredibly effective.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Security First&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When someone hears “access to your Drive,” it’s natural to worry.&lt;/p&gt;

&lt;p&gt;So from day one, we designed NexoDrive to be safe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Only &lt;em&gt;read-only&lt;/em&gt; access (no editing, deleting, downloading, or moving files)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You choose exactly what to show&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your Drive stays untouched&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All indexing is internal and controlled&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your privacy stays intact.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What the User Sees&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is the magic.&lt;/p&gt;

&lt;p&gt;Instead of the messy Google Drive UI, they get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clean file lists&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instant loading&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No login needed (unless you want it)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Only the files you choose to display&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It looks like a custom-built resource library — without you needing to build anything.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Early Feedback&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When we deployed this for the college platform:&lt;/p&gt;

&lt;p&gt;💬 Students said: &lt;em&gt;“Finally, everything is easy to find.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
💬 Teachers said: &lt;em&gt;“We don’t have to manage permissions anymore.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
💬 Admins said: &lt;em&gt;“This saves hours every week.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That’s when we realized the potential.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Who This Is For&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;NexoDrive can help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Educational institutions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Freelancers &amp;amp; agencies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Coaches &amp;amp; mentors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Businesses sharing documents&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creators delivering files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Teams with shared resources&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Communities hosting notes/materials&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your Google Drive is the heart of your workflow, NexoDrive becomes the face of it.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Try It Out&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We’ve launched our public beta here:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://nexodrive.xyz" rel="noopener noreferrer"&gt;&lt;strong&gt;https://nexodrive.xyz&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just version 1. We have big plans for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Custom branding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analytics&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access control&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Better search&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-account support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Embeddable file viewers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have ideas, feedback, or feature requests — we’d love to hear them.&lt;/p&gt;

&lt;p&gt;Thanks for reading, and welcome to the beginning of a much cleaner file-sharing experience. 🚀&lt;/p&gt;




</description>
      <category>google</category>
      <category>showdev</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Master–Slave (Primary–Replica) Replication</title>
      <dc:creator>Nishikanta Ray</dc:creator>
      <pubDate>Fri, 28 Nov 2025 18:39:16 +0000</pubDate>
      <link>https://dev.to/nishikantaray/master-slave-primary-replica-replication-5210</link>
      <guid>https://dev.to/nishikantaray/master-slave-primary-replica-replication-5210</guid>
      <description>&lt;p&gt;If you’re building a modern application that needs speed, availability, and fault tolerance, &lt;strong&gt;MongoDB replication&lt;/strong&gt; is one of the easiest and most powerful features you can use.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;📌 What Is Master–Slave (Primary–Replica) Replication?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Replication ensures you have &lt;strong&gt;multiple copies&lt;/strong&gt; of your data across different servers.&lt;/p&gt;

&lt;p&gt;In MongoDB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;Primary&lt;/strong&gt; node handles all writes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Secondary&lt;/strong&gt; nodes replicate data from the primary and handle reads (optional).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the primary fails, MongoDB automatically promotes a secondary → new primary.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup is known as a &lt;strong&gt;Replica Set&lt;/strong&gt;, which is MongoDB’s improved version of the old master–slave architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⭐ Why Do We Need Master–Slave (Primary–Replica) Architecture?
&lt;/h2&gt;

&lt;p&gt;Master–slave replication exists because &lt;strong&gt;one single database server cannot handle everything reliably, efficiently, and safely&lt;/strong&gt;. Splitting responsibilities between a &lt;strong&gt;master (primary)&lt;/strong&gt; and &lt;strong&gt;slaves (replicas)&lt;/strong&gt; solves several real-world problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;📐 MongoDB Replication Architecture&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;            &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
            &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="nx"&gt;Primary&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;---&lt;/span&gt; &lt;span class="nx"&gt;Write&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;Read&lt;/span&gt;
            &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
               &lt;span class="sr"&gt;/         &lt;/span&gt;&lt;span class="err"&gt;\
&lt;/span&gt;              &lt;span class="o"&gt;/&lt;/span&gt;           &lt;span class="o"&gt;\&lt;/span&gt;
&lt;span class="o"&gt;+-----------------+&lt;/span&gt;   &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="nx"&gt;Secondary&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="nx"&gt;Secondary&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------------+&lt;/span&gt;   &lt;span class="o"&gt;+-----------------+&lt;/span&gt;
     &lt;span class="nx"&gt;Read&lt;/span&gt; &lt;span class="nx"&gt;Only&lt;/span&gt;            &lt;span class="nx"&gt;Read&lt;/span&gt; &lt;span class="nx"&gt;Only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⭐ What Is Slave Replication (Explained Like You’re 5)
&lt;/h2&gt;

&lt;p&gt;Slave replication means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One database is the &lt;strong&gt;master&lt;/strong&gt; → accepts all writes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other databases are &lt;strong&gt;slaves/replicas&lt;/strong&gt; → copy whatever master does&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replicas stay almost up-to-date with the master&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like a &lt;strong&gt;teacher (master)&lt;/strong&gt; writing on the board, and&lt;br&gt;&lt;br&gt;
&lt;strong&gt;3 students (slaves/replicas)&lt;/strong&gt; copying everything in real time.&lt;/p&gt;

&lt;p&gt;Sometimes students copy late → this is &lt;strong&gt;replication lag&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔁 How Slave Replication Actually Works (Technical Flow)
&lt;/h2&gt;

&lt;p&gt;Below is the internal flow, no fluff:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. Master records every write into a log&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MySQL → Binary Log (binlog)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MongoDB → Oplog&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL → WAL Log&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example log entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;UPDATE&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="nx"&gt;SET&lt;/span&gt; &lt;span class="nx"&gt;stock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="nx"&gt;WHERE&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Slaves read these logs continuously&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A slave says:&lt;br&gt;&lt;br&gt;
➡️ “Master, give me the next log entry after position X.”&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3. Slaves apply the changes locally&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Whatever operation appears in the log:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;INSERT&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UPDATE&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DELETE&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…slaves replay them in the same order.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;4. After applying logs → slave becomes synced&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This cycle repeats &lt;strong&gt;non-stop&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  ⏳ Replication Delay (Lag): Why It Happens
&lt;/h2&gt;

&lt;p&gt;Slaves may fall behind due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Slow network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Heavy load on slave&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Large write burst on master&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Slow disk I/O&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complex queries running on slave&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the slave is behind, it shows &lt;strong&gt;old data&lt;/strong&gt; temporarily.&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ How Systems Handle Delays
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Read-from-master for critical operations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Apps often use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Normal read → from replica (fast)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Critical read (e.g., after update) → from master&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This avoids stale data issues.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ “Read-your-own-write” rules&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If a user writes something (POST/UPDATE):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You route that user’s next read to the master only&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Until replica catches up&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Frameworks like Rails, Laravel, Django already support this.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Monitoring replication lag&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Tools measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;replication_lag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;slave_last_applied_timestamp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;master_timestamp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If lag &amp;gt; X seconds:&lt;br&gt;&lt;br&gt;
→ temporarily stop sending reads to that replica&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;4️⃣ Write concerns (MongoDB)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;MongoDB allows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;writeConcern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;w&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;majority&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meaning:&lt;br&gt;&lt;br&gt;
→ Write is successful only when &lt;strong&gt;most&lt;/strong&gt; replicas have it&lt;/p&gt;

&lt;p&gt;This reduces risk of data inconsistency.&lt;/p&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;5️⃣ Semi-Sync Replication (MySQL / PostgreSQL)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Master waits until &lt;strong&gt;at least one slave&lt;/strong&gt; confirms:&lt;/p&gt;

&lt;p&gt;“Yep, I received the log.”&lt;/p&gt;

&lt;p&gt;This avoids data loss.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔄 How Updates Flow (Example With Steps)
&lt;/h2&gt;

&lt;p&gt;Let’s use a real example:&lt;/p&gt;
&lt;h3&gt;
  
  
  A user updates their profile:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;UPDATE&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="nx"&gt;SET&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Nishikanta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;WHERE&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here’s what happens:&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1 — Master writes to its DB&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Master updates row in its storage engine.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2 — Master logs the change&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Master adds entry to binlog/oplog:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;op&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;update&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Nishikanta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3 — Slaves fetch this log&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Replica 1 → “Give me log #520”&lt;br&gt;&lt;br&gt;
Replica 2 → “Give me log #520”&lt;/p&gt;

&lt;p&gt;Master streams them.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4 — Slaves apply changes&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Replica updates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Nishikanta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5 — Replicas catch up&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Once all logs are applied → they’re in sync.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Diagram: How Replication Works (Clean + Blog-Ready)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;                &lt;span class="err"&gt;┌───────────────────────┐&lt;/span&gt;
                &lt;span class="err"&gt;│&lt;/span&gt;       &lt;span class="nx"&gt;MASTER&lt;/span&gt;          &lt;span class="err"&gt;│&lt;/span&gt;
                &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Primary&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;All&lt;/span&gt; &lt;span class="nx"&gt;Writes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;│&lt;/span&gt;
                &lt;span class="err"&gt;└───────┬───────────────┘&lt;/span&gt;
                        &lt;span class="err"&gt;│&lt;/span&gt;
        &lt;span class="nx"&gt;Writes&lt;/span&gt; &lt;span class="err"&gt;→&lt;/span&gt; &lt;span class="nx"&gt;Binlog&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Oplog&lt;/span&gt; &lt;span class="nx"&gt;generated&lt;/span&gt;
                        &lt;span class="err"&gt;│&lt;/span&gt;
        &lt;span class="err"&gt;┌───────────────┴───────────────┐&lt;/span&gt;
        &lt;span class="err"&gt;│&lt;/span&gt;                               &lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;┌────────────────────┐&lt;/span&gt;        &lt;span class="err"&gt;┌────────────────────┐&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;    &lt;span class="nx"&gt;SLAVE&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;        &lt;span class="err"&gt;│&lt;/span&gt;        &lt;span class="err"&gt;│&lt;/span&gt;    &lt;span class="nx"&gt;SLAVE&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;        &lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Replica&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Reads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;│&lt;/span&gt;        &lt;span class="err"&gt;│&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Replica&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Reads&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="err"&gt;│&lt;/span&gt;
&lt;span class="err"&gt;└───────┬────────────┘&lt;/span&gt;        &lt;span class="err"&gt;└──────────┬─────────┘&lt;/span&gt;
        &lt;span class="err"&gt;│&lt;/span&gt;                                 &lt;span class="err"&gt;│&lt;/span&gt;
        &lt;span class="err"&gt;│&lt;/span&gt;    &lt;span class="nx"&gt;Fetch&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="nx"&gt;continuously&lt;/span&gt;       &lt;span class="err"&gt;│&lt;/span&gt;
        &lt;span class="err"&gt;│&lt;/span&gt;        &lt;span class="nx"&gt;Apply&lt;/span&gt; &lt;span class="nx"&gt;updates&lt;/span&gt;            &lt;span class="err"&gt;│&lt;/span&gt;
        &lt;span class="err"&gt;│&lt;/span&gt;     &lt;span class="nx"&gt;Handle&lt;/span&gt; &lt;span class="nx"&gt;replication&lt;/span&gt; &lt;span class="nx"&gt;lag&lt;/span&gt;      &lt;span class="err"&gt;│&lt;/span&gt;
        &lt;span class="err"&gt;▼&lt;/span&gt;                                 &lt;span class="err"&gt;▼&lt;/span&gt;
  &lt;span class="nx"&gt;Up&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="nx"&gt;copy&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;DB&lt;/span&gt;            &lt;span class="nx"&gt;Up&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="nx"&gt;copy&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;DB&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  &lt;strong&gt;🟩 Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Master–slave (primary–replica) replication is one of the most essential techniques for building &lt;strong&gt;fast, reliable, and highly available&lt;/strong&gt; modern applications. By separating write operations to the master and distributing read operations across multiple replicas, systems can handle far more traffic, avoid downtime, and guarantee that data remains safe even if a server fails.&lt;/p&gt;

&lt;p&gt;Although replication may introduce small delays (replication lag), most real-world systems manage this easily through smart routing, read-after-write strategies, and monitoring tools. The result is a database architecture that provides &lt;strong&gt;scalability, resilience, and real-time data redundancy&lt;/strong&gt; — all without changing how your application writes data.&lt;/p&gt;

&lt;p&gt;Whether you’re using MongoDB, MySQL, PostgreSQL, or Redis, mastering replication is a core skill that enables you to build applications that stay fast, stay online, and scale gracefully as your users grow.&lt;/p&gt;

</description>
      <category>distributedsystems</category>
      <category>database</category>
      <category>architecture</category>
      <category>mongodb</category>
    </item>
  </channel>
</rss>
