<?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: Ekim Cem Ülger</title>
    <description>The latest articles on DEV Community by Ekim Cem Ülger (@ekimcem).</description>
    <link>https://dev.to/ekimcem</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%2F481886%2Fff64fa9b-dd77-4a9e-ba50-896385203e19.png</url>
      <title>DEV Community: Ekim Cem Ülger</title>
      <link>https://dev.to/ekimcem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ekimcem"/>
    <language>en</language>
    <item>
      <title>Anyone tried it ?</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Thu, 16 Oct 2025 08:26:55 +0000</pubDate>
      <link>https://dev.to/ekimcem/anyone-tried-it--16jk</link>
      <guid>https://dev.to/ekimcem/anyone-tried-it--16jk</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21" class="crayons-story__hidden-navigation-link"&gt;Building a ChatGPT App with VoltAgent and the Apps SDK&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/ekimcem" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F481886%2Fff64fa9b-dd77-4a9e-ba50-896385203e19.png" alt="ekimcem profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ekimcem" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ekim Cem Ülger
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ekim Cem Ülger
                
              
              &lt;div id="story-author-preview-content-2928383" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/ekimcem" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F481886%2Fff64fa9b-dd77-4a9e-ba50-896385203e19.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ekim Cem Ülger&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 15 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21" id="article-link-2928383"&gt;
          Building a ChatGPT App with VoltAgent and the Apps SDK
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agents"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agents&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/chatgpt"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;chatgpt&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/voltagent"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;voltagent&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;17&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>agents</category>
      <category>mcp</category>
      <category>chatgpt</category>
      <category>voltagent</category>
    </item>
    <item>
      <title>Building a ChatGPT App with VoltAgent and the Apps SDK</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Wed, 15 Oct 2025 22:39:20 +0000</pubDate>
      <link>https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21</link>
      <guid>https://dev.to/ekimcem/building-a-chatgpt-app-with-voltagent-and-the-apps-sdk-4j21</guid>
      <description>&lt;p&gt;This guide shows how to use &lt;strong&gt;&lt;a href="https://voltagent.dev/" rel="noopener noreferrer"&gt;VoltAgent&lt;/a&gt;&lt;/strong&gt; — a TypeScript framework for creating &lt;strong&gt;agents&lt;/strong&gt;, &lt;strong&gt;MCP servers&lt;/strong&gt;, and &lt;strong&gt;workflows&lt;/strong&gt; — to deploy an MCP (Model Context Protocol) server and connect it to &lt;strong&gt;ChatGPT Apps&lt;/strong&gt; using the &lt;strong&gt;Apps SDK&lt;/strong&gt;. It demonstrates how to go from setup to a working ChatGPT-connected app step by step.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are ChatGPT Apps?
&lt;/h2&gt;

&lt;p&gt;OpenAI recently introduced &lt;strong&gt;&lt;a href="https://developers.openai.com/apps-sdk/" rel="noopener noreferrer"&gt;ChatGPT Apps&lt;/a&gt;&lt;/strong&gt; — a new framework that allows developers to build and publish their own tools and services directly inside ChatGPT. Using the &lt;strong&gt;Apps SDK&lt;/strong&gt;, you can connect APIs, workflows, and MCP servers to ChatGPT, turning them into interactive applications that users can access directly from the chat interface.&lt;/p&gt;

&lt;p&gt;ChatGPT Apps are the next evolution of the MCP (Model Context Protocol) ecosystem. They allow developers to define capabilities through tools, resources, and prompts, and make them discoverable within ChatGPT itself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 This is &lt;strong&gt;my personal perspective&lt;/strong&gt;: In the future, OpenAI is expected to expand this system into a &lt;strong&gt;marketplace&lt;/strong&gt; — a kind of “App Store for ChatGPT” — where developers can publish and share their MCP-powered apps with millions of users.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This tutorial focuses on building and deploying one of these ChatGPT Apps using &lt;strong&gt;VoltAgent&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Create the App
&lt;/h2&gt;

&lt;p&gt;Start by creating a new VoltAgent app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm create voltagent-app my-agent-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When prompted, &lt;strong&gt;select your provider&lt;/strong&gt; — for now, choose &lt;strong&gt;OpenAI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then install the MCP server package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add @voltagent/mcp-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Basic MCP Server Setup
&lt;/h2&gt;

&lt;p&gt;In your &lt;code&gt;mcp/server.ts&lt;/code&gt; file, import and initialize the MCP server:&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;MCPServer&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;@voltagent/mcp-server&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;const&lt;/span&gt; &lt;span class="nx"&gt;mcpServer&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;MCPServer&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;voltagent-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;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;0.1.0&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;VoltAgent MCP example&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;You can keep the configuration simple for now — we’ll update it later.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Integrate with VoltAgent
&lt;/h2&gt;

&lt;p&gt;When VoltAgent initializes, it automatically sets up your agent, workflows, and server. To include the MCP server, simply add it to the configuration.&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dotenv/config&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;VoltAgent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VoltOpsClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Memory&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;@voltagent/core&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;LibSQLMemoryAdapter&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;@voltagent/libsql&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;createPinoLogger&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;@voltagent/logger&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;openai&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;@ai-sdk/openai&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;honoServer&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;@voltagent/server-hono&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;expenseApprovalWorkflow&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;./workflows&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;weatherTool&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;./tools&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;mcpServer&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;./mcp/server&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create a logger instance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPinoLogger&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;my-voltagent-app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&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="c1"&gt;// Configure persistent memory (LibSQL / SQLite)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memory&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;Memory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LibSQLMemoryAdapter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file:./.voltagent/memory.db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;child&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;libsql&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;agent&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;Agent&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;my-voltagent-app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A helpful assistant that can check weather and help with various tasks&lt;/span&gt;&lt;span class="dl"&gt;"&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="nf"&gt;openai&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;weatherTool&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VoltAgent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expenseApprovalWorkflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;mcpServers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;mcpServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;honoServer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;voltOpsClient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VoltOpsClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;publicKey&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;VOLTAGENT_PUBLIC_KEY&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="na"&gt;secretKey&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;VOLTAGENT_SECRET_KEY&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="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;This is the automatically generated initialization code, with the addition of the &lt;code&gt;mcpServers&lt;/code&gt; key.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Create a Mock MCP Tool
&lt;/h2&gt;

&lt;p&gt;Let’s create a &lt;strong&gt;mock weather tool&lt;/strong&gt; to test the MCP connection.&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;createTool&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;@voltagent/core&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;MCPServer&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;@voltagent/mcp-server&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;z&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;zod&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;const&lt;/span&gt; &lt;span class="nx"&gt;getWeatherTool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createTool&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_weather&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;Return mock weather data for a given location&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Location to fetch weather for&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;execute&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="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;location&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;success&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;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;☀️ Sunny, 24°C (mock data)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mcpServer&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;MCPServer&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;voltagent-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;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;voltagent-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;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;0.1.0&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;VoltAgent MCP example with a mock Get Weather tool&lt;/span&gt;&lt;span class="dl"&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="na"&gt;getWeather&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;getWeatherTool&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;Then start the development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If successful, your terminal should display:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;══════════════════════════════════════════════════
  VOLTAGENT SERVER STARTED SUCCESSFULLY
══════════════════════════════════════════════════
  ✓ HTTP Server:  http://localhost:3141
  ✓ Swagger UI:   http://localhost:3141/ui

  ✓ Registered Endpoints: 10 total

    MCP Endpoints
      GET    /mcp/servers
      GET    /mcp/servers/{serverId}
      GET    /mcp/servers/{serverId}/tools
      GET    /mcp/servers/{serverId}/prompts
      GET    /mcp/servers/{serverId}/prompts/{promptName}
      GET    /mcp/servers/{serverId}/resources
      GET    /mcp/servers/{serverId}/resources/contents
      GET    /mcp/servers/{serverId}/resource-templates
      POST   /mcp/servers/{serverId}/tools/{toolName}
      POST   /mcp/servers/{serverId}/logging/level

  Test your agents with VoltOps Console: https://console.voltagent.dev
══════════════════════════════════════════════════
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Testing Locally with VoltOps Console
&lt;/h2&gt;

&lt;p&gt;Visit &lt;strong&gt;&lt;a href="https://console.voltagent.dev/mcp" rel="noopener noreferrer"&gt;https://console.voltagent.dev/mcp&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Enter your local HTTP server URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:3141
&lt;/code&gt;&lt;/pre&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%2Fv4cyotz13wb7whm594y8.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%2Fv4cyotz13wb7whm594y8.png" alt="URL Input field on VoltOps Console" width="464" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see your &lt;strong&gt;get-weather&lt;/strong&gt; tool listed. Try clicking it and typing a random location — you’ll get a mock weather response.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Don’t forget to adjust the MCP server description to match your tool’s purpose (e.g., mention weather forecasting).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Exposing a Public Endpoint
&lt;/h2&gt;

&lt;p&gt;ChatGPT requires an HTTPS endpoint. During development, you can use &lt;strong&gt;ngrok&lt;/strong&gt; to expose your local server.&lt;/p&gt;

&lt;p&gt;Install ngrok (see &lt;a href="https://ngrok.com" rel="noopener noreferrer"&gt;ngrok.com&lt;/a&gt;) and then, in a separate terminal window, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ngrok http 3141
&lt;span class="c"&gt;# Forwarding: https://&amp;lt;subdomain&amp;gt;.ngrok.app -&amp;gt; http://127.0.0.1:3141&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your VoltAgent Hono service runs on port &lt;strong&gt;3141&lt;/strong&gt; by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Connect Your MCP Server to ChatGPT
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open ChatGPT Settings&lt;/strong&gt; → Click your &lt;strong&gt;avatar (bottom-left)&lt;/strong&gt; → &lt;strong&gt;Settings → Go to Apps&lt;/strong&gt;.&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.amazonaws.com%2Fuploads%2Farticles%2Fdz7mh0ktqa631ebl6ps1.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%2Fdz7mh0ktqa631ebl6ps1.png" alt="ChatGPT UI" width="719" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Enable Developer Mode&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Request access from your OpenAI partner contact or workspace admin.&lt;/li&gt;
&lt;li&gt;Then toggle: &lt;code&gt;Settings → Connectors → Advanced → Developer Mode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Once enabled, you’ll see a &lt;strong&gt;Create&lt;/strong&gt; button under &lt;strong&gt;Settings → Connectors&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a Connector&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Ensure your MCP server is reachable over HTTPS (via ngrok).&lt;/li&gt;
&lt;li&gt;In ChatGPT: go to &lt;strong&gt;Settings → Connectors → Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fill in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Connector Name:&lt;/strong&gt; VoltAgent Example Server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description:&lt;/strong&gt; Provides example tools via VoltAgent MCP server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connector URL:&lt;/strong&gt; &lt;code&gt;https://&amp;lt;subdomain&amp;gt;.ngrok.app/mcp/voltagent-example/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;&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%2F0ix1f2u15dmn4tnkbj03.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%2F0ix1f2u15dmn4tnkbj03.png" alt=" " width="452" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Disable Authentication (for testing)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Disable auth during local testing; re-enable for production.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Verify the Integration&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;If successful, you’ll see your &lt;strong&gt;get-weather&lt;/strong&gt; tool listed in ChatGPT.&lt;/li&gt;
&lt;li&gt;You can now call your MCP tool directly from within ChatGPT — your VoltAgent app is live!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&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%2Fg9gjhunz8381my0y7drm.png" alt=" " width="800" height="565"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;Now that OpenAI is opening the door to custom &lt;strong&gt;ChatGPT Apps&lt;/strong&gt; built with the &lt;strong&gt;Apps SDK&lt;/strong&gt;, we’re at the start of a new developer ecosystem around MCP. Using VoltAgent makes it easier to structure these apps with agents, workflows, and tools.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;What do you think?&lt;/strong&gt; Which types of apps do you believe will perform best in a future ChatGPT marketplace — productivity tools, automations, educational helpers, or something else? And what are your own plans for building and sharing MCP-based apps?&lt;/p&gt;

&lt;p&gt;If you run into any issues while following this guide or during development, feel free to share your questions or problems here — happy to help troubleshoot and improve together! 🚀&lt;/p&gt;

</description>
      <category>agents</category>
      <category>mcp</category>
      <category>chatgpt</category>
      <category>voltagent</category>
    </item>
    <item>
      <title>Bring your Next.JS API Experience</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Mon, 01 May 2023 09:10:48 +0000</pubDate>
      <link>https://dev.to/ekimcem/bring-your-nextjs-api-experience-ppj</link>
      <guid>https://dev.to/ekimcem/bring-your-nextjs-api-experience-ppj</guid>
      <description>&lt;p&gt;Hello fellow developers,&lt;/p&gt;

&lt;p&gt;I've been noticing a lot of discussion around Next.js APIs lately. It seems that serverless functions can become expensive as user traffic grows, especially when compared to other providers besides Vercel. I'm curious to hear your thoughts on when and why you prefer to use Next.js APIs. Let's have a discussion about it in the comments below.&lt;/p&gt;

&lt;p&gt;By the way, if you're interested in learning about some of the challenges that Josh faced while using Next.js APIs, you may find this video helpful: &lt;a href="https://www.youtube.com/watch?v=6xvLUWpCSFM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=6xvLUWpCSFM&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>express</category>
      <category>discuss</category>
      <category>api</category>
    </item>
    <item>
      <title>NextAuth.js / Auth.js credential authentication with methods you need !</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Wed, 18 Jan 2023 20:49:24 +0000</pubDate>
      <link>https://dev.to/ekimcem/nextauthjs-authjs-credential-authentication-with-methods-you-need--21al</link>
      <guid>https://dev.to/ekimcem/nextauthjs-authjs-credential-authentication-with-methods-you-need--21al</guid>
      <description>&lt;p&gt;Hey Devs !&lt;/p&gt;

&lt;p&gt;As a front-end developer my nightmare was to handle the user authentication.&lt;/p&gt;

&lt;p&gt;With NextAuth.js (I will call it auth.js since they are changing their name) the user authentication handling is much easier. Let's take a look at how we handle it with Next.js&lt;/p&gt;

&lt;p&gt;Here are the steps that you need to follow;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a next app.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn create next-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go inside your project and add auth.js&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;yarn add next-auth&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To implement the auth.js, we need to create an api folder in our pages directory and create the [...nextauth].js&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;/pages
        /api
          /auth
            [...nextauth].js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;In your &lt;code&gt;pages/api/auth/[...nextauth].js&lt;/code&gt; create the default function and credential provider.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since you can configure your NextAuth, we will create an authOptions object to store the configurations that we want aplly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";

export const authOptions = {}

export default NextAuth(authOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Now let's start to adding options&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since we are using custom backend, we are going to use CredentialsProvider and we will pass this to providers key. This key stores all of providers that you want to use in your application with their configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;providers: [
    CredentialsProvider({
      type: "credentials",

 credentials: {
        email: {
          label: "Email",
          type: "email",
        },
        password: { label: "Password", type: "password" },
      },
  ],


...rest 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to use your own Sign In page, you do not need to pass email and password keys to credentials object. Anyway, we are going to use Auth.js's sign in page in this.&lt;/p&gt;

&lt;p&gt;In this case we need the email address and password of user to authenticate so we pass email and password fields.&lt;/p&gt;

&lt;p&gt;Now we all set in &lt;code&gt;[...nextAuth].js&lt;/code&gt; file with its credentials object.&lt;/p&gt;

&lt;p&gt;to fetch login data to your custom backend now we need to pass &lt;code&gt;authorize&lt;/code&gt; function with your custom sign in api;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; async authorize(credentials) {
        const credentialDetails = {
          email: credentials.email,
          password: credentials.password,
        };

        const resp = await fetch(backendURL + "/auth/login", {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
          },
          body: JSON.stringify(credentialDetails),
        });
        const user = await resp.json();
        if (user.is_success) {
          return user;
        } else {
          console.log("check your credentials");
          return null;
        }
      },


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, &lt;code&gt;backendURL&lt;/code&gt; is a constant of your server's ip and host, and the &lt;code&gt;auth/login&lt;/code&gt; is the endpoint of your backend.&lt;/p&gt;

&lt;p&gt;If your credentials are correct, the backend should response you a success message and you need to check it if its success or not.&lt;/p&gt;

&lt;p&gt;For now the &lt;code&gt;[...nextAuth].js&lt;/code&gt; is something 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;import NextAuth from "next-auth/next";
import CredentialsProvider from "next-auth/providers/credentials";

const backendURL = process.env.NEXT_PUBLIC_BACKEND_URL;
export const authOptions = {
  providers: [
    CredentialsProvider({
      type: "credentials",
      credentials: {
        email: {
          label: "Email",
          type: "email",
        },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        const credentialDetails = {
          email: credentials.email,
          password: credentials.password,
        };

        const resp = await fetch(backendURL + "/auth/login", {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
          },
          body: JSON.stringify(credentialDetails),
        });
        const user = await resp.json();
        if (user.is_success) {
          console.log("nextauth daki user: " + user.is_success);

          return user;
        } else {
          console.log("check your credentials");
          return null;
        }
      },
    }),
  ],
};

export default NextAuth(authOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;since we are using JWT , you need to pass session object with strategy key as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can pass a maxAge to store your user in the web browser as authenticated as you want, here it stores for 30 days.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do not forget that JWT maxAge can be also defined in the backend so you should consider the backend JWT maxAge when &lt;br&gt;
setting this value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Implementing the callbacks to use session in client-side&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you can fetch user in backend and your response should have some information that will be used in the client side while fetching some APIs.&lt;/p&gt;

&lt;p&gt;With the help of callbacks, we will persist the backend access token to token provided by auth.js right after signin.&lt;/p&gt;

&lt;p&gt;For this, we need to pass callbacks object to &lt;code&gt;[...nextauth].js&lt;/code&gt; file as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;callbacks: {
    jwt: async ({ token, user }) =&amp;gt; {
      if (user) {
        token.email = user.data.auth.email;
        token.username = user.data.auth.userName;
        token.userType = user.data.auth.userType;
        token.accessToken = user.data.auth.token;
      }

      return token;
    },
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, from the response provided by backend, user object has various values like email,userName,userType and token.&lt;/p&gt;

&lt;p&gt;In jwt object we are calling the async function that stores our response in token.&lt;/p&gt;

&lt;p&gt;After that, from frontend, we need to add the token to cookies in user session, 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;callbacks: {
    jwt: async ({ token, user }) =&amp;gt; {
      if (user) {
        token.email = user.data.auth.email;
        token.username = user.data.auth.userName;
        token.user_type = user.data.auth.userType;
        token.accessToken = user.data.auth.token;
      }

      return token;
    },
    session: ({ session, token, user }) =&amp;gt; {
      if (token) {
        session.user.email = token.email;
        session.user.username = token.userName;
        session.user.accessToken = token.accessToken;
      }
      return session;
    },
  },

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with the help of session callback, now we can use the useSession hook provided by auth.js in the client-side to get information that we pass to session object.&lt;/p&gt;

&lt;p&gt;Before going into the client side, lets check your &lt;code&gt;[...nextAuth].js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import NextAuth from "next-auth/next";
import CredentialsProvider from "next-auth/providers/credentials";

const backendURL = process.env.NEXT_PUBLIC_BACKEND_URL;
export const authOptions = {
session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  providers: [
    CredentialsProvider({
      type: "credentials",
      credentials: {
        email: {
          label: "Email",
          type: "email",
        },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        const credentialDetails = {
          email: credentials.email,
          password: credentials.password,
        };

        const resp = await fetch(backendURL + "/auth/login", {
          method: "POST",
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
          },
          body: JSON.stringify(credentialDetails),
        });
        const user = await resp.json();
        if (user.is_success) {
          console.log("nextauth daki user: " + user.is_success);

          return user;
        } else {
          console.log("check your credentials");
          return null;
        }
      },
    }),
  ],
callbacks: {
    jwt: async ({ token, user }) =&amp;gt; {
      if (user) {
        token.email = user.data.auth.email;
        token.username = user.data.auth.userName;
        token.user_type = user.data.auth.userType;
        token.accessToken = user.data.auth.token;
      }

      return token;
    },
    session: ({ session, token, user }) =&amp;gt; {
      if (token) {
        session.user.email = token.email;
        session.user.username = token.userName;
        session.user.accessToken = token.accessToken;
      }
      return session;
    },
  },
};

export default NextAuth(authOptions);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Use the session in client side !&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lets start wrapping our application with SessionProvider;&lt;/p&gt;

&lt;p&gt;Move to your &lt;strong&gt;_app.js&lt;/strong&gt; file in the route;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/pages
       _app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and import SessionProvider from next-auth&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SessionProvider } from "next-auth/react";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As well as you import the session provider, do not forget to pass session in to the page props and wrap your application with SessionProvider like this in your &lt;code&gt;_app.js&lt;/code&gt; file;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { SessionProvider } from "next-auth/react";

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
  return (
    &amp;lt;SessionProvider session={session}&amp;gt;
          &amp;lt;Component {...pageProps} /&amp;gt;
    &amp;lt;/SessionProvider&amp;gt;
  );
}

export default MyApp;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that everything is simple, just import &lt;code&gt;useSession()&lt;/code&gt;hook from next-auth and handle any session information that you passed in the session callback function in &lt;code&gt;[...nextauth].js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import { useSession} from "next-auth/react";
const { data, status } = useSession();

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can use any data that you passed in session callback function by using &lt;code&gt;data&lt;/code&gt; object from useSession().&lt;/p&gt;

&lt;p&gt;In this example we can access the user access token which we got from server as : &lt;code&gt;session.user.accessToken&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Also, you can check if the user is authenticated in the serverside, so you may want to protect your pages.&lt;/p&gt;

&lt;p&gt;In your component, you may use session in getServerSideProps function as:&lt;/p&gt;

&lt;p&gt;import getSession to use session in serverside from : &lt;/p&gt;

&lt;p&gt;&lt;code&gt;import {getSession } from "next-auth/react";&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getServerSideProps(context) {

  const session = await getSession(context);
  if (!session) {
    //if not exists, return a temporary 302 and replace the url with the given in Location.
    context.res.writeHead(302, { Location: "/signin" });
    context.res.end();

    //do not return any session.
    return { props: {} };
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this is a simple use of credentials provider from Auth.js&lt;/p&gt;

&lt;p&gt;Do let me know if you have any suggestions or questions in the commends !&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>authentication</category>
      <category>nextauth</category>
      <category>authjs</category>
    </item>
    <item>
      <title>When do you use which one?</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Sat, 17 Sep 2022 03:16:50 +0000</pubDate>
      <link>https://dev.to/ekimcem/when-do-you-use-which-one-5c2h</link>
      <guid>https://dev.to/ekimcem/when-do-you-use-which-one-5c2h</guid>
      <description>&lt;p&gt;Hey Front-end web developers, I have a question for you !&lt;/p&gt;

&lt;p&gt;Nowadays there are multiple choices between CSS frameworks and Component libraries.&lt;/p&gt;

&lt;p&gt;The question is simple, how you decide which technologies you are selecting. ( Bootstrap, TailwindCSS, MaterialUI, ChakraUI, Storybook etc...)&lt;/p&gt;

&lt;p&gt;Let's discuss it on comments. The points you should mention:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Size of project&lt;/li&gt;
&lt;li&gt;Technology requirements for project&lt;/li&gt;
&lt;li&gt;Time-efficiency curve&lt;/li&gt;
&lt;li&gt;Knowledge&lt;/li&gt;
&lt;li&gt;Your rating&lt;/li&gt;
&lt;li&gt;Number of people involved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Maybe we can generate a equation to select the most-suitable technology for our future projects&lt;/p&gt;

</description>
      <category>css</category>
      <category>discuss</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Desktop first vs Mobile First Design - How to decide ?</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Mon, 23 May 2022 19:21:40 +0000</pubDate>
      <link>https://dev.to/ekimcem/desktop-first-vs-mobile-first-design-how-to-decide--1eld</link>
      <guid>https://dev.to/ekimcem/desktop-first-vs-mobile-first-design-how-to-decide--1eld</guid>
      <description>&lt;p&gt;Since I do not want a fight over this question, I wanted to state from the beginning, I think we all agree that it should be decided according to different product requirements.(?)&lt;/p&gt;

&lt;p&gt;However, in such discussions, we need to consider those who use the product rather than the developers. I always take a look at the data outputs while making such decisions.&lt;/p&gt;

&lt;p&gt;Regarding to    &lt;a href="https://www.perficient.com/insights/research-hub/mobile-vs-desktop-usage#:~:text=Mobile%20devices%20drove%2061%25%20of,increase%20from%2063.3%25%20in%202019" rel="noopener noreferrer"&gt;perficient.com&lt;/a&gt;, at 2020, based on 30.02 trillion visits, 68% of users were browsing from their mobile phones but less than half the average time they spend per visit, according to desktop users.&lt;/p&gt;

&lt;p&gt;This may because of several reasons, one is most of desktop users are more likely to spend time on their computers of course. On the other hand, we should also consider that most of websites are not REALLY optimized for mobile users so, this may cause users not to prefer to browse the site anymore.&lt;/p&gt;

&lt;p&gt;It is always necessary to speed up and optimize any user experience;&lt;/p&gt;

&lt;p&gt;In 1979, Walter J. Doherty (IBM Researcher)  mentioned that &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;user experience turns from painful to addictive after the system feedback time drops below 400ms.”&lt;br&gt;
and they call it Doherty Threshold.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are not here to understand whether its true or not, the thing is response time has a large amount of importance while we use “computer”. &lt;/p&gt;

&lt;p&gt;My personal idea is to start with mobile design, and be &lt;strong&gt;minimalist.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I did not arrive at this conclusion solely for the reasons I have stated here. I always take note of the applications whose UI designs I like on websites, mobile applications and desktop applications. What they all have in common is that they are extremely simple and useful.&lt;/p&gt;

&lt;p&gt;First of all, we shouldn't consider the question of usability about which design we should base on because you can create a lousy user experience no matter which one you start with.&lt;/p&gt;

&lt;p&gt;But minimal animation also brings maximum response time, and if you start with mobile design, you inadvertently fit those requirements just a little bit more.&lt;/p&gt;

&lt;p&gt;In addition, you can present the contents that you fit on small screens (if you can) to the user in a more comfortable way as the screen expands.&lt;/p&gt;

&lt;p&gt;I'm not a UI designer, but I see a lot of designers give priority to mobile design these days.&lt;/p&gt;

&lt;p&gt;In fact, you can come across this while browsing websites where you can buy many templates, most of them put mobile application images at the beginning.&lt;/p&gt;

&lt;p&gt;It is of course debatable whether this decision is due to the fact that the demand is mostly in mobile designs or that the designers can express themselves better in mobile design.&lt;/p&gt;

&lt;p&gt;Which one you go first? &lt;/p&gt;

</description>
      <category>ux</category>
      <category>design</category>
      <category>discuss</category>
      <category>poll</category>
    </item>
    <item>
      <title>How to hide something on different screen sizes with Bootstrap?</title>
      <dc:creator>Ekim Cem Ülger</dc:creator>
      <pubDate>Tue, 02 Nov 2021 17:15:37 +0000</pubDate>
      <link>https://dev.to/ekimcem/how-to-hide-something-on-different-screen-sizes-with-bootstrap-3ha7</link>
      <guid>https://dev.to/ekimcem/how-to-hide-something-on-different-screen-sizes-with-bootstrap-3ha7</guid>
      <description>&lt;p&gt;Let's look at the display features with bootstrap, which is the most popular one of the frameworks when the subject is responsive web design.&lt;/p&gt;

&lt;p&gt;In order to understand the architecture of the display options of bootstrap, let’s check breakpoints.&lt;/p&gt;

&lt;p&gt;Breakpoints are the exact width pixel values that decide the screen size of the browser. &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%2Fleg8bbegx81tt37vax78.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%2Fleg8bbegx81tt37vax78.png" alt="Table of Breakpoints in Bootstrap" width="632" height="246"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Table 1: Dimensions regarding the screen size.&lt;/code&gt;&lt;br&gt;
&lt;a href="https://getbootstrap.com/docs/5.1/layout/breakpoints/" rel="noopener noreferrer"&gt;Bootstrap Source Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check the breakpoints in the table above. Those dimensions mean that if you are under 576px it means that your screen size is x-small, if your width pixel is higher than 576px it means that your screen size is small (until you reach 769 px), and it continues like this.&lt;/p&gt;

&lt;p&gt;Since Bootstrap developers used &lt;code&gt;min-width&lt;/code&gt; property of CSS while adding those breakpoints, if you only apply a display property to a small screen, it works on both small and larger screens rather than working only on small screens.&lt;br&gt;
&lt;a href="https://getbootstrap.com/docs/5.1/layout/breakpoints/#min-width" rel="noopener noreferrer"&gt;Bootstrap min-width&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means that; if you add &lt;code&gt;d-lg-flex&lt;/code&gt; to a class, flexbox property will be applied to lg, xl, and xxl screen sizes.&lt;/p&gt;

&lt;p&gt;In Bootstrap there is a display property called &lt;code&gt;none&lt;/code&gt;.&lt;br&gt;
If you add a class named &lt;code&gt;d-none&lt;/code&gt; to your element it will not show it.&lt;/p&gt;

&lt;p&gt;So if you want to hide something only on small devices, we need to assign two display classes to the HTML element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example, you want to use a flex display property on the container:&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;&amp;lt;div class= container d-flex&amp;gt; … &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;d-flex&lt;/code&gt; property will affect the all kind of screen sizes since it has no screen class infix (check Table-1). It means that you are applying that property to x-small and larger screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we want to hide something in x-small and small screens?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So now, we want to “hide” the container unless it is a medium or larger screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class= container d-none d-md-flex&amp;gt; … &amp;lt;div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, &lt;code&gt;d-md-flex&lt;/code&gt; property will override the d-none property after screen size reaches 769px ( which is breakpoint of medium screen)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we want to display something on small screens but not on large screens?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this situation, unless it is a medium screen, we want to show it as flex. If it is a medium or larger screen, we want it to be hidden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class= container d-flex d-md-none&amp;gt; … &amp;lt;div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, you may see that &lt;code&gt;d-flex&lt;/code&gt; property will be applied to whole screen types unless it reaches the medium screen. Since &lt;code&gt;d-md-none&lt;/code&gt;  affect medium or larger screens, you will be able to hide container for those screens.&lt;/p&gt;

&lt;p&gt;If you want to apply different display properties for every different screen sizes, it means that you need to add display properties individually with all breakpoint class infixes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.linkedin.com/in/ekimcem/" rel="noopener noreferrer"&gt;Ekim&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bootstrap</category>
      <category>webdev</category>
      <category>responsivedesign</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
