javascript

Что такое MCP-сервер, и зачем он нужен

  • понедельник, 29 декабря 2025 г. в 00:00:06
https://habr.com/ru/articles/981310/

Привет, Хабр! Меня зовут Андрей Слесаренко — frontend‑разработчик с опытом работы более 8 лет. Прошёл путь от джуна до тимлида, работал над разными высоко‑нагруженными проектами. В начале этого года начал активно использовать LLM‑агентов в повседневной работе — и за это время набил немало шишек.

В этой статье хочу поделиться своим опытом, где мои ожидания разошлись с результатом, а также рассказать об основных «шишках», которые я набил при работе с агентами. Поскольку я frontend разработчик, в конце приведены примеры MCP реализаций, которые стоит взять на вооружение.

Для кого эта статья: для разработчиков, которые только начинают использовать AI-ассистентов или хотят разобраться, что такое MCP. Людям, которые их активно используют, - это вряд ли будет интересно, я вас предупредил).

После прочтения этой статьи вы сможете улучшить свой опыт работы с LLM, и получать более точные результаты ответа. Отчасти мое рвение поделиться опытом, связано с тем что многие из бывших или текущих коллег не используют MCP в повседневной работе с LLM. Поэтому статья в первую очередь ориентировано на них

В статье приведены примеры кода на Javascript и VueJS 3 (где-то намеренно упрощены)

1. Введение

Я думаю, все, кто только начинал пользоваться LLM, сталкивались с историей, когда агент вроде решает задачу, которую вы ему дали, но идет не по тому пути, по которому вы бы хотели. Думаю, всем знакомая история, когда разрабатываете фичу в проекте, где есть специально созданные компоненты для кнопок/инпутов (например, AppButton.vue, AppInput.vue), и просите агента сделать следующее:

На странице /contacts нужно создать форму с двумя полями ввода, и кнопкой "Отправить данные". 

После чего, он создает следующий компонент, игнорируя уже созданные в проекте компоненты из ui-kit.

<template>
  <form @submit.prevent="onHandleSubmit">
      <input name="login" type="text" v-model="loginModelRef" placeholder="Введите ваш email"/>
      <input name="password" type="password" v-model="passwordModelRef"/>
      <button type="submit">Отправить данные</button>
  </form> 
</template>

<script setup lang="ts">
const loginModelRef = shallowRef('');
const passwordModelRef = shallowRef('');

const onHandleSubmit = () => {
  // Тут какая-то ваша логика для отправки данных на сервер 
};
</script>
┌─────────────────────────────────────────────────────────────────────────────┐
│                           ❌ БЕЗ КОНТЕКСТА                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Промпт:                           Результат:                               │
│  ┌─────────────────────────┐       ┌─────────────────────────────────────┐  │
│  │ "Создай форму с двумя   │       │ <input type="text" />               │  │
│  │  полями и кнопкой"      │  ───► │ <input type="password" />           │  │
│  └─────────────────────────┘       │ <button>Отправить</button>          │  │
│                                    └─────────────────────────────────────┘  │
│                                    ⚠️ Нативные элементы, не ваш UI-kit      │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│                            ✅ С КОНТЕКСТОМ                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  Промпт + контекст:                Результат:                               │
│  ┌─────────────────────────┐       ┌─────────────────────────────────────┐  │
│  │ "Создай форму..."       │       │ <AppInput v-model="login" />        │  │
│  │ + UI-kit: AppInput,     │  ───► │ <AppInput type="password" />        │  │
│  │   AppButton             │       │ <AppButton>Отправить</AppButton>    │  │
│  └─────────────────────────┘       └─────────────────────────────────────┘  │
│                                    ✅ Используются компоненты проекта       │
└─────────────────────────────────────────────────────────────────────────────┘

 

Проблема следующая: LLM ничего не знает о проекте. Не хватает контекста. Обычно это проблему решают следующим образом:

  1. Добавляют в корень проекта файл AGENTS.md - подавляющее число агентов перед обработкой вашего промпта, считывают этот файл и добавляют его содержимое в свой контекст.

  2. Если вы используете IDE Cursor, то дополнительно добавляют в .cursor/rules/ui_kit.mdc текст, где описано где и какие компоненты находятся в вашем проекте

  3. Вручную указывают в промпте, как именно задачу нужно решить. Промпт выше начинает выглядеть как

 На странице /contacts нужно создать форму с двумя полями ввода, и кнопкой "Отправить данные". Для компонента кнопки нужно использовать @package/ui-kit/AppButton.vue, для инпутов @package/ui-kit/AppInput.vue

┌─────────────────────────────────────────────────────────────────┐
│              Способы дать контекст LLM                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1️⃣  AGENTS.md                  📄 Файл в корне проекта         │
│      └── Агент читает при старте                                │
│                                                                 │
│  2️⃣  .cursor/rules/*.mdc        📁 Правила для Cursor           │
│      └── Описание UI-kit, архитектуры                           │
│                                                                 │
│  3️⃣  Руками в промпте           ✍️  "Используй AppButton..."    │
│      └── Работает, но утомительно                               │
│                                                                 │
│  4️⃣  MCP серверы                🚀 Автоматический контекст      │
│      └── AI сам запрашивает нужное                              │
│                                                                 │
├──────────────���──────────────────────────────────────────────────┤
│  1-3: ✋ ручное обновление   │  4: 🤖 автоматически актуально   │
└─────────────────────────────────────────────────────────────────┘

Примеры выше хорошо работают на небольших проектах, где не так много кода в целом: компонентов, классов, страниц, сторов и так далее. Но что делать, если у вас огромное количество кода, и вам не хочется каждый раз указывать контекст руками в промпте, или вручную поддерживать постоянно обновляющийся контекст приложения. (Который обновляется с каждым влитым PR).

Теперь расскажу вкратце о том, как работает общение с LLM, и объясню почему все решает контекст.

2. Как на самом деле работает общение с LLM

Прежде чем разбираться с MCP, давайте поймём, как вообще работают языковые модели - это важно для понимания, почему они иногда "галлюцинируют" и дают неработающий код.

LLM - это машина предсказаний

Большая языковая модель (LLM) — это, по сути, очень сложный предсказатель. Когда вы пишете промпт, модель не "думает" в привычном смысле. Она вычисляет: какой токен (слово, часть слова, символ) наиболее вероятно должен идти следующим?

Представьте, что вы начали фразу: "Привет, как твои...". Скорее всего, следующим словом будет "дела", верно? LLM делает то же самое — только учитывает миллиарды параметров и обучена на терабайтах текста.

Модель знает только то, на чём обучалась

Вот ключевой момент: LLM ничего не знает о вашем проекте.

Она обучалась на публичных данных — документации, Stack Overflow, GitHub-репозиториях, статьях. Если вы спросите про React или Vue - получите отличный ответ, потому что об этом написаны тысячи статей. Но если спросите: "Как у нас в проекте работает авторизация?" - модель начнёт... выдумывать.

Это не баг, а особенность. Модель не может ответить "не знаю" — она обучена генерировать правдоподобный текст. Отсюда и "галлюцинации": уверенные ответы, которые выглядят правильно, но не имеют отношения к реальности.

Формула хорошего ответа

Качество ответа LLM можно выразить простой формулой:

Качество ответа = Качество контекста + Качество промпта

Контекст - это информация, которую вы даёте модели вместе с вопросом. Чем точнее и релевантнее контекст, тем лучше ответ.

Промпт - это сам вопрос и инструкции. Чем конкретнее вы формулируете задачу, тем меньше пространства для "творчества" модели.

Пример плохого промпта:

«Сделай мне функцию авторизации»

Модель не знает: какой у вас фреймворк? Какой бэкенд? Какие типы данных? Она придумает что-то усреднённое, что скорее всего не подойдёт.

Пример хорошего промпта:

"Напиши функцию авторизации для Vue 3. Бэкенд возвращает JWT токен по endpoint POST /api/auth/login. Тело запроса: { email: string, password: string }. Ответ: { access_token: string, refresh_token: string }. Используй axios для запросов."

Здесь модель получила контекст и выдаст рабочий код.

Аналогия: LLM как гениальный стажёр

Мне нравится думать об LLM как об очень умном стажёре. Он:

  1. Прочитал всю документацию в интернете

  1. Знает синтаксис всех языков программирования

  1. Видел тысячи примеров кода

  1. Готов работать 24/7 без перерывов

Но при этом:

  • Никогда не видел ваш проект

  • Не знает вашу архитектуру и договорённости команды

  • Не понимает контекст бизнес-задачи

  • Будет уверенно нести чушь, если не дать ему нужную информацию

Что вы делаете, будучи лидом проекта, когда даёте задачу джуну? Даёте контекст, даете ссылку на документацию, скидываете ссылку на канал в рабочем мессенджере, где проходили обсуждения. 

Проще говоря - даете контекст. MCP - это как раз способ автоматически выдавать контекст вашему ассистенту, в упорядоченном вами формате, отдавая только то, что нужно. Кстати, вы ещё и экономите токены в контекстном окне, и тратите меньше денег.

                    ❌ Плохой промпт (без контекста)

  ┌─────────────────┐        ┌─────────────┐        ┌─────────────────┐
  │    Промпт       │        │             │        │     Ответ       │
  │                 │        │     LLM     │        │                 │
  │ "Сделай функцию │  ────► │     🤖      │  ────► │ function auth() │
  │  авторизации"   │        │     ???     │        │ { ??? }         │
  │                 │        │             │        │                 │
  └─────────────────┘        └─────────────┘        └─────────────────┘
                                   │
                         Какой фреймворк?
                         Какой endpoint?
                         Какие типы?
                                   │
                                   ▼
                           😵 Угадывает


                    ✅ Хороший промпт (с контекстом)

  ┌─────────────────┐        ┌─────────────┐        ┌─────────────────┐
  │    Промпт       │        │             │        │     Ответ       │
  │                 │        │     LLM     │        │                 │
  │ "Vue 3, axios   │  ────► │     🤖      │  ────► │ Рабочий код с   │
  │  POST /auth     │        │     💡      │        │ правильными     │
  │  JWT токены..." │        │             │        │ типами и API    │
  │                 │        │             │        │                 │
  └─────────────────┘        └─────────────┘        └─────────────────┘
          │                        ▲
          │                        │
          └────────────────────────┘
             Контекст = понимание

3. Контекст — ключ ко всему 

Мы подошли к контексту. Что такое контекст? Контекст в нашем случае - это текст, который понятным для языковой модели языком описывает проект и его составляющие. Это может быть как фраза: "Для запросов используй только window.fetch, и НИКОГДА не используй axios. Или указание, как в примере выше - использовать для кнопок в проекте только компонент AppButton.vue

Тут важно помнить: LLM-модели ограничены в размере контекстного окна (обычно это 128к/200к символов). Это значит, что если мы будем писать следующий промпт:

Прежде чем решить задачу по созданию формы, изучи весь код в папке apps/ensecai и пакете с ui-kit в папке packages/ui-kit

то мы выйдем за пределы контекстного окна прежде, чем получим ответ. Ведь в этих папках может быть много кода, ОЧЕНЬ много кода. Нужно найти способ, отдавать релеватную информацию в нужный момент по запросу от LLM. Ведь если другая ваша задача касается, например создания текстовых элементов, зачем модели что-то знать про компоненты кнопок и инпуты?

Пример плохого промпта:

"Сделай мне функцию авторизации" // нет контекста, LLM решит задачу по данным, которые были заложены в неё в процессе обучения (просто возьмет код из интернета)

Пример хорошего промпта:

"Мы используем JWT токены, бэкенд на FastAPI. Вот endpoint /auth/login, вот типы User и TokenResponse. Создай функцию для авторизации пользователя"

Теперь мы подошли к задаче, как же всё-таки закидывать в контекст только то, что нужно?  


4. Проблема: как автоматически давать правильный контекст?

Мы уже разобрались, что каждый раз вручную указывать контекст просто утомительно. Современные IDE имеют плагины (например copilot), которые могут анализировать ваши файлы в проекте, и учитывать их особенности (props, стили) в контексте, и верно их интерпретировать для решения задачи. Но эти плагины подходят только для файлов, которые находятся в вашем проекте.

Что делать, если контекст лежит где-то в другом месте? Например, у вас есть задача, добавить объект запроса для авторизации в системе. Обычно вы пишите такой промпт:

Добавь класс для запроса на авторизацию через url api/v4/auth/login

Но тут встает другая проблема: как llm понять, какие параметры для запроса она принимает, и какое тело ответа будет в случае успешного / неуспешного ответа?

Решение: Model Context Protocol (MCP)

5. Что такое MCP простыми словами

Model Context Protocol - это протокол общения между AI-ассистентом и внешними источниками данных, разработанный компанией Anthropic. Этот протокол как раз призван решить проблему "жирных" промптов и огромного количества текстовых инструкций для LLM. (Например те же файлы AGENTS.md или .cursor/rules/**

Мне очень нравится аналогия с USB разъемом. USB - это универсальный разьем для разного типа устройств. MCP - это универсальный разъем для источников контекста LLM. Данный протокол поддерживается всеми известными редакторами / IDE. 

Также сторонние сервисы уже реализовали свои MCP серверы для быстрого доступа к контексту в ваших приложениях. Например, существуют такие MCP реализации как:

  1. sentry-mcp - источник данных, который позволит llm агенту получать данные об ошибках пользователя. Пример: вы нашли в Sentry issue с багом от пользователя. Вы можете написать следующим промпт: В Sentry http://sentry.io/issues/12345789 случилась ошибка при заходе на главную страницу. Изучи метаданные браузера и пользователя, составь отчет и предложи решение проблемы

    В этом случае LLM запросит с помощью указанной в сервере tool данные по ошибке (о tools будет ниже), и сможет получить все необходимы данные. Следовательно, вам не нужно руками копировать контекст об ошибке в проект

  2. figma-mcp - позволит вам просто скинуть ссылку на макет в Figma, и llm сможет с помощью нужной tool получить сверстанный html, который потом превратит в подходящий вашему проекту компонент(ы).

  3. Больше mcp-реализаций вы можете найти в интернете, в том числе для git, github, gitlab, jira, confluence и прочее, тысячи их. Больши список готовых реализаций лежит здесь - https://github.com/modelcontextprotocol/servers?tab=readme-ov-file

┌─────────────────────────────────────────────────────────────────────────────────┐
│                                                                                 │
│                              MCP Protocol                                       │
│                           (единый стандарт)                                     │
│                                                                                 │
│   ┌─────────────┐           ┌───────┐           ┌───────────────────────────┐   │
│   │             │           │       │           │                           │   │
│   │    IDE      │           │       │           │  ┌─────┐ ┌─────┐ ┌─────┐  │   │
│   │   Client    │◄─────────►│  MCP  │◄─────────►│  │ Git │ │ API │ │ DB  │  │   │
│   │    🤖       │           │   🔌  │           │  └─────┘ └─────┘ └─────┘  │   │
│   │             │           │       │           │                           │   │
│   └─────────────┘           └───────┘           │  ┌─────┐ ┌─────┐ ┌─────┐  │   │
│                                                 │  │UI-  │ │Know-│ │Your │  │   │
│    Cursor                                       │  │kit  │ │ledge│ │Tool │  │   │
│    Claude Desktop                               │  └─────┘ └─────┘ └─────┘  │   │
│    Zed                                          │                           │   │
│    ...                                          │       MCP Servers         │   │
│                                                 │                           │   │
│                                                 └───────────────────────────┘   │
│                                                                                 │
└─────────────────────────────────────────────────────────────────────────────────┘

Архитектура MCP

Теперь давайте разберёмся, как MCP устроен под капотом. Не переживайте - никакой rocket science, архитектура максимально простая.

Клиент и сервер

MCP работает по классической клиент-серверной модели:

┌─────────────────┐         MCP Protocol         ┌─────────────────┐
│     CLIENT      │ ◄──────────────────────────► │     SERVER      │
│  (IDE/ChatBot)  │                              │   (ваш код)     │
└─────────────────┘                              └─────────────────┘
    Cursor, Claude,                                База знаний,
    Zed, VS Code...                                Swagger, Git...
  1. Client - это ваша IDE или AI-приложение (Cursor, Claude Desktop, Zed). Клиент знает, как общаться по протоколу MCP и запрашивать данные.

  2. Server - это программа, которую пишете вы (или используете готовую). Сервер предоставляет данные: документацию, информацию о компонентах, структуру API - что угодно.

Когда AI-ассистенту нужна информация, он обращается к серверу через протокол MCP, получает ответ и использует его для генерации кода.

Как они общаются: транспорты

MCP поддерживает два способа связи между клиентом и сервером:

stdio (standard input/output) — для локальных серверов. Клиент запускает сервер как обычный процесс и общается с ним через stdin/stdout. Это самый простой вариант - именно его мы будем использовать в примерах.

SSE (Server-Sent Events) — для удалённых серверов. Работает через HTTP, позволяет запустить сервер где угодно и подключаться к нему по сети.

Для начала вам хватит stdio — это буквально "запустил скрипт, и он работает".

Три кита MCP: Tools, Resources, Prompts

MCP предоставляет три типа возможностей:

🔧 Tools - функции для вызова

Tools - это функции, которые AI может вызывать для получения или изменения данных. Самая используемая концепция.

Примеры tools:

  • kb_search("авторизация") - поиск по базе знаний

  • swagger_get_endpoint("/api/users", "POST") - получить информацию об API

  • git_log(limit=5) - посмотреть последние коммиты

Когда вы создаёте MCP-сервер, вы описываете: какие tools доступны, какие у них параметры, что они возвращают. AI сам решает, когда и какой tool вызвать.

📄 Resources — данные для чтения

Resources — это статические данные, которые AI может запросить: файлы, документы, конфигурации. В отличие от tools, resources просто отдают данные без какой-либо логики.

Примеры resources:

  • Список файлов в директории

  • Конфигурация проекта

💬 Prompts — шаблоны промптов

Prompts - это готовые шаблоны запросов с параметрами. Полезно, когда у вас есть типовые сценарии использования.

Пример: шаблон "code_review" с параметром file_path, который подставляет нужный контекст для ревью кода.

На практике: в большинстве случаев вам хватит только Tools. Resources и Prompts — это дополнительные возможности для более сложных сценариев.

Как это работает: пример

Давайте посмотрим на реальный сценарий. Допустим, вы просите AI:

"Напиши функцию для получения списка пользователей из API"

Без MCP:

AI придумает какой-то endpoint /api/users, угадает структуру ответа, напишет код. С вероятностью 80% это не будет работать.

С MCP (Swagger-сервер):

1. Вы: "Напиши функцию для получения списка пользователей из API"

2. AI думает: "Мне нужно узнать структуру API"
   → Вызывает tool: swagger_search("users")

3. MCP-сервер отвечает:
   "Найдено: GET /api/v2/users
    Параметры: page (int), limit (int)
    Ответ: { users: User[], total: int }
    User: { id: string, email: string, name: string }"

4. AI генерирует код с правильным endpoint, параметрами и типами

Что важно понять

  1. AI сам решает, когда вызвать tool. Вы не пишете "сначала вызови swagger_search". AI анализирует задачу и понимает, что ему нужна информация.

  1. Сервер - это просто программа. Никакой магии. Python-скрипт на 100-200 строк, который отвечает на запросы.

  1. Протокол стандартный. Написали сервер один раз - он работает в Cursor, Claude Desktop, Zed и любом другом MCP-совместимом клиенте.

  1. Можно комбинировать несколько серверов. База знаний + Swagger + Git - каждый отвечает за свою область.

9. Пример реализации: MCP сервер для UI-kit

Ссылка на Github: https://github.com/TeodorDre/mcp-ui-kit-server-example

Тезисы:

  • Проблема: AI не знает про ваши компоненты и предлагает писать с нуля

  • Решение: MCP сервер, который "рассказывает" AI про доступные компоненты

  • Возможные tools:

  • ui_list_components — список компонентов

  • ui_get_component — детали компонента (props, slots, примеры)

  • ui_search — поиск по имени/описанию

  • ui_get_usage_examples — примеры использования

Схема данных:

  • Парсинг Vue SFC → извлечение props/emits/slots

  • Или ручная документация в JSON/YAML

Сценарий использования:

Разработчик: "Нужна кнопка с иконкой и loading состоянием"

AI: вызывает ui_search("button icon loading") → находит AppButton → предлагает готовый код с правильными props

10. Какие MCP серверы можно завести для вашего frontend проекта?

Теперь самое интересное - какие серверы реально полезны для frontend-разработки? Вот четыре идеи, которые дадут максимальный эффект.

🎨 UI-kit сервер (мой пример реализации на Node.js на Github выше)

Проблема: AI не знает про ваши компоненты и пишет <button> вместо <AppButton>.

Что делает: Даёт AI информацию о доступных компонентах, их props, slots и примерах использования.

Tools:

  • ui_list_components - список всех компонентов с кратким описанием

  • ui_get_component(name) - детальная информация: props, emits, slots, примеры

  • ui_search(query) - поиск по имени или описанию

Результат:

Вы: "Нужна форма с email и паролем"

AI вызывает: ui_search("input form")
AI получает: AppInput, AppPasswordInput, AppForm, AppButton

AI генерирует код с вашими компонентами ✅

📋 Swagger / OpenAPI сервер (есть open-source решения, например на Github). Но вы можете написать своё.

Проблема: AI придумывает endpoints и структуры ответов.

Что делает: Парсит вашу OpenAPI спецификацию и даёт точную информацию об API.

Tools:

  • swagger_list_endpoints(tag?, method?) - список endpoints с фильтрацией

  • swagger_get_endpoint(path, method) - детали: параметры, body, response

  • swagger_get_schema(name) - структура модели данных

  • swagger_search(query) - поиск по API

  • swagger_generate_request(path, method, format) - генерация примера запроса

Результат:

Вы: "Напиши функцию для получения профиля пользователя"

AI вызывает: swagger_search("user profile")
AI получает: GET /api/v2/users/me → { id, email, name, avatar }

AI генерирует код с правильным endpoint и типами ✅

 Sentry MCP сервер (есть официальная реализация от Sentry)

Проблема: При отладке багов приходится вручную копировать stack trace и контекст из Sentry.

Что делает: Подключается к вашему Sentry-проекту и даёт AI доступ к информации об ошибках: stack trace, breadcrumbs, контекст пользователя, частота.

Tools:

  • sentry_list_issues(status?, level?) - список активных ошибок с фильтрацией

  • sentry_get_issue(id) - детали: stack trace, affected users, частота

  • sentry_get_events(issue_id, limit?) - последние события по ошибке

  • sentry_search(query) - поиск по тексту ошибки

Результат:

Вы: "Почему падает страница профиля?"

AI вызывает: sentry_search("profile")
AI получает: 
  TypeError: Cannot read 'avatar' of undefined
  Stack: ProfilePage.vue:42 → useUserStore.ts:15
  Affected: 12% пользователей
  Browser: Safari 17

AI анализирует и предлагает фикс с учётом реального контекста ✅

🎨 Figma MCP сервер (есть уже официальная реализация от Figma)

Проблема: Дизайнер обновил макет, а вы вручную сверяете цвета, отступы и шрифты.

Что делает: Подключается к Figma API и даёт AI доступ к дизайн-токенам, компонентам и стилям из ваших макетов.

Tools:

  • figma_get_styles(file_id) - цвета, типографика, эффекты из файла

  • figma_get_component(file_id, node_id) - свойства конкретного компонента

  • figma_get_tokens - дизайн-токены (если используете Variables)

  • figma_compare(node_id, css) - сравнить реализацию с макетом

Результат:

Вы: "Сверстай карточку пользователя как в макете"

AI вызывает: figma_get_component(file_id, "UserCard")
AI получает:
  padding: 16px 24px
  border-radius: 12px
  background: var(--surface-secondary)
  shadow: 0 2px 8px rgba(0,0,0,0.08)

AI генерирует CSS, точно соответствующий дизайну ✅

11. Рекомендации

Начинайте работу постепенно: не нужно пытаться сразу на все создать mcp серверы. Обязательно идите итеративно. Подключили интеграцию для Figma - потестируйте ее неделю, поймите что нужно доработать в ваших компонентах - и правьте. И так шаг за шагом.

Теперь кажется действительно важным писать документацию по проекту: например описывать подробно пропсы/эмиты/слоты, что они делают, за что отвечают (можно комментариями в JSDoc или прямо в HTML). В примере выше, как раз описан способ как можно автоматически генерировать документацию из сурсов в вашем проекте. Можно признать, что не все люди любят читать документацию, но агенты - обязательно с ней ознакомятся, и все прочитают.

Кстати, хорошая идея даже организовать локальную базу знаний по истории задач/багов в вашем проекте. Можно описывать все технические решения в markdown файлов, и хранить их в проекте. Ну и как вы уже поняли - написать mcp сервер который уже будет изучать историю вашего проекта. И LLM например при попытке решить какую-то багу, будет искать похожие случаи в этой базе знаний.

Следите за актуальностью базы знаний вашего проекта / документации. Если где-то что-то не описано, то LLM постарается самостоятельно разобраться в исходном коде и решить, как с ним работать. Но будет хуже, если документация будет неактуальна - тогда результат будет некорректен.

Спасибо за ваше время!