Аннотация:
В этой статье мы разберёмся, как развернуть собственный MCP‑сервер на основе FastAPI, подключить его к Cursor‑Agent и дать LLM‑модели возможность динамически вызывать ваши инструменты — например, получать данные мониторинга или генерировать unit‑тесты на лету. Также покажем, как использование BitDive помогает ещё глубже анализировать трассы вызовов и повышать качество тестов.

Почему MCP и Cursor

Современные LLM‑агенты могут обходиться без внешних вызовов — выдавать ответы исключительно на основе prompt’а. Но когда речь идёт о живых данных (трассы вызовов, результаты SQL‑запросов, исходный код из GitLab), нужно динамически обогащать контекст модели и давать ей «функции» для вызова.

  • MCP (Model‑Context Protocol) описывает, как ваши инструменты («tools») сообщаются агенту: JSON‑схемы + HTTP‑эндпоинты + SSE‑канал для discovery.

  • Cursor‑Agent (IDE‑плагин или standalone) может подписаться на ваш MCP‑сервер, получить список функций и автоматически проксировать их вызовы к реальной логике.

Это даёт вам:

  1. Централизацию всех инструментов LLM в одном месте.

  2. Гибкое управление доступом и аудитом всех вызовов.

  3. Возможность декуплирования бизнес‑логики от обогащения prompt’а и post‑processing ответов модели.

Роль BitDive в экосистеме мониторинга

BitDive — это высокопроизводительная платформа мониторинга и трассировки, разработанная командой BitDive . Она сочетает в себе:

  • ByteBuddy‑инструментацию: перехват HTTP, REST, SQL, Kafka и вызовов методов в рантайме.

  • Цепочки вызовов: хранение полного дерева вызовов с параметрами и результатами.

  • Горячие точки производительности: автоматический анализ длительных операций и визуализация в UI.

  • GitLab‑интеграцию: возможность подгружать исходники, находить участки кода по trace_id и строить ссылки в merge request.

Используя BitDive совместно с MCP‑сервером, LLM‑ассистент получает не просто сырые данные, а уже обогащённые контекстом трассы с точки зрения производительности и защищённости, что позволяет генерировать более точные и релевантные unit‑тесты.

Проблематика на примере мониторинга

Предположим, у вас есть система мониторинга, которая:

  • С помощью ByteBuddy и AOP перехватывает REST‑вызовы, SQL‑запросы и цепочки методов.

  • Хранит полные трассы вызовов (trace_id → list<MethodCall>).

  • В BitDive вы уже видите UI с деталями — но хотите подтянуть эти данные внутрь LLM для автоматической генерации тестов и анализа «узких мест».

Задачи:

  1. Получить трассу по trace_id (из BitDive).

  2. Сгенерировать unit‑тест, опираясь на содержимое трассы и метрики.

  3. Сделать быстрый анализ «горячих точек» производительности.

Как это реализовать без громоздкой ручной подстановки данных в prompt?
В этом поможет связка MCP + Cursor + BitDive.

Шаг 1. Реализация MCP‑сервера на FastAPI

from fastapi import FastAPI, Request, Header, HTTPException
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
import os, asyncio

app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"])

API_KEY = os.getenv("API_KEY", "secret-token")

# 1) Discovery: список JSON‑схем инструментов
@app.get("/v1/tools")
async def list_tools(authorization: str = Header(None)):
    if authorization != f"Bearer {API_KEY}":
        raise HTTPException(401, "Unauthorized")
    return [
      {
        "name": "get_trace",
        "description": "Получить трассировку по trace_id из BitDive",
        "parameters": {
          "type": "object",
          "properties": {
            "trace_id": {"type": "string", "description": "ID трассы"}
          },
          "required": ["trace_id"]
        }
      },
      {
        "name": "generate_test",
        "description": "Сгенерировать unit-тест на основе трассы и метрик BitDive",
        "parameters": {
          "type": "object",
          "properties": {
            "trace": {"type": "string", "description": "Сериализованная трасса с метриками"}
          },
          "required": ["trace"]
        }
      }
    ]

# 2) SSE‑канал: Cursor подписывается и ждёт обновлений
@app.get("/v1/events")
async def events(request: Request):
    async def gen():
        yield "event: ready\ndata: {}\n\n"
        while not await request.is_disconnected():
            await asyncio.sleep(1)
    return app.response_class(gen(), media_type="text/event-stream")

# 3) Вызов get_trace
@app.post("/v1/tools/get_trace")
async def get_trace(body: dict, authorization: str = Header(None)):
    if authorization != f"Bearer {API_KEY}":
        raise HTTPException(401, "Unauthorized")
    trace_id = body["trace_id"]
    # интеграция с BitDive API: запрос трассы + метрик
    bitdive_data = fetch_from_bitdive(trace_id)
    return JSONResponse({"trace": bitdive_data})

# 4) Вызов generate_test
@app.post("/v1/tools/generate_test")
async def generate_test(body: dict, authorization: str = Header(None)):
    if authorization != f"Bearer {API_KEY}":
        raise HTTPException(401, "Unauthorized")
    trace = body["trace"]
    # запускаем локальную генерацию или обращаемся в LLM
    test_code = generate_test_from_trace(trace)
    return JSONResponse({"test": test_code})

Запускаем:

export API_KEY=super-secret
pip install fastapi uvicorn
uvicorn mcp_server:app --reload --port 8000

Шаг 2. Настройка Cursor

  1. Settings → MCP → MCP Servers → Add new MCP Server.

  2. Заполняем:

  3. Сохраняем. Cursor подключится к SSE и запросит /v1/tools, включая описания BitDive‑орiented функций.

Шаг 3. Пример диалога с агентом

Пользователь:
Напиши unit‑тест для трассы с callId="abc123".

  1. Cursor→LLM с функциями: get_trace, generate_test

  2. LLM→Cursor (function_call get_trace)

  3. Cursor→MCP /v1/tools/get_trace → BitDive API → возвращает трассу с задержками и SQL

  4. Cursor→LLM (trace) → LLM сама решает вызвать generate_test

  5. Cursor→MCP /v1/tools/generate_test → возвращает Java‑код теста с проверками по данным BitDive

  6. Cursor→LLM→Пользователь: готовый unit‑тест, включающий проверки задержек и SQL‑запросов из BitDive.

Выводы и рекомендации

  • BitDive + MCP дают LLM‑ассистенту контекст не просто вызовов, а обогащённые метриками производительности и безопасности.

  • Автоматизация. LLM‑агент сам решает, когда и какой инструмент вызвать.

  • Гибкость. Новый инструмент — и он сразу доступен модели.

  • Аудит и безопасность. Все вызовы проходят через централизованный прокси с логированием.

  • Расширяемость. Можно добавить инструменты для анализа hot‑spots, поиска кода, тестирования сценариев.

Комментарии (0)