Пользовательские MCP-инструменты

Создание пользовательских инструментов запросов к CPG для Claude Code и других MCP-клиентов через определение SQL-запросов в YAML-файле. Не требует изменения кода.

Обзор

Динамический загрузчик читает .codegraph/tools.yaml из корня проекта и регистрирует каждое определение как MCP-инструмент. Это позволяет создавать проектно-специфичные запросы анализа, которые Claude Code (или любой MCP-клиент) может вызвать по имени.

Основные возможности: - Определение пользовательских SQL-запросов как именованных MCP-инструментов - Параметры с типами и значениями по умолчанию - Параметризованные запросы — значения передаются через DuckDB-плейсхолдеры ? (не строковая интерполяция) - Только чтение (только SELECT-запросы) — операции записи и операции множеств отклоняются - Без изменения кода, без перезапуска сервера (инструменты загружаются при старте MCP-сервера)

Быстрый старт

1. Создайте файл инструментов

mkdir -p .codegraph

Создайте .codegraph/tools.yaml:

tools:
  - name: find_large_functions
    description: Найти функции длиннее N строк
    sql: |
      SELECT name, filename, (line_number_end - line_number) as lines
      FROM nodes_method
      WHERE (line_number_end - line_number) > {min_lines}
      ORDER BY lines DESC
      LIMIT {limit}
    parameters:
      - name: min_lines
        type: int
        default: 100
      - name: limit
        type: int
        default: 20

2. Настройте MCP-сервер

Убедитесь, что в config.yaml указано:

mcp:
  enabled: true
  dynamic_tools_path: .codegraph/tools.yaml

3. Запустите MCP-сервер

python -m src.mcp

Инструмент find_large_functions теперь доступен любому MCP-клиенту.

Полный список аргументов CLI:

python -m src.mcp --db data/projects/myproject.duckdb        # stdio (по умолчанию)
python -m src.mcp --transport sse --port 27495                # транспорт SSE
python -m src.mcp --transport http --port 27495               # Streamable HTTP
python -m src.mcp --transport sse --no-auth                   # SSE без аутентификации
python -m src.mcp --verbose                                   # отладочное логирование
Аргумент Описание
--db PATH Путь к базе данных DuckDB CPG
--transport {stdio,sse,http} Протокол транспорта (по умолчанию: из конфигурации или stdio)
--host HOST Адрес привязки для SSE/HTTP (по умолчанию: 0.0.0.0)
--port PORT Порт для SSE/HTTP (по умолчанию: 27495)
--no-auth Отключить аутентификацию для SSE/HTTP транспортов
--verbose, -v Включить отладочное логирование

4. Использование из Claude Code

Добавьте в .claude/mcp.json:

{
  "mcpServers": {
    "codegraph": {
      "command": "python",
      "args": ["-m", "src.mcp", "--db", "data/projects/myproject.duckdb"]
    }
  }
}

Затем спросите Claude: «Найди функции длиннее 200 строк» — он вызовет find_large_functions с min_lines=200.

Формат YAML

tools:
  - name: имя_инструмента        # Обязательно: уникальное имя (snake_case)
    description: Описание          # Обязательно: отображается MCP-клиентам
    sql: |                         # Обязательно: SQL-шаблон (только SELECT)
      SELECT ...
      WHERE column > {param}
      LIMIT {limit}
    parameters:                    # Необязательно: параметры инструмента
      - name: param               # Имя параметра (соответствует {param} в SQL)
        type: int                  # Тип: int, string, float
        default: 10                # Значение по умолчанию

Типы параметров

Тип Валидация Пример
int Преобразование в целое число, ValueError при ошибке 100
float Преобразование в число с плавающей точкой, ValueError при ошибке 3.14
string Проверка на SQL-метасимволы (отклоняет ', ", ;, --, /*, */) "src/"

Нераспознанные типы приводят к строковому приведению с усечением до 1000 символов (без проверки метасимволов).

Подстановка параметров

Параметры используют синтаксис {имя} в SQL-шаблонах. При выполнении каждый плейсхолдер {имя} заменяется на позиционный маркер ?, а очищенные значения передаются кортежем в API параметризованных запросов DuckDB (execute_query(sql, parameters=...)). Это исключает SQL-инъекции по дизайну.

sql: |
  SELECT name, filename
  FROM nodes_method
  WHERE CyclomaticComplexity > {threshold}
    AND filename LIKE {path_pattern}
  LIMIT {limit}
parameters:
  - name: threshold
    type: int
    default: 10
  - name: path_pattern
    type: string
    default: "%"
  - name: limit
    type: int
    default: 20

Примеры инструментов

Поиск невызываемых функций

- name: find_uncalled_functions
  description: Найти функции, которые нигде не вызываются
  sql: |
    SELECT m.name, m.filename, m.line_number
    FROM nodes_method m
    LEFT JOIN edges_call e ON m.id = e.dst
    WHERE e.src IS NULL
    ORDER BY m.filename, m.line_number
    LIMIT {limit}
  parameters:
    - name: limit
      type: int
      default: 50

Поиск сложных методов

- name: find_complex_methods
  description: Найти методы с высокой цикломатической сложностью
  sql: |
    SELECT name, filename, CyclomaticComplexity, FanIn, FanOut
    FROM nodes_method
    WHERE CyclomaticComplexity > {threshold}
    ORDER BY CyclomaticComplexity DESC
    LIMIT {limit}
  parameters:
    - name: threshold
      type: int
      default: 15
    - name: limit
      type: int
      default: 30

Поиск опасных вызовов

- name: find_dangerous_calls
  description: Найти вызовы потенциально опасных функций
  sql: |
    SELECT c.callee_name, c.filename, c.line_number, m.name as caller
    FROM nodes_call c
    JOIN nodes_method m ON c.method_id = m.id
    WHERE c.callee_name IN ('strcpy', 'strcat', 'sprintf', 'gets')
    ORDER BY c.callee_name, c.filename
    LIMIT {limit}
  parameters:
    - name: limit
      type: int
      default: 100

Поиск TODO/FIXME

- name: find_todos
  description: Найти методы с маркерами TODO или FIXME
  sql: |
    SELECT name, filename, line_number
    FROM nodes_method
    WHERE HasTodoFixme = true
    ORDER BY filename, line_number
    LIMIT {limit}
  parameters:
    - name: limit
      type: int
      default: 50

Безопасность

Гарантия только чтения

Разрешены только SELECT-запросы. Загрузчик валидирует SQL в двух точках:

  1. При загрузке — определения с не-SELECT SQL отклоняются
  2. При выполнении — сгенерированный SQL (после подстановки параметров) проверяется повторно

Запрещённые ключевые слова: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, GRANT, REVOKE, UNION, EXCEPT, INTERSECT.

Параметризованные запросы

Пользовательские значения параметров никогда не интерполируются в SQL-строки. Загрузчик заменяет плейсхолдеры {name} на маркеры ? и передаёт значения кортежем в API параметризованного выполнения DuckDB (execute_query(sql, parameters=...)).

Блокировка SQL-метасимволов

Строковые параметры (тип string) проверяются на наличие SQL-метасимволов: ', ", ;, --, /*, */. При обнаружении запрос отклоняется с ошибкой ValueError.

Лимиты размера и количества

Лимит Ключ конфигурации По умолчанию
Размер SQL-запроса security.dynamic_sql_max_length_kb 10 КБ
Количество параметров security.dynamic_sql_max_parameters 10

Лимиты проверяются при выполнении. Превышение вызывает ValueError.

Ограничение строк

Результаты ограничены значением mcp.max_query_rows (по умолчанию: 1000) для предотвращения исчерпания памяти. Если SQL-шаблон не содержит LIMIT, сервер добавляет его автоматически.

Аутентификация

Транспорты SSE и HTTP защищены MCPAuthMiddleware. Клиенты должны предоставить:

  • Заголовок Authorization: Bearer <jwt> — проверяется через verify_token()
  • Заголовок X-API-Key — проверяется через ApiKeyRepository

Отсутствующие или недействительные учётные данные возвращают HTTP 401. Транспорт stdio является локальным и не требует аутентификации.

Используйте --no-auth для отключения аутентификации при разработке:

python -m src.mcp --transport sse --no-auth

Справочник конфигурации

# config.yaml
mcp:
  enabled: true                           # Включить/выключить MCP-сервер
  transport: stdio                        # Транспорт: stdio | sse | http
  host: 0.0.0.0                           # Адрес привязки для SSE/HTTP
  http_port: 27495                        # Порт для SSE/HTTP
  max_query_rows: 1000                    # Максимум строк на результат запроса
  dynamic_tools_path: .codegraph/tools.yaml  # Путь к YAML с инструментами

# Лимиты безопасности (в секции security)
security:
  dynamic_sql_max_length_kb: 10           # Максимальный размер SQL в КБ
  dynamic_sql_max_parameters: 10          # Максимальное число параметров

Устранение неполадок

Инструмент не появляется? - Проверьте, что .codegraph/tools.yaml существует относительно корня проекта - Проверьте логи MCP-сервера на предупреждения валидации (--verbose для отладки) - Убедитесь в наличии mcp.enabled: true и mcp.dynamic_tools_path в config.yaml

SQL отклонён? - Убедитесь, что запрос начинается с SELECT - Проверьте на случайно включённые DDL/DML-ключевые слова (включая UNION, EXCEPT, INTERSECT) - Проверьте соответствие имён параметров между {param} и parameters - Убедитесь, что строковые параметры не содержат SQL-метасимволов (', ", ;, --)

Пустые результаты? - Протестируйте SQL напрямую: python -m src.cli gocpg query "ВАШ SQL" - Проверьте имена таблиц и столбцов в Справочнике схемы

Ошибки аутентификации (SSE/HTTP)? - Убедитесь, что предоставлен Bearer JWT или X-API-Key - Используйте --no-auth для локальной разработки

Встроенные MCP-инструменты

CodeGraph поставляется со 149 встроенными MCP-инструментами, которые охватывают анализ кода, безопасность, шаблоны, корпоративные функции, операции контекста OpenViking и интеграции с платформами. Эти инструменты доступны без дополнительной настройки.

Полный список встроенных инструментов см. в Интеграция ACP — Доступные инструменты.

Связанная документация


Модуль: src/mcp/dynamic_loader.py Последнее обновление: март 2026