Пользовательские MCP-инструменты¶
Создание пользовательских инструментов запросов к CPG для Claude Code и других MCP-клиентов через определение SQL-запросов в YAML-файле. Не требует изменения кода.
Обзор¶
Динамический загрузчик читает .codegraph/tools.yaml из корня проекта и регистрирует каждое определение как MCP-инструмент. Это позволяет создавать проектно-специфичные запросы анализа, которые Claude Code (или любой MCP-клиент) может вызвать по имени.
Основные возможности: - Определение пользовательских SQL-запросов как именованных MCP-инструментов - Параметры с типами и значениями по умолчанию - Только чтение (только 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-клиенту.
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, str, float
default: 10 # Значение по умолчанию
Подстановка параметров¶
Параметры используют синтаксис {имя} в SQL-шаблонах. Подстановка через Python str.format():
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: str
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 в двух точках:
- При загрузке — определения с не-SELECT SQL отклоняются
- При выполнении — сгенерированный SQL (после подстановки параметров) проверяется повторно
Запрещённые ключевые слова: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE, GRANT, REVOKE.
Ограничение строк¶
Результаты ограничены значением mcp.max_query_rows (по умолчанию: 1000) для предотвращения исчерпания памяти.
Справочник конфигурации¶
# config.yaml
mcp:
enabled: true # Включить/выключить MCP-сервер
transport: stdio # Транспорт: stdio | http | websocket
max_query_rows: 1000 # Максимум строк на результат запроса
dynamic_tools_path: .codegraph/tools.yaml # Путь к YAML с инструментами
Устранение неполадок¶
Инструмент не появляется?
- Проверьте, что .codegraph/tools.yaml существует относительно корня проекта
- Проверьте логи MCP-сервера на предупреждения валидации
- Убедитесь в наличии mcp.enabled: true и mcp.dynamic_tools_path в config.yaml
SQL отклонён?
- Убедитесь, что запрос начинается с SELECT
- Проверьте на случайно включённые DDL/DML-ключевые слова
- Проверьте соответствие имён параметров между {param} и parameters
Пустые результаты?
- Протестируйте SQL напрямую: python -m src.cli gocpg query "ВАШ SQL"
- Проверьте имена таблиц и столбцов в Справочнике схемы
Связанная документация¶
- Справочник схемы — таблицы и столбцы CPG
- SQL-рецепты — примеры SQL-запросов
- Интеграция ACP — настройка MCP для IDE
- Руководство CLI — команда
gocpg queryдля тестирования SQL
Модуль: src/mcp/dynamic_loader.py
Последнее обновление: февраль 2026