1C Testpilot
# 1C Testpilot
MCP-сервер для работы AI-агентов с интерфейсом **1С:Предприятия**. Позволяет агенту
открывать формы, читать и изменять данные, работать с таблицами, записывать и воспроизводить
сценарии действий.
Сервер подключается напрямую к локальному или удалённому клиенту тестирования 1С
по его сетевому протоколу.
## Возможности
- Подключение к локальному или удалённому тест-клиенту по адресу и порту; порядок подключения
определяется автоматически.
- Запуск/останов тест-клиента 1С на компьютере MCP-сервера (файловая или серверная база, логин/пароль) с ожиданием
готовности и авто-подключением — `tc_session(action="launch_client"/"stop_client")`.
- Навигация по дереву UI: активное окно → форма → элементы (по иерархическим ключам).
- Чтение: значения полей, вид/класс/заголовки элементов, таблицы, области табличного документа.
- Действия: ввод текста/HTML, клики, флажки, выбор из списков/меню, работа с таблицами и деревом,
календарь, гиперссылки, навигация по строкам и окнам.
- `click` при включённом READBACK возвращает активное окно. `diagnostics=True` дополнительно
читает текущие сообщения окна; они могут относиться к предыдущим действиям.
- Обзор формы — `get_context`: первое чтение возвращает описание, следующие — изменения;
`result_mode="full"` возвращает всё заново. `save_as_snapshot=True` отдельно сохраняет
фиксированный снимок для сравнения. Сохранение состояния не требует повторного чтения.
- Сравнение состояния формы: `create_snapshot` сохраняет снимок, `compare_snapshot`
показывает изменения относительно текущего состояния. `include_tables=True` при создании
снимка или обзоре формы добавляет сравнение строк по порядку, без раскрытия дерева.
Строки остаются выделенными; на 8.3 подготовка может вызвать обработчики активации строки.
Список и удаление — `list_snapshots`
и `delete_snapshot`. Снимки хранятся в памяти до удаления, вытеснения или остановки сервера.
- Чтение нескольких полей — `read_fields`; заполнение полей формы — `set_fields`,
ячеек текущей строки таблицы — `set_row_values`; добавление заполненных строк — `add_rows`.
При заполнении `text` задаёт текст поля, `checked` — нужное состояние флажка.
В `set_fields` параметр `select` выбирает значение через список или форму выбора.
Заполнение проверяет принятые значения и останавливается при проблеме, сохраняя результат выполненных шагов.
- `read_document` читает табличный документ целиком или прямоугольную область;
`find_text` ищет текст и возвращает адреса подходящих ячеек.
- Поиск строк таблицы: `find_rows` отбирает прочитанные строки по тексту колонок с учётом
текущих отборов и свёрнутых узлов. Это не поиск по всей базе.
- Поиск в списке средствами 1С — `search`: вводит текст в строку поиска и возвращает
строки после проверки стабильности результата; пустой текст очищает поиск.
- Выбор значения поля — `select_value`: по точному тексту из выпадающего списка
или по значениям колонок формы выбора, с проверкой результата.
- Настройки списка: `get_list_settings` читает отборы и сортировку,
`get_list_settings_fields` — доступные поля, `set_list_settings` изменяет настройки.
- Запись и воспроизведение сценариев (uilog): агент выполняет шаги → получает XML-сценарий →
воспроизводит его. Два режима записи (см. [переменные окружения](#переменные-окружения)).
- 10 инструментов по типам объектов клиента тестирования; конкретная операция выбирается
параметром `action` (до 160 действий). Версионный гейтинг по целевой версии платформы.
- [Совместимые сценарии Тестера](docs/compatible_scenarios/tester/README.md): запуск поддерживаемого
BSL из файлов через MCP и Python API, с параметрами и вложенными сценариями.
## Требования
- Windows, Linux или macOS для MCP-сервера. Платформа 1С (напр. 8.3.27 или 8.5.1)
нужна на компьютере тест-клиента.
- Python 3.10+.
- Тест-клиент 1С — либо поднимается действием `tc_session(action="launch_client")`, либо запускается заранее:
`1cv8.exe ENTERPRISE /F"<база>" /TESTCLIENT -TPort <порт>`
## Установка
Для сценариев на Python доступен [Python API с интеграцией pytest](docs/PYTHON_TESTING.md).
Тесты используют те же операции с 1С напрямую, без запуска MCP-сервера.
Установка из репозитория GitHub. Нужны Git и [pipx](https://github.com/pypa/pipx#install-pipx).
```bash
pipx install git+https://github.com/ROCTUP/1c-testpilot.git
pipx ensurepath
```
После установки перезапустите терминал и MCP-клиент, чтобы они увидели команду `1c-testpilot`.
Зависимости устанавливаются автоматически в отдельное окружение.
Если репозиторий уже скачан, установите проект из его корневой папки:
```bash
pipx install .
```
## Подключение к MCP-клиенту
Выберите способ подключения: **stdio** — MCP-клиент сам запускает 1C Testpilot;
**Streamable HTTP** — вы запускаете сервер отдельно, а MCP-клиент подключается по URL.
### Через stdio
Команда `1c-testpilot` должна быть доступна в `PATH` MCP-клиента. Если клиент её не находит,
укажите в `command` полный путь к исполняемому файлу.
**Claude Desktop** ([документация](https://support.claude.com/en/articles/10949351-getting-started-with-local-mcp-servers-on-claude-desktop)).
Откройте **Settings → Developer → Edit Config** и добавьте сервер в `mcpServers`:
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`.
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`.
```json
{
"mcpServers": {
"1c-testpilot": {
"command": "1c-testpilot",
"env": { "TC1C_TRANSPORT": "stdio" }
}
}
}
```
После изменения файла полностью перезапустите Claude Desktop.
**Claude Code** ([документация](https://code.claude.com/docs/en/mcp)):
```bash
claude mcp add --env TC1C_TRANSPORT=stdio --transport stdio --scope user 1c-testpilot -- 1c-testpilot
```
`--scope user` делает сервер доступным во всех проектах. Состояние подключения можно
посмотреть командой `/mcp` внутри Claude Code.
**Codex** ([документация](https://developers.openai.com/codex/mcp/)).
Добавьте в `~/.codex/config.toml`:
```toml
[mcp_servers.1c-testpilot]
command = "1c-testpilot"
env = { TC1C_TRANSPORT = "stdio" }
```
Или добавьте сервер через CLI:
```bash
codex mcp add 1c-testpilot --env TC1C_TRANSPORT=stdio -- 1c-testpilot
```
Состояние подключения — `/mcp` в Codex. Для длительных операций, например запуска 1С,
можно добавить `tool_timeout_sec = 120` в секцию сервера; стандартный таймаут Codex — 60 секунд.
Без установки пакета можно указать напрямую: `"command": "python", "args": ["<путь>/app/server.py"]`.
### Через Streamable HTTP
Запустите 1C Testpilot в отдельном терминале.
**Windows, PowerShell:**
```powershell
$env:TC1C_TRANSPORT = "streamable-http"
$env:TC1C_HTTP_HOST = "127.0.0.1"
$env:TC1C_HTTP_PORT = "6004"
$env:TC1C_HTTP_PATH = "/mcp"
1c-testpilot
```
**Linux, Bash:**
```bash
TC1C_TRANSPORT=streamable-http TC1C_HTTP_HOST=127.0.0.1 TC1C_HTTP_PORT=6004 TC1C_HTTP_PATH=/mcp 1c-testpilot
```
Пока сервер работает, он принимает MCP-подключения по адресу `http://127.0.0.1:6004/mcp`.
Настройки `TC1C_*` задаются в окружении этого процесса сервера.
**Claude Code:**
```bash
claude mcp add --transport http --scope user 1c-testpilot http://127.0.0.1:6004/mcp
```
Эта настройка работает и в локальных сессиях вкладки **Code** приложения Claude Desktop:
они используют MCP-конфигурацию Claude Code. Подключение к HTTP-серверу выполняется напрямую.
[Документация Claude Code Desktop](https://code.claude.com/docs/en/desktop#shared-configuration).
Если сервер с таким именем уже добавлен через stdio, сначала удалите прежнюю запись
командой `claude mcp remove --scope user 1c-testpilot`.
**Codex** — используйте URL в секции сервера в `~/.codex/config.toml`:
```toml
[mcp_servers.1c-testpilot]
url = "http://127.0.0.1:6004/mcp"
```
При переходе со stdio замените прежние `command`, `args` и `env` на `url`.
Для новой записи можно использовать CLI:
```bash
codex mcp add 1c-testpilot --url http://127.0.0.1:6004/mcp
```
Для подключения с другого компьютера задайте `TC1C_HTTP_HOST` равным сетевому IP компьютера
с 1C Testpilot и укажите этот IP в URL клиента. Порт `6004` должен быть доступен из сети клиента.
Встроенной HTTP-аутентификации в 1C Testpilot нет; доступ к серверу ограничивается вашей сетью
или внешним прокси с аутентификацией и HTTPS.
Также поддерживается прежний транспорт **SSE**: `TC1C_TRANSPORT=sse`, адрес подключения
`http://127.0.0.1:6004/sse`. У него стандартные пути `/sse` и `/messages/`;
`TC1C_HTTP_PATH` применяется только к Streamable HTTP.
### Подключение к клиенту тестирования 1С
Адрес, порт и версия платформы 1С передаются инструменту `tc_session` при выполнении
действия `connect`. Эти параметры относятся к клиенту тестирования 1С и не задаются
в конфигурации подключения MCP. Запуск клиента выполняется действием `launch_client`.
- При локальном подключении `host` можно опустить: по умолчанию `127.0.0.1`.
- Удалённый клиент запустите с `/TESTCLIENT -TPort <порт>`; его порт должен быть доступен
с компьютера MCP-сервера.
- `launch_client` и `stop_client` работают на компьютере MCP-сервера. На Linux для обычного
запуска клиента нужен графический сеанс; для подключения к уже запущенному — не нужен.
- На macOS обычный запуск не требует `DISPLAY`; поиск платформы учитывает путь
`/opt/1cv8/<версия>/`. `desktop="isolated"` и `get_screenshot` на macOS не поддерживаются.
- На Windows 10+ и Linux параметр `desktop="isolated"` в `launch_client` запускает 1С на отдельном
рабочем столе, не мешая пользователю. По умолчанию — `desktop="default"`, обычный запуск.
Изолированные клиенты поддерживают скриншоты и завершаются вместе с MCP-сервером.
На Linux требуется Xvfb (`sudo apt install xvfb` в Ubuntu/Debian); графический сеанс не нужен.
- Можно работать с несколькими базами или одной базой под разными пользователями.
Подключение выбирается через `connection_id`, список — `tc_session(action="list_connections")`.
При автоматическом выборе исполняемого файла используется самая новая подходящая установка.
Учитываются также установки только тонкого клиента. Например,
`version="8.3.27"` выбирает самую новую сборку этой ветки. Для определённой сборки
укажите полную версию или путь `exe`.
### Именованные профили
Настройки запуска и подключения можно сохранить в YAML-файле
([примеры всех допустимых параметров](profiles.example.yaml)), указав его путь в `TC1C_PROFILES_FILE`.
`tc_session(action="list_profiles")` показывает доступные профили;
`launch_client(profile="ut_admin")` запускает клиент, `connect(profile="remote_demo")`
подключается к работающему. Оба действия относятся к `tc_session`.
Явно переданные параметры переопределяют профиль. Имя использованного профиля видно в `list_connections`.
Для запуска профиль содержит `base` и параметры `launch_client`, для подключения — `port`
и необязательные `host`, `version`. Для серверной базы укажите `server: true` и `base: 'server1c\Trade'`.
`description` задаёт описание. Пароль — строка в `password`
или значение переменной окружения с именем из `password_env`; одновременно их задавать нельзя.
Пароли в YAML заключайте в кавычки. Значения паролей не выводятся в списке профилей и журнале;
при запуске 1С пароль передаётся в командной строке процесса.
Файл перечитывается при обращении. Относительные пути `base`, `exe` и `code_epf` в профиле считаются от его папки.
`wait` задаёт общий срок запуска и готовности подключения в секундах: по умолчанию `120`.
Для долгой загрузки базы его можно увеличить, например `wait: 180`. Ожидание заканчивается
сразу после подключения; само открытие порта ещё не означает готовность клиента.
## Переменные окружения
Задаются в окружении процесса сервера или в файле по образцу [.env.example](.env.example):
```bash
1c-testpilot --env-file "D:/Testpilot/.env"
```
При запуске из MCP-клиента добавьте аргументы к команде:
```json
{
"mcpServers": {
"1c-testpilot": {
"command": "1c-testpilot",
"args": ["--env-file", "D:/Testpilot/.env"]
}
}
}
```
Путь к файлу — абсолютный или относительно рабочего каталога сервера. Переменные окружения
имеют приоритет над значениями файла. Без `--env-file` файл `.env` не загружается;
если указанный файл недоступен, сервер сообщает об ошибке и не запускается.
- `TC1C_PROFILES_FILE` — путь к YAML-файлу профилей, абсолютный или от рабочего каталога сервера.
По умолчанию не задан.
- `TC1C_CONNECTION_LIMIT` — максимум зарегистрированных подключений, по умолчанию `16`.
Отключённый клиент, запущенный сервером, учитывается до `stop_client`. Лимит ссылок
`TC1C_REF_LIMIT` применяется отдельно к каждому подключению.
- `TC1C_QUEUE_TIMEOUT` — максимальное ожидание очереди к занятому соединению,
по умолчанию `60` секунд; положительное число. По истечении сервер возвращает
`connection_busy` с текущим действием и длительностью его выполнения. Таймаут
самого выполняющегося действия задаётся отдельно.
`list_connections` показывает `busy`, `active_action`, `active_seconds`; после
обнаруженного обрыва сокета — `connected=false`.
`tc_session(action="disconnect", force=true)` прерывает сетевое ожидание без очереди.
В Python API — `client.disconnect(force=True)`. Приложение 1С продолжает работать;
результат прерванного действия может быть неизвестен (`outcome_unknown`).
`cleanup_pending=true` означает, что обработчик ещё освобождает состояние соединения;
дождитесь `busy=false` либо удаления подключения из списка перед повторным подключением.
- `TC1C_RECORD_MODE` — режим записи сценариев: `synth` (по умолчанию — сервер собирает сценарий из
вызовов инструментов, покрывая все действия агента) или `native` (журнал тест-клиента;
составное чтение таблицы сервер дополняет командами снятия выделения).
- `TC_PLATFORM_VERSION` — целевая версия платформы (напр. `8.3.24.1548`): действия, чей метод в
этой версии отсутствует, не публикуются; версия используется в рукопожатии.
- `TC1C_RESPONSE_FORMAT` — формат ответов: `toon` (по умолчанию) или `json` (режим совместимости).
- `TC1C_RESPONSE_DETAIL` — `compact` (по умолчанию) сокращает служебные поля успешных MCP-ответов; `full` сохраняет их полностью. Журнал и ответы Python API не сокращаются.
- `TC1C_COMPACT_REFS` — адресация элементов: `id` (по умолчанию), `prefix` или `off`.
`id` работает с TOON и JSON; `prefix` сокращает адреса только в TOON.
Прежние `true` и `false` принимаются как синонимы `prefix` и `off`.
- `TC1C_REF_LIMIT` — максимум элементов в реестре одного подключения, по умолчанию `100000`;
положительное целое число. Ограничение действует во всех режимах адресации.
- `TC1C_VERIFY_TARGET` — проверка существования объекта перед действием, `true` (по умолчанию)
или `false`.
- `TC1C_READBACK` — чтение состояния до и после действия, `true` (по умолчанию) или `false`.
- `TC1C_SNAPSHOT_LIMIT` — максимум сохранённых состояний форм на сервере, по умолчанию `100`.
- `TC1C_SNAPSHOT_MEMORY_MB` — лимит хранилища состояний в МиБ, по умолчанию `128`.
Лимиты общие для явных снимков и автоматических состояний `get_context` (одно на форму).
При переполнении вытесняются давно не использовавшиеся снимки.
- `TC1C_SCREENSHOTS` — снимки окна 1С, `true` (по умолчанию) или `false`.
При `false` действие `get_screenshot` и его параметры не публикуются.
- `TC1C_LOGGING` — журнал MCP-вызовов, по умолчанию `true`; при `false` действия управления журналом скрыты.
- `TC1C_LOG_AUTO_START` — начинать журнал автоматически, по умолчанию `false`.
- `TC1C_LOG_DIR` — каталог журналов на сервере, по умолчанию `logs`.
- `TC1C_LOG_REPORTS` — отчёты: `html` (по умолчанию), `allure`, `html,allure` или `none`.
JSONL-журнал сохраняется при любом выборе; скриншоты настраиваются отдельно.
- `TC1C_LOG_SCREENSHOTS` — разрешить снимки в журнале, по умолчанию `true`; независимо от `TC1C_SCREENSHOTS`.
- `TC1C_LOG_MAX_MB` — общий лимит журналов в МиБ, по умолчанию `1024`.
Старые завершённые журналы удаляются; если места недостаточно, запись приостанавливается.
## Формат ответов
Формат ответов — **TOON** (компактный, по умолчанию) или **JSON**.
Выбор: `TC1C_RESPONSE_FORMAT`.
По умолчанию успешные MCP-ответы сокращены (`TC1C_RESPONSE_DETAIL=compact`):
в простых действиях не повторяются переданный `target` и успешная проверка его наличия;
`connection_id` опускается при единственном подключении. У окна после нажатия или перехода
остаются адрес, название и возможная диагностика. Если описание окна не изменилось,
вместо блока `window` возвращается `window_changed: false`; первое или изменившееся
описание приходит с `window_changed: true`. Сравнение отдельно для каждого подключения;
переподключение сбрасывает запомненное описание.
Ответы подключения сохраняют `connection_id`. Ошибки и признаки неполных результатов
не сокращаются. `full` возвращает полные служебные поля; журнал и Python API всегда их сохраняют.
Режим адресации элементов задаётся через `TC1C_COMPACT_REFS`:
- `id` — короткие ссылки `ref`, передаваемые в действия без изменений; по умолчанию.
- `prefix` — сокращённые адреса со словарями в ответе TOON; в JSON адреса полные.
- `off` — полные адреса `key` и `handle`.
## Инструменты
`find_objects` по умолчанию возвращает все совпадения. Для больших результатов доступны
`limit` и продолжение через `cursor`, без повторного поиска. Примеры — в [справочнике](docs/TOOLS.md#tc_find--search-the-ui-tree-for-objects).
Сервер публикует **10 инструментов** — по типам объектов клиента тестирования; операция выбирается
параметром `action`, до 160 действий. Список действий с методами 1С, применимыми типами и
параметрами вынесен в отдельный документ:
**[docs/TOOLS.md](docs/TOOLS.md)**.
Дополнительно доступны инструменты без параметра `action`:
- `tc_execute_code` — выполнение BSL-кода в клиентском или серверном контексте;
- `tc_execute_query` — запрос с параметрами, до 500 строк результата (по умолчанию 100);
- `tc_get_metadata` — структура конфигурации: объекты, реквизиты, типы, табличные части и перечисления;
- `tc_list_custom_bsl_functions` и `tc_execute_custom_bsl_function` — описание и вызов
[пользовательских BSL-функций](onec/Testpilot/CUSTOM_FUNCTIONS.md), зарегистрированных в обработке.
Они работают через [внешнюю обработку Testpilot](onec/Testpilot/README.md), которую
сервер автоматически открывает при запуске клиента. Произвольный код, запросы и
пользовательские функции включаются независимо; по умолчанию выключены.
`TC1C_METADATA=auto` включает метаданные вместе с кодом или запросами; `true` включает
их отдельно, `false` скрывает. При `TC1C_FUNCTIONS=true` инструменты функций появляются,
когда подключена обработка с непустым реестром. В Python API те же методы вызываются
без префикса `tc_` и работают при запуске клиента с обработкой через `code_epf`,
независимо от настроек публикации MCP.
Действие `get_screenshot` в `tc_app` возвращает изображение окна 1С со всплывающими списками,
не переключая фокус. MCP-сервер и клиент должны работать на одном компьютере:
Windows или Linux с X11/XWayland. На Linux нужен доступ к сеансу клиента через `DISPLAY` и `XAUTHORITY`;
захват приложений, работающих напрямую через Wayland, не поддерживается. Свёрнутое окно нужно открыть.
`scale` задаёт масштаб 25–100%, `grid` включает координатную сетку, `region=[x,y,width,height]`
ограничивает область в пикселях исходного снимка. Неполный снимок сопровождается предупреждением.
В сценарий снимки не записываются.
## Журнал работы агента
В `tc_session`: `start_logging` начинает запись, `get_logging_status` показывает состояние,
`stop_logging` завершает её и возвращает пути к JSONL-журналу и выбранным отчётам.
Параметр `reports` в `start_logging` переопределяет `TC1C_LOG_REPORTS` для новой сессии:
`["html"]`, `["allure"]`, `["html", "allure"]` или `["none"]` для одного JSONL-журнала.
Параметр `screenshot_mode`: `off` — без снимков, `actions` — после изменений и при ошибках,
`all` — после каждого вызова. По умолчанию `actions`, либо `off`, если снимки журнала запрещены.
PNG сохраняются рядом с отчётом и не добавляются в ответы агенту. Для снимков нужен локальный клиент.
Журнал каждого подключения независим; отключение клиента завершает запись. Повторный `start_logging`
сохраняет текущий журнал и выбранные настройки. Вызов `run_scenario` содержит отдельные шаги
с их результатами и скриншотами; одинаковый снимок используется во всех выбранных отчётах.
HTML доступен во время записи. При выборе Allure после завершения сессии в `allure-results`
появляются результаты и вложения для сборки отчёта Allure. Поле `allure_results` содержит путь
к ним, `report_errors` — ошибки формирования отчёта, если они возникли. Для просмотра установите
[Allure Report](https://allurereport.org/docs/install/) и выполните:
```bash
allure generate "logs/session-…/allure-results" -o allure-report
allure open allure-report
```
В Allure сессия MCP отображается в группе `Testpilot sessions`. Её статус описывает ошибки
вызовов и полноту записи; выполнение пользовательской задачи оценивается отдельно.
Для Python-тестов используется интеграция с `allure-pytest`: шаги относятся к тестам,
а результат определяет pytest. Подробнее — [отчёты pytest](docs/PYTHON_TESTING.md#форматы-отчётов).
## Запись и воспроизведение сценариев
`tc_scenario(action="record_start")` → выполнить действия → `tc_scenario(action="record_finish")` возвращает
XML-сценарий (`uilog`) и `lost_actions` (действия, не попавшие в сценарий; при непустом списке
сценарий неполный). Воспроизведение — `tc_scenario(action="run_scenario", uilog=...)`.
Ответ по умолчанию краткий: итог, счётчики и последний шаг с ошибкой. Для списка всех шагов
передайте `result_mode="full"`. При включённом логировании журнал сохраняет подробности
в обоих режимах. Это поведение действует также в Python API.
Режим записи — `TC1C_RECORD_MODE`.
## Ограничения
- Протокол закрытый и может отличаться между версиями платформы. Локальное подключение проверено
на Windows с 8.3.27 и 8.5.1; удалённое — к Windows с 8.3.27
и к Ubuntu с 8.3.27. Способ подключения выбирается автоматически по ответу тест-клиента.
TDQS
Scored across 10 tools
Top-level tools are split by domain (session, app, window, field, table, form, etc.), but several overlap in practice: tc_table and tc_field both edit table cells, tc_app and tc_window both expose window state, and tc_form, tc_app, and tc_find all provide element discovery or reading. An agent can often distinguish them, but there are enough cross-cutting concerns to cause misselection.
All 10 tools use a consistent tc_<noun> pattern in snake_case, making the set highly predictable. Action names within each group are also uniformly snake_case and descriptive, even when they use varied phrasing.
10 tools is well within the ideal 3–15 range and each tool maps to a distinct functional area of the 1C test client. The grouping is logical, even though individual tools contain many actions.
The surface covers a broad UI automation lifecycle: connection/launch, window and form state, field and table editing, documents, calendars, scenarios, and object finding. Minor gaps may exist, such as explicit document-saving operations, but the core workflows are well represented.