<?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: Dang Tran</title>
    <description>The latest articles on DEV Community by Dang Tran (@dang_tran_63f9ff8ece59c73).</description>
    <link>https://dev.to/dang_tran_63f9ff8ece59c73</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3673024%2F4eda0aff-2974-4b22-881b-72141716c683.jpg</url>
      <title>DEV Community: Dang Tran</title>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dang_tran_63f9ff8ece59c73"/>
    <language>en</language>
    <item>
      <title>Pair - your personal stylist</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Sat, 23 May 2026 11:31:53 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/a-clothing-pairing-app-1egd</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/a-clothing-pairing-app-1egd</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Build with Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Pair is a personal stylist in your pocket. You take a photo of something you already own — a jacket, a pair of jeans, whatever — and the app finds you a complementary piece from a catalogue of 44,000 products. Then it generates an editorial fashion photo showing both items styled together on a model, so you can actually see how the outfit looks before you buy anything.&lt;/p&gt;

&lt;p&gt;The product catalogue is the Myntra fashion dataset (~44k products), available at &lt;a href="https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset" rel="noopener noreferrer"&gt;kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The app is a full-stack TypeScript project — Vite + React on the frontend, Hono on Node.js on the backend. The interesting part is the AI pipeline: I send the uploaded image to Gemma 4, which returns structured JSON — category, gender, style tags, dominant colour. Then I query MongoDB with a $match + $sample aggregation to pull 30 random candidates from the right complementary category, and send those to Gemma 4 again to pick the best pairing. Finally, Gemini 2.5 Flash generates the editorial look image.&lt;/p&gt;

&lt;p&gt;Upload a photo&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%2Fndq5d85n26unzp36fnn4.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%2Fndq5d85n26unzp36fnn4.png" alt="Upload a photo" width="800" height="615"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The app finds a match&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%2F90mgkbzo8spmc64m5cfz.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%2F90mgkbzo8spmc64m5cfz.png" alt="The app finds a match" width="800" height="768"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Generate an editorial image of both items on a model&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%2Fnt99d4kd34u8s0dfxxur.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%2Fnt99d4kd34u8s0dfxxur.png" alt="Generate an editorial image of both items on a model" width="683" height="830"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/fzoA7PLkRK4"&gt;
  &lt;/iframe&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://pair-vite.vercel.app/" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;pair-vite.vercel.app&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sea2709" rel="noopener noreferrer"&gt;
        sea2709
      &lt;/a&gt; / &lt;a href="https://github.com/sea2709/pair" rel="noopener noreferrer"&gt;
        pair
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Pair.&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A clothing pairing app — upload a photo of one piece you own, get a complementary match from a curated catalogue, then see both styled together in an AI-generated editorial image.&lt;/p&gt;
&lt;p&gt;The product catalogue is the Myntra fashion dataset (~44k products), available at &lt;a href="https://www.kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset" rel="nofollow noopener noreferrer"&gt;kaggle.com/datasets/paramaggarwal/fashion-product-images-dataset&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Upload&lt;/strong&gt; a photo of a top, bottom, shoes, or accessory — optionally add a hint if the photo contains multiple pieces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analyze&lt;/strong&gt; — Gemma 4 identifies the piece: category, gender, style, palette&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm&lt;/strong&gt; — review the AI's interpretation; re-analyse with a corrected hint if needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Match&lt;/strong&gt; — a complementary item is randomly sampled from the catalogue, then Gemma 4 picks the best fit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lookbook&lt;/strong&gt; — Gemini generates a fashion editorial photo of both pieces styled on a model&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Stack&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tech&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vite + React + TypeScript + Tailwind CSS v4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Hono on Node.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Google GenAI SDK (Gemma 4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sea2709/pair" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Used Gemma 4
&lt;/h2&gt;

&lt;p&gt;Gemma 4 (gemma-4-31b-it) is used for two tasks where we need text output from a structured prompt:&lt;/p&gt;

&lt;p&gt;Clothing analysis — given an image, return a JSON object with category, gender, style, colors, etc.&lt;br&gt;
Match selection — given 30 product candidates from MongoDB, pick the best one and return a JSON object with the index, match score, and stylist note.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>Notion Bookmarks Manager</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Sun, 29 Mar 2026 14:53:58 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/notion-bookmark-manager-2gka</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/notion-bookmark-manager-2gka</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;The web content I browse every day is part of my personal knowledge base — but finding something I read weeks ago is frustratingly hard. I built this Chrome extension to solve that: it saves any page I bookmark directly to Notion, uses AI to generate a summary of the page content, and lets me search across everything I've saved using natural language.&lt;/p&gt;

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

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/GkO73fwNz_E"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Show us the code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sea2709" rel="noopener noreferrer"&gt;
        sea2709
      &lt;/a&gt; / &lt;a href="https://github.com/sea2709/notion-bookmark-manager" rel="noopener noreferrer"&gt;
        notion-bookmark-manager
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Notion Bookmark Manager&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A Chrome extension that saves browser tabs to your Notion workspace, with folder organization, notes, AI-generated summaries, and AI-powered search.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Save bookmarks&lt;/strong&gt; — Save the current tab to a Notion database with a title, URL, and optional notes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folder tree&lt;/strong&gt; — Organize bookmarks into nested folders synced from Notion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI summaries&lt;/strong&gt; — Optionally generate a page summary using Gemini AI based on a custom prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse bookmarks&lt;/strong&gt; — View all your bookmarks grouped by folder in a collapsible tree&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt; — Search your Notion bookmarks using natural language via Gemini AI and the Notion MCP&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Architecture&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;Chrome Extension (Manifest V3)
├── popup/          UI for saving, browsing, and searching bookmarks
├── background/     Service worker — routes messages between popup and server
├── shared/         Shared types, constants, and chrome.storage helpers
└── dist/           Built output (load this directory in Chrome)
Local Server (Express)
└── server/         Handles all Notion API&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sea2709/notion-bookmark-manager" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Used Notion MCP
&lt;/h2&gt;

&lt;p&gt;MCP (Model Context Protocol) is used only in the searchBookmark function in server/notion-api.ts. It is not used anywhere else — all other Notion operations (create bookmark, fetch folders, etc.) go through the @notionhq/client SDK directly.&lt;/p&gt;

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

&lt;p&gt;User presses Enter in search&lt;br&gt;
    → popup sends SEARCH_BOOKMARKS message&lt;br&gt;
    → service worker calls POST /call { tool: "search_bookmarks" }&lt;br&gt;
    → server calls searchBookmark()&lt;br&gt;
    → searchBookmark() connects to Notion MCP via npx mcp-remote&lt;br&gt;
    → Gemini AI uses the MCP tools to query Notion&lt;br&gt;
    → AI response text returned to popup&lt;/p&gt;

&lt;p&gt;The three components involved (MCP Client, mcpToTool adapter, Gemini)&lt;/p&gt;

&lt;p&gt;1.MCP Client (@modelcontextprotocol/sdk)&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;const&lt;/span&gt; &lt;span class="nx"&gt;notionClient&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;McpClient&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;notion-client&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="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;StdioClientTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;npx&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&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;-y&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;mcp-remote&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;https://mcp.notion.com/mcp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;NOTION_TOKEN&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;NOTION_API_KEY&lt;/span&gt; &lt;span class="p"&gt;},&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;notionClient&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP client spawns npx mcp-remote as a child process (stdio transport), which acts as a proxy connecting to Notion's official MCP server at &lt;a href="https://mcp.notion.com/mcp" rel="noopener noreferrer"&gt;https://mcp.notion.com/mcp&lt;/a&gt;. This exposes Notion's capabilities (search pages, read content, etc.) as MCP tools.&lt;/p&gt;

&lt;p&gt;2.mcpToTool adapter (@google/genai)&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;config&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;mcpToTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notionClient&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;mcpToTool wraps the MCP client so that Gemini can discover and call Notion's MCP tools automatically — Gemini decides which Notion tools to invoke based on the prompt.&lt;/p&gt;

&lt;p&gt;3.Gemini as the orchestrator&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;const&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Search for pages under the database with the ID &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;databaseId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; mentioning '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;keyword&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;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;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&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="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;GEMINI_MODEL&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;config&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="nf"&gt;mcpToTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;notionClient&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;p&gt;Gemini receives the natural language prompt and autonomously calls Notion MCP tools to find relevant pages, then summarizes the results into a text response.&lt;/p&gt;

&lt;p&gt;Why MCP for search vs. the SDK for everything else?&lt;br&gt;
The Notion SDK's search() API only matches page titles — it cannot search page body content. Notion's MCP server exposes richer capabilities including content-level search. By routing the query through Gemini + MCP, the search can find bookmarks by their AI-generated summary text, not just the title.&lt;/p&gt;

</description>
      <category>notionchallenge</category>
    </item>
    <item>
      <title>Apparel Shopping - Chatbot</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Mon, 09 Feb 2026 04:08:41 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-chatbot-4j2d</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-chatbot-4j2d</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia"&gt;Algolia Agent Studio Challenge&lt;/a&gt;: Consumer-Facing Conversational Experiences&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;A apparel shopping site with 2 pages (homepage and product details page) and a chatbot assistanting customers looking for products via conversation.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://apparel-web.vercel.app/" rel="noopener noreferrer"&gt;https://apparel-web.vercel.app/&lt;/a&gt;&lt;br&gt;
Source code: &lt;a href="https://bitbucket.org/hdang2709/apparel/src/main/" rel="noopener noreferrer"&gt;https://bitbucket.org/hdang2709/apparel/src/main/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;p&gt;I set up an application in Alogolia, create a new index and use the apparel sample dataset which has 2000 items.&lt;/p&gt;

&lt;p&gt;I configure searchable attributes and related facets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;product_type&lt;/li&gt;
&lt;li&gt;color&lt;/li&gt;
&lt;li&gt;categories&lt;/li&gt;
&lt;li&gt;price&lt;/li&gt;
&lt;li&gt;tags&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%2Fgrvg3vy0ghh6v91hblt6.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%2Fgrvg3vy0ghh6v91hblt6.png" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leverage InstantSearch.js widget to build the UI including a chat widget.&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%2Fk4tj8437hxl9au881wfb.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%2Fk4tj8437hxl9au881wfb.png" alt=" " width="698" height="713"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;The built-in chat widget in InstantSearch.js is very convenient. From the basic coding perspective, all you need are an agent ID and a container element to render to widget to build a chat interface that interacts with a generative AI assistant built with Algolia Agent Studio. And you can focus on constructing constructions and tools for the AI Agent.&lt;br&gt;
Algolia Studio also provides all conversations lists on the site with insights about how the response conducted (Reasoning and Tool used), which is very helpful to configure the Tools and setting up search attributes.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>ai</category>
      <category>agents</category>
    </item>
    <item>
      <title>Apparel Shopping</title>
      <dc:creator>Dang Tran</dc:creator>
      <pubDate>Mon, 09 Feb 2026 03:09:10 +0000</pubDate>
      <link>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-4m43</link>
      <guid>https://dev.to/dang_tran_63f9ff8ece59c73/apparel-shopping-4m43</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia"&gt;Algolia Agent Studio Challenge&lt;/a&gt;: Consumer-Facing Non-Conversational Experiences&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;A apparel shopping site with 2 pages (homepage and product details page) and a chatbot assistanting customers looking for products via conversation.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://apparel-web.vercel.app/" rel="noopener noreferrer"&gt;https://apparel-web.vercel.app/&lt;/a&gt;&lt;br&gt;
Source code: &lt;a href="https://bitbucket.org/hdang2709/apparel/src/main/" rel="noopener noreferrer"&gt;https://bitbucket.org/hdang2709/apparel/src/main/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;p&gt;I set up an application in Alogolia, create a new index and use the apparel sample dataset which has 2000 items.&lt;/p&gt;

&lt;p&gt;I configure searchable attributes and related facets.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;product_type&lt;/li&gt;
&lt;li&gt;color&lt;/li&gt;
&lt;li&gt;categories&lt;/li&gt;
&lt;li&gt;price&lt;/li&gt;
&lt;li&gt;tags&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%2Fgrvg3vy0ghh6v91hblt6.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%2Fgrvg3vy0ghh6v91hblt6.png" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leverage InstantSearch.js widget to build the UI for list products, refinement, search box, auto complete, chat, etc.&lt;/p&gt;

&lt;p&gt;With a traditional shopping site, customers use existing filter widgets to find their products. I added a tweak to let customers using a prompt to filter products by leveraging Generative AI in Algolia Agent Studio. I set up 2 agents, one for the chat and one for the filter functionality. The 2 agents are pretty similar, but the filter agent will not response with follow up questions to clarify some details.&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%2Fw7hllrnidkhxrkdja4k4.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%2Fw7hllrnidkhxrkdja4k4.png" alt=" " width="593" height="456"&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%2F4bsin1inuui8qagoc86r.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%2F4bsin1inuui8qagoc86r.png" alt=" " width="800" height="574"&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%2F3acpn5ks60mne73ccxxe.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%2F3acpn5ks60mne73ccxxe.png" alt=" " width="800" height="216"&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%2Fif0y5ccpg521aj4vrs45.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%2Fif0y5ccpg521aj4vrs45.png" alt=" " width="800" height="748"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;Algolia agent can form a query based on the user's prompt or conversation. The query is flexible depending on the indexed data, configurable search attributes.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>ai</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
