| 1 | using System.Text.Json; |
| 2 | using ModelContextProtocol.Protocol; |
| 3 | using Tool = ModelContextProtocol.Protocol.Tool; |
| 4 | |
| 5 | namespace WebcamCaptureMcp; |
| 6 | |
| 7 | /// <summary>Каталог MCP-тулов. Согласован с <c>mcp-tools.manifest.json</c> и <c>docs/MCP-TOOLS.md</c> (генерация: <c>tools/ExportMcpManifest</c>).</summary> |
| 8 | internal static class ToolCatalog |
| 9 | { |
| 10 | private static JsonElement Schema(object schema) => JsonSerializer.SerializeToElement(schema); |
| 11 | |
| 12 | internal static List<Tool> Build() => |
| 13 | [ |
| 14 | new() |
| 15 | { |
| 16 | Name = "capture_webcam_frame", |
| 17 | Description = "Сделать снимок с веб-камеры по явному запросу. Сохраняет изображение в workspace (по умолчанию .cascade-ide/webcam-captures) и возвращает JSON с путём и параметрами кадра.", |
| 18 | InputSchema = Schema(new |
| 19 | { |
| 20 | type = "object", |
| 21 | properties = new |
| 22 | { |
| 23 | workspace_path = new { type = "string", description = "Каталог workspace (корень проекта в Cursor)." }, |
| 24 | camera_index = new { type = "integer", description = "Индекс камеры (по умолчанию 0)." }, |
| 25 | width = new { type = "integer", description = "Желаемая ширина кадра (опционально)." }, |
| 26 | height = new { type = "integer", description = "Желаемая высота кадра (опционально)." }, |
| 27 | warmup_frames = new { type = "integer", description = "Количество прогревочных кадров перед снимком (по умолчанию 5)." }, |
| 28 | image_format = new { type = "string", description = "Формат: jpg или png (по умолчанию jpg)." }, |
| 29 | jpeg_quality = new { type = "integer", description = "Качество JPEG 1..100 (по умолчанию 92)." }, |
| 30 | output_subdir = new { type = "string", description = @"Подкаталог внутри workspace для сохранения кадров (по умолчанию .cascade-ide\webcam-captures)." }, |
| 31 | file_name = new { type = "string", description = "Имя файла без расширения (опционально)." } |
| 32 | }, |
| 33 | required = new[] { "workspace_path" } |
| 34 | }) |
| 35 | }, |
| 36 | new() |
| 37 | { |
| 38 | Name = "capture_webcam_burst", |
| 39 | Description = "Сделать быструю серию кадров с веб-камеры. Сохраняет кадры в подпапку внутри workspace и (опционально) собирает короткий видеофайл.", |
| 40 | InputSchema = Schema(new |
| 41 | { |
| 42 | type = "object", |
| 43 | properties = new |
| 44 | { |
| 45 | workspace_path = new { type = "string", description = "Каталог workspace (корень проекта в Cursor)." }, |
| 46 | camera_index = new { type = "integer", description = "Индекс камеры (по умолчанию 0)." }, |
| 47 | width = new { type = "integer", description = "Желаемая ширина кадра (опционально)." }, |
| 48 | height = new { type = "integer", description = "Желаемая высота кадра (опционально)." }, |
| 49 | warmup_frames = new { type = "integer", description = "Количество прогревочных кадров перед серией (по умолчанию 5)." }, |
| 50 | duration_sec = new { type = "integer", description = "Длительность серии в секундах (по умолчанию 2)." }, |
| 51 | target_fps = new { type = "integer", description = "Целевой FPS съёмки (по умолчанию 24)." }, |
| 52 | image_format = new { type = "string", description = "Формат кадров: jpg или png (по умолчанию jpg)." }, |
| 53 | jpeg_quality = new { type = "integer", description = "Качество JPEG 1..100 (по умолчанию 92)." }, |
| 54 | output_subdir = new { type = "string", description = @"Подкаталог внутри workspace для сохранения серии (по умолчанию .cascade-ide\webcam-captures)." }, |
| 55 | burst_name = new { type = "string", description = "Имя серии (опционально)." }, |
| 56 | save_video = new { type = "boolean", description = "Сохранить также видеофайл (по умолчанию false)." }, |
| 57 | video_fps = new { type = "integer", description = "FPS для сохранённого видео (по умолчанию 24)." }, |
| 58 | video_format = new { type = "string", description = "Формат видео: mp4 или avi (по умолчанию mp4)." } |
| 59 | }, |
| 60 | required = new[] { "workspace_path" } |
| 61 | }) |
| 62 | }, |
| 63 | new() |
| 64 | { |
| 65 | Name = "capture_screen_burst", |
| 66 | Description = "Сделать быструю серию кадров с экрана. Сохраняет кадры в подпапку внутри workspace и (опционально) собирает короткий видеофайл.", |
| 67 | InputSchema = Schema(new |
| 68 | { |
| 69 | type = "object", |
| 70 | properties = new |
| 71 | { |
| 72 | workspace_path = new { type = "string", description = "Каталог workspace (корень проекта в Cursor)." }, |
| 73 | monitor = new |
| 74 | { |
| 75 | description = "Монитор: номер (1-based слева направо) или 'all'. Если указан и x/y/width/height не заданы, регион берётся автоматически.", |
| 76 | anyOf = new object[] |
| 77 | { |
| 78 | new { type = "integer" }, |
| 79 | new { type = "string" } |
| 80 | } |
| 81 | }, |
| 82 | x = new { type = "integer", description = "Левая координата области захвата (по умолчанию виртуальный экран)." }, |
| 83 | y = new { type = "integer", description = "Верхняя координата области захвата (по умолчанию виртуальный экран)." }, |
| 84 | width = new { type = "integer", description = "Ширина области захвата (по умолчанию ширина виртуального экрана)." }, |
| 85 | height = new { type = "integer", description = "Высота области захвата (по умолчанию высота виртуального экрана)." }, |
| 86 | duration_sec = new { type = "integer", description = "Длительность серии в секундах (по умолчанию 2)." }, |
| 87 | target_fps = new { type = "integer", description = "Целевой FPS съёмки (по умолчанию 24)." }, |
| 88 | image_format = new { type = "string", description = "Формат кадров: jpg или png (по умолчанию jpg)." }, |
| 89 | jpeg_quality = new { type = "integer", description = "Качество JPEG 1..100 (по умолчанию 92)." }, |
| 90 | output_subdir = new { type = "string", description = @"Подкаталог внутри workspace для сохранения серии (по умолчанию .cascade-ide\screen-captures)." }, |
| 91 | burst_name = new { type = "string", description = "Имя серии (опционально)." }, |
| 92 | save_video = new { type = "boolean", description = "Сохранить также видеофайл (по умолчанию false)." }, |
| 93 | video_fps = new { type = "integer", description = "FPS для сохранённого видео (по умолчанию 24)." }, |
| 94 | video_format = new { type = "string", description = "Формат видео: mp4 или avi (по умолчанию mp4)." } |
| 95 | }, |
| 96 | required = new[] { "workspace_path" } |
| 97 | }) |
| 98 | }, |
| 99 | new() |
| 100 | { |
| 101 | Name = "capture_audio_burst", |
| 102 | Description = "Записать короткий аудиофрагмент с микрофона в WAV по явной команде. Сохраняет файл в workspace (по умолчанию .cascade-ide/audio-captures).", |
| 103 | InputSchema = Schema(new |
| 104 | { |
| 105 | type = "object", |
| 106 | properties = new |
| 107 | { |
| 108 | workspace_path = new { type = "string", description = "Каталог workspace (корень проекта в Cursor)." }, |
| 109 | duration_sec = new { type = "integer", description = "Длительность записи в секундах (по умолчанию 10)." }, |
| 110 | sample_rate = new { type = "integer", description = "Частота дискретизации (по умолчанию 16000)." }, |
| 111 | channels = new { type = "integer", description = "Число каналов (по умолчанию 1)." }, |
| 112 | device_number = new { type = "integer", description = "Номер устройства микрофона (по умолчанию 0)." }, |
| 113 | output_subdir = new { type = "string", description = @"Подкаталог внутри workspace (по умолчанию .cascade-ide\audio-captures)." }, |
| 114 | file_name = new { type = "string", description = "Имя wav-файла без расширения (опционально)." } |
| 115 | }, |
| 116 | required = new[] { "workspace_path" } |
| 117 | }) |
| 118 | }, |
| 119 | new() |
| 120 | { |
| 121 | Name = "capture_av_burst", |
| 122 | Description = "Одновременная запись короткой A/V-сессии: кадры с веб-камеры + WAV с микрофона + метаданные синхронизации.", |
| 123 | InputSchema = Schema(new |
| 124 | { |
| 125 | type = "object", |
| 126 | properties = new |
| 127 | { |
| 128 | workspace_path = new { type = "string", description = "Каталог workspace (корень проекта в Cursor)." }, |
| 129 | duration_sec = new { type = "integer", description = "Длительность захвата в секундах (по умолчанию 10)." }, |
| 130 | target_fps = new { type = "integer", description = "Целевой FPS для кадров (по умолчанию 24)." }, |
| 131 | camera_index = new { type = "integer", description = "Индекс камеры (по умолчанию 0)." }, |
| 132 | audio_device_number = new { type = "integer", description = "Индекс микрофона (по умолчанию 0)." }, |
| 133 | width = new { type = "integer", description = "Желаемая ширина кадра (опционально)." }, |
| 134 | height = new { type = "integer", description = "Желаемая высота кадра (опционально)." }, |
| 135 | audio_sample_rate = new { type = "integer", description = "Частота аудио (по умолчанию 16000)." }, |
| 136 | audio_channels = new { type = "integer", description = "Каналы аудио (по умолчанию 1)." }, |
| 137 | warmup_frames = new { type = "integer", description = "Прогрев кадров перед записью (по умолчанию 5)." }, |
| 138 | image_format = new { type = "string", description = "Формат кадров: jpg|png (по умолчанию jpg)." }, |
| 139 | jpeg_quality = new { type = "integer", description = "Качество JPEG 1..100 (по умолчанию 92)." }, |
| 140 | output_subdir = new { type = "string", description = @"Подкаталог внутри workspace (по умолчанию .cascade-ide\av-captures)." }, |
| 141 | session_name = new { type = "string", description = "Имя A/V-сессии (опционально)." }, |
| 142 | save_video = new { type = "boolean", description = "Собрать mp4 из кадров (по умолчанию true)." }, |
| 143 | video_fps = new { type = "integer", description = "FPS для mp4 (по умолчанию 24)." } |
| 144 | }, |
| 145 | required = new[] { "workspace_path" } |
| 146 | }) |
| 147 | }, |
| 148 | new() |
| 149 | { |
| 150 | Name = "capture_screen_av_burst", |
| 151 | Description = "Одновременная запись короткой A/V-сессии: кадры с экрана + WAV с микрофона + метаданные синхронизации.", |
| 152 | InputSchema = Schema(new |
| 153 | { |
| 154 | type = "object", |
| 155 | properties = new |
| 156 | { |
| 157 | workspace_path = new { type = "string", description = "Каталог workspace (корень проекта в Cursor)." }, |
| 158 | duration_sec = new { type = "integer", description = "Длительность захвата в секундах (по умолчанию 10)." }, |
| 159 | target_fps = new { type = "integer", description = "Целевой FPS для кадров (по умолчанию 24)." }, |
| 160 | audio_device_number = new { type = "integer", description = "Индекс микрофона (по умолчанию 0)." }, |
| 161 | monitor = new |
| 162 | { |
| 163 | description = "Монитор: номер (1-based слева направо) или 'all'. Если указан и x/y/width/height не заданы, регион берётся автоматически.", |
| 164 | anyOf = new object[] |
| 165 | { |
| 166 | new { type = "integer" }, |
| 167 | new { type = "string" } |
| 168 | } |
| 169 | }, |
| 170 | x = new { type = "integer", description = "Левая координата области экрана (по умолчанию виртуальный экран)." }, |
| 171 | y = new { type = "integer", description = "Верхняя координата области экрана (по умолчанию виртуальный экран)." }, |
| 172 | width = new { type = "integer", description = "Ширина области экрана (по умолчанию виртуальный экран)." }, |
| 173 | height = new { type = "integer", description = "Высота области экрана (по умолчанию виртуальный экран)." }, |
| 174 | audio_sample_rate = new { type = "integer", description = "Частота аудио (по умолчанию 16000)." }, |
| 175 | audio_channels = new { type = "integer", description = "Каналы аудио (по умолчанию 1)." }, |
| 176 | image_format = new { type = "string", description = "Формат кадров: jpg|png (по умолчанию jpg)." }, |
| 177 | jpeg_quality = new { type = "integer", description = "Качество JPEG 1..100 (по умолчанию 92)." }, |
| 178 | output_subdir = new { type = "string", description = @"Подкаталог внутри workspace (по умолчанию .cascade-ide\av-captures)." }, |
| 179 | session_name = new { type = "string", description = "Имя A/V-сессии (опционально)." }, |
| 180 | save_video = new { type = "boolean", description = "Собрать mp4 из кадров (по умолчанию true)." }, |
| 181 | video_fps = new { type = "integer", description = "FPS для mp4 (по умолчанию 24)." } |
| 182 | }, |
| 183 | required = new[] { "workspace_path" } |
| 184 | }) |
| 185 | } |
| 186 | ]; |
| 187 | } |