Skip to main content
Glama
CLAUDE.md22.5 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## 🎯 Обзор проекта MCP-сервер для интеграции R2R (Retrieval-Augmented Generation) с Claude Desktop через Model Context Protocol. ### Доступные инструменты (Tools) **Базовые:** - `search` — векторный поиск по базе знаний R2R с логированием и progress tracking - `rag` — полноценный RAG-запрос с генерацией ответа **Расширенные:** - `advanced_search` — поиск с hybrid search (семантический + full-text), настраиваемыми весами и фильтрами - `graph_search` — поиск с интеграцией knowledge graph для улучшенных результатов - `advanced_rag` — RAG с настройками модели, температуры, hybrid search и веб-поиском ### Доступные ресурсы (Resources) - `r2r://config` — текущая конфигурация сервера (URL, API key status) - `r2r://health` — проверка здоровья и доступности R2R сервера ### Ключевые особенности - **Context-aware logging**: Все инструменты используют FastMCP Context для логирования и отслеживания прогресса - **Error handling middleware**: Централизованная обработка ошибок с детальным логированием - **Tool annotations**: Метаданные для клиентов (readOnlyHint, idempotentHint, etc.) - **Progress reporting**: Визуальное отслеживание выполнения длительных операций ### Структура проекта ```text r2r-rag-search-agent/ ├── server.py # Основной MCP сервер (FastMCP) ├── pyproject.toml # Конфигурация проекта и зависимости (uv) ├── uv.lock # Lock-файл зависимостей ├── .python-version # Версия Python (3.12) ├── Makefile # Команды для разработки ├── .env # Переменные окружения (не в git) ├── .env.example # Шаблон для .env ├── .gitignore # Исключения для git ├── CLAUDE.md # Документация для Claude Code └── README.md # Основная документация ``` ### Архитектурные решения **Почему FastMCP вместо низкоуровневого MCP SDK:** - FastMCP упрощает регистрацию инструментов через декораторы - Автоматическая валидация параметров и типизация - Поддержка нескольких транспортов (HTTP, stdio, streamable-http) через единый API - server.py:105 — инициализация FastMCP сервера - server.py:154 — экспорт ASGI приложения для production (`app = mcp.http_app(transport="streamable-http", path="/mcp")`) **Структура форматирования результатов (server.py:22-91):** - `format_search_results_for_llm()` агрегирует 4 типа результатов: - Chunk search (векторный поиск по фрагментам) - Graph search (граф сущностей/отношений) - Web search (поиск в интернете) - Document search (локальные документы с чанками) - Короткие ID через `id_to_shorthand()` для экономии токенов (первые 7 символов) **Error Handling Middleware (server.py:105-133):** - `R2RErrorHandlingMiddleware` перехватывает все ошибки в MCP операциях - Логирует ошибки с контекстом (тип ошибки, метод, детали) - Отслеживает статистику ошибок по типам - Специальная обработка R2R connection errors с понятными сообщениями **Context Integration (server.py:136+):** - Все tools используют `Context` для: - Логирования (`ctx.info()`, `ctx.error()`, `ctx.debug()`) - Progress reporting (`ctx.report_progress(progress, total, message)`) - Request tracking (`ctx.request_id`) - Context автоматически инжектится через type hint `ctx: Context` ## 🛠️ Команды разработки ### Makefile команды (предпочтительный способ) ```bash make install # Установка всех зависимостей (production + dev) через uv make sync # Синхронизация зависимостей из pyproject.toml make dev # Установка только dev зависимостей make lint # Полная проверка (format + typecheck) make fix # Автоисправление ruff проблем make format # Форматирование кода ruff make typecheck # Проверка типов mypy make run # Запуск MCP сервера через uv run make clean # Очистка кэша и виртуального окружения make help # Справка по командам ``` **Важно:** Проект использует `uv` для управления зависимостями и виртуальным окружением. Все команды запускаются через `uv run`. ### Запуск сервера **Локальная разработка:** ```bash # Через Makefile (streamable HTTP на порту 8000) make run # Прямой запуск (streamable HTTP на порту 8000) # Доступен по адресу http://localhost:8000/mcp python server.py ``` **Production деплой (ChatMCP, Uvicorn):** Сервер экспортирует ASGI приложение через `app = mcp.http_app(transport="streamable-http", path="/mcp")` (server.py:154). **Важно:** - Используется Streamable HTTP transport - рекомендуемый для production деплоев - `path="/mcp"` — явно указан endpoint путь, ожидаемый MCP клиентами - `http_app()` вместо `streamable_http_app()` для совместимости с разными версиями FastMCP ```bash # Через uvicorn напрямую uvicorn server:app --host 0.0.0.0 --port 8000 # Production с несколькими workers uvicorn server:app --host 0.0.0.0 --port 8000 --workers 4 ``` **Claude Desktop интеграция (stdio):** Для Claude Desktop используй `mcp install` (не для веб-деплоя): ```bash mcp install server.py -v R2R_BASE_URL=http://localhost:7272 ``` ### Настройка окружения Создай `.env` файл с переменными: ```bash R2R_BASE_URL=http://your-r2r-instance:7272 API_KEY=your_r2r_api_key PYTHONWARNINGS=ignore::DeprecationWarning ``` **Важно:** Не используй кавычки в .env файле для PYTHONWARNINGS - это вызовет ошибку "Invalid -W option". **ВАЖНО:** `.env` содержит чувствительные данные и исключен из git ### Установка зависимостей ```bash # Через Makefile (рекомендуется) - создаст .venv и установит все зависимости make install # Или напрямую через uv uv sync --all-extras # Только production зависимости uv sync # Только dev зависимости uv sync --extra dev ``` **Структура зависимостей (pyproject.toml):** - **Production:** fastmcp==2.13.1 (закреплена версия для production), r2r>=3.6.0 - **Dev:** ruff>=0.8.0, mypy>=1.14.0 **ВАЖНО:** FastMCP использует закреплённую версию (==2.13.1) по рекомендациям из документации FastMCP, т.к. breaking changes могут происходить в minor версиях. uv.lock включён в git для воспроизводимости зависимостей в production окружении. Виртуальное окружение создаётся в `.venv/` и управляется автоматически через `uv`. ### Проверка качества кода ```bash # Полная проверка (форматирование + типы) make lint # Только форматирование make format # Только типы make typecheck # Автоматическое исправление проблем make fix ``` ### Тестирование инструментов После установки в Claude Desktop, проверь доступность: 1. Открой Claude Desktop 2. Проверь Tools → должны появиться 5 инструментов и 2 ресурса 3. Тестовые запросы: - "Search for information about X" - "Use advanced search with hybrid mode for Y" - "Search knowledge graph for connections between A and B" ## 📚 Документация инструментов ### Базовые инструменты #### `search(query: str) -> str` **Описание:** Базовый семантический поиск по R2R knowledge base **Annotations:** readOnlyHint=True, idempotentHint=True, openWorldHint=True **Progress tracking:** 10% → 30% → 80% → 100% ```python # Пример использования result = await search("What is deep learning?") ``` **Возвращает:** Форматированные результаты включая vector, graph, web и document results #### `rag(query: str) -> str` **Описание:** Полноценный RAG-запрос с генерацией ответа **Annotations:** readOnlyHint=False, destructiveHint=False, openWorldHint=True **Progress tracking:** 20% → 40% → 90% → 100% ```python # Пример использования answer = await rag("Explain the concept of neural networks") ``` **Возвращает:** Сгенерированный ответ на основе релевантного контекста ### Расширенные инструменты #### `advanced_search(query, use_hybrid_search=False, semantic_weight=5.0, full_text_weight=1.0, limit=10) -> str` **Описание:** Поиск с hybrid search и настраиваемыми параметрами **Annotations:** readOnlyHint=True, openWorldHint=True **Параметры:** - `use_hybrid_search` (bool): Включить hybrid search (semantic + full-text) - `semantic_weight` (float): Вес для semantic search (default: 5.0) - `full_text_weight` (float): Вес для full-text search (default: 1.0) - `limit` (int): Максимальное количество результатов (default: 10) ```python # Пример с hybrid search result = await advanced_search( query="quantum computing applications", use_hybrid_search=True, semantic_weight=7.0, full_text_weight=3.0, limit=15 ) ``` **Конфигурация hybrid_settings:** - `full_text_limit`: 200 (количество full-text результатов для обработки) - `rrf_k`: 50 (параметр Reciprocal Rank Fusion) #### `graph_search(query, enable_graph=True, kg_search_type="local", use_hybrid_search=False, semantic_weight=5.0, full_text_weight=1.0, limit=20) -> str` **Описание:** Поиск с интеграцией knowledge graph и опциональным hybrid search **Annotations:** readOnlyHint=True, openWorldHint=True **Параметры:** - `enable_graph` (bool): Включить knowledge graph integration - `kg_search_type` (str): Тип graph search ("local" или "global") - `use_hybrid_search` (bool): Включить hybrid search (semantic + full-text) - `semantic_weight` (float): Вес для semantic search (default: 5.0) - `full_text_weight` (float): Вес для full-text search (default: 1.0) - `limit` (int): Максимальное количество результатов (default: 20) ```python # Пример с knowledge graph и hybrid search result = await graph_search( query="relationships between machine learning concepts", enable_graph=True, kg_search_type="local", use_hybrid_search=True, semantic_weight=7.0, limit=25 ) ``` **Особенности:** - Комбинирует knowledge graph с hybrid search для максимальной точности - Возвращает entities, relationships и communities из knowledge graph - Поддерживает все параметры hybrid search из `advanced_search` #### `advanced_rag(query, model="openai/gpt-4o-mini", temperature=0.7, use_hybrid_search=False, include_web_search=False) -> str` **Описание:** RAG с настраиваемой генерацией **Annotations:** readOnlyHint=False, destructiveHint=False, openWorldHint=True **Параметры:** - `model` (str): LLM модель для генерации (default: "openai/gpt-4o-mini") - `temperature` (float): Температура генерации 0.0-1.0 (default: 0.7) - `use_hybrid_search` (bool): Включить hybrid search для retrieval - `include_web_search` (bool): Включить web search results ```python # Пример с Claude и веб-поиском answer = await advanced_rag( query="Latest developments in AI safety", model="anthropic/claude-3-haiku-20240307", temperature=0.5, use_hybrid_search=True, include_web_search=True ) ``` **Доступные модели:** - OpenAI: `openai/gpt-4o-mini`, `openai/gpt-4o`, `openai/gpt-4-turbo` - Anthropic: `anthropic/claude-3-haiku-20240307`, `anthropic/claude-3-sonnet-20240229` - И другие LLM провайдеры, поддерживаемые R2R ### Ресурсы #### `r2r://config` **Описание:** Текущая конфигурация сервера **Возвращает:** ```json { "r2r_base_url": "http://localhost:7272", "api_key_configured": true, "request_id": "req-123...", "server_name": "R2R Retrieval System" } ``` #### `r2r://health` **Описание:** Проверка здоровья R2R сервера **Возвращает (healthy):** ```json { "status": "healthy", "r2r_url": "http://localhost:7272", "timestamp": "req-123...", "api_key_configured": true } ``` **Возвращает (unhealthy):** ```json { "status": "unhealthy", "error": "connection refused", "r2r_url": "http://localhost:7272" } ``` ## 🔧 Интеграция с R2R ### R2RClient настройки - Клиент инициализируется для каждого запроса - Использует переменные окружения из `.env` - Базовый URL: `R2R_BASE_URL` (по умолчанию http://localhost:7272) - API Key аутентификация: `client.set_api_key(API_KEY)` если API_KEY установлен ### Context Integration Все инструменты используют FastMCP Context для: - **Логирования:** `await ctx.info()`, `await ctx.error()`, `await ctx.debug()` - **Progress reporting:** `await ctx.report_progress(progress, total, message)` - **Request tracking:** `ctx.request_id` для отслеживания запросов **Пример из search():** ```python await ctx.info(f"Starting search query: {query}") await ctx.report_progress(progress=30, total=100, message="Executing search") await ctx.info(f"Search completed successfully, returned {len(formatted)} chars") ``` ### Типы поисковых результатов **Vector Search (chunk_search_results):** - Возвращает фрагменты текста с ID и содержимым - Формат: `Source ID [краткий_id]: текст` **Graph Search (graph_search_results):** - Три типа объектов: - Communities (id, name, summary) - Entities (name, description) - Relationships (subject-predicate-object) **Web Search (web_search_results):** - Структура: title, link, snippet - Форматируется как веб-источники **Document Search (document_search_results):** - Документы с метаданными (title, summary) - Вложенные chunks с ID и текстом - Полезно для локального контекста ## ⚠️ Важные нюансы ### Подавление DeprecationWarning server.py:5-7 явно отключает предупреждения перед импортом: ```python os.environ["PYTHONWARNINGS"] = "ignore::DeprecationWarning" warnings.filterwarnings("ignore", category=DeprecationWarning) ``` **Причина:** R2R SDK или зависимости генерируют deprecation warnings, которые засоряют логи MCP ### Обработка ошибок **R2RErrorHandlingMiddleware:** - Централизованная обработка всех ошибок на уровне middleware - Логирование ошибок с полным контекстом (метод, тип ошибки, детали) - Отслеживание статистики ошибок по типам - Специальная обработка R2R connection errors: ```python ConnectionError( f"Failed to connect to R2R server at {R2R_BASE_URL}. " "Please check R2R_BASE_URL and ensure R2R is running." ) ``` **Tool-level error handling:** - Все tools используют `try/except` с Context логированием - Ошибки перебрасываются после логирования для обработки клиентом - Пример: ```python except Exception as e: await ctx.error(f"Search failed: {e!s}") raise ``` ### Типизация и async - Все инструменты MCP объявлены как `async` (server.py:114, 135) - R2RClient методы синхронные, но вызываются внутри async функций - FastMCP обрабатывает это автоматически ## 🔍 Отладка ### Проверка подключения к R2R ```python from r2r import R2RClient client = R2RClient() result = client.retrieval.search(query="test") print(result) ``` ### Логирование MCP FastMCP автоматически логирует вызовы инструментов в stderr Claude Desktop ### Типичные проблемы 1. **`'FastMCP' object has no attribute 'http_app'` или `got an unexpected keyword argument 'path'`** - **Причина:** Несовместимость версий FastMCP между локальной разработкой и production окружением - **Решение:** Используй универсальный метод `app = mcp.http_app(transport="streamable-http", path="/mcp")` - **Проверка:** Убедись, что версия fastmcp==2.13.1 в pyproject.toml 2. **`POST /mcp 400 Bad Request`** при деплое на ChatMCP/Uvicorn - **Причина:** Неправильный путь endpoint'а или сервер не экспортирует ASGI приложение - **Решение:** Убедись, что в server.py есть `app = mcp.http_app(transport="streamable-http", path="/mcp")` на уровне модуля - **Проверка:** В логах должен быть `INFO: Application startup complete` и запросы к `/mcp` должны возвращать 200 3. **`RuntimeError: Type not yet supported: str | None`** при `mcp install` - **Причина:** Старая версия typer (0.9.0) несовместима с текущим MCP CLI - **Решение:** `pip install --upgrade 'mcp[cli]'` (обновит typer до 0.20.0+) 4. **"R2R connection refused"** → проверь `R2R_BASE_URL` в `.env` или переменной окружения 5. **"MCP tool not appearing"** в Claude Desktop → перезапусти Claude Desktop (Cmd+Q, затем открой) 6. **Empty search results** → проверь, что R2R база проиндексирована и доступна 7. **Invalid -W option ignored: invalid action: '"ignore'** - **Причина:** Лишние кавычки в `.env` файле вокруг PYTHONWARNINGS - **Решение:** Используй `PYTHONWARNINGS=ignore::DeprecationWarning` без кавычек ## 📝 Workflow разработки ### Добавление нового инструмента 1. Добавь функцию с декоратором `@mcp.tool()` 2. Укажи docstring с описанием (используется в UI Claude) 3. Добавь типы аргументов и возвращаемого значения 4. Перезапусти MCP сервер ### Модификация форматирования результатов При изменении `format_search_results_for_llm()`: - Сохраняй структуру "Source ID [shorthand]:" - Используй `id_to_shorthand()` для консистентности - Тестируй на всех 4 типах результатов ## ⛔️ Запрещенные практики - **НЕ коммить .env файл** — содержит API ключи - **НЕ хардкодить R2R_BASE_URL** — всегда через переменные окружения - **НЕ использовать синхронный код** в инструментах MCP — только async - **НЕ удалять suppression warnings** без понимания последствий Always use context7 when I need code generation, setup or configuration steps, or library/API documentation. This means you should automatically use the Context7 MCP tools to resolve library id and get library docs without me having to explicitly ask.

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/evgenygurin/r2r-rag-search-agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server