[feature][ai-chat] Кнопка «Test» на каждой строке списка внешних MCP-серверов (inline-статус подключения) #170

Closed
opened 2026-06-24 16:21:07 +03:00 by Ghost · 0 comments

Мотивация

Кнопка «Test» для проверки подключения к внешнему MCP-серверу сейчас живёт только внутри формы редактирования (AiMcpServerForm) и доступна лишь для уже сохранённого сервера. Чтобы проверить любой сервер из списка, приходится открывать модалку редактирования. Хочется быстрый inline-статус: проверить подключение прямо из строки списка одним кликом.

Что уже есть

  • Бэкенд готов: POST /workspace/ai-mcp-servers/testMcpServersService.test()McpClientsService.testServer(). Возвращает { ok: true, tools: string[] } (где tools — все инструменты, которые сервер отдаёт при подключении, с таймаутом и SSRF-защитой) либо { ok: false, error } (короткий санитизированный текст).
  • Клиентская мутация готова: useTestAiMcpServerMutation (ai-mcp-server-query.ts) — без уведомлений, результат рендерит вызывающий код.
  • Существующая кнопка в форме: ai-mcp-server-form.tsx (только edit-режим).

→ Бэкенд, сервис и мутацию менять не нужно — только UI списка + строки переводов.

Предлагаемое решение

Добавить на каждую строку списка (ai-mcp-servers.tsx) кнопку «Test», которая по результату меняет цвет и надпись. Без попапов/тостов.

Состояния кнопки

Состояние Условие Цвет / variant Надпись
Покой начальное default (нейтр.) Test
Проверка isPending loading Test
Успех data.ok === true зелёная (green, light) OK · {n}
Ошибка data.ok === false красная (red, light) Failed

{n} = data.tools.length — количество инструментов сервера. Иконки: IconPlugConnected / IconCheck / IconX. Цвет не единственный сигнал — надпись тоже меняется (ок для дальтоников/a11y). Повторный клик перезапускает проверку.

Архитектурное решение

Каждой строке нужно независимое состояние проверки (загрузка + результат). Один общий useTestAiMcpServerMutation() на весь список дал бы глобальный isPending — спиннер и цвет «прыгали» бы на всех строках. Поэтому строку нужно вынести в отдельный компонент AiMcpServerRow с собственным инстансом мутации → изоляция состояния, можно тестировать несколько строк параллельно.

i18n

По политике en-US + ru-RU поддерживаются полностью. Test уже есть. Добавить:

  • Failed → ru: «Ошибка»
  • OK · {{count}} (число без слова; слово «инструментов» — опционально в тултипе с plural-ключами)

Краевые случаи

  • OK · 0 — подключились, но сервер не отдал инструментов: зелёная, 0.
  • Устаревший результат после правки: строка не перемонтируется (key = server.id), поэтому старый цвет «прилипнет» после смены URL/заголовков. Сбрасывать mutation.reset() через useEffect на server.url / server.transport / server.hasHeaders.
  • Выключенный сервер: кнопка активна (тест полезен перед включением); блокировать только во время isPending.
  • Зафиксировать miw кнопки (~88px), чтобы строка не дёргалась при смене надписи TestOK · 5Failed.

Открытые вопросы

  1. Надпись «OK · 5» (число) vs «OK · 5 tools» (со словом, нужны plural-ключи).
  2. Нужен ли тултип на hover с текстом ошибки / списком инструментов (без него «Failed» не объясняет причину).

Объём работ

  • ai-mcp-servers.tsx — вынести строку в AiMcpServerRow + добавить кнопку (основной объём).
  • en-US/translation.json + ru-RU/translation.json — 2–3 ключа.
  • Бэкенд / сервис / мутация — без изменений.
## Мотивация Кнопка «Test» для проверки подключения к внешнему MCP-серверу сейчас живёт **только внутри формы редактирования** (`AiMcpServerForm`) и доступна лишь для уже сохранённого сервера. Чтобы проверить любой сервер из списка, приходится открывать модалку редактирования. Хочется быстрый inline-статус: проверить подключение прямо из строки списка одним кликом. ## Что уже есть - **Бэкенд готов**: `POST /workspace/ai-mcp-servers/test` → `McpServersService.test()` → `McpClientsService.testServer()`. Возвращает `{ ok: true, tools: string[] }` (где `tools` — все инструменты, которые сервер отдаёт при подключении, с таймаутом и SSRF-защитой) либо `{ ok: false, error }` (короткий санитизированный текст). - **Клиентская мутация готова**: `useTestAiMcpServerMutation` (`ai-mcp-server-query.ts`) — без уведомлений, результат рендерит вызывающий код. - **Существующая кнопка** в форме: `ai-mcp-server-form.tsx` (только edit-режим). → Бэкенд, сервис и мутацию менять **не нужно** — только UI списка + строки переводов. ## Предлагаемое решение Добавить на каждую строку списка (`ai-mcp-servers.tsx`) кнопку «Test», которая по результату меняет цвет и надпись. **Без попапов/тостов.** ### Состояния кнопки | Состояние | Условие | Цвет / variant | Надпись | |---|---|---|---| | Покой | начальное | `default` (нейтр.) | `Test` | | Проверка | `isPending` | `loading` | `Test` | | Успех | `data.ok === true` | зелёная (`green`, `light`) | `OK · {n}` | | Ошибка | `data.ok === false` | красная (`red`, `light`) | `Failed` | `{n}` = `data.tools.length` — количество инструментов сервера. Иконки: `IconPlugConnected` / `IconCheck` / `IconX`. Цвет не единственный сигнал — надпись тоже меняется (ок для дальтоников/a11y). Повторный клик перезапускает проверку. ### Архитектурное решение Каждой строке нужно **независимое** состояние проверки (загрузка + результат). Один общий `useTestAiMcpServerMutation()` на весь список дал бы глобальный `isPending` — спиннер и цвет «прыгали» бы на всех строках. Поэтому строку нужно вынести в отдельный компонент `AiMcpServerRow` с собственным инстансом мутации → изоляция состояния, можно тестировать несколько строк параллельно. ### i18n По политике `en-US` + `ru-RU` поддерживаются полностью. `Test` уже есть. Добавить: - `Failed` → ru: «Ошибка» - `OK · {{count}}` (число без слова; слово «инструментов» — опционально в тултипе с plural-ключами) ## Краевые случаи - `OK · 0` — подключились, но сервер не отдал инструментов: зелёная, `0`. - **Устаревший результат после правки**: строка не перемонтируется (`key = server.id`), поэтому старый цвет «прилипнет» после смены URL/заголовков. Сбрасывать `mutation.reset()` через `useEffect` на `server.url` / `server.transport` / `server.hasHeaders`. - **Выключенный сервер**: кнопка активна (тест полезен перед включением); блокировать только во время `isPending`. - Зафиксировать `miw` кнопки (~88px), чтобы строка не дёргалась при смене надписи `Test`→`OK · 5`→`Failed`. ## Открытые вопросы 1. Надпись «`OK · 5`» (число) vs «`OK · 5 tools`» (со словом, нужны plural-ключи). 2. Нужен ли тултип на hover с текстом ошибки / списком инструментов (без него «Failed» не объясняет причину). ## Объём работ - `ai-mcp-servers.tsx` — вынести строку в `AiMcpServerRow` + добавить кнопку (основной объём). - `en-US/translation.json` + `ru-RU/translation.json` — 2–3 ключа. - Бэкенд / сервис / мутация — без изменений.
Ghost added the feature label 2026-06-24 16:21:07 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: vvzvlad/gitmost#170