<?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: Siarhei</title>
    <description>The latest articles on DEV Community by Siarhei (@petrashka).</description>
    <link>https://dev.to/petrashka</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%2F1213686%2F77fc8fc0-b131-4cef-86d5-7c99c88f6785.jpg</url>
      <title>DEV Community: Siarhei</title>
      <link>https://dev.to/petrashka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/petrashka"/>
    <language>en</language>
    <item>
      <title>From Bolt.new to Production: How I built a React Native app using Copilot and MCP.</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Sun, 14 Dec 2025 12:11:07 +0000</pubDate>
      <link>https://dev.to/petrashka/from-boltnew-to-production-how-i-built-a-react-native-app-using-copilot-and-mcp-ebg</link>
      <guid>https://dev.to/petrashka/from-boltnew-to-production-how-i-built-a-react-native-app-using-copilot-and-mcp-ebg</guid>
      <description>&lt;p&gt;When my son was born, my life changed completely. Like any new parent, we needed a way to track sleep, feeding, and diapers. There are a million apps for this, but I wanted something &lt;em&gt;ours&lt;/em&gt;. Private, simple, and tailored exactly to what my wife and I needed.&lt;/p&gt;

&lt;p&gt;But more than that, I made a challenge to myself: &lt;strong&gt;Can I build a full-stack mobile app solo, using all these new AI tools?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I decided to "vibe code" it. No big team, no over-engineering—just me, AI, and a goal.&lt;/p&gt;

&lt;p&gt;Here is the story of how I built &lt;strong&gt;&lt;a href="https://zaspa.online" rel="noopener noreferrer"&gt;Zaspa&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Magic" Start
&lt;/h2&gt;

&lt;p&gt;I’m a developer, not a designer. Usually, this is where I get stuck. But this time, I leaned heavily on AI.&lt;/p&gt;

&lt;p&gt;I started with &lt;strong&gt;&lt;a href="https://bolt.new" rel="noopener noreferrer"&gt;Bolt.new&lt;/a&gt;&lt;/strong&gt; to generate the initial MVP. It was honestly mind-blowing. It didn't just give me code; it generated the entire design system and the initial screens. I had a working visual prototype almost instantly.&lt;/p&gt;

&lt;p&gt;For the splash screens and icons, I didn't hire anyone. I ran &lt;strong&gt;Flux&lt;/strong&gt; (an image generation model) locally on my machine and used &lt;strong&gt;ChatGPT&lt;/strong&gt; to refine the prompts. The result was professional-looking assets for $0.&lt;/p&gt;

&lt;p&gt;My wife and I sat down with a simple piece of paper. We listed exactly what features we needed. No Jira, no backlog—just a list on the kitchen table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack &amp;amp; The Workflow
&lt;/h2&gt;

&lt;p&gt;I went with a stack I could control fully (self-hosted):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Mobile:&lt;/strong&gt; React Native (Expo)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Backend:&lt;/strong&gt; Fastify + MongoDB&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Web (Landing + Admin):&lt;/strong&gt; React + Vite&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Repo:&lt;/strong&gt; GitHub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I started coding exclusively with &lt;strong&gt;Cursor&lt;/strong&gt;. It was great... until it wasn't. I burned through my fast tokens incredibly quickly. So, I switched to &lt;strong&gt;VS Code + GitHub Copilot&lt;/strong&gt;. And honestly? It surprised me.&lt;/p&gt;

&lt;p&gt;Copilot is powerful, but it can write messy code if you let it. I realized I needed to "manage" it like a junior dev.&lt;/p&gt;

&lt;p&gt;Context became king. I created a &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; file to describe the project structure and enforce rules like &lt;strong&gt;DRY&lt;/strong&gt; and &lt;strong&gt;SOLID&lt;/strong&gt; principles. I also added specific &lt;strong&gt;Frontend Instructions&lt;/strong&gt; to enforce component structure (e.g., "Always use SCSS modules for layout and &lt;code&gt;sx&lt;/code&gt; prop for dynamic styles").&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom "Chat Modes" (Prompts)
&lt;/h3&gt;

&lt;p&gt;Instead of typing the same requirements every time, I created reusable prompts that act as "modes" for the AI. I keep these stored in my MCP tool to call them instantly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Refactoring Mode:&lt;/strong&gt; &lt;em&gt;"Scan for duplication. Extract logic to custom hooks. Ensure design consistency. DO NOT change functionality."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Frontend Mode:&lt;/strong&gt; &lt;em&gt;"You are a Senior React Native Dev. Use functional components, strict TypeScript, and our specific folder structure."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Testing Mode:&lt;/strong&gt; &lt;em&gt;"Write unit tests for this component using Jest. Cover edge cases first."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(I wrote a &lt;a href="https://dev.to/petrashka/reliable-ai-workflow-with-github-copilot-complete-guide-with-examples-1bho"&gt;detailed guide on this workflow here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;This simple system saved me from the "spaghetti code" that AI often generates after a few hours of coding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it got real (The Roadblocks)
&lt;/h2&gt;

&lt;p&gt;It wasn't all smooth sailing. I hit two major walls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Firebase Nightmare&lt;/strong&gt;&lt;br&gt;
I wanted push notifications and analytics, so I reached for the standard: Firebase. Big mistake. Integrating Firebase with React Native was a dependency hell. Version conflicts everywhere. I spent days fighting build errors instead of coding.&lt;/p&gt;

&lt;p&gt;So I ditched it. I switched to &lt;strong&gt;Expo Push Services&lt;/strong&gt; which just works. For analytics, I wrote my own lightweight JS logic to send simple events (install, screen view) to my Fastify backend. I built a custom Admin Dashboard to show daily/weekly stats. Now I own my data, and the app is lighter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Localization Hell&lt;/strong&gt;&lt;br&gt;
My wife and I speak different languages. We understand each other, but for the app, multi-language support was non-negotiable.&lt;/p&gt;

&lt;p&gt;At first, I just hardcoded JSON files. But as I refactored the code (thanks to my "Refactoring Mode"), the localization files became a mess. Huge JSON files, hundreds of "orphan" keys for buttons I deleted weeks ago, and duplicates like &lt;code&gt;button.save&lt;/code&gt;, &lt;code&gt;common.save&lt;/code&gt;, &lt;code&gt;actions.save&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I was spending more time managing &lt;code&gt;en.json&lt;/code&gt; than playing with my son.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix (and how I accidentally built a startup)&lt;/strong&gt;&lt;br&gt;
I couldn't find a tool that worked &lt;em&gt;inside&lt;/em&gt; my IDE properly, so I built one. I created &lt;strong&gt;&lt;a href="https://goman.live" rel="noopener noreferrer"&gt;goman.live&lt;/a&gt;&lt;/strong&gt;, an MCP server that integrates directly with Cursor/Copilot.&lt;/p&gt;

&lt;p&gt;Instead of editing JSON, I just tell the AI: &lt;em&gt;"Add a translation for this button."&lt;/em&gt;&lt;br&gt;
The agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Checks if the key exists (deduplication).&lt;/li&gt;
&lt;li&gt; Adds translations for all languages automatically.&lt;/li&gt;
&lt;li&gt; Audits the files for unused keys.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It started as a script for Zaspa, but it worked so well I released it. It turned a headache into a background task.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch &amp;amp; Reality
&lt;/h2&gt;

&lt;p&gt;I didn't do a big Product Hunt launch. I just wrote a few posts on Reddit and shared it in local Telegram channels for parents.&lt;/p&gt;

&lt;p&gt;Currently, we have about 20-30 organic installs per month. But most importantly, it's used daily by my family.&lt;/p&gt;

&lt;p&gt;Building &lt;strong&gt;Zaspa&lt;/strong&gt; proved to me that one person &lt;em&gt;can&lt;/em&gt; build a complex, full-stack product if they use AI correctly. But you can't trust AI blindly—you need to guide it with context and strict rules. And don't over-engineer early; sometimes a custom solution is faster than fighting with a massive library like Firebase.&lt;/p&gt;




&lt;h3&gt;
  
  
  MCP Tools Used:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; For repo management.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;MongoDB:&lt;/strong&gt; For database interactions.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;goman.live:&lt;/strong&gt; For localization &amp;amp; prompt management.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Postman:&lt;/strong&gt; For API testing.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tooling</category>
      <category>showdev</category>
      <category>reactnative</category>
      <category>ai</category>
    </item>
    <item>
      <title>Goman.live: Guide for AI Developers and Vibe Coders</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Wed, 10 Dec 2025 15:10:07 +0000</pubDate>
      <link>https://dev.to/petrashka/gomanlive-guide-for-ai-developers-and-vibe-coders-5a7h</link>
      <guid>https://dev.to/petrashka/gomanlive-guide-for-ai-developers-and-vibe-coders-5a7h</guid>
      <description>&lt;p&gt;Greetings!&lt;br&gt;&lt;br&gt;
If you are tired of manually editing endless JSON files with translations and want your AI agent (Copilot, Cursor, Claude) to do it for you - this article is for you.&lt;/p&gt;

&lt;p&gt;Today we will look at &lt;strong&gt;Goman.live&lt;/strong&gt; - a tool that turns the routine of localization into magic. We will discuss why it is needed, how it saves your time, and why it is a must-have for the modern "vibe coder".&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Goman.live and why do you need it?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goman.live&lt;/strong&gt; is not just another translator. It is a smart backend for managing your application's content.&lt;/p&gt;

&lt;p&gt;Imagine: you write code, and all texts - buttons, errors, descriptions - automatically appear in all required languages, taking into account the context and style of your project. No manual copying to Google Translate, no errors in keys, and no "broken" localization files.&lt;/p&gt;

&lt;p&gt;The service works in two modes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Autopilot (via MCP)&lt;/strong&gt;: You simply ask your AI agent in the IDE to "add a button", and everything happens by itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control Center (Web Editor)&lt;/strong&gt;: A powerful interface for manual tuning, quality checking, and managing complex contexts.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Who really needs this?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Goman.live&lt;/strong&gt; was created to remove pain from the development process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🚀 &lt;strong&gt;Vibe Coders (AI-Native Developers)&lt;/strong&gt;: You are used to working fast. Context switching to edit JSON kills the flow. Goman allows you not to leave the IDE.&lt;/li&gt;
&lt;li&gt;👨‍💻 &lt;strong&gt;Pet Project and Startup Developers&lt;/strong&gt;: Want to launch immediately in 10 languages? With Goman, it takes as much time as for one.&lt;/li&gt;
&lt;li&gt;👩‍💼 &lt;strong&gt;Teams&lt;/strong&gt;: A single source of truth for all texts. The developer doesn't wait for the translator, the translator doesn't break the JSON.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  MCP: Automation of localization in IDE
&lt;/h2&gt;

&lt;p&gt;This is the main feature. &lt;strong&gt;MCP (Model Context Protocol)&lt;/strong&gt; allows you to connect Goman directly to your Copilot or Cursor.&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=FnvfFEsJVN8" rel="noopener noreferrer"&gt;🎬 See it in action: Init Demo&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=fimdB5eOeNo" rel="noopener noreferrer"&gt;🎬 See it in action: Adding Spanish language support&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does it look in practice?&lt;/strong&gt;&lt;br&gt;
Instead of opening 5 files (&lt;code&gt;en.json&lt;/code&gt;, &lt;code&gt;de.json&lt;/code&gt;, &lt;code&gt;es.json&lt;/code&gt;...), searching for the right key, and inserting text, you write in the IDE chat:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Scan the open file and create translations for all text strings."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or even for a whole module:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Localize all components in the &lt;code&gt;src/features/auth&lt;/code&gt; folder. Save keys in the &lt;code&gt;auth&lt;/code&gt; namespace."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can ask to localize the entire project at once, but for better control, it is recommended to do it in parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens under the hood:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The agent checks if such a key exists (to avoid duplicates).&lt;/li&gt;
&lt;li&gt;Generates translations into all languages supported by the project.&lt;/li&gt;
&lt;li&gt;Saves them to the database.&lt;/li&gt;
&lt;li&gt;You can immediately use &lt;code&gt;t('actions.save')&lt;/code&gt; in the code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is important to note: besides the translations themselves, the system stores &lt;strong&gt;context&lt;/strong&gt; for each key (this works both via MCP and via the Editor). Thus, the agent and you can always know where a specific localization is used and what it means.&lt;/p&gt;

&lt;p&gt;This saves hours of routine work and allows you to focus on application logic, not dictionaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Set of Tools (MCP Tools)
&lt;/h3&gt;

&lt;p&gt;The MCP server gives your agent &lt;strong&gt;full control&lt;/strong&gt; over the localization process. The service covers the entire lifecycle of working with texts:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Project Discovery (Discovery)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;get_active_languages&lt;/code&gt;&lt;/strong&gt;: The first thing the agent does is check which languages are active in the project. This guarantees that translations will be created only for the required locales.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;get_namespaces&lt;/code&gt;&lt;/strong&gt;: Shows the project structure (list of files/namespaces) so the agent knows exactly where to save new texts (e.g., in &lt;code&gt;common&lt;/code&gt; or &lt;code&gt;auth&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Search &amp;amp; Verification
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;search_localizations&lt;/code&gt;&lt;/strong&gt;: Powerful search by keys and values. The agent can find all buttons with the word "Cancel" or check how the word "Save" is translated elsewhere to maintain consistency.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;get_localization_exists&lt;/code&gt;&lt;/strong&gt;: Precise check of a specific key. Allows avoiding duplication and overwriting of existing important texts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Content Management (Management)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;create_localization&lt;/code&gt;&lt;/strong&gt;: The main tool. Creates or updates translations. Understands context and can add translations immediately to all active project languages in one request.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;delete_localization&lt;/code&gt;&lt;/strong&gt;: Allows deleting obsolete or erroneous keys, maintaining cleanliness in the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This set of tools turns your AI agent into a full-fledged localization manager.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ready-made Templates (Prompts) for a Quick Start
&lt;/h3&gt;

&lt;p&gt;To avoid wasting time writing instructions for AI, the system already has a &lt;strong&gt;set of proven prompts&lt;/strong&gt; for typical tasks. They are available &lt;strong&gt;exclusively via MCP&lt;/strong&gt; and are ready for use by your agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;init-project&lt;/code&gt;&lt;/strong&gt;: Full localization setup from scratch. Helps choose the project structure, scans files, and creates the first keys.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;localize-component&lt;/code&gt;&lt;/strong&gt;: Just insert the component code (React, Vue, etc.), and the agent will find all texts, create keys, and even show how to change the code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;localize-folder&lt;/code&gt;&lt;/strong&gt;: The same, but for entire folders. Ideal for mass localization.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;add-language&lt;/code&gt;&lt;/strong&gt;: Want to add Polish? This prompt will take all existing English keys and translate them into the new language.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;check-coverage&lt;/code&gt;&lt;/strong&gt;: Project audit. Shows which keys are missing in which languages (e.g., "5 translations missing in &lt;code&gt;ru&lt;/code&gt;").&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;&lt;code&gt;localization-audit&lt;/code&gt;&lt;/strong&gt;: Deep analysis. Finds keys that are no longer used in the code and suggests deleting them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just choose the necessary template, and the system itself will substitute the optimal settings for a high-quality result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context and Prompt Management in IDE
&lt;/h3&gt;

&lt;p&gt;This function links settings in the web interface with the developer's working environment. The system provides a &lt;strong&gt;Prompt Editor&lt;/strong&gt;, which allows creating specialized instructions for AI agents.&lt;/p&gt;

&lt;p&gt;This solves the "blank slate" problem when the model needs the context of the task explained every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the editor allows you to do:&lt;/strong&gt;&lt;br&gt;
The main function is the creation and editing of the prompts themselves. It is through them that you manage the context in your IDE or agent. You write the rules of the game once, and the agent starts following them.&lt;/p&gt;

&lt;p&gt;It is important to note: this works &lt;strong&gt;not only for translations&lt;/strong&gt;. You can create prompts for any development tasks - from refactoring to writing tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usage examples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;For coding&lt;/strong&gt;: "Use arrow functions, avoid &lt;code&gt;any&lt;/code&gt;, write comments in JSDoc format, and always cover new code with tests."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;For interface&lt;/strong&gt;: You can set a strict rule: "Translate as briefly as possible so the text fits into buttons, use Apple HIG terminology."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;For marketing&lt;/strong&gt;: "Write emotionally, address the user as 'you', add appropriate emojis."&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;For technical documentation&lt;/strong&gt;: "Maintain an official style, do not translate specific terms (e.g., 'middleware', 'token'), formulate thoughts precisely and dryly."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The user simply selects the necessary prompt from the list in Copilot or Cursor, and the agent instantly switches to the required mode of operation.&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%2Fidx9ro85ptd46ubdrg49.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%2Fidx9ro85ptd46ubdrg49.png" alt="editor" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Editor: Full Control Over Quality
&lt;/h2&gt;

&lt;p&gt;If MCP is speed, then the web editor is precision.&lt;/p&gt;

&lt;p&gt;Here you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;See the full picture&lt;/strong&gt;: All languages side by side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edit context&lt;/strong&gt;: Add a description for AI so it understands that "Home" is a page, not a building.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix nuances&lt;/strong&gt;: If AI slightly missed the style, you can quickly fix it manually or ask to redo the variant.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is ideal for marketing texts, landing pages, and important messages where every word matters.&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%2F83lyzrqmrkxr8105cyuq.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%2F83lyzrqmrkxr8105cyuq.png" alt="prompt" width="800" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompts: Your Personal Style
&lt;/h2&gt;

&lt;p&gt;Why do AI translations sometimes look "machine-like"? Because the model doesn't know your context.&lt;br&gt;
In &lt;strong&gt;Goman.live&lt;/strong&gt;, you create &lt;strong&gt;Prompts&lt;/strong&gt; - a set of rules for your project.&lt;/p&gt;

&lt;p&gt;This is a replacement for outdated "glossaries". You can tell the model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Address the user as 'you'"&lt;/li&gt;
&lt;li&gt;"Do not translate the brand name 'SuperApp'"&lt;/li&gt;
&lt;li&gt;"Use a cheerful, informal tone"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI Assistant for Prompts
&lt;/h3&gt;

&lt;p&gt;Don't know how to write a prompt correctly? The built-in AI chat will help formulate ideal instructions for the model so the result is exactly as you expect.&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%2Fqhwuwu2qxlf8xcofn0k0.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%2Fqhwuwu2qxlf8xcofn0k0.png" alt="versions" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt Storage and Versioning
&lt;/h3&gt;

&lt;p&gt;You can store up to four (currently four) versions of a single prompt and switch between them in one click.&lt;br&gt;&lt;br&gt;
This is very convenient if you want to experiment with formulations or translation rules. Prompt versioning, when used properly, can significantly reduce token consumption. It can also be useful when testing and searching for the most suitable prompts - a prompt testing system has been added to the service - you can immediately run requests for execution and get results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaboration
&lt;/h3&gt;

&lt;p&gt;If you are not working alone - just add a colleague's email.&lt;br&gt;&lt;br&gt;
They will get access to your project, and you can work together on localizations and translations. Restrictions are only by tariff plan. Tokens for translation are taken from the owner's account - that is, the one who "shared".&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%2F48pu629m9n5rmgibbakg.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%2F48pu629m9n5rmgibbakg.png" alt="languages" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Supported Languages
&lt;/h2&gt;

&lt;p&gt;There is no full list of languages in the service - and that's good.&lt;br&gt;&lt;br&gt;
Models are used that can work with dozens and hundreds of languages, so there are effectively no restrictions.&lt;br&gt;&lt;br&gt;
Translation quality depends on the text itself, the prevalence of the language, and whether there are similar translations in your database.&lt;/p&gt;

&lt;p&gt;Translations via the editor often turn out better than via standard tools because context and previous results are taken into account.&lt;br&gt;&lt;br&gt;
And if you work via MCP, the quality depends on the model your agent uses - for example, Claude, GPT, etc.&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%2Fvl9ldwbnqw0br39vqymn.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%2Fvl9ldwbnqw0br39vqymn.png" alt="mistakes" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Quality Control: Trust, but Verify
&lt;/h2&gt;

&lt;p&gt;AI is a powerful tool but not perfect. Therefore, Goman.live has built-in insurance mechanisms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Syntax Check&lt;/strong&gt;: The service watches so AI doesn't break variables (e.g., &lt;code&gt;{{name}}&lt;/code&gt;) or HTML tags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Highlighting Suspicious Places&lt;/strong&gt;: In the editor, you will see warnings if the translation looks uncertain.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You always have the last word. The service proposes - you approve.&lt;/p&gt;




&lt;h2&gt;
  
  
  Limitations and Features
&lt;/h2&gt;

&lt;p&gt;Since the service runs on LLMs, it has its own features.&lt;br&gt;&lt;br&gt;
First of all - this is the &lt;strong&gt;context size&lt;/strong&gt;: the model can process only a certain amount of information at a time (on average about 8–10 thousand tokens).&lt;br&gt;&lt;br&gt;
If the text is too large, it is better to divide it into logical parts - this way the model better understands the structure and context, and translations come out more accurate.&lt;/p&gt;

&lt;p&gt;When using RAG, the context may also be incomplete because separate pieces of text are stored in it and search occurs through it.&lt;br&gt;&lt;br&gt;
Therefore, it is better to translate in small blocks and avoid overloading the model.&lt;/p&gt;

&lt;p&gt;This is not a disadvantage, but rather a feature of LLM operation; they simply must "understand" the text within their context window.&lt;br&gt;&lt;br&gt;
But this allows achieving stable results and easily processing translations.&lt;/p&gt;




&lt;h2&gt;
  
  
  About Tokens and Cost
&lt;/h2&gt;

&lt;p&gt;The principle of operation is honesty.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Via MCP&lt;/strong&gt;: You use your own API key (Copilot, Cursor, OpenAI), so Goman.live does not charge any additional fees for tokens. It is effectively free from the service side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Via Editor&lt;/strong&gt;: The service's capacities are used, so internal tokens are deducted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to get a discount?
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;referral program&lt;/strong&gt; is active: bring a friend and get &lt;strong&gt;up to 90% discount&lt;/strong&gt;.&lt;br&gt;
You can contact &lt;a href="mailto:goman.live.service@gmail.com"&gt;goman.live.service@gmail.com&lt;/a&gt; if you want to learn more.&lt;/p&gt;




&lt;h2&gt;
  
  
  About Data Retention
&lt;/h2&gt;

&lt;p&gt;All your data is stored &lt;strong&gt;on our own servers&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;A dump is made every 6 hours&lt;/strong&gt;, and information &lt;strong&gt;is not transferred to third parties&lt;/strong&gt; except for models (LLMs) that process translations.&lt;br&gt;
Data after application deletion may be stored for some time - done for the possibility of restoring them upon personal request. You can also export localizations in the form offered in the service at any time. Uploading data is possible via MCP, via a form (one record at a time), or immediately many from a file in the required format.&lt;/p&gt;




&lt;h2&gt;
  
  
  About Cooperation
&lt;/h2&gt;

&lt;p&gt;The project team is open to new ideas and cooperation.&lt;br&gt;&lt;br&gt;
If you have a service or business that can be integrated with Goman.live, or if there is interest in the project - you can contact the developers.&lt;br&gt;&lt;br&gt;
Creation of custom plans, API integrations, and even separate solutions for specific needs is possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Additional Functionality
&lt;/h2&gt;

&lt;p&gt;Goman.live is not just localizations.&lt;br&gt;&lt;br&gt;
The service allows testing prompts, viewing results, saving them in different versions, and even working in a team. This is described in more detail in the&lt;br&gt;
 &lt;a href="https://goman.live/documentation" rel="noopener noreferrer"&gt;service documentation&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Work is underway on the following things:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;improving prompt integration with &lt;strong&gt;GitHub Copilot, Cursor, and other IDEs&lt;/strong&gt;,
&lt;/li&gt;
&lt;li&gt;choice of translation model and use of &lt;strong&gt;own API keys&lt;/strong&gt;,
&lt;/li&gt;
&lt;li&gt;improving RAG and automatic update of localizations,
&lt;/li&gt;
&lt;li&gt;and many more ideas that will make working with translations even more convenient.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Summary: Why is it worth trying?
&lt;/h2&gt;

&lt;p&gt;If you want to create global products but don't want to waste your life on spreadsheets with translations - Goman.live is for you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed&lt;/strong&gt;: Localization becomes part of writing code, not a separate stage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality&lt;/strong&gt;: AI knows context and style better than Google Translate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Convenience&lt;/strong&gt;: Manage everything right from your favorite IDE.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 &lt;strong&gt;Try it yourself at &lt;a href="https://goman.live?source=dev_to" rel="noopener noreferrer"&gt;goman.live&lt;/a&gt;&lt;/strong&gt; and feel the difference. Your users will say "Thank you" (in their native language 😉).&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
      <category>mcp</category>
    </item>
    <item>
      <title>I built a free baby tracker that syncs across devices without requiring an account</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Mon, 01 Dec 2025 09:30:48 +0000</pubDate>
      <link>https://dev.to/petrashka/i-built-a-free-baby-tracker-that-syncs-across-devices-without-requiring-an-account-35bp</link>
      <guid>https://dev.to/petrashka/i-built-a-free-baby-tracker-that-syncs-across-devices-without-requiring-an-account-35bp</guid>
      <description>&lt;p&gt;Hey everyone! I recently became a dad, and let me tell you - nobody warns you about the logistics nightmare that comes with a newborn.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;First few days home, we tried tracking everything on paper. Feeding times, which breast, how long, diaper changes, sleep... The notebook quickly became an unreadable mess. Then came the constant texts between me and my wife: "When did you last feed her?" "Which side?" "Did you change her?" "How long has she been sleeping?"&lt;/p&gt;

&lt;p&gt;We tried existing baby tracker apps. One wanted us to create accounts and verify emails - not happening at 3 AM with a screaming baby. Another had half the features locked behind a $10/month subscription. A third one had sync, but required both of us to sign up separately and then somehow "connect" our accounts through a confusing process.&lt;/p&gt;

&lt;p&gt;I just wanted something simple. Log stuff. Share with my wife. That's it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution (That Grew Into Something More)
&lt;/h2&gt;

&lt;p&gt;So I built a quick app for myself. Just feedings at first - tap, log, done. Shared it with my wife through a simple sync key.&lt;/p&gt;

&lt;p&gt;Then we needed sleep tracking. Added that. Then diapers. Then weight for doctor visits. Then a timer because we kept forgetting when the feeding started. Then dark mode because I blinded myself one too many times at night.&lt;/p&gt;

&lt;p&gt;Two months later, that "quick app" became Zaspa - a full baby tracker that actually solves the problems we had.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It Different
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No accounts, no passwords, no BS&lt;/strong&gt; - You generate a random sync key, text it to your partner, they enter it, done. You're both tracking the same baby in real-time. No email verification, no "forgot password", no account management. Your data stays anonymous on our servers - we don't store baby names or any personal info.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actually works at 3 AM&lt;/strong&gt; - Big buttons, one-handed operation, minimal steps to log anything. When you're half-asleep holding a baby, you don't want to navigate through menus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix mistakes easily&lt;/strong&gt; - Forgot to log a feeding an hour ago? Just adjust the timestamp. Started the timer late? Edit the start time. Life with a newborn is messy, the app handles that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features for Parents
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Feeding tracker&lt;/strong&gt; - Breastfeeding with side switching, formula with amounts, solid foods when you get there. Built-in timer so you don't have to watch the clock.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sleep tracker&lt;/strong&gt; - Log naps and night sleep. Timer for real-time tracking. Helps you spot patterns in your baby's schedule (if they have one).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diaper log&lt;/strong&gt; - Quick taps for wet/dirty. Simple but important for making sure baby is eating enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Growth tracking&lt;/strong&gt; - Weight and height over time. Have real data ready when the pediatrician asks "how's the weight gain?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Activity log&lt;/strong&gt; - Walks, baths, tummy time, medicine, pumping. Notes on everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excel export&lt;/strong&gt; - Generate spreadsheets for doctor visits. No more "I think she ate around... maybe 6 times yesterday?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple kids&lt;/strong&gt; - Twins? Toddler and newborn? Separate profiles for each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dark mode&lt;/strong&gt; - Your eyes will thank you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6 languages&lt;/strong&gt; - English, Spanish, German, Ukrainian, Belarusian, Polish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Completely Free
&lt;/h2&gt;

&lt;p&gt;No ads. No premium tier. No subscriptions. I built this because my family needed it, and I figured other parents might too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://zaspa.online/" rel="noopener noreferrer"&gt;https://zaspa.online/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Works on iOS, Android. Your data is encrypted and private. You can disconnect sync anytime and keep everything local.&lt;/p&gt;

&lt;p&gt;Would love to hear from other parents - what's missing? What would make this actually useful for your situation?&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Thanks for checking it out!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dadlife</category>
      <category>newparents</category>
    </item>
    <item>
      <title>MCP servers I use for vibecoding in my daily life</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Mon, 01 Dec 2025 09:10:35 +0000</pubDate>
      <link>https://dev.to/petrashka/mcp-servers-i-use-in-my-daily-life-4kah</link>
      <guid>https://dev.to/petrashka/mcp-servers-i-use-in-my-daily-life-4kah</guid>
      <description>&lt;p&gt;Today, I want to share a brief list of MCP servers that I use daily in my work and projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. GitHub MCP Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What It Does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub MCP Server enables you to work with GitHub through an AI assistant: view code, search for files, read and summarize documentation in repositories, manage issues and pull requests, and get an overall view of projects. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I read and create documentation in repositories.&lt;/li&gt;
&lt;li&gt;I add to or create new technical documentation.&lt;/li&gt;
&lt;li&gt;I analyze pull requests (what has changed, what risks are involved, what needs to be amended) with the help of rules that impose code style restrictions.&lt;/li&gt;
&lt;li&gt;I create pull requests.&lt;/li&gt;
&lt;li&gt;I look at issues that are relevant to me to understand what to prioritize. This significantly reduces the number of switches between the IDE and the browser, especially when you need to quickly dive into several PRs at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it's suitable for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers who "live" in the IDE and dislike constantly opening GitHub in the browser.&lt;/li&gt;
&lt;li&gt;Those who work extensively with PRs and technical documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcp/github/github-mcp-server" rel="noopener noreferrer"&gt;GitHub MCP&lt;/a&gt; &lt;/p&gt;




&lt;h3&gt;
  
  
  Atlassian MCP Server (Jira / Confluence)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Atlassian MCP Server provides access to Jira and Confluence through an AI assistant. You can create and update tasks, read pages in Confluence, search for information, and receive summaries of documentation and backlogs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I read large Confluence pages and receive concise summaries instead of manually scrolling.&lt;/li&gt;
&lt;li&gt;I write and refine technical documentation, such as design documents, meeting notes, and instructions.&lt;/li&gt;
&lt;li&gt;I create tasks in Jira (bug, task, sub-task) from simple text notes.&lt;/li&gt;
&lt;li&gt;I edit existing tasks, including descriptions, acceptance criteria, status, and priorities.&lt;/li&gt;
&lt;li&gt;I quickly review tasks that are specifically relevant to me, such as those in progress, those "to do," and those that are blocked. In fact, this is my primary way of working with Jira without delving into its cumbersome web interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it's suitable for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PMs, BAs, Team/Tech Leads who "live" in Jira and Confluence.&lt;/li&gt;
&lt;li&gt;Engineers who want to see "what is expected of me" in a convenient text format.&lt;/li&gt;
&lt;li&gt;Teams with a lot of documentation and lengthy Confluence pages.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;a href="https://github.com/mcp/atlassian/atlassian-mcp-server" rel="noopener noreferrer"&gt;Atlassian MCP&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Figma MCP Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Figma MCP Server integrates design context into the assistant, including frames, components, styles, tokens, and layouts. It helps transfer designs from Figma to code by understanding the screen structure, spacing, component names, and connections between elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I use it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It significantly simplifies the writing of components, especially when the screen is complex.&lt;/li&gt;
&lt;li&gt;I obtain the frame structure and can easily transfer it into code.&lt;/li&gt;
&lt;li&gt;I make fewer mistakes in details: consistent spacing, correct colors, and text styles. As a result, the time from "design is in Figma" to "screen is functional in code" is reduced, and the implementation quality is closer to the original design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it's for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend developers who work extensively with Figma.&lt;/li&gt;
&lt;li&gt;Designers and engineers who want to minimize manual adjustments when transferring designs to code.&lt;/li&gt;
&lt;li&gt;Teams with a complete design system and tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcp/com.figma.mcp/mcp" rel="noopener noreferrer"&gt;Figma MCP&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Goman.live – MCP Localization Manager
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Through MCP, Goman.live assists with localization: creating new keys, viewing existing ones, obtaining draft translations in multiple languages without manually editing JSON files, and translating texts without losing context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During vibe coding, when it's clear that the text will need translation.&lt;/li&gt;
&lt;li&gt;In projects that require localization into multiple languages (I have several such projects).&lt;/li&gt;
&lt;li&gt;When new keys need to be quickly added and a draft translation obtained, which can then be properly reviewed on the service page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the moment, I am satisfied: the localization process has become more predictable and less stressful. However, it is important to monitor the relevance of the keys, as agents tend to create a lot of irrelevant ones. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who it's suitable for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams that require internationalization (i18n) and support multiple interface languages.&lt;/li&gt;
&lt;li&gt;Developers who prefer not to manually maintain JSON translation files.&lt;/li&gt;
&lt;li&gt;Localizers and content teams seeking a centralized location for translations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://goman.live/mcp-localization-manager?source=devto" rel="noopener noreferrer"&gt;MCP Localization Manager&lt;/a&gt; &lt;/p&gt;




&lt;h3&gt;
  
  
  Playwright MCP
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Playwright MCP allows you to control the browser through an assistant based on Playwright: open pages, fill out forms, click buttons, check tables, and read texts on the page. It works with the semantic structure (a11y tree) rather than "screen images," making it more stable in its operations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It / When It's Useful&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For simple smoke tests of main user scenarios (login, checkout, order form, etc.).&lt;/li&gt;
&lt;li&gt;For quickly checking that key flows haven't broken after changes.&lt;/li&gt;
&lt;li&gt;For gathering information from pages without writing full e2e tests manually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't a magical replacement for all tests, but it's a good tool to give agents access to the browser and automate routine checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who It's Suitable For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QA professionals who are already using Playwright.&lt;/li&gt;
&lt;li&gt;For developers who want to easily verify main scenarios after changes.&lt;/li&gt;
&lt;li&gt;For analysts who need to automatically extract data from web pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcp/microsoft/playwright-mcp" rel="noopener noreferrer"&gt;Playwright MCP&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  Brief Conclusion
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atlassian MCP&lt;/strong&gt; — My main tool for documentation and tasks (Jira/Confluence).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub MCP&lt;/strong&gt; — For code, PRs, and repository reviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Figma MCP&lt;/strong&gt; — For implementing designs and staying close to the layout. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goman MCP&lt;/strong&gt; — when a project requires localization in multiple languages. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playwright MCP&lt;/strong&gt; — used for UI automation, smoke testing, and verifying main user scenarios.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>mcp</category>
      <category>i18</category>
    </item>
    <item>
      <title>MCP servers I use in my daily life</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Mon, 01 Dec 2025 07:48:12 +0000</pubDate>
      <link>https://dev.to/petrashka/mcp-servers-i-use-in-my-daily-life-2nga</link>
      <guid>https://dev.to/petrashka/mcp-servers-i-use-in-my-daily-life-2nga</guid>
      <description>&lt;p&gt;Today, I want to share a brief list of MCP servers that I use daily in my work and projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. GitHub MCP Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What It Does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub MCP Server enables you to work with GitHub through an AI assistant: view code, search for files, read and summarize documentation in repositories, manage issues and pull requests, and get an overall view of projects. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I read and create documentation in repositories.&lt;/li&gt;
&lt;li&gt;I add to or create new technical documentation.&lt;/li&gt;
&lt;li&gt;I analyze pull requests (what has changed, what risks are involved, what needs to be amended) with the help of rules that impose code style restrictions.&lt;/li&gt;
&lt;li&gt;I create pull requests.&lt;/li&gt;
&lt;li&gt;I look at issues that are relevant to me to understand what to prioritize. This significantly reduces the number of switches between the IDE and the browser, especially when you need to quickly dive into several PRs at once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it's suitable for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers who "live" in the IDE and dislike constantly opening GitHub in the browser.&lt;/li&gt;
&lt;li&gt;Those who work extensively with PRs and technical documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcp/github/github-mcp-server" rel="noopener noreferrer"&gt;GitHub MCP&lt;/a&gt; &lt;/p&gt;




&lt;h3&gt;
  
  
  Atlassian MCP Server (Jira / Confluence)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Atlassian MCP Server provides access to Jira and Confluence through an AI assistant. You can create and update tasks, read pages in Confluence, search for information, and receive summaries of documentation and backlogs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I read large Confluence pages and receive concise summaries instead of manually scrolling.&lt;/li&gt;
&lt;li&gt;I write and refine technical documentation, such as design documents, meeting notes, and instructions.&lt;/li&gt;
&lt;li&gt;I create tasks in Jira (bug, task, sub-task) from simple text notes.&lt;/li&gt;
&lt;li&gt;I edit existing tasks, including descriptions, acceptance criteria, status, and priorities.&lt;/li&gt;
&lt;li&gt;I quickly review tasks that are specifically relevant to me, such as those in progress, those "to do," and those that are blocked. In fact, this is my primary way of working with Jira without delving into its cumbersome web interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it's suitable for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PMs, BAs, Team/Tech Leads who "live" in Jira and Confluence.&lt;/li&gt;
&lt;li&gt;Engineers who want to see "what is expected of me" in a convenient text format.&lt;/li&gt;
&lt;li&gt;Teams with a lot of documentation and lengthy Confluence pages.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;a href="https://github.com/mcp/atlassian/atlassian-mcp-server" rel="noopener noreferrer"&gt;Atlassian MCP&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Figma MCP Server
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Figma MCP Server integrates design context into the assistant, including frames, components, styles, tokens, and layouts. It helps transfer designs from Figma to code by understanding the screen structure, spacing, component names, and connections between elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I use it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It significantly simplifies the writing of components, especially when the screen is complex.&lt;/li&gt;
&lt;li&gt;I obtain the frame structure and can easily transfer it into code.&lt;/li&gt;
&lt;li&gt;I make fewer mistakes in details: consistent spacing, correct colors, and text styles. As a result, the time from "design is in Figma" to "screen is functional in code" is reduced, and the implementation quality is closer to the original design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Who it's for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend developers who work extensively with Figma.&lt;/li&gt;
&lt;li&gt;Designers and engineers who want to minimize manual adjustments when transferring designs to code.&lt;/li&gt;
&lt;li&gt;Teams with a complete design system and tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcp/com.figma.mcp/mcp" rel="noopener noreferrer"&gt;Figma MCP&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Goman.live – MCP Localization Manager
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Through MCP, Goman.live assists with localization: creating new keys, viewing existing ones, obtaining draft translations in multiple languages without manually editing JSON files, and translating texts without losing context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During vibe coding, when it's clear that the text will need translation.&lt;/li&gt;
&lt;li&gt;In projects that require localization into multiple languages (I have several such projects).&lt;/li&gt;
&lt;li&gt;When new keys need to be quickly added and a draft translation obtained, which can then be properly reviewed on the service page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the moment, I am satisfied: the localization process has become more predictable and less stressful. However, it is important to monitor the relevance of the keys, as agents tend to create a lot of irrelevant ones. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who it's suitable for&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Teams that require internationalization (i18n) and support multiple interface languages.&lt;/li&gt;
&lt;li&gt;Developers who prefer not to manually maintain JSON translation files.&lt;/li&gt;
&lt;li&gt;Localizers and content teams seeking a centralized location for translations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://goman.live/mcp-localization-manager?source=devto" rel="noopener noreferrer"&gt;MCP Localization Manager&lt;/a&gt; &lt;/p&gt;




&lt;h3&gt;
  
  
  Playwright MCP
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Playwright MCP allows you to control the browser through an assistant based on Playwright: open pages, fill out forms, click buttons, check tables, and read texts on the page. It works with the semantic structure (a11y tree) rather than "screen images," making it more stable in its operations. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Use It / When It's Useful&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For simple smoke tests of main user scenarios (login, checkout, order form, etc.).&lt;/li&gt;
&lt;li&gt;For quickly checking that key flows haven't broken after changes.&lt;/li&gt;
&lt;li&gt;For gathering information from pages without writing full e2e tests manually.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This isn't a magical replacement for all tests, but it's a good tool to give agents access to the browser and automate routine checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who It's Suitable For&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;QA professionals who are already using Playwright.&lt;/li&gt;
&lt;li&gt;For developers who want to easily verify main scenarios after changes.&lt;/li&gt;
&lt;li&gt;For analysts who need to automatically extract data from web pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Links&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mcp/microsoft/playwright-mcp" rel="noopener noreferrer"&gt;Playwright MCP&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  Brief Conclusion
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Atlassian MCP&lt;/strong&gt; — My main tool for documentation and tasks (Jira/Confluence).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub MCP&lt;/strong&gt; — For code, PRs, and repository reviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Figma MCP&lt;/strong&gt; — For implementing designs and staying close to the layout. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Goman MCP&lt;/strong&gt; — when a project requires localization in multiple languages. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playwright MCP&lt;/strong&gt; — used for UI automation, smoke testing, and verifying main user scenarios.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>github</category>
      <category>i18</category>
    </item>
    <item>
      <title>LangGraph for Beginners: A Complete Guide</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Fri, 28 Nov 2025 09:56:32 +0000</pubDate>
      <link>https://dev.to/petrashka/langgraph-for-beginners-a-complete-guide-2310</link>
      <guid>https://dev.to/petrashka/langgraph-for-beginners-a-complete-guide-2310</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you'll learn:&lt;/strong&gt; How to build AI agent systems with LangGraph - from basic concepts to working code. We'll create an article-writing pipeline with multiple AI agents that collaborate, review each other's work, and iterate until the result is perfect.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  PART 1: Basic Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a Graph?
&lt;/h3&gt;

&lt;p&gt;Before diving into LangGraph, it's essential to understand what a &lt;strong&gt;graph&lt;/strong&gt; is in programming.&lt;/p&gt;

&lt;h4&gt;
  
  
  A Graph is a Data Structure
&lt;/h4&gt;

&lt;p&gt;Imagine a subway map:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stations&lt;/strong&gt; are the &lt;strong&gt;nodes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lines between stations&lt;/strong&gt; are the &lt;strong&gt;edges&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Typical Graph:              Subway Map (Analogy):

        [A]                         [Victory Square]
         │                                 │
         ▼                                 ▼
        [B]───────►[C]              [October]───►[Kupala]
         │                                 │
         ▼                                 ▼
        [D]                         [Cultural Institute]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  In LangGraph:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nodes&lt;/strong&gt; are functions (agents) that perform tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges&lt;/strong&gt; are rules indicating the order in which tasks are executed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Why is LangGraph Needed?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Problem: Traditional AI Programs are Linear
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Typical Chain:

    Question → LLM → Answer

    or

    Question → Tool 1 → LLM → Tool 2 → Answer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works for simple tasks, but what if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to &lt;strong&gt;go back&lt;/strong&gt; and redo something?&lt;/li&gt;
&lt;li&gt;You need to &lt;strong&gt;verify the result&lt;/strong&gt; and possibly repeat?&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;multiple agents&lt;/strong&gt; with different roles?&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Solution: LangGraph Allows Creating Cycles
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LangGraph (Graph):

                    ┌──────────────────────┐
                    │                      │
                    ▼                      │
    Question → [Researcher] → [Writer] → [Reviewer]
                                               │
                                               ▼
                                          Good? ───NO───► back to Writer
                                               │
                                              YES
                                               │
                                               ▼
                                           [Result]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  What is "state"?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  State is the memory of the program.
&lt;/h4&gt;

&lt;p&gt;Imagine you are writing an article with a team:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The researcher gathered &lt;strong&gt;materials&lt;/strong&gt; → needs to write them down somewhere.&lt;/li&gt;
&lt;li&gt;The writer created a &lt;strong&gt;draft&lt;/strong&gt; → needs to pass it to the reviewer.&lt;/li&gt;
&lt;li&gt;The reviewer wrote &lt;strong&gt;comments&lt;/strong&gt; → needs to return them to the writer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;State&lt;/strong&gt; is like a "basket" where everyone puts their results and from which they take data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                        STATE (Стан)                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   topic: "What I Write"                                     │
│   research: "Materials from the Researcher"                 │
│   draft: "Draft from the Writer"                            │
│   review: "Comments from the Reviewer"                      │
│   finalArticle: "Final Article"                             │
│   messages: [history of all messages]                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘
              ▲               ▲               ▲
              │               │               │
         Researcher        Writer         Reviewer
      (reads and writes) (reads and writes) (reads and writes)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  PART 2: Annotation - How State is Created
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is Annotation?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Annotation&lt;/code&gt; is a way of &lt;strong&gt;describing the structure of a state&lt;/strong&gt;. It is like creating a form with fields.&lt;/p&gt;

&lt;h4&gt;
  
  
  Analogy: Survey
&lt;/h4&gt;

&lt;p&gt;Imagine you are creating a survey:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│            EMPLOYEE SURVEY              │
├─────────────────────────────────────────┤
│ Name: ___________________               │
│ Age: _____                              │
│ Work Experience (years): _____          │
│ Skills List: ___, ___, ___              │
└─────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In code, it looks like this:&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;// ANALOGY: Creating a survey form&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Survey&lt;/span&gt; &lt;span class="o"&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="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Text field&lt;/span&gt;
    &lt;span class="na"&gt;age&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="c1"&gt;// Number&lt;/span&gt;
    &lt;span class="na"&gt;experience&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="c1"&gt;// Number&lt;/span&gt;
    &lt;span class="na"&gt;skills&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;// List&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  In LangGraph: Annotation.Root
&lt;/h4&gt;

&lt;p&gt;In LangGraph, state is created using &lt;code&gt;Annotation.Root()&lt;/code&gt;. This is a special function that describes the structure of your data - what fields exist and how they should be updated.&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;Annotation&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="s1"&gt;@langchain/langgraph&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;ResearchState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// Each field is described through Annotation&amp;lt;Type&amp;gt;&lt;/span&gt;
    &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;research&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&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;draft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({...}),&lt;/span&gt;
    &lt;span class="c1"&gt;// etc.&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each field inside &lt;code&gt;Annotation.Root&lt;/code&gt; has two important properties: &lt;strong&gt;reducer&lt;/strong&gt; (how to update the value) and &lt;strong&gt;default&lt;/strong&gt; (initial value). We'll explore these next.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a Reducer?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Problem: How to merge data?
&lt;/h4&gt;

&lt;p&gt;What should you do when multiple agents write to the same field?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent 1 writes: topic = "Topic A"
Agent 2 writes: topic = "Topic B"

What should be in topic? "Topic A"? "Topic B"? "Topic A + Topic B"?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Solution: Reducer - a function that resolves
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Reducer&lt;/strong&gt; is a function that takes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Current value&lt;/strong&gt; (what is already there)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New Value&lt;/strong&gt; (what comes in)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It returns: &lt;strong&gt;result&lt;/strong&gt; (what to keep)&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="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//         ▲         ▲           ▲&lt;/span&gt;
&lt;span class="c1"&gt;//         │         │           └── What will be kept&lt;/span&gt;
&lt;span class="c1"&gt;//         │         └── New value&lt;/span&gt;
&lt;span class="c1"&gt;//         └── Current value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Examples of Reducers:
&lt;/h4&gt;

&lt;h5&gt;
  
  
  1. Reducer "REPLACE"
&lt;/h5&gt;

&lt;p&gt;The new value completely replaces the old one.&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;// Code:&lt;/span&gt;
&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Example:&lt;/span&gt;
&lt;span class="c1"&gt;// Current: "Theme A"&lt;/span&gt;
&lt;span class="c1"&gt;// New:     "Theme B"&lt;/span&gt;
&lt;span class="c1"&gt;// Result:   "Theme B"  ← new replaces old&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Analogy:&lt;/strong&gt; You overwrite a file - the new content replaces the old one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;file.txt
──────────────
Was:   "Old text"
        ▼ (overwrite)
Is:    "New text"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. Reducer "APPEND"
&lt;/h5&gt;

&lt;p&gt;New elements are added to the existing ones.&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;// Code:&lt;/span&gt;
&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;update&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="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Example:&lt;/span&gt;
&lt;span class="c1"&gt;// Current: ["Message 1", "Message 2"]&lt;/span&gt;
&lt;span class="c1"&gt;// New:     ["Message 3"]&lt;/span&gt;
&lt;span class="c1"&gt;// Result:   ["Message 1", "Message 2", "Message 3"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Analogy:&lt;/strong&gt; You add new entries to a diary - the old ones remain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diary.txt
──────────────
Was:    "Monday: did A"
        "Tuesday: did B"
             ▼ (adding)
Became: "Monday: did A"
        "Tuesday: did B"
        "Wednesday: did C" ← added
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Full example of the state:
&lt;/h4&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;ResearchState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// FIELD: messages (messages)&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BaseMessage&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="c1"&gt;// REDUCER: Add new messages to existing ones&lt;/span&gt;
        &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;update&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="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="c1"&gt;// DEFAULT: Initial value - empty array&lt;/span&gt;
        &lt;span class="na"&gt;default&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="p"&gt;[],&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// How it works:&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Beginning:    messages = []&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Researcher:  messages = [] + [AIMessage] = [AIMessage]&lt;/span&gt;
    &lt;span class="c1"&gt;// 3. Writer: messages = [AIMessage] + [AIMessage] = [AIMessage, AIMessage]&lt;/span&gt;
    &lt;span class="c1"&gt;// 4. And so on - all messages are stored&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// FIELD: topic (topic)&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="c1"&gt;// REDUCER: Replace old value with new one&lt;/span&gt;
        &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "_" means "ignore"&lt;/span&gt;
        &lt;span class="na"&gt;default&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="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;//&lt;/span&gt;
    &lt;span class="c1"&gt;// How it works:&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Beginning:    topic = ""&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. User:   topic = "" → "LangChain"&lt;/span&gt;
    &lt;span class="c1"&gt;// If someone else writes in topic - the old value will disappear&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// FIELD: iterationCount (iteration counter)&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="na"&gt;iterationCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Annotation&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&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;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Simply replace&lt;/span&gt;
        &lt;span class="na"&gt;default&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Start from 0&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="c1"&gt;// The writer writes each time: iterationCount: state.iterationCount + 1&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Start:         iterationCount = 0&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Writer (1):   iterationCount = 0 + 1 = 1&lt;/span&gt;
    &lt;span class="c1"&gt;// 3. Writer (2):   iterationCount = 1 + 1 = 2&lt;/span&gt;
    &lt;span class="c1"&gt;// 4. Writer (3): iterationCount = 2 + 1 = 3&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Visualization of Reducers:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────┐
│                       REDUCER: REPLACE                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Current: █████████████  "Old text"                            │
│                  ▼                                              │
│   New:     ░░░░░░░░░░░░░  "New text"                            │
│                  ▼                                              │
│   Result:  ░░░░░░░░░░░░░  "New text" ← only new                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                         REDUCER: ADD                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Current:  [█] [█] [█]      ← three elements                   │
│                  +                                              │
│   New:      [░] [░]          ← two new                          │
│                  =                                              │
│   Result:   [█] [█] [█] [░] [░]  ← all together                 │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  What is default?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;default&lt;/code&gt; is a function that returns the &lt;strong&gt;initial value&lt;/strong&gt; of a field.&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;default&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="nx"&gt;value&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why a function and not just a value?
&lt;/h4&gt;

&lt;p&gt;This is a common JavaScript pitfall. If you use a plain object or array as default, all instances will share the same reference - changes in one place will affect all others!&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;// POOR: If this is an object or array&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;// All instances will refer to the same array!&lt;/span&gt;

&lt;span class="c1"&gt;// GOOD: The function creates a new array each time&lt;/span&gt;
&lt;span class="k"&gt;default&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="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;// Each instance will get its own array&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Examples:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// For a string&lt;/span&gt;
&lt;span class="k"&gt;default&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="dl"&gt;''&lt;/span&gt;        &lt;span class="c1"&gt;// Empty string&lt;/span&gt;

&lt;span class="c1"&gt;// For a number&lt;/span&gt;
&lt;span class="k"&gt;default&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="mi"&gt;0&lt;/span&gt;         &lt;span class="c1"&gt;// Zero&lt;/span&gt;

&lt;span class="c1"&gt;// For an array&lt;/span&gt;
&lt;span class="k"&gt;default&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="p"&gt;[]&lt;/span&gt;        &lt;span class="c1"&gt;// Empty array&lt;/span&gt;

&lt;span class="c1"&gt;// For an object&lt;/span&gt;
&lt;span class="k"&gt;default&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="p"&gt;({})&lt;/span&gt;      &lt;span class="c1"&gt;// Empty object&lt;/span&gt;

&lt;span class="c1"&gt;// For boolean&lt;/span&gt;
&lt;span class="k"&gt;default&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="kc"&gt;false&lt;/span&gt;     &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  PART 3: Nodes - Agents
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a node?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Node&lt;/strong&gt; is a function that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Receives&lt;/strong&gt; the full state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performs&lt;/strong&gt; some work (for example, calls LLM)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Returns&lt;/strong&gt; a partial state update&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Analogy: Worker on the Assembly Line
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────┐
│                       ASSEMBLY LINE                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   [Box] ──► [Worker 1] ───────► [Worker 2] ──────►          │
│                  │                    │                     │
│                  ▼                    ▼                     │
│            Adds part A          Adds part B                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Each worker:
1. Sees what has already been done (state)
2. Does their part of the work
3. Passes it on with additions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Node Structure in Code:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchStateType&lt;/span&gt; &lt;span class="c1"&gt;// ← INPUT: Full state&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ← OUTPUT: Partial update&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Read data from state&lt;/span&gt;
    &lt;span class="kd"&gt;const&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;someField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Do the work&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;doSomething&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="c1"&gt;// 3. Returning the update (only what has changed)&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;someField&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="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;
  
  
  Important: Partial
&lt;/h4&gt;

&lt;p&gt;A node doesn't need to return the entire state - only the fields that changed. LangGraph will merge your partial update with the existing state using the reducers you defined.&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;// The full state has 6 fields:&lt;/span&gt;
&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;research&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;draft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;review&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;finalArticle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
    &lt;span class="na"&gt;iterationCount&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="c1"&gt;// But the node can only return what it has changed:&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;draft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New draft&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;// Changed&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt; &lt;span class="c1"&gt;// Added&lt;/span&gt;
    &lt;span class="c1"&gt;// The other fields are not mentioned - they will remain as they were&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Our nodes in detail
&lt;/h3&gt;

&lt;p&gt;Now let's look at the four nodes in our article-writing system. Each node has a specific role and passes its results to the next one through the shared state.&lt;/p&gt;

&lt;h4&gt;
  
  
  Node 1: Researcher (researcherNode)
&lt;/h4&gt;

&lt;p&gt;The researcher is the first agent in our pipeline. It takes the topic and generates research materials that will be used by the writer.&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;researcherNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 1: Get the topic for research                         │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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="nx"&gt;state&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="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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="o"&gt;||&lt;/span&gt;
        &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;//            ▲               ▲&lt;/span&gt;
    &lt;span class="c1"&gt;//            │               └── Or the last message&lt;/span&gt;
    &lt;span class="c1"&gt;//            └── First, try to take topic&lt;/span&gt;

    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 2: Form the prompt for LLM                            │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&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;`You are an expert researcher. Your task is to gather key information.
    Topic: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    Conduct a brief research...`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 3: Call LLM                                           │&lt;/span&gt;
    &lt;span class="c1"&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;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&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="s1"&gt;system&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="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="c1"&gt;// Instructions for AI&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="s1"&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="s2"&gt;`Research the topic: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;topic&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="c1"&gt;// Request&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;research&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&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="c1"&gt;// Result from LLM&lt;/span&gt;

    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 4: Return state update                                │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;research&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Store the research result&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&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="s2"&gt;`[Research completed]
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;research&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="c1"&gt;// ▲ Add a message to the history&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;What happens:&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;INPUT (state):                       OUTPUT (update):
┌─────────────────────┐              ┌─────────────────────┐
│ topic: "LangChain"  │              │ research: "LangCh.. │
│ research: ""        │  ──────►     │ messages: [+1 msg]  │
│ draft: ""           │              └─────────────────────┘
│ messages: [1 msg]   │
└─────────────────────┘
                                     ▼ After merging:

                                ┌─────────────────────┐
                                │ topic: "LangChain"  │
                                │ research: "LangCh...│ ← updated
                                │ draft: ""           │
                                │ messages: [2 msgs]  │ ← added
                                └─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Node 2: Writer (writerNode)
&lt;/h4&gt;

&lt;p&gt;The writer takes the research and creates an article draft. If this is a revision (after reviewer feedback), it also considers the review comments. Notice how &lt;code&gt;iterationCount&lt;/code&gt; helps us track how many times the article has been rewritten.&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;writerNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 1: Read the research and possible review              │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&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;`You are a technical writer. Based on the research, write an article.

Research:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;research&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`Previous review (consider comments): &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&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="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 2: Call LLM                                           │&lt;/span&gt;
    &lt;span class="c1"&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;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&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="s1"&gt;system&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="nx"&gt;prompt&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="s1"&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="s1"&gt;Write an article based on the research&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;draft&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&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="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 3: Return the update                                  │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Draft of the article&lt;/span&gt;
        &lt;span class="na"&gt;iterationCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterationCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Increment the counter&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&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="s2"&gt;`[Draft &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterationCount&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens on repeat call:&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;FIRST CALL:                          SECOND CALL (after review):
┌─────────────────────┐              ┌─────────────────────┐
│ research: "..."     │              │ research: "..."     │
│ review: ""          │              │ review: "Refine..." │ ← there are comments!
│ iterationCount: 0   │              │ iterationCount: 1   │
└─────────────────────┘              └─────────────────────┘
         │                                    │
         ▼                                    ▼
Writing without comments             Considering comments
         │                                    │
         ▼                                    ▼
┌─────────────────────┐              ┌─────────────────────┐
│ draft: "Version 1"  │              │ draft: "Version 2"  │
│ iterationCount: 1   │              │ iterationCount: 2   │
└─────────────────────┘              └─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Node 3: Reviewer (reviewerNode)
&lt;/h4&gt;

&lt;p&gt;The reviewer evaluates the draft and decides if it's ready for publication. The key here is the output: if the review contains "APPROVED", the article moves to finalization. Otherwise, it goes back to the writer for improvements. This is what enables the &lt;strong&gt;cycle&lt;/strong&gt; in our graph.&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;reviewerNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 1: Formulating the review request                      │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&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;`You are a strict editor. Evaluate the article.

Article:
&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

Evaluate based on the criteria:
1. Accuracy of information
2. Structure and logic
3. Language quality
4. Completeness of the topic coverage

If the article is good - say "APPROVED". When improvements are needed, please provide specific recommendations.
`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 2: Get the review                                     │&lt;/span&gt;
    &lt;span class="c1"&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;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&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;review&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&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="c1"&gt;// ┌─────────────────────────────────────────────────────────────┐&lt;/span&gt;
    &lt;span class="c1"&gt;// │ STEP 3: Return the review                                  │&lt;/span&gt;
    &lt;span class="c1"&gt;// └─────────────────────────────────────────────────────────────┘&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Review (either "APPROVED" or comments)&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&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="s2"&gt;`[Review]\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;review&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Two possible outcomes:&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;OPTION A: The article is good             OPTION B: Needs improvement
┌───────────────────────────┐             ┌───────────────────────────┐
│ review: "APPROVED.        │             │ review: "Improve:         │
│ The article is excellent!"│             │ 1. Add examples           │
│                           │             │ 2. Clarify the terms"     │
└───────────────────────────┘             └───────────────────────────┘
             │                                        │
             ▼                                        ▼
        Moving to                              Returning to
        finalizer                                 writer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Node 4: Finalizer (finalizerNode)
&lt;/h4&gt;

&lt;p&gt;The finalizer is the simplest node - it just copies the approved draft to the &lt;code&gt;finalArticle&lt;/code&gt; field, marking the end of our workflow. This is called when the reviewer approves the article.&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;finalizerNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Simple node - copies the draft to the final article&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;finalArticle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;draft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Final article&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AIMessage&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="s2"&gt;`[READY]\n\n&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;draft&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens:&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;INPUT:                              OUTPUT:
┌─────────────────────┐             ┌─────────────────────┐
│ draft: "Ready..."   │  ──────►    │ finalArticle:       │
│ finalArticle: ""    │             │   "Ready..."        │
└─────────────────────┘             └─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  PART 4: Edges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is an edge?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Edge&lt;/strong&gt; is a rule that states: "After this node, the following node is executed."&lt;/p&gt;

&lt;h4&gt;
  
  
  Analogy: Arrows on the Diagram
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recipe steps:

    [Make dough] ────► [Add sauce] ────► [Add cheese] ────► [Bake]
          │                  │                  │               │
          ▼                  ▼                  ▼               ▼
      TRANSITION         TRANSITION        TRANSITION         END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Two Types of Transitions in LangGraph:
&lt;/h4&gt;

&lt;h5&gt;
  
  
  1. Simple Transitions (addEdge)
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;Always&lt;/strong&gt; go to the same node.&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="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;researcher&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;writer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//                    ▲            ▲&lt;/span&gt;
&lt;span class="c1"&gt;//                    │            └── Where are we going&lt;/span&gt;
&lt;span class="c1"&gt;//                    └── From where are we coming&lt;/span&gt;

&lt;span class="c1"&gt;// Meaning: After researcher, we ALWAYS go to writer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Visualization:&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;    [researcher] ───────────────► [writer]
                   (always)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. Conditional Transitions (addConditionalEdges)
&lt;/h5&gt;

&lt;p&gt;The choice of the next node &lt;strong&gt;depends on the state&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="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addConditionalEdges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reviewer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Source node&lt;/span&gt;
    &lt;span class="nx"&gt;shouldContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Function that decides where to go&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;writer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// If the function returns 'writer' → go to writer&lt;/span&gt;
        &lt;span class="na"&gt;finalizer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;finalizer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// If the function returns 'finalizer' → go to finalizer&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;Visualization:&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;                            ┌──────────► [writer]
                            │
    [reviewer] ─────► [?] ──┤
                            │
                            └──────────► [finalizer]

    The function shouldContinue decides which arrow to take.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Detailed Function shouldContinue
&lt;/h3&gt;

&lt;p&gt;This is the "brain" of our conditional edge. It examines the current state and decides where to go next. The function must return a string that matches one of the keys in the mapping object we defined in &lt;code&gt;addConditionalEdges&lt;/code&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;function&lt;/span&gt; &lt;span class="nf"&gt;shouldContinue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ResearchStateType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;writer&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;finalizer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//                                              ▲&lt;/span&gt;
    &lt;span class="c1"&gt;//                                              └── Returns one of these strings&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;review&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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;maxIterations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// CONDITION 1: Reviewer said "APPROVED"&lt;/span&gt;
    &lt;span class="c1"&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;review&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&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="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;review&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;approved&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Article approved&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;finalizer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ← Proceed to finalize&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// CONDITION 2: Too many attempts (protection against infinite loop)&lt;/span&gt;
    &lt;span class="c1"&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterationCount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;maxIterations&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Maximum iterations reached&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;finalizer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ← Force finalize&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// OTHERWISE: Needs revision&lt;/span&gt;
    &lt;span class="c1"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Revision needed&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;writer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ← Go back to writer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Decision flowchart:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         ┌───────────────────┐
                         │  shouldContinue   │
                         │    (function)     │
                         └─────────┬─────────┘
                                   │
                                   ▼
                    ┌──────────────────────────────┐
                    │   Is "approved" present      │
                    │   in the review?             │
                    └──────────────┬───────────────┘
                                   │
                      ┌────────────┴────────────┐
                      │                         │
                     YES                       NO
                      │                         │
                      ▼                         ▼
               ┌────────────┐      ┌──────────────────────────┐
               │  return    │      │ Is iterationCount &amp;gt;= 3?  │
               │'finalizer' │      └──────────────┬───────────┘
               │            │                     │
               └────────────┘        ┌────────────┴────────────┐
                                     │                         │
                                    YES                       NO
                                     │                         │
                                     ▼                         ▼
                              ┌────────────┐            ┌────────────┐
                              │  return    │            │  return    │
                              │'finalizer' │            │  'writer'  │
                              │            │            │            │
                              └────────────┘            └────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  How the graph is built
&lt;/h3&gt;

&lt;p&gt;Now let's put everything together! Building a graph in LangGraph follows a simple pattern: create the graph, add nodes, connect them with edges, and compile.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sequence of creation:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════════&lt;/span&gt;
&lt;span class="c1"&gt;// STEP 1: Create StateGraph with our state&lt;/span&gt;
&lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════════&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workflow&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;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ResearchState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// STEP 2: Add nodes (register functions)&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;researcher&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;researcherNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Name 'researcher' → function&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;writer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writerNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Name 'writer' → function&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reviewer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reviewerNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Name 'reviewer' → function&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;finalizer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;finalizerNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Name 'finalizer' → function&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// STEP 3: Add simple transitions&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;__start__&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;researcher&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Start → Researcher&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;researcher&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;writer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Researcher → Writer&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;writer&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;reviewer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Writer → Reviewer&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// STEP 4: Add conditional transition&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addConditionalEdges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reviewer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shouldContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;writer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// If 'writer' → back to writer&lt;/span&gt;
        &lt;span class="na"&gt;finalizer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;finalizer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// If 'finalizer' → to finalizer&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="c1"&gt;// STEP 5: Add final transition&lt;/span&gt;
    &lt;span class="c1"&gt;// ═══════════════════════════════════════════════════════════&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;finalizer&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;__end__&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Finalizer → End&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Special nodes:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────┬─────────────────────────────────────────────┐
│  '__start__'  │  Virtual start node                         │
│               │  LangGraph automatically starts from it     │
├───────────────┼─────────────────────────────────────────────┤
│  '__end__'    │  Virtual end node                           │
│               │  When reached - the graph is completed      │
└───────────────┴─────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  PART 5: Compilation and execution
&lt;/h2&gt;

&lt;p&gt;We've defined our state, nodes, and edges. Now it's time to turn this blueprint into a running application!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is compile()?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;compile()&lt;/code&gt; is the process of transforming a &lt;strong&gt;graph description&lt;/strong&gt; into an &lt;strong&gt;executable program&lt;/strong&gt;. Until you call &lt;code&gt;compile()&lt;/code&gt;, you just have a description of what you want to build - not an actual runnable system.&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;// Graph description (blueprint)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;workflow&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;StateGraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ResearchState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;

&lt;span class="c1"&gt;// Compilation into an executable program&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;//    ▲&lt;/span&gt;
&lt;span class="c1"&gt;//    └── Now this can be run!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Analogy: Recipe vs. Finished Dish
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;workflow (description)                 app (compiled program)
──────────────────────                 ──────────────────────
Recipe on paper                        Ready pizza
   - How to make the dough                (can be eaten)
   - What to add
   - How to bake

Cannot be eaten!                       Can be eaten!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Checkpointer (MemorySaver)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  What is it?
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Checkpointer&lt;/strong&gt; is a mechanism for &lt;strong&gt;saving state&lt;/strong&gt; after each step.&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;MemorySaver&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="s1"&gt;@langchain/langgraph&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;checkpointer&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;MemorySaver&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;checkpointer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// ← Adding checkpointer&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why is this needed?
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITHOUT CHECKPOINTER:
═════════════════════════════════════════════════════════════════

    Run 1:   START → researcher → writer → ... → END

    Run 2:   START → researcher → ... (everything from the beginning!)

    ✗ Cannot continue from the stopping point
    ✗ Cannot view history


WITH CHECKPOINTER:
═════════════════════════════════════════════════════════════════

    Run 1:   START → researcher → [SAVED]
                                      │
                               thread_id: "chat-123"

    Run 2:   [RESUMING] → writer → reviewer → ...
                     │
              thread_id: "chat-123"

    ✓ Can continue from the stopping point
    ✓ Can view history
    ✓ Can have multiple independent "conversations"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Thread ID - identifier of the "thread"
&lt;/h4&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&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;configurable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Unique ID for this "conversation"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Each thread_id is a separate story&lt;/span&gt;
&lt;span class="c1"&gt;// 'article-1' - about one article&lt;/span&gt;
&lt;span class="c1"&gt;// 'article-2' - about another article&lt;/span&gt;
&lt;span class="c1"&gt;// They do not overlap!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Running the Graph
&lt;/h3&gt;

&lt;p&gt;Finally! Let's run our graph. The &lt;code&gt;invoke()&lt;/code&gt; function takes initial state values and configuration, then executes the entire graph from start to finish.&lt;/p&gt;

&lt;h4&gt;
  
  
  The invoke() Function
&lt;/h4&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;result&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;// Initial data for the state&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Benefits of LangChain&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Benefits of LangChain&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;// Configuration&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;configurable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;article-1&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;h4&gt;
  
  
  What Happens When &lt;code&gt;invoke()&lt;/code&gt; is Called:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────────────┐
│                         invoke()                                │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 1. INITIALIZATION OF STATE                                      │
│    state = {                                                    │
│        topic: "Advantages of LangChain",                        │
│        messages: [HumanMessage],                                │
│        research: "",  ← default                                 │
│        draft: "",     ← default                                 │
│        review: "",    ← default                                 │
│        finalArticle: "", ← default                              │
│        iterationCount: 0, ← default                             │
│    }                                                            │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 2. BEGINNING: __start__ → researcher                            │
│    Executing researcherNode(state)                              │
│    → Receiving update {research: "...", messages: [...]}        │
│    → Merging with state through reducers                        │
│    Saving checkpoint                                            │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 3. TRANSITION: researcher → writer                              │
│    Execute writerNode(state)                                    │
│    → Receive update {draft: "...", iterationCount: 1}           │
│    → Merge with state                                           │
│    Save checkpoint                                              │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 4. TRANSITION: writer → reviewer                                │
│    Execute reviewerNode(state)                                  │
│    → Receive update {review: "..."}                             │
│    → Merge with state                                           │
│    Save checkpoint                                              │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 5. CONDITIONAL TRANSITION: shouldContinue(state)                │
│    → Returns 'writer' or 'finalizer'                            │
│    → If 'writer' - return to step 3                             │
│    → If 'finalizer' - proceed further                           │
└───────────────────────────────┬─────────────────────────────────┘
                                │ (if 'finalizer')
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 6. TRANSITION: reviewer → finalizer                             │
│    Execute finalizerNode(state)                                 │
│    → Receive update {finalArticle: "..."}                       │
│    → Merge with state                                           │
│    Save checkpoint                                              │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
┌─────────────────────────────────────────────────────────────────┐
│ 7. FINALIZER: finalizer → __end__                               │
│    The graph has completed                                      │
│    Returning the final state                                    │
└───────────────────────────────┬─────────────────────────────────┘
                                │
                                ▼
                        return state (full)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  PART 6: FAQ - Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why does the reducer add messages but replace the topic?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Messages&lt;/strong&gt; represent history. We want to keep all messages throughout the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topic&lt;/strong&gt; is the current theme. When the topic changes, the old one is no longer needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What happens if I don’t specify a reducer?
&lt;/h3&gt;

&lt;p&gt;LangGraph will use the default behavior - &lt;strong&gt;replacement&lt;/strong&gt; (like for the topic).&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is iterationCount needed?
&lt;/h3&gt;

&lt;p&gt;To &lt;strong&gt;protect against infinite loops&lt;/strong&gt;. If the reviewer never says "approved", the program will keep cycling between the writer and the reviewer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can one node directly invoke another?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt; Nodes do not know about each other. They only read/write state. LangGraph determines who executes next based on transitions.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are &lt;strong&gt;start&lt;/strong&gt; and &lt;strong&gt;end&lt;/strong&gt;?
&lt;/h3&gt;

&lt;p&gt;These are &lt;strong&gt;special virtual nodes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;__start__&lt;/code&gt; - where the graph begins&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;__end__&lt;/code&gt; - where the graph ends&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They do not execute code - they only mark the boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can there be multiple end nodes?
&lt;/h3&gt;

&lt;p&gt;Yes! For example:&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&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;__end__&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;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&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;__end__&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;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You've learned the core concepts of LangGraph. Let's recap what we covered:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State + Annotation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Defines the data structure passed between agents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reducer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Specifies how to combine new data with existing data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Nodes&lt;/strong&gt; (Agents)&lt;/td&gt;
&lt;td&gt;Functions that process the state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Edges&lt;/strong&gt; (Transitions)&lt;/td&gt;
&lt;td&gt;Rules determining the order of operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Conditional Edges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dynamic selection of the next node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Checkpointer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Saves the state for continuation later&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;Now that you understand the basics, you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build your own agent system&lt;/strong&gt; - Start with a simple two-node graph and gradually add complexity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experiment with different flows&lt;/strong&gt; - Try creating graphs with multiple conditional branches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add persistence&lt;/strong&gt; - Use &lt;code&gt;MemorySaver&lt;/code&gt; or database-backed checkpointers for production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore advanced features&lt;/strong&gt; - Look into subgraphs, parallel execution, and human-in-the-loop patterns&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Think in graphs&lt;/strong&gt;: Break down your AI workflow into discrete steps (nodes) connected by rules (edges)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State is everything&lt;/strong&gt;: All communication between nodes happens through the shared state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reducers matter&lt;/strong&gt;: Choose the right reducer for each field - append for history, replace for current values&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cycles enable iteration&lt;/strong&gt;: Unlike simple chains, graphs can loop back for refinement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The article-writing example we built demonstrates a real-world pattern: &lt;strong&gt;research → write → review → (repeat if needed) → finalize&lt;/strong&gt;. This same pattern applies to many AI applications: code review, content moderation, multi-step reasoning, and more.&lt;/p&gt;

&lt;p&gt;Happy building! 🚀&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>beginners</category>
      <category>langgraph</category>
    </item>
    <item>
      <title>How to Work with Feedback in Prompting: A Live Guide with Examples</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Tue, 25 Nov 2025 16:12:16 +0000</pubDate>
      <link>https://dev.to/petrashka/how-to-work-with-feedback-in-prompting-a-live-guide-with-examples-570p</link>
      <guid>https://dev.to/petrashka/how-to-work-with-feedback-in-prompting-a-live-guide-with-examples-570p</guid>
      <description>&lt;h3&gt;
  
  
  Hello, everyone!
&lt;/h3&gt;

&lt;p&gt;We continue our wonderful series of articles on prompting 🤖✨&lt;/p&gt;

&lt;p&gt;Today, we will explore four effective feedback prompting techniques that will help you achieve even better results from AI! 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 What Are These Techniques and Where Did They Come From?
&lt;/h3&gt;

&lt;p&gt;To work with AI as efficiently as possible, experts have developed a range of powerful techniques 🛠️. They were born at the intersection of science, engineering practice, and everyday user experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  Main methods of feedback prompting:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;✍️ &lt;strong&gt;Explicit Feedback Prompting&lt;/strong&gt; — open expression of comments and suggestions.&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Iterative Refinement&lt;/strong&gt; — gradual refinement of responses through multiple iterations.&lt;/li&gt;
&lt;li&gt;🧐 &lt;strong&gt;Critique and Revision Prompting&lt;/strong&gt; — the model critiques and improves the results itself.&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;RLHF (Reinforcement Learning from Human Feedback)&lt;/strong&gt; — choosing the best from several options. ---&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ✍️ 1. Explicit Feedback Prompting
&lt;/h3&gt;

&lt;p&gt;Let's start with a simple yet very effective method!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You provide the model with specific and polite feedback 📜: what needs to be changed and how to improve the response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When useful:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When the first response seems superficial or incomplete 🔍&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it looks:&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write an article about interesting facts about Antarctica.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Antarctica is a cold continent. There is almost no vegetation or animals here.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The text seems too general.
Please add specific data about temperatures, research stations, and local fauna.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revised Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Antarctica is the coldest continent, where the average winter temperature can reach -60°C.
There are approximately 70 research stations, and the known animals include emperor penguins and Weddell seals.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🔄 2. Iterative Refinement
&lt;/h3&gt;

&lt;p&gt;Let's continue! Let's see how you can refine results step by step 🔧&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Gradual refinement and improvement of responses in multiple stages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it's useful:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you want to achieve maximum quality ✨&lt;/p&gt;

&lt;p&gt;Prompt 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write a summary of the book "1984" by George Orwell.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"1984" is a novel about a totalitarian state where the protagonist, Winston, tries to resist the system.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add more emotional moments and emphasize Winston's fear of Big Brother
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revised Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"1984" tells the story of life under total surveillance, where Winston Smith lives in constant fear and tries to maintain his humanity.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And so on. In this way, we refine each iteration of the model's work until we achieve the format we need.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧐 3. Critique and Revision Prompting
&lt;/h3&gt;

&lt;p&gt;Next level! Forcing AI to Criticize Itself 🕵️‍♂️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The model evaluates the quality of its own response and suggests improvements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When it's useful:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you want to awaken critical thinking in the model 🧠&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write an essay on the importance of environmental awareness. Then evaluate and improve your text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Environmental awareness is crucial for preserving nature and sustaining life on the planet. It is important to sort waste and conserve resources.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Critique of the Model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Analyze the text, identify stylistic and grammatical errors, and correct them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revised Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Every day, we choose the future: recycling plastic, conserving water, supporting local producers. Environmental awareness is our contribution to a healthy planet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this way, we instruct the model to analyze and apply the corrections to the text. Sometimes, this can be very useful. This technique is actively used in creating agents. We will explore this in more detail next time.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 4. RLHF (Reinforcement Learning from Human Feedback)
&lt;/h3&gt;

&lt;p&gt;And finally, a technique for those who want to choose the best 🔥&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Creating several options → choosing the best one → improving it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When useful:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you want a truly perfect result 🌟&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provide 3 answer options to the question: Why is it important to preserve biodiversity?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Supporting Ecological Balance
2. Providing Food and Medicine for Humanity
3. Impact on Climate Stability

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The third option seems the best! Add specific facts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Biodiversity plays a central role in climate stability: forests absorb CO2, and oceans regulate temperature. The loss of species leads to ecological disasters.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This technique works when you have conducted some analysis yourself and more or less know what you want to achieve. ### 🎯 Results&lt;/p&gt;

&lt;p&gt;Now you know:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;How to give AI clear and precise feedback ✍️&lt;/li&gt;
&lt;li&gt;How to refine results over several iterations 🔄&lt;/li&gt;
&lt;li&gt;How to make the model self-evaluate its responses 🧐&lt;/li&gt;
&lt;li&gt;How to select and improve the best options 🧩&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Attention! The best results are achieved by combining different approaches. However, it should be noted that since the context size in models is not unlimited, they may eventually lose the initial requirements or reduce their importance. Therefore, when giving feedback, it is advisable to periodically clarify previous requirements.&lt;/p&gt;




&lt;p&gt;📣 Try it yourself!&lt;/p&gt;

&lt;p&gt;Write a simple prompt and:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluate the result 🎯&lt;/li&gt;
&lt;li&gt;Provide feedback 🤓&lt;/li&gt;
&lt;li&gt;Ask the model to clarify or critique itself 🔍&lt;/li&gt;
&lt;li&gt;Create several versions and choose the best one 🌟&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  PS:
&lt;/h3&gt;

&lt;p&gt;Thank you, friends, for staying with me! I hope, as always, my article will be useful to you. I would be very grateful for your likes, comments, and support of the project -  &lt;a href="https://bel-geek.com" rel="noopener noreferrer"&gt;bel-geek.com&lt;/a&gt; !&lt;/p&gt;

</description>
      <category>promptengineering</category>
      <category>ai</category>
    </item>
    <item>
      <title>Painless Vibe-Coding: A Complete Practical Guide from Real-Life Experience</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Tue, 11 Nov 2025 19:07:11 +0000</pubDate>
      <link>https://dev.to/petrashka/painless-vibe-coding-a-complete-practical-guide-from-real-life-experience-16nc</link>
      <guid>https://dev.to/petrashka/painless-vibe-coding-a-complete-practical-guide-from-real-life-experience-16nc</guid>
      <description>&lt;h2&gt;
  
  
  Vibe Coding Without Pain: A Complete Practical Guide from Real Experience
&lt;/h2&gt;

&lt;p&gt;Vibe coding isn't "magic in a vacuum," but a conscious technique of rapid development with a reliable framework. Over the past months, I've transitioned from Bolt.New to Copilot, Claude, Cursor, and Google AI Studio: over a thousand prompts, dozens of iterations, and many lessons. Below is not a collection of platitudes but a polished set of principles, tools, and templates that truly save time, money, and nerves as the codebase grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction: What is Vibe-Coding and How Not to Burn Out
&lt;/h2&gt;

&lt;p&gt;The idea is simple: we move in small but precise steps, committing results to Git, asking AI to make local "diff-only" patches instead of rewriting the world, and maintaining a design system from the very first lines. Instead of "an agent that does everything for you," pair with a wise assistant to whom you clearly formulate the task and boundaries. This way, we avoid "hallucinations," unnecessary restructuring, and do not lose control over tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Planning and Mini-Contract: How Not to Get Lost in the First 30 Minutes
&lt;/h2&gt;

&lt;p&gt;Before any coding, create a brief but concrete plan:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1–2 sentences about what we are doing: "The user does X and gets Y" (example: "Creates and shares task lists in 30 seconds without registration"). - 3 to 7 main flows/screens - without excessive detail.&lt;/li&gt;
&lt;li&gt;Framework in terms of files: "routes -&amp;gt; modules -&amp;gt; reusable components."&lt;/li&gt;
&lt;li&gt;Blacklist items: "do not reinvent the wheel" such as buttons, inputs, alerts, helpers, validation schemas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, a feature mini-contract: inputs, outputs, errors, constraints, criteria for completion. Afterwards, all prompts are within the scope of this contract. &lt;/p&gt;

&lt;h2&gt;
  
  
  2) Design System and Consistency: The Framework for the Project
&lt;/h2&gt;

&lt;p&gt;The most costly mistake is starting "on a vibe" without a grid and basic typography. To avoid turning refactoring into manual alignment of margins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One base file: breakpoints, spacing scale, grid, typography.&lt;/li&gt;
&lt;li&gt;Main components right away: Button, Input, Select, Alert, Loader, Empty/Error states.&lt;/li&gt;
&lt;li&gt;Check after each iteration: ensure sizes and fonts haven't "spread out."&lt;/li&gt;
&lt;li&gt;In prompts: "Use existing ButtonX, InputY." New styles should not be introduced unnecessarily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Resource for starting and inspiration: 21st.dev - ready-made UI patterns with prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) A Stack that Helps, Not Hinders
&lt;/h2&gt;

&lt;p&gt;The broader the community and documentation, the more accurately AI hits the API and patterns. Practical combinations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js - frontend + lightweight API layer.&lt;/li&gt;
&lt;li&gt;Tailwind CSS - fast, consistent styles without "CSS-mess" at the start.&lt;/li&gt;
&lt;li&gt;Fastify + MongoDB or Supabase - minimal rituals, many ready-made recipes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main thing is not exotic, but reliable model answers. &lt;/p&gt;

&lt;h2&gt;
  
  
  4) Git Discipline: "Freeze Time" More Often
&lt;/h2&gt;

&lt;p&gt;Your best insurance policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One feature per branch.&lt;/li&gt;
&lt;li&gt;Small work chunks - frequent commits with clear messages.&lt;/li&gt;
&lt;li&gt;Before risky generations/reorganizations - commit or branch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way, you won't have to "roll back" 700 lines if the AI "optimized" in the wrong place.&lt;/p&gt;

&lt;h2&gt;
  
  
  5) Breaking Down the Complex: Spec -&amp;gt; Skeleton -&amp;gt; Flesh -&amp;gt; Harden
&lt;/h2&gt;

&lt;p&gt;Not "do the whole module," but a sequential assembly line:&lt;/p&gt;

&lt;p&gt;1) Routes and file skeletons. 2. Basic markup and components.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Logic, validation, states.&lt;/li&gt;
&lt;li&gt;Tests, security, optimization.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI works more stably when the task boundaries are narrow and clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  6) Prompts without "magic" and with protective boundaries
&lt;/h2&gt;

&lt;p&gt;The final formulation is your control lever. The minimal template:&lt;/p&gt;

&lt;p&gt;"Refactor &lt;code&gt;ProfileForm.tsx&lt;/code&gt;: move validation to a separate hook, do not touch the API, preserve prop names and public API, use &lt;code&gt;InputX&lt;/code&gt; and &lt;code&gt;ButtonY&lt;/code&gt;." The protective phrase "Do not change anything that was not requested" is mandatory.&lt;/p&gt;

&lt;h2&gt;
  
  
  7) Context and "Reset": When to Open a New Chat
&lt;/h2&gt;

&lt;p&gt;A large chat = drift of patterns, loss of context. Restarting is not a failure, but a form of hygiene:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brief introduction for a new window: "Feature X, files A/B/C, only allowed to touch …"&lt;/li&gt;
&lt;li&gt;Remember: too much context is as harmful as too little - leave only the essential.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8) Token Economy: Be cautious with the budget
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Small patches instead of giant "rewrites."&lt;/li&gt;
&lt;li&gt;Diff-first: "Show the patch plan + diff, then apply."&lt;/li&gt;
&lt;li&gt;Model switching: simple - Auto/smaller model; reviews and security - Gemini 2.5 Pro / Sonnet.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9) Engineering Hygiene: Tests, Logs, Types
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Small, clean functions without "lazy" side effects.&lt;/li&gt;
&lt;li&gt;Use ESLint with autofixes; remove dead code at every step.&lt;/li&gt;
&lt;li&gt;Minimum unit tests: "happy path" and edge cases (null/empty/unknown type).&lt;/li&gt;
&lt;li&gt;TypeScript with strict rules - fewer comments, more guarantees.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before committing: remove unnecessary logs and "temporary" comments - they consume attention during iterations and use up tokens.&lt;/p&gt;

&lt;h2&gt;
  
  
  10) Security: A Brief but Serious Checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Secrets and keys should only be stored on the server (use environment variables, .gitignore, and ensure they are not exposed to the client).&lt;/li&gt;
&lt;li&gt;Validate and sanitize inputs on the server, and ensure output is properly escaped.&lt;/li&gt;
&lt;li&gt;Permissions should not rely solely on login: each action and resource must undergo permission checks.&lt;/li&gt;
&lt;li&gt;Errors: provide a general message for the user and maintain a detailed log for the developer.&lt;/li&gt;
&lt;li&gt;IDOR and resource ownership: ensure the user has the right to access the specific ID. - DB rules (RLS and analogs) are better at the database level when appropriate. &lt;/li&gt;
&lt;li&gt;Rate limiting and encryption (HTTPS, data "at rest").&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  11) Iterative Review with a "Big Head" (Google AI Studio / Gemini 2.5 Pro)
&lt;/h2&gt;

&lt;p&gt;When deep inspection is needed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brief overview: "The module does X for Y; main logic in functions..."&lt;/li&gt;
&lt;li&gt;Goals: security, performance, duplicates, unnecessary dependencies.&lt;/li&gt;
&lt;li&gt;Boundaries: "No global restructuring; suggest local patches/steps." &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Response Format that Works:
&lt;/h3&gt;

&lt;p&gt;1) Issue;&lt;br&gt;
2) Why it is an issue;&lt;br&gt;
3) Risk;&lt;br&gt;
4) Specific patch/steps.&lt;/p&gt;

&lt;p&gt;Then proceed with local diff patches, small tests, and a review.&lt;/p&gt;




&lt;h2&gt;
  
  
  12) "Embedded" Errors: Procedure Without Panic
&lt;/h2&gt;

&lt;p&gt;If, after 2-3 attempts, things are still "off":&lt;/p&gt;

&lt;p&gt;1) Ask the model to name the top suspects in the dependency chain.&lt;br&gt;
2) Add logs to narrow spots, add facts (stack, payload, boundaries).&lt;br&gt;
3) If necessary, rollback to a "green" commit and take small steps forward. &lt;/p&gt;

&lt;h2&gt;
  
  
  13) The Rule "Don't Touch Unless Asked" - and Why I Always Repeat It
&lt;/h2&gt;

&lt;p&gt;AI loves to "tidy up" when it sees an opportunity. Protection - the concluding phrase in each prompt: "Don't change anything beyond the listed." After several iterations, the model begins to respect boundaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  14) "Common AI Mistakes" File and "Instructions" as Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Maintain &lt;code&gt;ai_common_mistakes.md&lt;/code&gt;: AI likes to move validation to UI, change prop names, and delete necessary imports - all of this goes here. - Folder &lt;code&gt;instructions/&lt;/code&gt; with markdown examples, prompt templates, "Cursor Rules," and short best practices.&lt;/li&gt;
&lt;li&gt;In the new feature, add a link to the file of mistakes - saves tokens and time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  15) Tools and Patterns That Accelerate Without Fuss
&lt;/h2&gt;

&lt;p&gt;Tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storybook - isolated UI and documentation of patterns.&lt;/li&gt;
&lt;li&gt;Playwright / Vitest - fast E2E/unit tests; work well with diff patches.&lt;/li&gt;
&lt;li&gt;CodeSandbox / StackBlitz - instant sandboxes for PoC. - Sourcegraph Cody: deep search and contextual patches.&lt;/li&gt;
&lt;li&gt;Continue / Aider / Windsurf / Codeium: lightweight assistants for "getting stuck."&lt;/li&gt;
&lt;li&gt;Tabby / local LLM: affordable generation for template code.&lt;/li&gt;
&lt;li&gt;Perplexity / Phind: quick technical research and approach comparison.&lt;/li&gt;
&lt;li&gt;MCP (Model Context Protocol): standardized access to files/commands without "chatter" in the prompt.&lt;/li&gt;
&lt;li&gt;Commit message generators (see also CommitGPT): save time, but read before pushing. - ESLint with autofix: "entry-level" machine hygiene.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Work Patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Triple Pass Review: structure -&amp;gt; logic/data flow -&amp;gt; edge cases/security.&lt;/li&gt;
&lt;li&gt;Interface Freeze: lock the public API/props before deep generations.&lt;/li&gt;
&lt;li&gt;Context Ledger: short notes on features (files, solutions, outstanding TODOs) - easily transferable to a new chat.&lt;/li&gt;
&lt;li&gt;Session Reset Cadence: regular reset of long sessions.&lt;/li&gt;
&lt;li&gt;Red Team Self-Check: separate pass for injections, IDOR, races. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  16) About Cursor Rules, Instructions, and "Not Being Afraid to Go Back"
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cursor Rules: An excellent starting point; fix the stack, patterns, prohibitions, and anti-patterns.&lt;/li&gt;
&lt;li&gt;A folder with instructions: examples of components, short recipes for typical tasks (replacing the "hot memory" of the chat).&lt;/li&gt;
&lt;li&gt;If the model goes astray: go back one step, clarify the prompt and context—continuing "by inertia" is more costly. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  17) Preventing Undesirable Changes from AI - Politely but Firmly
&lt;/h2&gt;

&lt;p&gt;Be persistent in every request: "Do not add, delete, or rename anything that was not requested." This significantly reduces the "optimization reflex." Vulgar language is unnecessary - clear boundaries work better.&lt;/p&gt;

&lt;h2&gt;
  
  
  18) Mini-checklist before Commit
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The function fits into existing patterns and components.&lt;/li&gt;
&lt;li&gt;Types are strict, without any; basic tests and logs are present.&lt;/li&gt;
&lt;li&gt;Security: Secrets are on the server; permissions and validation are checked. - UI is consistent: spacing, states, names.&lt;/li&gt;
&lt;li&gt;Commit message is short and informative.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Useful External Resources
&lt;/h2&gt;

&lt;p&gt;Below are external, public sources (services and tools) that provide practical value in the "vibe" approach.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bolt.new" rel="noopener noreferrer"&gt;&lt;strong&gt;bolt.new&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: An online environment for quickly creating a framework (Full-stack/frontend) with initial code generation through AI.&lt;br&gt;&lt;br&gt;
Why: Instant MVP/prototype before investing in the structure of the main repository. When: In the phase of idea validation or searching for a general form without detailed architecture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/features/copilot" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: A tool for autocomplete and inline suggestions in the editor (VS Code, JetBrains).&lt;br&gt;&lt;br&gt;
Why: To speed up template code (configurations, helper functions, small React components) and reduce the amount of manual typing.&lt;br&gt;&lt;br&gt;
When: When a quick "sketch" or line completion is needed, rather than deep multi-file logic generation. What: Models with strong contextual understanding and cautious outputs.&lt;br&gt;
Why: Review of large code blocks, suggestions on structure, security, and style.&lt;br&gt;
When: Before refactoring, to find duplications or potential vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cursor.sh" rel="noopener noreferrer"&gt;&lt;strong&gt;Cursor&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;
What: IDE (fork of VS Code) with deep integration of LLM (chat + patch generation + "Rules"). Why: Managed prompts, local diff-patches, quick iterations without manual copying.&lt;br&gt;&lt;br&gt;
When: In main development, when many small structural changes are needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cursor.directory" rel="noopener noreferrer"&gt;&lt;strong&gt;cursor.directory&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: A catalog of ready-made Cursor Rules and prompt templates.&lt;br&gt;&lt;br&gt;
Why: A starter set of rules (style, architecture, protective constraints) instead of manual development.&lt;br&gt;&lt;br&gt;
When: At the stage of setting up "rules of the game" in the project. &lt;a href="https://aistudio.google.com" rel="noopener noreferrer"&gt;&lt;strong&gt;Google AI Studio (Gemini 2.5 Pro)&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: An interface to models with a large context window.&lt;br&gt;&lt;br&gt;
Why: Comprehensive checks - security, performance, duplications, dependencies; summarization before restructuring.&lt;br&gt;&lt;br&gt;
When: When the codebase is already significant, and a "strategic overview" is needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.21st.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;21st.dev&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: A collection of UI patterns with example prompts.&lt;br&gt;&lt;br&gt;
Why: To unify styles and component structures without inventing "from scratch." When: before scaling the frontend or standardizing forms/lists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sourcegraph.com/cody" rel="noopener noreferrer"&gt;&lt;strong&gt;Sourcegraph Cody&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: Intelligent search across large repositories and patch generation.&lt;br&gt;&lt;br&gt;
Why: To find all function usages/dependencies and build a picture of connections before making changes.&lt;br&gt;&lt;br&gt;
When: before deep refactoring or module removal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io" rel="noopener noreferrer"&gt;&lt;strong&gt;CodeSandbox&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: Cloud sandboxes for instant application launch without local installation. Why: To test a library, evaluate an idea, or demonstrate a concept to a colleague.&lt;br&gt;&lt;br&gt;
When: Early validation or isolated demonstration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://storybook.js.org" rel="noopener noreferrer"&gt;&lt;strong&gt;Storybook&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: An isolated environment for viewing and testing UI components.&lt;br&gt;&lt;br&gt;
Why: To ensure the consistency of the design system and visually check states (loading/empty/error).&lt;br&gt;&lt;br&gt;
When: During the extraction of common components or before scaling the front end. &lt;a href="https://playwright.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;Playwright&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: A tool for E2E tests (browser scenarios with high accuracy).&lt;br&gt;&lt;br&gt;
Why: To check key user flows after automatic patches by AI.&lt;br&gt;&lt;br&gt;
When: Before merging important changes or releasing a version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://vitest.dev" rel="noopener noreferrer"&gt;&lt;strong&gt;Vitest&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: A fast unit/integration tester for the Vite ecosystem/modern TS.&lt;br&gt;&lt;br&gt;
Why: To cover pure functions and hooks to stabilize refactoring. When: Right after extracting small utilities or logic into separate modules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://perplexity.ai" rel="noopener noreferrer"&gt;&lt;strong&gt;Perplexity&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: LLM search engines with summarized answers and links.&lt;br&gt;&lt;br&gt;
Why: Instantly learn API nuances, library statuses, and compare approaches.&lt;br&gt;&lt;br&gt;
When: Before choosing a stack or optimization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.langchain.com/langsmith" rel="noopener noreferrer"&gt;&lt;strong&gt;LangSmith&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
What: Tools for assessing the quality of LLM integrations and prompts.&lt;br&gt;&lt;br&gt;
Why: Objectively evaluate if the result improves with your rules or corrections. When: when the number of prompts and models is greater than 1, and quality management is required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://regex101.com" rel="noopener noreferrer"&gt;Regex101&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
What: An online debugger for regular expressions with explanations.&lt;br&gt;&lt;br&gt;
Why: To quickly verify and correctly construct validation/parsing rules.&lt;br&gt;&lt;br&gt;
When: Before implementing complex validation in a form/API.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to effectively combine:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Idea -&amp;gt; bolt.new (prototype) -&amp;gt; transfer to Cursor.&lt;/li&gt;
&lt;li&gt;Structure -&amp;gt; Sourcegraph (dependencies) -&amp;gt; Claude (comments) -&amp;gt; local patches.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  UI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;21st.dev (pattern) + Storybook (review) + Tailwind (styles).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OWASP (checklist) + Gemini (audit) + Playwright (flows).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cleanliness
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;ESLint (rules) + TypeScript (strict types) + Vitest (tests).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gradually introduce resources—not all at once: this reduces cognitive load and increases process stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Speed with a Framework.
&lt;/h2&gt;

&lt;p&gt;Vibe coding is not chaos or an "end in itself." It is a cycle of "vision -&amp;gt; small step -&amp;gt; check -&amp;gt; stabilization." The better the vision and patterns, the more AI becomes a partner rather than a source of surprises and problems. Mistakes will occur, but with this set, you won't get lost—just continue to iterate without pain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thank You for Your Attention
&lt;/h2&gt;

&lt;p&gt;Thank you for reading. I hope the material will be useful to you. If you liked it, please support our project.&lt;/p&gt;

&lt;h3&gt;
  
  
  P.S.: The image in the header is intentionally a bit quirky.
&lt;/h3&gt;

</description>
      <category>vibecoding</category>
      <category>tutorial</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>About context and LLM</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Wed, 05 Nov 2025 08:34:21 +0000</pubDate>
      <link>https://dev.to/petrashka/about-ai-and-context-323n</link>
      <guid>https://dev.to/petrashka/about-ai-and-context-323n</guid>
      <description>&lt;h3&gt;
  
  
  Hello! Folks!
&lt;/h3&gt;

&lt;p&gt;We continue our series of articles about AI (Artificial Intelligence) and how to use it. Today's article will be more theoretical. We will try to figure out what models are, their types, how to use them, and what features they have.&lt;/p&gt;

&lt;p&gt;I hope you find it interesting, so let's go!&lt;/p&gt;

&lt;p&gt;And so, as usual (as it seemed in school), let's understand the concept of AI models.&lt;/p&gt;




&lt;h3&gt;
  
  
  Artificial Intelligence — It's Not Magic, It's Math on Steroids
&lt;/h3&gt;

&lt;p&gt;When you hear "AI model," it might seem like we're talking about something like a robot that thinks like a human. But in reality, it's much simpler (and more complex at the same time). An AI model is a mathematical construct that has been trained on data to later predict, classify, or even generate new texts, images, or codes.&lt;/p&gt;

&lt;p&gt;For example, if you use a translator, get recommendations on Spotify, or filter spam in your mail, there's one or more of these models at work. But it's important to understand: a model is not the algorithm itself, but the result of its application to data.&lt;/p&gt;

&lt;p&gt;The process usually looks like this: you take an algorithm (e.g., gradient boosting, neural network, or SVM), "feed" it data, and get a model. This model can then independently make decisions, such as determining whether there's a cat in a photo or if it's just a fluffy blanket.&lt;/p&gt;

&lt;p&gt;In this article, we'll delve deeper: how different models differ, why foundational models (like GPT, Claude, etc.) are needed, and why you can't make even a simple chatbot today without powerful GPUs.&lt;/p&gt;




&lt;h3&gt;
  
  
  How an AI Model "Remembers" Information: Vectors, Spaces, and Mathematical Magic
&lt;/h3&gt;

&lt;p&gt;Okay, we already know that a model is the result of training on data. But a logical question arises: how does it store all this? Does it not store it like Google Docs?&lt;/p&gt;

&lt;p&gt;No. An AI model remembers nothing "human-like." It doesn't know that a "cat" meows or that "pizza" is tasty. Instead, it envisions the world through vectors—mathematical objects consisting of sets of numbers. Roughly speaking, each word, image, request, or even concept is converted into a digital code—a set of values in a space with hundreds or thousands of dimensions.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🧠 Example:&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;"cat" = [0.12, -0.98, 3.45, …]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a model "thinks" about the word "cat" (usually it creates vectors for entire expressions), it doesn't work with text but with its vector representation. The same goes for the words "dog," "fluffy," "purrs," etc.&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%2Fhiu9w7qiva4fdpcr4qqb.webp" 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%2Fhiu9w7qiva4fdpcr4qqb.webp" alt="vectors" width="800" height="774"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Vector visualization. Top left - vectors of texts about prompting. Bottom right - vectors of texts about the Belarusian language.)&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Interestingly, vectors close in this multidimensional space represent concepts that are close in meaning. For example, if the vector "cat" is near "dog," it means the model has learned to see something common between them (animals, domestic, fluffy).&lt;/p&gt;

&lt;h4&gt;
  
  
  How Are Vectors Compared?
&lt;/h4&gt;

&lt;p&gt;The model measures cosine similarity or Euclidean distance between vectors. Simply put, it calculates how "parallel" or "close" vectors are to each other. The smaller the distance or the larger the cosine, the stronger the connection between concepts.&lt;/p&gt;

&lt;p&gt;For example, in large language models (LLM) like GPT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Minsk" + "Belarus" ≈ "Paris" + "France"&lt;/li&gt;
&lt;li&gt;"Book" + "read" - "paper" ≈ "electronic"&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  And Why Is This Needed?
&lt;/h4&gt;

&lt;p&gt;Everything, from understanding user questions to generating answers, happens through manipulating these vectors. If you write in chat: "suggest a movie like Inception," the model searches for the vector "Inception," finds its neighbors in the space (e.g., "Interstellar," "Tenet"), and based on this, generates a recommendation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not All AI Models Are the Same: How They Are Divided
&lt;/h3&gt;

&lt;p&gt;The variety of models is impressive. You can find models that analyze maps or detect diseases from images.&lt;/p&gt;

&lt;p&gt;Let's try to typify AI models.&lt;/p&gt;

&lt;p&gt;Starting with the fact that models can be divided by the types of data they work with:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;🧠 Language Models (LLM)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Work with text: understand, continue, analyze, generate.&lt;br&gt;
Modern examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Qwen 3 — supports both dense and Mixture-of-Experts architectures.&lt;/li&gt;
&lt;li&gt;Gemma 3 — compact, efficient, works even on 1 GPU.&lt;/li&gt;
&lt;li&gt;DeepSeek-R1 — focuses on reasoning and logic.&lt;/li&gt;
&lt;li&gt;LLaMA 3.3 / 4 — new open-source LLM.&lt;/li&gt;
&lt;/ul&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;👁 Visual Models (Computer Vision / Multimodal Vision)&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Work with images: recognize, analyze, generate.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLaMA 4 Vision — understands images and can answer questions based on visual context.&lt;/li&gt;
&lt;li&gt;Gemma Vision — scalable visual model from Google.&lt;/li&gt;
&lt;li&gt;DALL-E&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;🎤 Audio and Speech Models&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;For speech recognition, voice generation, emotions, etc.&lt;br&gt;
(Currently, there are few open-source competitors to Whisper or VALL-E, but they are expected.)&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;🔀 Multimodal&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Capable of processing multiple types of data: text + image, text + audio, etc.&lt;br&gt;
For example, &lt;code&gt;LLaMA 4&lt;/code&gt; — combines a language model with the ability to analyze images and supports agents (more on them in future articles).&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;🧰 Models Can Also Be Divided by Functionality:&lt;/strong&gt;
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Task-specific models
Finely tuned for a single task (e.g., SQL generation, automatic medical analysis).&lt;/li&gt;
&lt;li&gt;General-purpose models
Perform multiple tasks without specific adaptation.
These include all modern flagship models: Qwen 3, LLaMA 3.3, Gemma 3, DeepSeek-R1.&lt;/li&gt;
&lt;li&gt;Tool-augmented models
Can use tools like calculators, search, databases, even other AIs.
Example: GPT-4 Turbo with tools, LLaMA 4 Agents, DeepSeek Agent (based on R1).&lt;/li&gt;
&lt;/ol&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;🏋️ Models Can Be Divided by Size Based on the Number of Parameters They Support &lt;code&gt;(B - Billions)&lt;/code&gt;:&lt;/strong&gt;
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;Tiny / Small (0.6B – 4B parameters) — works on local devices.&lt;/li&gt;
&lt;li&gt;Medium (7B – 14B) — requires GPU, works stably.&lt;/li&gt;
&lt;li&gt;Large (30B – 70B) — for data centers or enthusiasts with clusters.&lt;/li&gt;
&lt;li&gt;Ultra-large (100B – 700B+) — requires special equipment.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Let's Discuss Features of Models You Might Not Know.
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;🧠 A Model Is Not Human. It Remembers Nothing&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;One might think that if a model answers your questions taking into account previous ones, it "remembers" the conversation. But that's an illusion. In reality, a model is a mathematical function that has no memory in the human sense.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Context Is Where All Memory "Lives"&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Every time you send a request to a model, a so-called context is transmitted with it—the text of previous conversations, documents, instructions. It's like giving a person a cheat sheet before asking something. And if the next request doesn't contain the previous text, the model "forgets" everything.&lt;/p&gt;

&lt;p&gt;📌 The model doesn't store any information after responding. Everything it "knows" is what you provided at the current moment.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Why Is This Important?&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Because it means the model cannot remember users, the context of the conversation, or events. The model only remembers the data it was trained on during training or fine-tuning. If it seems like it "remembers," it's not the model's merit but the system around it that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stores context,&lt;/li&gt;
&lt;li&gt;dynamically loads it,&lt;/li&gt;
&lt;li&gt;or uses vector databases or other tools to retrieve needed information.&lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;🧊 The Model Is "Frozen Math"&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;To simplify: a model is a function that converts input (request + context) into output (response). And that's it. There's no internal dynamics that change between calls. (In simpler models, you can notice that the same prompt will yield the same answer)&lt;/p&gt;

&lt;p&gt;It's like a calculator: you enter 2 + 2 and get 4. If you want to get 4 again, you need to enter 2 + 2 again.&lt;/p&gt;

&lt;p&gt;Everything related to "memory," "personal history," "recall," are architectural add-ons. For example, agents with "memory" work like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The entire dialogue is stored externally (in a database, file, or vector system).&lt;/li&gt;
&lt;li&gt;For each new request, the agent retrieves relevant fragments from "memory."&lt;/li&gt;
&lt;li&gt;It adds them to the context and only then passes everything to the model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The model itself doesn't even "know" this text is from memory—for it, it's just another part of the input.&lt;/p&gt;

&lt;h4&gt;
  
  
  🙅‍♂️ Can a Model Learn During a Conversation?
&lt;/h4&gt;

&lt;p&gt;No. A typical AI model (including GPT, Claude, LLaMA) doesn't change itself during operation. For it to "learn" something, retraining or fine-tuning must occur, and that's a separate process that doesn't happen during a chat.&lt;/p&gt;

&lt;p&gt;Even if the model answers incorrectly 100 times, it will continue to do the same until you create a new model or change the context.&lt;/p&gt;

&lt;h5&gt;
  
  
  📏 Context Isn't Infinite: Why a Model Can't "Read Everything"
&lt;/h5&gt;

&lt;p&gt;One of the most common user misconceptions about AI is the illusion that a model can work with "the whole book," "the whole database," or "a lot of documents at once." But that's not true. Models have a strict limit on the context size they can process at one time.&lt;/p&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;What Is Context in a Technical Sense?&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;Context is the entire set of information you provide to the model in one call: your request, instructions, documents, dialogue history, etc. It's not just "text" but a set of tokens—special units to which text is broken down for processing.&lt;/p&gt;

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

&lt;p&gt;The word "cat" is 1 token.&lt;br&gt;
The word "automobile" might contain 2-3 tokens.&lt;br&gt;
The English "The quick brown fox jumps over the lazy dog." is 9 tokens.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;strong&gt;How Many Tokens Can Modern Models "Hold"?&lt;/strong&gt;
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;GPT-3.5 - 4,096 tokens&lt;/li&gt;
&lt;li&gt;GPT-4 - 8,192 - 32,000 tokens&lt;/li&gt;
&lt;li&gt;GPT-4o - up to 128,000 tokens&lt;/li&gt;
&lt;li&gt;Claude 3 - up to 200,000 tokens&lt;/li&gt;
&lt;li&gt;LLaMA 3 - usually - 8k - 32k tokens&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;128,000 tokens&lt;/strong&gt; is about 300 pages of text. Seems like a lot? But it quickly runs out when you add, for example, technical documentation or code.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;🧨 What Happens If You Provide Too Much?&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;The prompt won't fit—the model will refuse to process it or cut off part (usually the beginning) and some data will be lost.&lt;/li&gt;
&lt;li&gt;If you supply overly long texts, important parts may be "pushed" out of visibility.&lt;/li&gt;
&lt;li&gt;Lower accuracy—even if all information fits, the model can "get lost" in volume and miss important parts.&lt;/li&gt;
&lt;/ol&gt;




&lt;h5&gt;
  
  
  &lt;strong&gt;Why Not Just Make "Infinite Context"?&lt;/strong&gt;
&lt;/h5&gt;

&lt;p&gt;The problem is that all tokens are processed together—and the more there are, the:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more memory is required on the GPU (Processors that process data),&lt;/li&gt;
&lt;li&gt;more time computation takes,&lt;/li&gt;
&lt;li&gt;worse the attention (attention) works: the model "spreads out" and doesn't understand what to focus on.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;How to Work with Large Data?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If the text doesn't fit into the context, there are solutions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;🔍 RAG (Retrieval-Augmented Generation) — selecting the most relevant pieces before each request&lt;/li&gt;
&lt;li&gt;📚 Vector search — finding text similar in meaning&lt;/li&gt;
&lt;li&gt;🪓 Splitting — you provide information in parts&lt;/li&gt;
&lt;li&gt;🧠 Agent with memory — uses an external database to "recall" previous material&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  ✨ Let's Summarize…
&lt;/h3&gt;

&lt;p&gt;Phew! If you've read this far—you're almost an expert 😎&lt;br&gt;
Let's briefly go over the main points again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ An AI model isn't magic; it's math that has learned from data&lt;/li&gt;
&lt;li&gt;✅ All a model's "knowledge" is not stored like human memory but in vectors&lt;/li&gt;
&lt;li&gt;✅ The model doesn't remember you—all "memory" lives in context&lt;/li&gt;
&lt;li&gt;✅ There are many different models: by data type, functionality, and size&lt;/li&gt;
&lt;li&gt;✅ Context is limited—and that's not a bug, but a feature you need to work with&lt;/li&gt;
&lt;li&gt;✅ "Teaching a model in conversation"—is still not quite reality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if it seems like AI "understands" or "remembers," remember that you're actually facing a very smart calculator, not a virtual Jan Bayan with amnesia 🙂&lt;/p&gt;




</description>
      <category>ai</category>
      <category>llm</category>
      <category>rag</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Create your first MCP server</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Mon, 03 Nov 2025 09:45:20 +0000</pubDate>
      <link>https://dev.to/petrashka/create-your-first-mcp-server-44kh</link>
      <guid>https://dev.to/petrashka/create-your-first-mcp-server-44kh</guid>
      <description>&lt;h2&gt;
  
  
  Hi there!
&lt;/h2&gt;

&lt;p&gt;I've been meaning to write this article for more than a month now, but there hasn't been time or the right mood. Still, I gathered my thoughts and finally cobbled together something. I hope you find it useful. Take a look at GitHub — there are ready-to-run working examples that you can launch. For a better understanding of what's happening, get acquainted with the structure and code of the  &lt;a href="https://github.com/bel-frontend/RAG/tree/main/lesson8_mcp/mcp_server" rel="noopener noreferrer"&gt;MCP server&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Today we connect Cursor and VS Code to your APIs via MCP.
&lt;/h3&gt;

&lt;p&gt;Sometimes you look at your own useful scripts and think: 'How can you neatly connect them to AI without unnecessary hassle? What do you need for this? From which side should you approach?' Today, in this article, we will try to solve this problem and learn how to create your own MCPs. And you can also check my previous AI articles.&lt;/p&gt;




&lt;h3&gt;
  
  
  MCP in a nutshell
&lt;/h3&gt;

&lt;p&gt;MCP (Model Context Protocol) is a unified 'translator' between your tools and intelligent clients (chat assistants; for example, agents in Cursor). Instead of another fragmented API, you precisely describe what your tool can do and what its inputs/outputs are — then everything works according to the standard. &lt;/p&gt;

&lt;h4&gt;
  
  
  Why is MCP convenient?
&lt;/h4&gt;

&lt;p&gt;The main idea of MCP is that your API can be connected to the model as a separate agent with transparent rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardization. A single language for tools and clients instead of a set of different protocols.&lt;/li&gt;
&lt;li&gt;Governance. Tools connected to the model have explicit schemas, predictable behavior, clear rights.&lt;/li&gt;
&lt;li&gt;Fast integration. Connect API/FS/DB/DevOps processes — and use them from the IDE or the chat.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Where MCP is particularly relevant
&lt;/h4&gt;

&lt;p&gt;MCP is suitable for a range of tasks, most of which relate to development (now primarily editors adapted to work with external tools via MCP). For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DevTools and ChatOps: CI/CD commands, diagnostics, and access to logs.&lt;/li&gt;
&lt;li&gt;Data/BI: aggregated queries, insightful summaries.&lt;/li&gt;
&lt;li&gt;Internal APIs: a single control point for the team.&lt;/li&gt;
&lt;li&gt;RAG/automation: data collection and pre- and post-processing.&lt;/li&gt;
&lt;li&gt;Working with documentation (for example, Confluence) and others. List of proposed MCPs for VS Code: &lt;a href="https://github.com/mcp?utm_source=vscode-website&amp;amp;utm_campaign=mcp-registry-server-launch-2025" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  How to build a simple MCP server with HTTP transport (Bun/Node)
&lt;/h3&gt;

&lt;p&gt;Back to building our server. I have already prepared several examples of tools in the training repository; you can explore them at the link &lt;a href="https://github.com/bel-frontend/RAG/tree/main/lesson8_mcp/mcp_server" rel="noopener noreferrer"&gt;lesson8_mcp/mcp_server&lt;/a&gt; in the &lt;strong&gt;bel_geek&lt;/strong&gt; repository. Code compatible with Bun and Node.js.&lt;/p&gt;

&lt;h4&gt;
  
  
  What we'll build
&lt;/h4&gt;

&lt;p&gt;We'll create a simple server without unnecessary bells and whistles.&lt;br&gt;
This will be a local HTTP server with &lt;code&gt;/healthz&lt;/code&gt; and &lt;code&gt;/mcp&lt;/code&gt;, stateless, with three demo tools (the same set as in the repository) to immediately test MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routes:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /healthz&lt;/code&gt; - health check.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt; - MCP endpoint (&lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stateless mode (no sessions).&lt;/li&gt;
&lt;li&gt;Three tools:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;echo&lt;/code&gt; - returns the transmitted text. - &lt;code&gt;get_proverb_by_topic&lt;/code&gt; — proverbs by topic (&lt;code&gt;topic&lt;/code&gt;, &lt;code&gt;random&lt;/code&gt;, &lt;code&gt;limit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_weather&lt;/code&gt; — local weather from wttr.in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚀 Setting up the server and connecting it to Cursor/VS Code
&lt;/h3&gt;

&lt;p&gt;The theory is done; time to act: clone, install, run — and MCP is up and running.&lt;/p&gt;
&lt;h4&gt;
  
  
  🔑 Prerequisites (what you need before starting)
&lt;/h4&gt;

&lt;p&gt;No surprises here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js ≥ 18 or Bun ≥ 1.x (Bun starts faster — fewer unnecessary moves). - Two packages: @modelcontextprotocol/sdk (the MCP foundation) and zod (to describe input parameters precisely and reliably).&lt;/li&gt;
&lt;li&gt;Docker — only if you want to package everything into a container right away. For local testing, it's not required. &lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  ⚡️ Running an example
&lt;/h4&gt;

&lt;p&gt;No unnecessary philosophy—simply clone the repository and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/bel-frontend/RAG
cd RAG/lesson8_mcp/mcp_server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bun install
bun index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything goes well, the console will display the message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MCP Streamable HTTP Server on http://localhost:3002/mcp
Available endpoints: /healthz, /mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  🎉 Server! It's alive! Let's check its heartbeat:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -s http://localhost:3002/healthz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response should be in the format &lt;code&gt;{ ok: true, timestamp: ... }&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 Architecture in simple terms
&lt;/h3&gt;

&lt;p&gt;How the server works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An MCP server is created — it registers tools (&lt;code&gt;echo&lt;/code&gt;, &lt;code&gt;get_proverb_by_topic&lt;/code&gt;, &lt;code&gt;get_weather&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;An HTTP transport is added — MCP can receive and send requests via &lt;code&gt;/mcp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Routes:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/healthz&lt;/code&gt; — returns a simple JSON object to verify that the server is alive.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt; - the main endpoint through which Cursor or VS Code connects to the tools.&lt;/li&gt;
&lt;li&gt;Context — the headers (&lt;code&gt;apikey&lt;/code&gt;, &lt;code&gt;applicationid&lt;/code&gt;) are stored in storage so that the tools can use them.&lt;/li&gt;
&lt;li&gt;Termination — on shutdown (SIGINT/SIGTERM) the server closes properly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Key Implementation Details
&lt;/h4&gt;

&lt;p&gt;The server architecture consists of three main components:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. MCP Server &amp;amp; Transport&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;mcp&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="s1"&gt;test-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;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="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;StreamableHTTPServerTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;sessionIdGenerator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;  &lt;span class="c1"&gt;// Stateless mode&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;mcp&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;&lt;strong&gt;2. HTTP Routing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two endpoints handle all traffic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/healthz&lt;/code&gt; - health checks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt; - MCP protocol communication (POST for tool calls, GET/DELETE for sessions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. CORS &amp;amp; Error Handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The server includes proper CORS headers and graceful shutdown on SIGINT/SIGTERM signals.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠 Tools — the main magic here
&lt;/h3&gt;

&lt;p&gt;Three simple tools demonstrate MCP capabilities:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Echo Tool&lt;/strong&gt; - Returns input text (useful for testing)&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="nx"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;echo&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Echo&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="s1"&gt;Return the same 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;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;text&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="p"&gt;}&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;text&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;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="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&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;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Proverbs Tool&lt;/strong&gt; - Fetches Belarusian proverbs with filtering&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="nx"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get_proverb_by_topic&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;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;topic&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;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;random&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;boolean&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="na"&gt;limit&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;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;positive&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;max&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="nf"&gt;optional&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;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&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="nx"&gt;data&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PROVERBS_URL&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&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;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;d&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="c1"&gt;// Filter by topic&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;topic&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Random selection with Fisher-Yates shuffle&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;random&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ... shuffle logic&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="s1"&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="nx"&gt;items&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="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;&lt;strong&gt;3. Weather Tool&lt;/strong&gt; - Shows current weather via wttr.in&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="nx"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="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;city&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="p"&gt;}&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;city&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="nx"&gt;weather&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;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://wttr.in/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;city&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?format=3`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&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="s1"&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="nx"&gt;weather&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;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;Zod schemas&lt;/strong&gt; for input validation&lt;/li&gt;
&lt;li&gt;Return format: &lt;code&gt;{ content: [{ type: 'text', text: string }] }&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Handle errors gracefully with try-catch&lt;/li&gt;
&lt;li&gt;Add timeout handling for external APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🖇 Connecting to Cursor and VS Code
&lt;/h3&gt;

&lt;p&gt;And now the most interesting part — integration.&lt;br&gt;
When MCP is running, we can use it through Cursor or GitHub Copilot in VS Code.&lt;/p&gt;
&lt;h4&gt;
  
  
  Cursor:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Start the server (&lt;code&gt;bun index.ts&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Create the file in the project at &lt;code&gt;./.cursor/mcp.json&lt;/code&gt; with the following configuration:
&lt;/li&gt;
&lt;/ol&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;"test-mcp"&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;"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;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:3002/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;"headers"&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;"apiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API_KEY_1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"applicationId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"APPLICATION_ID"&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;Open Settings → Model Context Protocol and make sure that &lt;code&gt;test-mcp&lt;/code&gt; is in the list. In the Cursor chat, type (make sure that the agent is enabled): "Invoke the get_weather tool for Minsk" - and see the response.&lt;/p&gt;
&lt;h4&gt;
  
  
  VS Code (Copilot Chat)
&lt;/h4&gt;

&lt;p&gt;Here it's almost the same, only the file needs to be placed into &lt;code&gt;.vscode/mcp.json&lt;/code&gt;.&lt;br&gt;
After that, in the Copilot Chat toolbar your tool should appear.&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;"servers"&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;"test-mcp"&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;"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;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:3002/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;"headers"&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;"apiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API_KEY_1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"applicationId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"APPLICATION_ID"&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;Pro tip:&lt;/strong&gt; You can configure multiple MCP servers or use environment variables for credentials.&lt;/p&gt;

&lt;h4&gt;
  
  
  🐳 Docker Deployment - Production Ready
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Quick Start:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Would you like to package it right away? Build and run it in Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose build &lt;span class="nt"&gt;--no-cache&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP will be available at &lt;code&gt;http://localhost:3002/mcp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Understanding the Docker Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The repository includes a complete Docker configuration:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;oven/bun:1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package.json bun.lockb ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;bun &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--frozen-lockfile&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3002&lt;/span&gt;

&lt;span class="k"&gt;HEALTHCHECK&lt;/span&gt;&lt;span class="s"&gt; --interval=30s --timeout=3s CMD \&lt;/span&gt;
  curl -f http://localhost:3002/healthz || exit 1

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["bun", "index.ts"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;docker-compose.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;mcp-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mcp-server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3002:3002"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NODE_ENV=production&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Useful Docker Commands:&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="c"&gt;# View logs&lt;/span&gt;
docker compose logs &lt;span class="nt"&gt;-f&lt;/span&gt; mcp-server

&lt;span class="c"&gt;# Restart service&lt;/span&gt;
docker compose restart

&lt;span class="c"&gt;# Stop and remove&lt;/span&gt;
docker compose down

&lt;span class="c"&gt;# Rebuild and restart&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Team-friendly collaboration: everyone uses the same mental model and doesn't waste time on "what works for me—doesn't work for you."&lt;/p&gt;

&lt;h4&gt;
  
  
  🤔 Typical pitfalls and how to bypass them
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CORS&lt;/code&gt;—when connecting from a browser, you must allow headers. We added a basic variant in the code.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Stateless/Stateful&lt;/code&gt; — in the example the server is stateless. If you need sessions, enable &lt;code&gt;sessionIdGenerator&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;API headers—in Node.js they arrive in lowercase (&lt;code&gt;apikey&lt;/code&gt;), not &lt;code&gt;apiKey&lt;/code&gt;. It’s easy to get confused. External services (proverbs and weather) can slow things down. Add timeouts and caching. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ✍️ How to build your own tool
&lt;/h4&gt;

&lt;p&gt;Here is a simple example:&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="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="s1"&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;import&lt;/span&gt; &lt;span class="nx"&gt;type&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="s1"&gt;@modelcontextprotocol/sdk/server/mcp.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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;registerMyTools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mcp&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="nx"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my_tool&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;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my_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;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A simple tool that adds 2+2&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;name&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="p"&gt;},&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;name&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;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="s1"&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;`Hello, &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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ready—now you can add your own 'tricks' to MCP and use them from the IDE.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✍️ Building Custom Tools
&lt;/h4&gt;

&lt;p&gt;Here's a practical example of a database query tool:&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;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="s1"&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pool&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="s1"&gt;pg&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;pool&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;Pool&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="cm"&gt;/* config */&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;registerDatabaseTools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mcp&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="nx"&gt;mcp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;query_users&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;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Search users by name or email&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;searchTerm&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;min&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="na"&gt;limit&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;number&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;limit&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="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="nx"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SELECT id, name, email FROM users WHERE name ILIKE $1 LIMIT $2&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="s2"&gt;`%&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&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;limit&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="s1"&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="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rows&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;r&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;r&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; &amp;lt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;r&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;&amp;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="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;p&gt;&lt;strong&gt;Best Practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always validate inputs with Zod&lt;/li&gt;
&lt;li&gt;Use parameterized queries to prevent SQL injection&lt;/li&gt;
&lt;li&gt;Handle errors gracefully and return useful messages&lt;/li&gt;
&lt;li&gt;Add timeouts for external API calls&lt;/li&gt;
&lt;li&gt;Keep tool descriptions clear and concise&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🎯 Results
&lt;/h3&gt;

&lt;p&gt;We built an MCP server on Bun/Node, added three demo tools, connected it to Cursor and VS Code, ran it in Docker and discussed typical issues.&lt;br&gt;
The main thing is that MCP makes connecting your own tools to smart IDEs simple and standardized.&lt;/p&gt;

&lt;p&gt;The future lies only in your imagination: you can integrate DevOps processes, databases, BI queries, and internal APIs. MCP makes it possible for other team members to simply pick it up and use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next
&lt;/h3&gt;

&lt;p&gt;We built a simple MCP server with HTTP transport, added three practical tools, configured CORS, and demonstrated configurations for Cursor and GitHub Copilot (VS Code), as well as a Docker deployment. &lt;br&gt;
The next steps are to extend the toolset, implement authentication, and add logging and caching.&lt;br&gt;
If needed, stateful sessions and a production deployment. If this resonates with you, create your own tools and share them with the community!&lt;br&gt;
Will create smart and useful things.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Reliable AI workflow with GitHub Copilot: complete guide with examples</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Thu, 30 Oct 2025 07:34:46 +0000</pubDate>
      <link>https://dev.to/petrashka/reliable-ai-workflow-with-github-copilot-complete-guide-with-examples-1bho</link>
      <guid>https://dev.to/petrashka/reliable-ai-workflow-with-github-copilot-complete-guide-with-examples-1bho</guid>
      <description>&lt;p&gt;Greetings! Today, I’m sharing a short guide on how to set up a project to work with GitHub Copilot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reliable AI workflow with GitHub Copilot: complete guide with examples
&lt;/h2&gt;

&lt;p&gt;This guide shows how to build predictable and repeatable AI processes (workflows) in your repository and IDE/CLI using agentic primitives and context engineering. Here you will find the file structure, ready-made templates, security rules, and commands.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Note: the functionality of prompt files and agent mode in IDE/CLI may change - adapt the guide to the specific versions of Copilot and VS Code you use.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1) Overview: what the workflow consists of
&lt;/h2&gt;

&lt;p&gt;The main goal is to break the agent's work into transparent steps and make them controllable. For this there are the following tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom Instructions (&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;) - global project rules (how to build, how to test, code style, PR policies).&lt;/li&gt;
&lt;li&gt;Path-specific Instructions (&lt;code&gt;.github/instructions/*.instructions.md&lt;/code&gt;) - domain rules targeted via &lt;code&gt;applyTo&lt;/code&gt; (glob patterns).&lt;/li&gt;
&lt;li&gt;Chat Modes (&lt;code&gt;.github/agents/*.agent.md&lt;/code&gt;) - specialized chat modes (for example, Plan/Frontend/DBA) with fixed tools and model.&lt;/li&gt;
&lt;li&gt;Prompt Files (&lt;code&gt;.github/prompts/*.prompt.md&lt;/code&gt;) - reusable scenarios/"programs" for typical tasks (reviews, refactoring, generation).&lt;/li&gt;
&lt;li&gt;Context helpers (&lt;code&gt;docs/*.spec.md&lt;/code&gt;, &lt;code&gt;docs/*.context.md&lt;/code&gt;, &lt;code&gt;docs/*.memory.md&lt;/code&gt;) - specifications, references, and project memory for precise context.&lt;/li&gt;
&lt;li&gt;MCP servers (&lt;code&gt;.vscode/mcp.json&lt;/code&gt; or via UI) - tools and external resources the agent can use.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2) Project file structure
&lt;/h2&gt;

&lt;p&gt;The following structure corresponds to the tools described above and helps to compose a full workflow for agents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.github/
  copilot-instructions.md
  instructions/
    backend.instructions.md
    frontend.instructions.md
    actions.instructions.md
  prompts/
    implement-from-spec.prompt.md
    security-review.prompt.md
    refactor-slice.prompt.md
    test-gen.prompt.md
  agents/
    plan.agent.md
    frontend.agent.md
.vscode/
  mcp.json
docs/
  feature.spec.md
  project.context.md
  project.memory.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3) Files and their purpose - technical explanation
&lt;/h2&gt;

&lt;p&gt;Now let's review each tool separately and its role. Below is how it’s arranged under the hood: what these files are, why they exist, how they affect the agent's understanding of the task, and in what order they are merged/overridden. The code examples below match the specification.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File/folder&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;th&gt;Where it applies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Global project rules&lt;/td&gt;
&lt;td&gt;Consistent standards for all responses&lt;/td&gt;
&lt;td&gt;Entire repository&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.github/instructions/*.instructions.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Targeted instructions for specific paths&lt;/td&gt;
&lt;td&gt;Different rules for frontend/backend/CI&lt;/td&gt;
&lt;td&gt;Only for files matching the &lt;code&gt;applyTo&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.github/agents/*.agent.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A set of rules + allowed tools for a chat mode&lt;/td&gt;
&lt;td&gt;Separate work phases (plan/refactor/DBA)&lt;/td&gt;
&lt;td&gt;When that chat mode is selected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.github/prompts/*.prompt.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Task "scenarios" (workflow)&lt;/td&gt;
&lt;td&gt;Re-run typical processes&lt;/td&gt;
&lt;td&gt;When invoked via &lt;code&gt;/name&lt;/code&gt; or CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docs/*.spec.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specifications&lt;/td&gt;
&lt;td&gt;Precise problem statements&lt;/td&gt;
&lt;td&gt;When you @-mention them in dialogue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docs/*.context.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stable references&lt;/td&gt;
&lt;td&gt;Reduce "noise" in chats&lt;/td&gt;
&lt;td&gt;By link/@-mention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docs/*.memory.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Project memory&lt;/td&gt;
&lt;td&gt;Record decisions to avoid repeats&lt;/td&gt;
&lt;td&gt;By link/@-mention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.vscode/mcp.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;MCP servers configuration&lt;/td&gt;
&lt;td&gt;Access to GitHub/other tools&lt;/td&gt;
&lt;td&gt;For this workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Merge order of rules and settings: &lt;strong&gt;Prompt frontmatter → Chat mode → Repo/Path instructions → Defaults&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;And now let's review each tool separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1. Global rules - &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; A Markdown file with short, verifiable rules: how to build, how to test, code style, and PR policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; So that all responses rely on a single set of standards (no duplication in each prompt).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; The file automatically becomes part of the system context for all questions within the repository. No &lt;code&gt;applyTo&lt;/code&gt; (more on that later) - it applies everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimal example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Repository coding standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Build: &lt;span class="sb"&gt;`npm ci &amp;amp;&amp;amp; npm run build`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Tests: &lt;span class="sb"&gt;`npm run test`&lt;/span&gt; (coverage ≥ 80%)
&lt;span class="p"&gt;-&lt;/span&gt; Lint/Typecheck: &lt;span class="sb"&gt;`npm run lint &amp;amp;&amp;amp; npm run typecheck`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Commits: Conventional Commits; keep PRs small and focused
&lt;span class="p"&gt;-&lt;/span&gt; Docs: update &lt;span class="sb"&gt;`CHANGELOG.md`&lt;/span&gt; in every release PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tips.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep points short.&lt;/li&gt;
&lt;li&gt;Avoid generic phrases.&lt;/li&gt;
&lt;li&gt;Include only what can affect the outcome (build/test/lint/type/PR policy).&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  3.2. Path-specific instructions - &lt;code&gt;.github/instructions/*.instructions.md&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Modular rules with YAML frontmatter &lt;code&gt;applyTo&lt;/code&gt; - glob patterns of files for which they are included.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; To differentiate standards for different areas (frontend/backend/CI). Allows controlling context based on the type of task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; When processing a task, Copilot finds all &lt;code&gt;*.instructions.md&lt;/code&gt; whose &lt;code&gt;applyTo&lt;/code&gt; matches the current context (files you are discussing/editing). Matching rules are &lt;strong&gt;added&lt;/strong&gt; to the global ones.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;applyTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apps/web/**/*.{ts,tsx},packages/ui/**/*.{ts,tsx}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; React: function components and hooks
&lt;span class="p"&gt;-&lt;/span&gt; State: Zustand; data fetching with TanStack Query
&lt;span class="p"&gt;-&lt;/span&gt; Styling: Tailwind CSS; avoid inline styles except dynamic cases
&lt;span class="p"&gt;-&lt;/span&gt; Testing: Vitest + Testing Library; avoid unstable snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Avoid duplicating existing global rules.&lt;/li&gt;
&lt;li&gt;Ensure the glob actually targets the intended paths.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  3.3. Chat modes - &lt;code&gt;.github/agents/*.agent.md&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Config files that set the agent’s operational mode for a dialogue: a short description, the model (if needed) and a list of allowed tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; To separate work phases (planning/frontend/DBA/security) and &lt;strong&gt;restrict tools&lt;/strong&gt; in each phase. This makes outcomes more predictable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File structure:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Plan&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;analyze&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code/specs&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;propose&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;plan;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;read-only&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tools"&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="s"&gt;tools:[ "search/codebase"]&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
In this mode:
&lt;span class="p"&gt;-&lt;/span&gt; Produce a structured plan with risks and unknowns
&lt;span class="p"&gt;-&lt;/span&gt; Do not edit files; output a concise task list instead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;The chat mode applies &lt;strong&gt;to the current chat&lt;/strong&gt; in the IDE.&lt;/li&gt;
&lt;li&gt;If you activate a prompt file, its &lt;strong&gt;frontmatter takes precedence&lt;/strong&gt; over the chat mode (it can change the model and narrow &lt;code&gt;tools&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Effective allowed tools: chat mode tools, limited by prompt tools and CLI &lt;code&gt;--allow&lt;/code&gt;/&lt;code&gt;--deny&lt;/code&gt; flags.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Management and switching:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the IDE (VS Code):&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Open the Copilot Chat panel.&lt;/li&gt;
&lt;li&gt;In the top bar, choose the desired chat mode from the dropdown (the list is built from &lt;code&gt;.github/agents/*.agent.md&lt;/code&gt; + built-in modes).&lt;/li&gt;
&lt;li&gt;The mode applies &lt;strong&gt;only to this thread&lt;/strong&gt;. To change - select another or create a new thread with the desired mode.&lt;/li&gt;
&lt;li&gt;Check the active mode in the header/panel of the conversation; the &lt;em&gt;References&lt;/em&gt; will show the &lt;code&gt;*.agent.md&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;In the CLI: (a bit hacky, better via prompts)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is usually no dedicated CLI flag to switch modes; &lt;strong&gt;encode desired constraints in the prompt file frontmatter&lt;/strong&gt; and/or via &lt;code&gt;--allow-tool/--deny-tool&lt;/code&gt; flags.&lt;/li&gt;
&lt;li&gt;You can instruct in the first line: &lt;em&gt;“Use the i18n chat mode.”&lt;/em&gt; - if the version supports it, the agent may switch; if not, the prompt frontmatter will still enforce tools.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Without switching the mode: run a prompt with the required &lt;code&gt;tools:&lt;/code&gt; in frontmatter - it will limit tools regardless of chat mode.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Diagnostics:&lt;/strong&gt; if the agent uses "extra" tools or does not see needed ones - check: (1) which chat mode is selected; (2) &lt;code&gt;tools&lt;/code&gt; in the prompt frontmatter; (3) CLI &lt;code&gt;--allow/--deny&lt;/code&gt; flags; (4) &lt;em&gt;References&lt;/em&gt; in the response (visible &lt;code&gt;*.agent.md&lt;/code&gt;/&lt;code&gt;*.prompt.md&lt;/code&gt; files).&lt;/p&gt;




&lt;h3&gt;
  
  
  3.4. Prompt files - &lt;code&gt;.github/prompts/*.prompt.md&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Scenario files for repeatable tasks. They consist of YAML frontmatter (config) and a body (instructions/steps/acceptance criteria). They are invoked in chat via &lt;code&gt;/name&lt;/code&gt; or via CLI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; When you need a predictable, automatable process: PR review, test generation, implementing a feature from a spec, etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  Frontmatter structure
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt; - short goal of the scenario.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mode&lt;/code&gt; - &lt;strong&gt;&lt;code&gt;ask&lt;/code&gt;&lt;/strong&gt; (Q&amp;amp;A, no file edits) · &lt;strong&gt;&lt;code&gt;edit&lt;/code&gt;&lt;/strong&gt; (local edits in open files) · &lt;strong&gt;&lt;code&gt;agent&lt;/code&gt;&lt;/strong&gt; (multistep process with tools).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;model&lt;/code&gt; - desired model profile.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tools&lt;/code&gt; - list of allowed tools for the scenario (limits even what the chat mode allowed).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Execution algorithm (sequence)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Where to run:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;In chat&lt;/em&gt;: type &lt;code&gt;/prompt-name&lt;/code&gt; and arguments in the message field.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;In CLI&lt;/em&gt;: call &lt;code&gt;copilot&lt;/code&gt; and pass the &lt;code&gt;/prompt-name …&lt;/code&gt; line (interactive or via heredoc / &lt;code&gt;-p&lt;/code&gt; flag).&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Context collection:&lt;/strong&gt; Copilot builds the execution context in the following order:&lt;br&gt;
&lt;code&gt;repo-instructions&lt;/code&gt; → &lt;code&gt;path-instructions (applyTo)&lt;/code&gt; → &lt;code&gt;chat mode&lt;/code&gt; → &lt;strong&gt;&lt;code&gt;frontmatter prompt&lt;/code&gt;&lt;/strong&gt; (the prompt frontmatter has the highest priority and can narrow tools/change the model).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Parameter parsing (where and how):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;In chat&lt;/em&gt;: parameters go in the same message after the name, for example:
&lt;code&gt;/security-review prNumber=123 target=apps/web&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;In CLI&lt;/em&gt;: parameters go in the same &lt;code&gt;/…&lt;/code&gt; line in stdin or after the &lt;code&gt;-p&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;Inside the prompt file they are available as &lt;code&gt;${input:name}&lt;/code&gt;. If a required parameter is missing, the prompt can ask for it textually in the dialog.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resolving tool permissions:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Effective allowed tools: chat mode tools, limited by prompt tools and CLI &lt;code&gt;--allow&lt;/code&gt;/&lt;code&gt;--deny&lt;/code&gt; flags.&lt;/li&gt;
&lt;li&gt;If a tool is denied, the corresponding step is skipped or requires confirmation/change of policy.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Executing steps from the prompt body:&lt;/strong&gt; the agent strictly follows the Steps order, doing only what is permitted by policies/tools (searching the codebase, generating diffs, running tests, etc.). For potentially risky actions, it requests confirmation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validation gates:&lt;/strong&gt; at the end, the prompt runs checks (build/tests/lint/typecheck, output format checks). If a gate fails - the agent returns a list of issues and proposes next steps (without auto-merging/writing changes).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Where the result appears (what and where you see it):&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Main response&lt;/strong&gt; - in the chat panel (IDE) or in stdout (CLI): tables, lists, textual reports, code blocks with &lt;code&gt;diff&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File changes&lt;/strong&gt; - in your working tree: in IDE you see a diff/suggested patches; in CLI files change locally (if allowed by tools).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Additional artifacts&lt;/strong&gt; - e.g., a PR comment if GitHub tools are allowed and the prompt specifies it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Output format and checks (recommended)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Always specify the &lt;em&gt;output format&lt;/em&gt; (for example, table "issue | file | line | severity | fix").&lt;/li&gt;
&lt;li&gt;Add &lt;em&gt;validation gates&lt;/em&gt;: build/tests/lint/typecheck; require unified-diff for proposed changes; a TODO list for unresolved issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Example of a complete prompt file
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;search/codebase'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Implement&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;feature&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;spec'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Goal: Implement the feature described in @docs/feature.spec.md.

Steps:
1) Read @docs/feature.spec.md and produce a short implementation plan (bullets)
2) List files to add/modify with paths
3) Propose code patches as unified diff; ask before installing new deps
4) Generate minimal tests and run them (report results)

Validation gates:
&lt;span class="p"&gt;-&lt;/span&gt; Build, tests, lint/typecheck must pass
&lt;span class="p"&gt;-&lt;/span&gt; Output includes the final diff and a TODO list for anything deferred
&lt;span class="p"&gt;-&lt;/span&gt; If any gate fails, return a remediation plan instead of "done"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Anti-patterns
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Watered-down descriptions: keep &lt;code&gt;description&lt;/code&gt; 1–2 lines.&lt;/li&gt;
&lt;li&gt;Missing output format.&lt;/li&gt;
&lt;li&gt;Too many tools: allow only what is needed (&lt;code&gt;tools&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Quick start
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Chat: &lt;code&gt;/implement-from-spec&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;CLI: &lt;code&gt;copilot &amp;lt;&amp;lt;&amp;lt;'/implement-from-spec'&lt;/code&gt; or &lt;code&gt;copilot -p "Run /implement-from-spec"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3.5. Context files - specs/context/memory
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Helper Markdown files (not special types) that you @-mention in dialogue/prompt. Typically stored as documentation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docs/*.spec.md&lt;/code&gt; - precise problem statements (goal, acceptance, edge cases, non-goals).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/*.context.md&lt;/code&gt; - short references (API policies, security, UI styleguide, SLA).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/*.memory.md&lt;/code&gt; - "decision log" with dates and reasons so the agent does not return to old disputes.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Feature: Export report to CSV&lt;/span&gt;
Goal: Users can export the filtered table to CSV.
Acceptance criteria:
&lt;span class="p"&gt;-&lt;/span&gt; "Export CSV" button on /reports
&lt;span class="p"&gt;-&lt;/span&gt; Server generates file ≤ 5s for 10k rows
&lt;span class="p"&gt;-&lt;/span&gt; Column order/headers match UI; locale-independent values
Edge cases: empty values, large numbers, special characters
Non-goals: XLSX, multi-column simultaneous filters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3.6. MCP - &lt;code&gt;.vscode/mcp.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it is:&lt;/strong&gt; Configuration for Model Context Protocol servers (for example, GitHub MCP) which enable tools for the agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; So the agent can read PRs/issues, run tests, interact with DB/browser - within allowed permissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&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;"servers"&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-mcp"&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;"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;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.githubcopilot.com/mcp"&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;Security.&lt;/strong&gt; Connect only trusted servers; use allow/deny tool lists in prompts/chat modes/CLI.&lt;/p&gt;




&lt;h3&gt;
  
  
  3.7. General context merge order and priorities (rules &amp;amp; tools)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instructions&lt;/strong&gt;: copilot-instructions + all &lt;code&gt;*.instructions.md&lt;/code&gt; with &lt;code&gt;applyTo&lt;/code&gt; that match current paths. A specific instruction &lt;strong&gt;is added&lt;/strong&gt; to the common context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chat mode&lt;/strong&gt;: restricts the toolset and (if needed) the model for the session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt frontmatter&lt;/strong&gt;: has the &lt;strong&gt;highest priority&lt;/strong&gt;; can limit tools and override the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context&lt;/strong&gt;: anything you @-mention is guaranteed to be considered by the model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Diagnostics.&lt;/strong&gt; Check the &lt;em&gt;References&lt;/em&gt; section in outputs - it shows which instruction files were considered and which prompt was run.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.8. Example: full i18n cycle with Goman MCP (create/update/prune)
&lt;/h3&gt;

&lt;p&gt;Below is the exact process and templates on how to ensure: (a) when creating UI components localization keys are created/updated in Goman; (b) when removing components - unused entries are detected and (after confirmation) &lt;strong&gt;deleted&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code snippets and frontmatter are in English.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  3.8.1. MCP config - connect Goman
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.vscode/mcp.json&lt;/code&gt;&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;"servers"&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;"goman-mcp"&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;"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;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://mcp.goman.live/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;"headers"&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;"apiKey"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;YOUR_API_KEY&amp;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;"applicationid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;YOUR_APPLICATION_ID&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;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;h4&gt;
  
  
  3.8.2. Repo/Path rules - enforce i18n by default
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/instructions/frontend.instructions.md&lt;/code&gt; (addition)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;applyTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apps/web/**/*.{ts,tsx}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; All user-facing strings &lt;span class="gs"&gt;**must**&lt;/span&gt; use i18n keys (no hardcoded text in JSX/TSX)
&lt;span class="p"&gt;-&lt;/span&gt; Key naming: &lt;span class="sb"&gt;`&amp;lt;ui_component_area&amp;gt;.&amp;lt;name&amp;gt;`&lt;/span&gt; (e.g., &lt;span class="sb"&gt;`ui_button_primary.label`&lt;/span&gt;)
&lt;span class="p"&gt;-&lt;/span&gt; When creating components, run &lt;span class="sb"&gt;`/i18n-component-scaffold`&lt;/span&gt; and commit both code and created keys
&lt;span class="p"&gt;-&lt;/span&gt; When deleting components, run &lt;span class="sb"&gt;`/i18n-prune`&lt;/span&gt; and confirm removal of unused keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.8.3. Chat mode - limited i18n tools
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/agents/i18n.agent.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;i18n&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;manage&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;localization&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;keys&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;via&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Goman&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;MCP;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;enforce&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;no&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;hardcoded&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;strings"&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;files"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;goman-mcp:*"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
In this mode, prefer:
&lt;span class="p"&gt;-&lt;/span&gt; Creating/updating keys in Goman before writing code
&lt;span class="p"&gt;-&lt;/span&gt; Checking for existing keys and reusing them
&lt;span class="p"&gt;-&lt;/span&gt; Producing a table of changes (created/updated/skipped)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.8.4. Prompt - scaffold component + keys in Goman
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/i18n-component-scaffold.prompt.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;files'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;goman-mcp:*'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Scaffold&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;React&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;component&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;i18n&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;keys&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;synced&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Goman'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Inputs: componentName, namespace (e.g., &lt;span class="sb"&gt;`ui.button`&lt;/span&gt;), path (e.g., &lt;span class="sb"&gt;`apps/web/src/components`&lt;/span&gt;)

Goal: Create a React component and ensure all user-visible strings use i18n keys stored in Goman.

Steps:
1) Plan the component structure and list all user-visible strings
2) For each string, propose a key under &lt;span class="sb"&gt;`${namespace}`&lt;/span&gt;; reuse if it exists
3) Using Goman MCP, create/update translations for languages: en, be, ru (values may be placeholders)
4) Generate the component using &lt;span class="sb"&gt;`t('&amp;lt;key&amp;gt;')`&lt;/span&gt; and export it; add a basic test
5) Output a Markdown table: key | en | be | ru | action(created/updated/reused)

Validation gates:
&lt;span class="p"&gt;-&lt;/span&gt; No hardcoded literals in the produced .tsx
&lt;span class="p"&gt;-&lt;/span&gt; Confirm Goman actions succeeded (report tool responses)
&lt;span class="p"&gt;-&lt;/span&gt; Tests and typecheck pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example component code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&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;t&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="s1"&gt;@/i18n&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="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PrimaryButton&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ui.button.primary.aria&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ui.button.primary.label&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;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;
  
  
  3.8.5. Prompt - prune unused keys when removing components
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/i18n-prune.prompt.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;files'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;goman-mcp:*'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Find&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;prune&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;unused&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;localization&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;keys&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;in&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Goman&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;after&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deletions'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Inputs: pathOrDiff (e.g., a deleted component path or a PR number)

Goal: Detect keys that are no longer referenced in the codebase and remove them from Goman after confirmation.

Steps:
1) Compute the set of removed/renamed UI elements (scan git diff or provided paths)
2) Infer candidate keys by namespace (e.g., &lt;span class="sb"&gt;`ui.&amp;lt;component&amp;gt;.*`&lt;/span&gt;) and check code references
3) For keys with &lt;span class="gs"&gt;**zero**&lt;/span&gt; references, ask for confirmation and delete them via Goman MCP
4) Produce a Markdown table: key | status(kept/deleted) | reason | notes

Validation gates:
&lt;span class="p"&gt;-&lt;/span&gt; Never delete keys that still have references
&lt;span class="p"&gt;-&lt;/span&gt; Require explicit confirmation before deletion
&lt;span class="p"&gt;-&lt;/span&gt; Provide a rollback list of deleted keys
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.8.6. Prompt - sync and check missing translations (optional)
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/i18n-sync.prompt.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;files'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;goman-mcp:*'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Sync&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;new/changed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;i18n&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;keys&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;missing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;translations'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Goal: Compare code references vs Goman and fill gaps.

Steps:
1) Scan code for &lt;span class="sb"&gt;`t('...')`&lt;/span&gt; keys under provided namespaces
2) For missing keys in Goman - create them (placeholder text ok)
3) For missing languages - create placeholders and report coverage
4) Output coverage table: key | en | be | de | missing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4) How to use this (IDE and CLI)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1. In VS Code / other IDE
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Copilot Chat - choose Agent/Edit/Ask in the dropdown.&lt;/li&gt;
&lt;li&gt;For prompt files just type &lt;code&gt;/file-name&lt;/code&gt; without extension (e.g. &lt;code&gt;/security-review&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Add context using &lt;code&gt;@&lt;/code&gt;-mentions of files and directories.&lt;/li&gt;
&lt;li&gt;Switch chat mode (Plan/Frontend/DBA) when the task changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.2. In Copilot CLI (terminal)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Example install: &lt;code&gt;npm install -g @github/copilot&lt;/code&gt; → run &lt;code&gt;copilot&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Interactively: “Run &lt;code&gt;/implement-from-spec&lt;/code&gt; on &lt;a class="mentioned-user" href="https://dev.to/docs"&gt;@docs&lt;/a&gt;/feature.spec.md”.&lt;/li&gt;
&lt;li&gt;Programmatically/in CI: &lt;code&gt;copilot -p "Implement feature from @docs/feature.spec.md" --deny-tool shell("rm*")&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add/restrict tools with flags: &lt;code&gt;--allow-all-tools&lt;/code&gt;, &lt;code&gt;--allow-tool&lt;/code&gt;, &lt;code&gt;--deny-tool&lt;/code&gt; (global or by pattern, e.g. &lt;code&gt;shell(npm run test:*)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.3. Cookbook commands for CLI (chat modes and prompts)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Below are ready recipes. All commands should run from the repository root and respect your deny/allow lists.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;A. Run a prompt file in an interactive session&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;copilot
&lt;span class="c"&gt;# inside the session (enter the line as-is)&lt;/span&gt;
/security-review &lt;span class="nv"&gt;prNumber&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;B. Run a prompt file non-interactively (heredoc)&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;copilot &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/security-review prNumber=123
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;C. Pass prompt file parameters&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;copilot &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/implement-from-spec path=@docs/feature.spec.md target=apps/web
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Inside the prompt you can read values as &lt;code&gt;${input:target}&lt;/code&gt; and &lt;code&gt;${input:path}&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;D. Run a prompt with safe tool permissions&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;copilot &lt;span class="nt"&gt;--allow-tool&lt;/span&gt; &lt;span class="s2"&gt;"shell(npm run test:*)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--deny-tool&lt;/span&gt;  &lt;span class="s2"&gt;"shell(rm*)"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/security-review prNumber=123
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;E. Use a chat mode (specialized mode) in the CLI&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;copilot
&lt;span class="c"&gt;# inside the session - ask to switch to the required mode and run the prompt&lt;/span&gt;
Use the i18n chat mode.
/i18n-component-scaffold &lt;span class="nv"&gt;componentName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;PrimaryButton &lt;span class="nv"&gt;namespace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ui.button &lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;apps/web/src/components
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If your client supports selecting the mode via a menu - choose &lt;strong&gt;i18n&lt;/strong&gt; before running the prompt. If not - specify constraints in the prompt frontmatter (&lt;code&gt;tools&lt;/code&gt; and rules in the prompt body).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;F. Send file links/diffs as context&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;copilot &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
Please review these changes:
@apps/web/src/components/PrimaryButton.tsx
@docs/feature.spec.md
/security-review prNumber=123
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;G. Change the model for a specific run&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We recommend specifying the model in the prompt frontmatter. If supported, you can also pass a model flag at runtime:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot &lt;span class="nt"&gt;--model&lt;/span&gt; GPT-4o &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/implement-from-spec
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;H. i18n cycle with Goman MCP (CHAT)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run sequentially in a chat thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/i18n-component-scaffold componentName=PrimaryButton namespace=ui.button path=apps/web/src/components
/i18n-prune pathOrDiff=@last-diff
/i18n-sync namespace=ui.button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resulting tables/reports in the chat panel;&lt;/li&gt;
&lt;li&gt;code changes in your working tree (IDE shows diffs);&lt;/li&gt;
&lt;li&gt;no CLI commands for Goman MCP are required here.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5) Context engineering: how not to "dump" excess context
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Split sessions by phases: Plan → Implementation → Review/Tests. Each phase has its own Chat Mode.&lt;/li&gt;
&lt;li&gt;Attach only necessary instructions: use path-specific &lt;code&gt;*.instructions.md&lt;/code&gt; instead of dumping everything.&lt;/li&gt;
&lt;li&gt;Project memory: record short ADRs in &lt;code&gt;project.memory.md&lt;/code&gt; - this reduces agent "forgetting" between tasks.&lt;/li&gt;
&lt;li&gt;Context helpers: keep frequent references (API/security/UI) in &lt;code&gt;*.context.md&lt;/code&gt; and link to them from prompt files.&lt;/li&gt;
&lt;li&gt;Focus on the task: in prompt files always state the goal, steps and output format (table, diff, checklist).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  6) Security and tool management
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Require explicit confirmation before running commands/tools. In CI use &lt;code&gt;--deny-tool&lt;/code&gt; by default and add local allow lists.&lt;/li&gt;
&lt;li&gt;Permission patterns: allow only what is necessary (&lt;code&gt;shell(npm run test:*)&lt;/code&gt;, &lt;code&gt;playwright:*&lt;/code&gt;), deny dangerous patterns (&lt;code&gt;shell(rm*)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Secrets: never put keys in prompts or instructions; use GitHub Environments or local secret managers and &lt;code&gt;.env&lt;/code&gt; with .gitignore.&lt;/li&gt;
&lt;li&gt;Any MCP - only from trusted origins; review the code/config before enabling.&lt;/li&gt;
&lt;li&gt;Patch checks: require unified-diff and explanations in prompt files - this makes review easier.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7) CI/CD recipe (optional example)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ensure "everything builds":&lt;/strong&gt; run Copilot CLI in a dry/safe mode to produce a comment for the PR.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/ai-review.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Review (Copilot CLI)&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ai_review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Copilot CLI&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install -g @github/copilot&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run security review prompt (no dangerous tools)&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;PR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.number }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;copilot -p "Run /security-review with prNumber=${PR}" \&lt;/span&gt;
            &lt;span class="s"&gt;--deny-tool shell("rm*") --deny-tool shell("curl*") \&lt;/span&gt;
            &lt;span class="s"&gt;--allow-tool shell("npm run test:*") \&lt;/span&gt;
            &lt;span class="s"&gt;--allow-tool "github:*" \&lt;/span&gt;
            &lt;span class="s"&gt;&amp;gt; ai-review.txt || true&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Comment PR with results&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;gh pr comment ${{ github.event.pull_request.number }} --body-file ai-review.txt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tip: keep tight deny/allow lists; do not give the agent "full freedom" in CI.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  8) Small scenarios and tips that might be useful
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;From idea to PR: &lt;code&gt;/plan&lt;/code&gt; - discuss the plan - &lt;code&gt;/implement-from-spec&lt;/code&gt; → local tests - PR - &lt;code&gt;/security-review&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Maintenance: &lt;code&gt;/refactor-slice&lt;/code&gt; for local improvements without behavior changes.&lt;/li&gt;
&lt;li&gt;Tests: &lt;code&gt;/test-gen&lt;/code&gt; for new modules + manual additions for edge cases.&lt;/li&gt;
&lt;li&gt;Gradual rollout: start with 1–2 prompt files and one chat mode; expand later.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9) Quality checks (validation gates)
&lt;/h2&gt;

&lt;p&gt;In each prompt file, fix "what counts as done":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Output format&lt;/strong&gt;: risk table, unified-diff, checklist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated checks&lt;/strong&gt;: build, unit/integration tests, lint/typecheck.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual check&lt;/strong&gt;: "OK to merge?" with rationale and residual risks.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  10) Anti-patterns and hacks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Anti-pattern: one huge instructions.md. Prefer multiple &lt;code&gt;*.instructions.md&lt;/code&gt; with &lt;code&gt;applyTo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Anti-pattern: generic words instead of rules. Prefer concrete commands/steps.&lt;/li&gt;
&lt;li&gt;Anti-pattern: running dangerous shell commands without a gate. Use deny/allow and manual confirmation.&lt;/li&gt;
&lt;li&gt;Anti-pattern: forgetting specs/memory. Maintain &lt;code&gt;feature.spec.md&lt;/code&gt; and &lt;code&gt;project.memory.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Anti-pattern: mixing tasks in one session. Create a Chat Mode per phase.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  11) Implementation checklist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt; (at least 5–8 bullets about build/tests/style).&lt;/li&gt;
&lt;li&gt;Create 1–2 &lt;code&gt;*.instructions.md&lt;/code&gt; with &lt;code&gt;applyTo&lt;/code&gt; (frontend/backend or workflows).&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;plan.chatmode.md&lt;/code&gt; and one prompt (for example, &lt;code&gt;implement-from-spec.prompt.md&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Create &lt;code&gt;docs/feature.spec.md&lt;/code&gt; and &lt;code&gt;docs/project.memory.md&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Include MCP (GitHub MCP at minimum) via &lt;code&gt;.vscode/mcp.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run the workflow in VS Code: &lt;code&gt;/implement-from-spec&lt;/code&gt; - verify - PR.&lt;/li&gt;
&lt;li&gt;(Optional) Add a simple AI review in CI via Copilot CLI with strict deny/allow lists.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  12) Questions and answers (FAQ)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; How to ensure Copilot "sees" my instructions?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Check the response's summary/References; also keep rules short and concrete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Can I pass parameters dynamically into prompt files?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Yes, typically via placeholder variables (like &lt;code&gt;${prNumber}&lt;/code&gt;) or simply via the text query when running &lt;code&gt;/prompt&lt;/code&gt; in chat.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Where to store secrets for MCP?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; In GitHub Environments or local secret managers; not in &lt;code&gt;.prompt.md&lt;/code&gt;/&lt;code&gt;.instructions.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q:&lt;/strong&gt; Which to choose: Chat Mode vs Prompt File?&lt;br&gt;
&lt;strong&gt;A:&lt;/strong&gt; Chat Mode defines the "frame" (model/tools/role). Prompt File is a "scenario" within that frame.&lt;/p&gt;


&lt;h2&gt;
  
  
  13) Next steps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add a second prompt for your most frequent manual process.&lt;/li&gt;
&lt;li&gt;Make &lt;code&gt;project.memory.md&lt;/code&gt; mandatory after all architecture decisions.&lt;/li&gt;
&lt;li&gt;Gradually move collective knowledge into &lt;code&gt;*.context.md&lt;/code&gt; and reference it from prompt files.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  Appendix A - Quickstart templates
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;All keys, paths, and flags match the docs (Oct 28, 2025).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/copilot-instructions.md&lt;/code&gt; - repository-wide rules&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Repository coding standards&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Build: &lt;span class="sb"&gt;`npm ci &amp;amp;&amp;amp; npm run build`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Tests: &lt;span class="sb"&gt;`npm run test`&lt;/span&gt; (coverage ≥ 80%)
&lt;span class="p"&gt;-&lt;/span&gt; Lint/Typecheck: &lt;span class="sb"&gt;`npm run lint &amp;amp;&amp;amp; npm run typecheck`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Commits: Conventional Commits; keep PRs small and focused
&lt;span class="p"&gt;-&lt;/span&gt; Docs: update &lt;span class="sb"&gt;`CHANGELOG.md`&lt;/span&gt; in every release PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/instructions/frontend.instructions.md&lt;/code&gt; - path-specific rules&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;applyTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;apps/web/**/*.{ts,tsx},packages/ui/**/*.{ts,tsx}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; React: function components and hooks
&lt;span class="p"&gt;-&lt;/span&gt; State: Zustand; data fetching with TanStack Query
&lt;span class="p"&gt;-&lt;/span&gt; Styling: Tailwind CSS; avoid inline styles except dynamic cases
&lt;span class="p"&gt;-&lt;/span&gt; Testing: Vitest + Testing Library; avoid unstable snapshots
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/instructions/backend.instructions.md&lt;/code&gt; - path-specific rules&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;applyTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;services/api/**/*.{ts,js},packages/server/**/*.{ts,js}"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; HTTP: Fastify; version APIs under &lt;span class="sb"&gt;`/v{N}`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; DB access: Prisma; migrations via &lt;span class="sb"&gt;`prisma migrate`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Security: schema validation (Zod), rate limits, audit logs
&lt;span class="p"&gt;-&lt;/span&gt; Testing: integration tests via &lt;span class="sb"&gt;`vitest --config vitest.integration.ts`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/instructions/actions.instructions.md&lt;/code&gt; - GitHub Actions&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;applyTo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.github/workflows/**/*.yml"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Keep jobs small; reuse via composite actions
&lt;span class="p"&gt;-&lt;/span&gt; Cache: &lt;span class="sb"&gt;`actions/setup-node`&lt;/span&gt; + built-in cache for npm/pnpm
&lt;span class="p"&gt;-&lt;/span&gt; Secrets: only through GitHub Environments; never hardcode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/agents/plan.agent.md&lt;/code&gt; - custom chat mode&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Plan&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;analyze&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code/specs&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;propose&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;plan;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;read-only&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tools"&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;search/codebase"&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
In this mode:
&lt;span class="p"&gt;-&lt;/span&gt; Produce a structured plan with risks and unknowns
&lt;span class="p"&gt;-&lt;/span&gt; Do not edit files; output a concise task list instead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/security-review.prompt.md&lt;/code&gt; - prompt file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;search/codebase'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Perform&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;security&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;review&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;pull&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;request'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Goal: Review PR ${input:prNumber} for common security issues.

Checklist:
&lt;span class="p"&gt;-&lt;/span&gt; Authentication/authorization coverage
&lt;span class="p"&gt;-&lt;/span&gt; Input validation and output encoding (XSS/SQLi)
&lt;span class="p"&gt;-&lt;/span&gt; Secret management and configuration
&lt;span class="p"&gt;-&lt;/span&gt; Dependency versions and known CVEs

Output:
&lt;span class="p"&gt;-&lt;/span&gt; A Markdown table: issue | file | line | severity | fix
&lt;span class="p"&gt;-&lt;/span&gt; If trivial, include a unified diff suggestion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/implement-from-spec.prompt.md&lt;/code&gt; - prompt file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;search/codebase'&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Implement&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;feature&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;from&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;spec'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Your task is to implement the feature described in @docs/feature.spec.md.

Steps:
1) Read @docs/feature.spec.md and summarize the plan
2) List files to add or modify
3) Propose code changes; ask before installing new dependencies
4) Generate minimal tests and run them

Validation gates:
&lt;span class="p"&gt;-&lt;/span&gt; Build, tests, lint/typecheck must pass
&lt;span class="p"&gt;-&lt;/span&gt; Provide a TODO list for anything deferred
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/refactor-slice.prompt.md&lt;/code&gt; - prompt file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Refactor&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;specific&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;slice&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;without&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changing&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;behavior'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Goal: Improve readability and reduce side effects in @src/feature/&lt;span class="err"&gt;*&lt;/span&gt; while keeping behavior unchanged.
Criteria: fewer side effects, clearer structure, all tests pass.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.github/prompts/test-gen.prompt.md&lt;/code&gt; - prompt file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;agent'&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;GPT-4o-mini&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Generate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;given&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;file/module'&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
Ask the user to @-mention the target file; generate unit/integration tests and edge cases.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/docs/feature.spec.md&lt;/code&gt; - spec skeleton&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Feature: Export report to CSV&lt;/span&gt;
Goal: Users can export the filtered table to CSV.
Acceptance criteria:
&lt;span class="p"&gt;-&lt;/span&gt; "Export CSV" button on /reports
&lt;span class="p"&gt;-&lt;/span&gt; Server generates file ≤ 5s for 10k rows
&lt;span class="p"&gt;-&lt;/span&gt; Column order/headers match UI; locale-independent values
Edge cases: empty values, large numbers, special characters
Non-goals: XLSX, multi-column simultaneous filters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;/.vscode/mcp.json&lt;/code&gt; - minimal MCP config&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;"servers"&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-mcp"&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;"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;"http"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.githubcopilot.com/mcp"&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;h2&gt;
  
  
  Appendix B - Operational extras (CLI &amp;amp; CI examples)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;These examples complement Appendix A; they cover runtime/automation usage and &lt;strong&gt;do not&lt;/strong&gt; duplicate templates above.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Copilot CLI - safe tool permissions (interactive/CI)
&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;# Start an interactive session in your repo&lt;/span&gt;
copilot

&lt;span class="c"&gt;# Allow/deny specific tools (exact flags per GitHub docs)&lt;/span&gt;
copilot &lt;span class="nt"&gt;--allow-tool&lt;/span&gt; &lt;span class="s2"&gt;"shell(npm run test:*)"&lt;/span&gt; &lt;span class="nt"&gt;--deny-tool&lt;/span&gt; &lt;span class="s2"&gt;"shell(rm*)"&lt;/span&gt;

&lt;span class="c"&gt;# Run a prompt file non-interactively (example)&lt;/span&gt;
copilot &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
/security-review prNumber=123
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GitHub Actions - comment review results on a PR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AI Security Review (Copilot CLI)&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;opened&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;synchronize&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;reopened&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;review&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;read&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;22&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Copilot CLI&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install -g @github/copilot&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run security review prompt&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;PR&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.number }}&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;copilot --allow-tool "shell(npm run test:*)" --deny-tool "shell(rm*)" &amp;lt;&amp;lt;'EOF'&lt;/span&gt;
          &lt;span class="s"&gt;/security-review prNumber=${PR}&lt;/span&gt;
          &lt;span class="s"&gt;EOF&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Post results&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;gh pr comment ${{ github.event.pull_request.number }} --body "Copilot review completed. See artifacts/logs for details."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/copilot/customization/custom-chat-modes" rel="noopener noreferrer"&gt;Custom chat modes in VS Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/copilot/customization/mcp-servers" rel="noopener noreferrer"&gt;Use MCP servers in VS Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.github.com/en/copilot/how-tos/configure-custom-instructions/add-repository-instructions" rel="noopener noreferrer"&gt;Adding repository custom instructions for GitHub Copilot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.blog/ai-and-ml/github-copilot/how-to-build-reliable-ai-workflows-with-agentic-primitives-and-context-engineering/?utm_source=blog-release-oct-2025&amp;amp;utm_campaign=agentic-copilot-cli-launch-2025" rel="noopener noreferrer"&gt;How to build reliable AI workflows with agentic primitives and context engineering&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🙌 PS:
&lt;/h3&gt;

&lt;p&gt;Thank you for reading to the end! If the material was useful, we would be very glad if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💬 Leave a comment or question,&lt;/li&gt;
&lt;li&gt;📨 Suggest an idea for the next article,&lt;/li&gt;
&lt;li&gt;🚀 Or simply share it with friends!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technology becomes more accessible when it is understood. And you have already made the first important step 💪&lt;/p&gt;

&lt;p&gt;See you in the next article! Thank you for your support!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>githubcopilot</category>
      <category>mcp</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Overengineering in code: Programming for the Sake of Programming?</title>
      <dc:creator>Siarhei</dc:creator>
      <pubDate>Fri, 23 Aug 2024 10:49:24 +0000</pubDate>
      <link>https://dev.to/petrashka/overengineering-in-code-programming-for-the-sake-of-programming-4jlo</link>
      <guid>https://dev.to/petrashka/overengineering-in-code-programming-for-the-sake-of-programming-4jlo</guid>
      <description>&lt;p&gt;Recently, a situation in one of my pull requests made me reflect on the rationality of certain approaches in programming. My colleagues suggested removing comments from the code and splitting it into components. This made me think that sometimes code optimization turns into overengineering, which is the unnecessary complexity justified not by practical needs but by the ideals of "proper" code. Let’s delve deeper into this topic.&lt;/p&gt;

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

&lt;p&gt;Let’s consider a simple example of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Spinner --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"animate-spin rounded-full h-32 w-32 border-t-4 border-b-4 border-gray-300"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Text --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-8 text-center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Loading...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code is straightforward: one part handles the spinner, and the other handles the text. The comments make it easy to understand what is happening. However, the suggestions for refactoring were as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove comments.&lt;/li&gt;
&lt;li&gt;Split the code into separate components.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Pros and Cons of Comments in Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arguments "for" Comments:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Simplifies code readability: Comments help quickly understand the purpose of code blocks without delving into implementation details.&lt;/li&gt;
&lt;li&gt;Supports teamwork: In a team with varying levels of knowledge and experience, comments can be a valuable guide for new team members.&lt;/li&gt;
&lt;li&gt;Reduces cognitive load: A quick glance at a comment allows the developer to focus on more important parts of the work without getting distracted by code analysis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Arguments "against" Comments:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Redundancy: Code should be self-documenting, and if it requires comments to be understood, it may indicate that the code is not clear enough on its own.&lt;/li&gt;
&lt;li&gt;Maintaining comments: Over time, comments can become outdated if not maintained along with the code, potentially misleading other developers.&lt;/li&gt;
&lt;li&gt;Reduces readability: If there are too many comments, it can clutter the source file and detract from the overall readability.&lt;/li&gt;
&lt;li&gt;Splitting into Components&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Arguments "for" Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reusability: Components allow code to be reused in other parts of the application, increasing efficiency.&lt;/li&gt;
&lt;li&gt;Separation of concerns: Each component is responsible for a single function, making testing and maintenance easier.&lt;/li&gt;
&lt;li&gt;Better code organization: Composing code from components often results in a cleaner, more modular architecture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Arguments "against" Components:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Complexity: Excessive decomposition can add unnecessary complexity to a project, making navigation and understanding of the system harder.&lt;/li&gt;
&lt;li&gt;Overengineering: Breaking even simple elements into components can turn into "programming for the sake of programming" without clear benefits for the final product.&lt;/li&gt;
&lt;li&gt;Increased number of files: The more components there are, the more files are added to the project, complicating its structure and navigation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;My Opinion&lt;/strong&gt;&lt;br&gt;
Personally, I believe that using comments and keeping the code simple have their advantages, especially when the code is straightforward and easy to understand. In this example, comments serve as markers and help quickly grasp the purpose of code blocks. Splitting such code into separate components might lead to unnecessary complication.&lt;/p&gt;

&lt;p&gt;That said, I acknowledge that each approach has its strengths, and depending on the project context, different practices might be beneficial. It’s essential to find a balance between maintainability and overcomplication.&lt;/p&gt;

&lt;p&gt;Please share your thoughts on this. How do you balance simplicity and structure in your projects?&lt;/p&gt;

</description>
      <category>code</category>
      <category>codestyle</category>
    </item>
  </channel>
</rss>
