ADR 0181: MCP ImageContent → vision агента (opt-in, host consumer)
Статус: Proposed
Дата: 2026-07-25
Tags: #mcp #imagecontent #vision #multimodal #harness #agent-comfort #equal-standing #adr #cascade-ide #cdp
Резюме
- Сервер может честно отдавать
ImageContent в CallToolResult.content (CDP take + PlantUML PNG).
- Не инжектить картинку в контекст агента по умолчанию — моветон; управление у агента (
vision=true / see=true), иначе sidecar preview_path + Read.
- Dogfood Cursor: даже при
attached_image=true пиксели до модели часто не доезжают (host / CallDynamicTool text-only) — gap потребителя, twin к 0179.
- CIDE owed: end-to-end ImageContent → session/model при agent opt-in; Cursor hosts документировать честно.
Связанные ADR
| ADR |
Роль |
| 0179 |
Twin: канал без потребителя (progress); здесь — image blocks |
| 0177 |
Host mid-turn signals; presence ≠ multimodal |
| 0166 |
Comfort + «ничего о нас без нас» (агент выбирает, когда смотреть) |
| 0165 |
Host matrix: кто реально кормит vision |
| 0048 |
Cursor tool surface parity |
| 0023 |
Diagram language tooling (PlantUML files) |
| 0180 |
Habitat comfort sibling |
Контекст (dogfood 2026-07-25)
- CDP 0.5.152+:
ToolMediaOutbox → ImageContentBlock после text; PlantUML -tpng -pipe.
- 0.5.153: default
take пишет PNG на preview_path, без ImageContent; vision=true|see=true — attach + annotations.audience=assistant.
- Факт: JSON
attached_image: true, но в Cursor agent turn через dynamic MCP wrapper пришёл только text — vision сработал через host Read файла, не через MCP image block.
- Оператор: всегда пихать PNG в контекст без желания агента — моветон; ручка агенту.
Решение
Контракт (сервер / CDP)
| Режим |
Поведение |
Default take (диаграмма) |
Verify/render OK; preview_path; attached_image=false |
vision=true / see=true |
+ ImageContent (PNG), audience=assistant, cap bytes/count |
| Fallback |
Агент Read preview_path (надёжный path, пока host image broken) |
Контракт (host / CIDE)
- CIDE agent harness: при opt-in tool result с
type=image — доставить в multimodal context модели (не только UI preview для человека).
- Cursor / чужие hosts: если strip ImageContent — документировать; не врать в tool note «attached for vision», пока e2e не подтверждён на этом host.
- Annotations:
audience=[assistant] = для модели; user = UI-only (если host различает).
Follow-up (не забыть)
- [ ] Dogfood e2e в CIDE loopback MCP:
take vision=true → модель описывает пиксели без Read.
- [ ] Проверить Cursor native MCP path (не только
CallDynamicTool) — где именно дропается content[].
- [ ] Mermaid / другие diagram kinds — тот же opt-in контракт.
- [ ] Telemetry анти-паттерна: auto-attach image без флага агента.
Последствия
- Comfort metric: агент видит диаграмму когда попросила; контекст не раздувается PNG на каждый ship.
- Бэклог harness рядом с presence/progress: multimodal tool-result consumer.
- CDP может оставаться правильным сервером при «глухом» Cursor host.
Отклонённые альтернативы
- Всегда ImageContent на PlantUML take — отклонено (моветон + token tax).
- Только base64 в JSON text — отклонено (обход протокола; хуже для CIDE).
- Только
Read path, без ImageContent ever — отклонено как долгосрочный канон; path = interim + fallback.