# gRPC

## 1. Роль протокола в проекте

gRPC поддерживается как третий основной протокол платформы, но в самой узкой и управляемой форме. Цель состоит не в том, чтобы покрыть все возможности gRPC, а в том, чтобы представить unary RPC-методы как обычные MCP tools с формой входа и формой выхода.

## 2. Что поддерживается в MVP

- только unary RPC
- загрузка `.proto`
- загрузка descriptor set
- загрузка примеров JSON для MCP input/output при необходимости
- извлечение `services`, `methods`, request/response messages
- отображение входных и выходных параметров в UI
- mapping `MCP input -> protobuf request`
- mapping `protobuf response -> MCP output`
- автогенерация чернового mapping
- ручная донастройка через `JSONPath`
- вызов метода по descriptor metadata
- auth/transport settings на уровне соединения
- тестовый вызов перед публикацией

## 3. Что не входит в MVP

- `server streaming`
- `client streaming`
- `bidirectional streaming`
- обязательная поддержка server reflection
- генерация нового Rust-кода под каждый загруженный `.proto`
- сложные сценарии с долгоживущими сессиями вызовов

## 4. Ключевое архитектурное ограничение

В проекте поддерживаются только unary-методы, потому что MCP tool в этой архитектуре соответствует модели `один запрос -> один ответ`.

Это означает:

- один request message;
- один response message;
- один завершенный вызов;
- отсутствие потоковых сообщений;
- отсутствие отдельного жизненного цикла stream-сессии.

Streaming gRPC не нужен для выбранной модели взаимодействия с LLM и только усложнит runtime, UI и хранение состояния.

## 5. Внутренняя модель gRPC operation

gRPC operation должна включать:

- `server_addr`
- `package`
- `service`
- `method`
- `descriptor_ref`
- `descriptor_set_b64`
- `input_schema`
- `output_schema`
- `input_mapping`
- `output_mapping`
- `execution_config`
- `tool_description`

## 6. Как оператор настраивает gRPC operation

1. Загружает `.proto` или descriptor set.
2. Система извлекает список services и methods.
3. Оператор выбирает конкретный unary-метод.
4. UI показывает структуру request message и response message.
5. При необходимости загружает примеры JSON для MCP input/output.
6. Система строит черновую схему, стартовый mapping и runtime-ready snapshot descriptor set для выбранного метода.
7. Оператор задает или уточняет входные MCP-параметры.
8. Настраивает маппинг во входные protobuf fields.
9. Настраивает маппинг из response fields в MCP output.
10. При необходимости уточняет mapping через `JSONPath`.
11. Выполняет тест.
12. Публикует operation как MCP tool.

## 7. Поведение runtime

При выполнении gRPC operation runtime должен:

1. Валидировать MCP input по нормализованной схеме.
2. Применить input mapping.
3. Построить protobuf request message из JSON.
4. Выполнить unary RPC вызов.
5. Преобразовать protobuf response в нормализованный JSON.
6. Применить output mapping.
7. Вернуть итоговый результат.

## 8. Критические нюансы

- `.proto` и descriptor handling должны быть отделены от runtime-вызова;
- protobuf discovery не должен жить внутри gRPC adapter;
- runtime использует сохраненный `descriptor_set_b64`, а не исходный `.proto`;
- `oneof`, `enum`, `repeated`, `map` и well-known types требуют отдельной нормализации;
- `map` на слое нормализованной schema модели представляется как `array` объектов вида `{ key, value }`;
- `oneof` на слое нормализованной schema модели представляется как `oneof` с вариантами-объектами, каждый из которых содержит одно допустимое поле;
- схема сообщения должна быть представлена в UI как обычная форма полей, а не как сырой protobuf descriptor;
- пользователь не должен видеть внутреннюю сложность protobuf-контракта больше, чем это нужно для настройки operation.
- `JSONPath` используется как единый способ точечной адресации вложенных полей при настройке mapping поверх нормализованной JSON-модели.

## 9. Почему gRPC ограничивается unary

Причина не только в сложности реализации. Главное ограничение архитектурное:

- MCP tool моделируется как завершенный вызов;
- LLM работает с запросом и конечным ответом;
- UI платформы построен вокруг формы входа и формы выхода;
- streaming требует отдельной session-модели, buffering, cancellation и состояния.

Поэтому unary gRPC - это не "обрезанная" поддержка, а осознанно выбранная форма, которая действительно совместима с MCP-платформой.
