Что происходит
В v1.7.0 инструмент get_screenshot возвращает MCP-клиенту {"success": true, "data": "null", "error": null} вместо ImageContent, хотя .epf фактически захватывает PNG и пишет в свой журнал событий: изображение image/png, base64 длина N символов.
Картинка теряется по пути от .epf к mcp_handler.get_screenshot в режиме «Прокси». Причина — три места, где новые поля скриншота (image_base64, mime_type, window_rect, grid_coords) не были добавлены в whitelist'ы/модели при релизе v1.7.0. Достаточно починить любое одно — картинка всё равно будет резаться следующим фильтром, нужно все три.
Точки регрессии
1. .epf — whitelist при отправке HTTP body на /1c/result
1c/MCPToolkit/MCPToolkit/Forms/Форма/Ext/Form/Module.bsl, функция ОтправитьРезультатНаСервер, массив ДопПоля (около строк 1981-1993):
ДопПоля = Новый Массив;
ДопПоля.Добавить("truncated");
ДопПоля.Добавить("limit");
ДопПоля.Добавить("returned");
ДопПоля.Добавить("count");
ДопПоля.Добавить("offset");
ДопПоля.Добавить("has_more");
ДопПоля.Добавить("next_offset");
ДопПоля.Добавить("last_date");
ДопПоля.Добавить("next_same_second_offset");
ДопПоля.Добавить("configuration");
ДопПоля.Добавить("extension");
ДопПоля.Добавить("received");
// нет image_base64, mime_type, window_rect, grid_coords
Цикл ниже пропускает в ТелоЗапроса только поля из whitelist'а — поэтому .epf сама вырезает PNG из HTTP-запроса ещё до отправки прокси.
2. Прокси — Pydantic-модель CommandResult
onec_mcp_toolkit_proxy/server.py (около строк 203-224):
class CommandResult(BaseModel):
"""Result from 1C processing."""
id: str
success: bool
data: Optional[Any] = None
schema: Optional[Any] = None
error: Optional[str] = None
count: Optional[int] = None
truncated: Optional[bool] = None
# ... остальные поля ...
received: Optional[bool] = None
# нет image_base64, mime_type, window_rect, grid_coords
Pydantic v2 по умолчанию выкидывает extra-поля при валидации body эндпоинта /1c/result — то есть даже если .epf отправит PNG, прокси его обрежет при парсинге.
3. Прокси — whitelist optional_meta_fields в receive_result
Тот же server.py (около строк 327-340):
optional_meta_fields = (
"truncated", "limit", "returned", "count", "offset",
"has_more", "next_offset", "configuration", "extension",
"last_date", "next_same_second_offset",
"received",
# нет image_base64, mime_type, window_rect, grid_coords
)
for key in optional_meta_fields:
value = getattr(result, key, None)
if value is not None:
result_data[key] = value
Даже если модель из (2) принимает поля — здесь getattr(result, key, None) вернёт None для отсутствующих в whitelist'е ключей, и поля не дойдут до result_data, который кладётся в queue.
В итоге mcp_handler.get_screenshot (строка 1450):
if isinstance(result, dict) and result.get("success") and result.get("image_base64"):
image = ImageContent(...)
проверка result.get("image_base64") всегда falsy → возвращается голый result без ImageContent.
Воспроизведение
- Поднять прокси из
roctup/1c-mcp-toolkit-proxy:latest (получится 1.27.0)
- Открыть
MCP_Toolkit.epf v1.7.0 в 1С на Windows, подключить ScreenCapture (разрешить запуск внешней программы при первом запуске)
- Из MCP-клиента вызвать
get_screenshot (без параметров либо с form_name)
Ожидаемо: пришёл ImageContent с PNG, клиент рендерит скриншот.
Фактически: клиент получает {"success": true, "data": "null", "error": null}. В журнале .epf при этом есть строка Результат команды отправлен успешно (изображение image/png, base64 длина N символов) — то есть захват прошёл.
Предлагаемый фикс
Добавить 4 поля в три места:
.epf Module.bsl, массив ДопПоля:
ДопПоля.Добавить("image_base64");
ДопПоля.Добавить("mime_type");
ДопПоля.Добавить("window_rect");
ДопПоля.Добавить("grid_coords");
server.py модель CommandResult:
image_base64: Optional[str] = None
mime_type: Optional[str] = None
window_rect: Optional[Any] = None
grid_coords: Optional[Any] = None
server.py кортеж optional_meta_fields:
"image_base64",
"mime_type",
"window_rect",
"grid_coords",
Локальный обход (если кому-то нужен сейчас)
Тонкий Docker overlay поверх roctup/...:latest + ручная правка .epf через Конфигуратор воспроизводят оба фикса прокси и фикс .epf. После применения всех трёх get_screenshot возвращает ImageContent корректно — проверено end-to-end на 1С 8.3.27.1688, БП 3.0.197.22, прокси 1.27.0.
Среда
- Платформа 1С: 8.3.27.1688 (Windows толстый клиент)
- Toolkit: v1.7.0 / proxy 1.27.0 (
roctup/1c-mcp-toolkit-proxy:latest, image digest sha256:be6c619b966c..., build 2026-04-29)
- MCP-клиент: claude-code 2.1.145 (VSCode), протокол MCP 2025-11-25
- Режим подключения: «Прокси» (HTTP long-polling)
Что происходит
В v1.7.0 инструмент
get_screenshotвозвращает MCP-клиенту{"success": true, "data": "null", "error": null}вместоImageContent, хотя.epfфактически захватывает PNG и пишет в свой журнал событий:изображение image/png, base64 длина N символов.Картинка теряется по пути от
.epfкmcp_handler.get_screenshotв режиме «Прокси». Причина — три места, где новые поля скриншота (image_base64,mime_type,window_rect,grid_coords) не были добавлены в whitelist'ы/модели при релизе v1.7.0. Достаточно починить любое одно — картинка всё равно будет резаться следующим фильтром, нужно все три.Точки регрессии
1.
.epf— whitelist при отправке HTTP body на/1c/result1c/MCPToolkit/MCPToolkit/Forms/Форма/Ext/Form/Module.bsl, функцияОтправитьРезультатНаСервер, массивДопПоля(около строк 1981-1993):Цикл ниже пропускает в
ТелоЗапросатолько поля из whitelist'а — поэтому.epfсама вырезает PNG из HTTP-запроса ещё до отправки прокси.2. Прокси — Pydantic-модель
CommandResultonec_mcp_toolkit_proxy/server.py(около строк 203-224):Pydantic v2 по умолчанию выкидывает extra-поля при валидации body эндпоинта
/1c/result— то есть даже если.epfотправит PNG, прокси его обрежет при парсинге.3. Прокси — whitelist
optional_meta_fieldsвreceive_resultТот же
server.py(около строк 327-340):Даже если модель из (2) принимает поля — здесь
getattr(result, key, None)вернётNoneдля отсутствующих в whitelist'е ключей, и поля не дойдут доresult_data, который кладётся в queue.В итоге
mcp_handler.get_screenshot(строка 1450):проверка
result.get("image_base64")всегда falsy → возвращается голыйresultбезImageContent.Воспроизведение
roctup/1c-mcp-toolkit-proxy:latest(получится 1.27.0)MCP_Toolkit.epfv1.7.0 в 1С на Windows, подключить ScreenCapture (разрешить запуск внешней программы при первом запуске)get_screenshot(без параметров либо сform_name)Ожидаемо: пришёл
ImageContentс PNG, клиент рендерит скриншот.Фактически: клиент получает
{"success": true, "data": "null", "error": null}. В журнале.epfпри этом есть строкаРезультат команды отправлен успешно (изображение image/png, base64 длина N символов)— то есть захват прошёл.Предлагаемый фикс
Добавить 4 поля в три места:
.epfModule.bsl, массивДопПоля:server.pyмодельCommandResult:server.pyкортежoptional_meta_fields:Локальный обход (если кому-то нужен сейчас)
Тонкий Docker overlay поверх
roctup/...:latest+ ручная правка.epfчерез Конфигуратор воспроизводят оба фикса прокси и фикс.epf. После применения всех трёхget_screenshotвозвращаетImageContentкорректно — проверено end-to-end на 1С 8.3.27.1688, БП 3.0.197.22, прокси 1.27.0.Среда
roctup/1c-mcp-toolkit-proxy:latest, image digestsha256:be6c619b966c..., build 2026-04-29)