Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Winrig

FreeNot checked

MCP-сервер удалённого администрирования Windows-хостов по WinRM/NTLM: один статический бинарь на Rust, без контейнера

GitHubEmbed

About

MCP-сервер удалённого администрирования Windows-хостов по WinRM/NTLM: один статический бинарь на Rust, без контейнера

README

CI Release License: MIT Rust

MCP-сервер для удалённого администрирования Windows-хостов по WinRM/NTLM, написанный на Rust. Диагностируйте, изучайте и администрируйте любой Windows-хост, введённый в домен AD, из Cursor, Claude Code, Codex, opencode или любого клиента MCP (Model Context Protocol). Пароль AD вводится один раз через winrig setup, хранится только аутентифицированным шифртекстом под ключом, который остаётся у клиента, и никогда не записывается в конфиг клиента открытым текстом.

winrig — преемник Python-проекта win-mcp-server на Rust. Он сохраняет те же доменные правила, границы модулей и контракты инструментов, но поставляется одним статическим бинарём без контейнера и интерпретатора, работая либо как HTTP-сервис (winrig serve), либо как локальный stdio-процесс (winrig stdio).

  • Мало памяти, один бинарь: один release-бинарь, без runtime, без контейнера. Резидентная память держится около 11 МиБ после старта и повторных запросов на машине разработки (VmRSS из /proc).
  • 37 инструментов плюс write_file, когда оператор его включит: файловая система, службы, реестр, журналы событий, сертификаты, процессы, сеть, запланированные задачи и прочее. Это портированные на сегодня инструменты; в Python-версии win-mcp-server были передача файлов (копирование/перемещение/переименование/архивы), invoke_http_request и инструменты SFTP, которые пока не портированы.
  • Один процесс на профиль: winrig setup создаёт шифрованный профиль; напечатанный токен — единственный ключ, и показывается он один раз. Второй процесс на том же профиле отказывает в старте и указывает на HTTP-режим.
  • Два секрета, по одному на запрос: запрос аутентифицируется либо WINRIG_AUTH_TOKEN (путь по заголовкам с X-AD-User), либо токеном профиля, который задаёт идентичность и заставляет игнорировать X-AD-*.
  • Никаких секретов на диске: ни учётных данных в конфигах, ни в журналах. В файле профиля лежит только аутентифицированный шифртекст.

Почему Rust

  • Один release-бинарь, cargo build --release; без Docker, без Python, без pip.
  • Память ограничена и мала; одна длинная команда не может заблокировать другой запрос, потому что транспорт асинхронный.
  • Клиент WinRM/NTLM, протокол MCP и HTTP-стек — зрелые крейты, поэтому проект несёт доменную логику, а не протокольную обвязку. См. docs/adr/0007-rust-stack.md.

Инструменты

Сессия

Инструмент Описание
connect Открыть WinRM-сессию к Windows-хосту и вернуть session_id (HTTP 5985 или HTTPS 5986 через use_ssl)
disconnect Закрыть активную WinRM-сессию
list_sessions Список активных WinRM-сессий с деталями использования

Файловая система (только чтение)

Инструмент Описание
list_directory Список файлов и каталогов по пути
find_files Рекурсивный поиск файлов по шаблону
read_file Чтение содержимого файла с нумерацией строк
search_file_content Текстовый поиск в файле или по каталогу, аналог grep
file_info Метаданные файла или каталога в JSON
compare_files Построчный diff двух файлов

Диагностика системы (только чтение)

Инструмент Описание
get_event_log Журнал событий Windows: падения, отказы служб, ошибки аутентификации
get_services Сводка служб или полные детали по каждой службе в JSON
list_processes Процессы с сортировкой по CPU, памяти или дескрипторам
get_system_info Версия ОС, uptime, RAM, число CPU, домен, часовой пояс
get_disk_space Место на всех фиксированных дисках
get_perf_snapshot Снимок CPU, памяти, дискового I/O и сети, не зависящий от локали
get_registry Чтение ключа или значения реестра (только чтение)
get_certificates Сертификаты личного хранилища с сортировкой по дням до истечения
get_network_config IP, шлюз и DNS по каждому сетевому адаптеру
test_network ICMP-пинг или проверка TCP-порта с удалённого хоста

Идентичность и конфигурация (только чтение)

Инструмент Описание
get_environment_variables Переменные окружения по областям
get_scheduled_tasks Запланированные задачи с последним/следующим запуском и результатом
get_local_users Локальные учётные записи со статусом и последним входом
get_user_groups Членство в локальных группах
get_security_context Идентичность текущей сессии, группы, привилегии
get_permissions Записи ACL для файлов и каталогов

Сеть и ПО (только чтение)

Инструмент Описание
get_tcp_connections Активные TCP-соединения с процессом-владельцем
get_dns_cache Локальный кэш DNS-клиента
get_installed_software Установленное ПО из 64- и 32-битных ключей удаления
resolve_dns_name Цепочка разрешения DNS с удалённого сервера

Active Directory — решено, но не построено

Ни одного из этих инструментов в бинаре сегодня нет: раздел фиксирует решение (ADR-0014, срезы W19–W21), а не возможность. Он здесь потому, что само отсутствие вводит в заблуждение: агент, видящий WinRM и хост в домене, предполагает, что каталог доступен, а он не доступен.

Почему так: NTLM даёт удалённому хосту network logon без делегируемых учётных данных, поэтому запрос к каталогу с рядового сервера — второй хоп к контроллеру домена, и он отказывает с An operations error occurred. run_command это не изменит — он исполняется в той же сессии с тем же токеном. Маршрут, который работает, делегирования не требует вовсе: подключиться к самому контроллеру домена, где запрос локален. Сегодня AD касается только get_security_context, и лишь потому, что доменные группы лежат в токене сессии.

Планируется в срезе W19, только чтение, опрос через System.DirectoryServices, а не командлетами RSAT (те ходят в ADWS и требуют установленного модуля и запущенной службы):

Инструмент Описание
get_ad_object Один пользователь, группа или компьютер: состояние учётной записи, сроки пароля, последний вход, DN, OU
get_ad_membership Членство в обе стороны, при необходимости вложенное
find_ad_objects Поиск по имени или sAMAccountName с потолком результатов
get_ad_domain_info Домен, лес, уровни функционирования, роли FSMO, контроллеры, доверия, сайты, парольная политика и PSO
get_ad_health Партнёры репликации и отставание, службы NTDS/DNS/ADWS/W32Time, состояние SYSVOL
get_ad_stale_objects Залежавшиеся пользователи и компьютеры по lastLogonTimestamp и pwdLastSet

Запись в каталог (срезы W20–W21) решена в том же ADR и намеренно оставлена за пределами первой волны: она будет выключена по умолчанию за WINRIG_ALLOW_AD_WRITE, будет подтверждать каждый вызов с DN объекта, будет отвергать защищённые объекты и встроенные группы до обращения к сети, будет принимать ровно один явно названный объект на вызов и никогда фильтр, и примет атрибут только если он проходит WINRIG_AD_WRITABLE_ATTRIBUTES. Текущий бинарь не читает ни одну из этих переменных. Изменение топологии домена или леса — захват ролей FSMO, чистка метаданных, принудительная репликация — и удаление объектов каталога не планируются вовсе.

Модифицирующие операции (все требуют подтверждения)

Инструмент Описание
restart_service / stop_service / start_service Управление службами с состоянием до и после
kill_process Принудительное завершение процесса по PID
set_registry Запись значения реестра с показом старого и нового
delete_file / delete_directory Удаление с запросом подтверждения; защищённые пути отвергаются
flush_dns Очистка кэша DNS-клиента
write_file Запись файла с заменой целиком. Выключен по умолчанию: задайте WINRIG_ALLOW_FILE_WRITE=true, иначе инструмент не объявляется и вызвать его нельзя

write_file отвергает защищённые пути тем же списком, что охраняет удаление, и отвергает существующий файл, если не задан overwrite. Содержимое идёт кусками по ~2 КБ, потому что командная строка WinRS ограничена примерно 8191 символом; поэтому инструмент годится для конфигов и скриптов, а не для больших объёмов, а остаток ограничивает WINRIG_MAX_WRITE_BYTES (по умолчанию 64 КиБ). Куски ложатся во временный файл рядом с целью, а цель заменяется переименованием, поэтому сбой на середине оставляет существующий файл нетронутым.

Это ограничение на длину относится к командной строке, а не к выводу. Скрипт, не влезающий в одну команду, записывается write_file и затем запускается по пути — команда остаётся короткой, каким бы длинным ни был скрипт.

Установка

К каждому релизу приложены готовые бинари для Linux, macOS и Windows, рядом с каждым архивом — контрольная сумма sha256. Linux-бинари слинкованы статически (musl), поэтому не несут требования к версии glibc.

# Замените версию и таргет на свою платформу.
curl -LO https://github.com/fgbm/winrig/releases/latest/download/winrig-v0.1.0-x86_64-unknown-linux-musl.tar.gz
curl -LO https://github.com/fgbm/winrig/releases/latest/download/winrig-v0.1.0-x86_64-unknown-linux-musl.sha256
sha256sum -c winrig-v0.1.0-x86_64-unknown-linux-musl.sha256
tar xzf winrig-v0.1.0-x86_64-unknown-linux-musl.tar.gz
install -m 0755 winrig ~/.local/bin/winrig

Архивы называются winrig-v<версия>-<таргет>, где таргет — один из x86_64-unknown-linux-musl, aarch64-unknown-linux-musl, x86_64-apple-darwin, aarch64-apple-darwin или x86_64-pc-windows-msvc. На macOS архив aarch64 — для Apple Silicon, x86_64 — для Intel; подходят и tar, и unzip, потому что в архиве рядом с бинарём лежат LICENSE и README.md.

Чтобы собрать из исходников, см. Быстрый старт.

Быстрый старт

Соберите один раз:

cargo build --release

Создайте шифрованный профиль. Пароль читается без эха, токен печатается ровно один раз:

./target/release/winrig setup corp --user 'DOMAIN\your-ad-username'

Команда печатает токен доступа и JSON-определение MCP-сервера. Либо вставьте определение в клиент вручную, либо дайте setup записать его за вас (конфиг обновляется на месте, чужие записи не трогаются):

./target/release/winrig setup corp --user 'DOMAIN\your-ad-username' --write-config opencode --scope global
./target/release/winrig setup corp --user 'DOMAIN\your-ad-username' --write-config claude-code --scope project

--write-config требует уровень. Передайте --scope global для пользовательского конфига или --scope project для текущего репозитория; без флага setup спрашивает в терминале, а в неинтерактивном запуске (скрипт, CI) отказывает и указывает на --scope.

Запись называется так же, как та, что уже обслуживает этот профиль, поэтому повторный setup обновляет её на месте, а не добавляет вторую. Это важно: две записи на один профиль поднимают два процесса, второй теряет блокировку профиля и выходит, а клиент сообщает лишь MCP error -32000: Connection closed. Когда профиль ещё никем не обслуживается, имя — winrig; --server-name задаёт его явно.

Поддерживаемые клиенты: opencode, claude-code, codex, cursor. Project-уровень находит ближайший каталог-предок с .git (с откатом к текущему каталогу) и пишет в <root>/opencode.json, <root>/.mcp.json, <root>/.codex/config.toml или <root>/.cursor/mcp.json; global-уровень сохраняет пользовательские пути. Для opencode токен пишется в отдельный файл 0600 и подставляется ссылкой {file:...}, поэтому он никогда не лежит внутри конфига; на project-уровне этот файл живёт в WINRIG_STATE_DIR, а не в репозитории. Для остальных трёх токен пишется в конфиг клиента значением; на project-уровне такой файл обычно коммитится, поэтому setup печатает предупреждение, а winrig выставляет файлу 0600 на Unix.

Запустите сервер в одном из двух режимов:

# Локальный stdio-процесс для одного клиента (токен приходит из окружения клиента)
WINRIG_TOKEN='<токен из setup>' ./target/release/winrig stdio --profile corp

# HTTP-сервис на 127.0.0.1:8005/mcp для нескольких проектов
WINRIG_TOKEN='<токен из setup>' ./target/release/winrig serve --profile corp

# Переопределить адрес из командной строки (важнее окружения)
./target/release/winrig serve --profile corp --port 9000 --host 0.0.0.0

# Передать секреты аргументами вместо окружения (важнее окружения)
./target/release/winrig serve --profile corp --token '<токен из setup>'
./target/release/winrig serve --auth-token '<общий секрет>'

Флаги --token и --auth-token перекрывают WINRIG_TOKEN и WINRIG_AUTH_TOKEN. Секрет, переданный аргументом, виден в списке процессов, поэтому предпочитайте окружение или конфиг клиента, где это возможно.

Определение сервера, которое печатает и записывает setup, включает WINRIG_TOKEN, WINRIG_PROFILE_DIR и WINRIG_STATE_DIR, поэтому клиент находит профиль даже при нестандартных каталогах.

Чтобы оставить путь по заголовкам вместо профиля, задайте общий секрет и обойдитесь без профиля:

echo "WINRIG_AUTH_TOKEN=$(openssl rand -base64 32)" >> .env
set -a; . ./.env; set +a
./target/release/winrig serve

В HTTP-режиме привязка по умолчанию — 127.0.0.1:8005, эндпоинт — /mcp. Нужен хотя бы один секрет: сервер отказывает в старте, если нет ни токена профиля, ни WINRIG_AUTH_TOKEN.

Профили

winrig setup corp --user 'DOMAIN\user'   # создать; печатает токен один раз
winrig setup corp --user 'DOMAIN\user' --overwrite   # заменить существующий профиль
winrig list                              # таблица: NAME, USER, PATH; секретов нет
winrig list --json                       # те же данные в JSON
winrig rotate corp                       # перешифровать под свежим токеном
winrig forget corp                       # удалить профиль (идемпотентно)

Файл профиля — corp.json в каталоге профилей: версия формата, каноническое имя учётной записи, соль HKDF-SHA256, nonce XChaCha20-Poly1305 и шифртекст; имя учётной записи связано как associated data. На Unix файл 0600 внутри каталога 0700; более широкие права дают предупреждение, а не отказ. Неверный токен и повреждённый файл различаются в журнале, но клиенту оба отвечают 401. Если WINRIG_AUTH_TOKEN совпал с токеном профиля, старт отказывает.

Учётная запись задаётся как DOMAIN\user; деление для NTLM повторяет spnego (движок requests-ntlm, использовавшийся в Python-сервере): имя делится по первому обратному слэшу, UPN (user@realm) или голое имя остаются целыми с пустым доменом. Профиль хранит учётную запись в каноническом нижнем регистре, и то же значение уходит на хост; NTLM сам приводит имя пользователя к верхнему регистру, когда строит хеш, поэтому регистр домена на результат не влияет.

Один процесс на профиль: lock-файл в каталоге состояния профиля останавливает второй процесс на том же профиле и указывает на HTTP-режим. Изменения профиля на диске вступают в силу при следующем старте. Пароль профиля по-прежнему подчинён блокировке учётной записи AD; если его отвергли дважды в разных окнах блокировки, профиль отказывает до перезапуска процесса, и вам следует выполнить setup заново.

Конфигурация

Всё настраивается через окружение; файла конфигурации нет. Файл профиля — не конфигурация, а хранилище шифртекста (ADR-0009).

Переменная По умолчанию Назначение
WINRIG_AUTH_TOKEN Общий секрет для пути по заголовкам; запрос обязан предъявить его как Authorization: Bearer <token> или X-MCP-Token. Не обязателен, когда используется токен профиля
WINRIG_PROFILE Имя профиля; опускается, когда профиль ровно один, обязательно при нескольких
WINRIG_TOKEN Токен доступа, напечатанный setup; обязателен в stdio-режиме и для пути профиля в HTTP
WINRIG_PROFILE_DIR каталог конфигов ОС Переопределяет каталог профилей (~/.config/winrig на Linux)
WINRIG_STATE_DIR каталог состояния ОС Переопределяет корень каталога состояния; winrig сам добавляет имя профиля, поэтому блокировки и журналы по умолчанию ложатся в <WINRIG_STATE_DIR>/<профиль>. Указывайте корень, а не каталог самого профиля, иначе блокировка уедет на уровень в сторону от того места, где её ждёт конфиг
WINRIG_BIND_HOST 127.0.0.1 Адрес, который слушает HTTP-сервер
WINRIG_PORT 8005 Порт, который слушает HTTP-сервер
WINRIG_PASSWORD_TTL_SECONDS 3600 Сколько живёт закэшированный пароль AD без использования. 0 отключает истечение. В режиме профиля ограничивает лишь то, как долго расшифрованный пароль остаётся в памяти; повторный ввод он не вызывает никогда
WINRIG_LOG_DIR каталог состояния профиля Каталог для winrig.log и winrig-audit.log. Создаётся 0700, файлы 0600
WINRIG_LOG_LEVEL INFO Уровень журнала сервера (DEBUG, INFO, WARNING, ERROR, CRITICAL). На аудит не влияет, тот пишется всегда
WINRIG_LOG_MAX_BYTES 10485760 Размер, при котором журнал ротируется
WINRIG_LOG_BACKUP_COUNT 5 Сколько ротированных файлов хранится на журнал
WINRIG_AUDIT_MAX_OUTPUT_CHARS 2000 Сколько символов stdout/stderr на вызов сохраняется в аудите
WINRIG_AUDIT_LOG_BODY 1 0, false, no или off пишут только метаданные вызова: ни текста команды, ни вывода
WINRIG_CONFIRM_TIMEOUT_SECONDS 300 Сколько модифицирующий инструмент ждёт ответа подтверждения, прежде чем отказать (fail-closed)
WINRIG_LOCKOUT_ATTEMPTS 3 Число неудачных попыток пароля AD, после которого пароль не предъявляется до конца окна блокировки
WINRIG_LOCKOUT_WINDOW_SECONDS 1800 Сколько секунд отвергнутый пароль не повторяется
WINRIG_SECRET_REDACT_MIN_LENGTH 4 Кратчайший секрет, вырезаемый из ответа агенту. Аудит и файлы журнала вырезают секреты любой длины, безусловно
WINRIG_ALLOWED_HOSTS (пусто) Allowlist через запятую; пустое значение разрешает любой хост. Запись — точное имя хоста или IP (без учёта регистра); запись, начинающаяся с ., совпадает по суффиксу
WINRIG_ALLOW_INSECURE_TLS true Принимается ли verify_cert=false. false отвергает такой вызов до любой сетевой активности
WINRIG_ALLOW_FILE_WRITE false Существует ли инструмент write_file. Пока false, он удалён из роутера: не объявляется и не вызывается
WINRIG_MAX_WRITE_BYTES 65536 Наибольшее содержимое, которое принимает write_file, в байтах. Отвергается до сетевой активности. Не может быть меньше одного куска в 2000 байт
WINRIG_SFTP_CRED_TTL_SECONDS 3600 Зарезервировано под инструменты SFTP (пока не портированы); разбирается и проверяется при старте

Безопасность транспорта

winrig отдаёт открытый HTTP на /mcp; TLS-слушателя в бинаре нет. Bearer-токен теперь ключ: кто его перехватит, тот и достигнет сервера, и расшифрует пароль AD. Не привязывайтесь к не-loopback адресу без TLS-терминирующего обратного прокси впереди (nginx, Caddy или ingress). Адрес по умолчанию — 127.0.0.1 именно поэтому: многопользовательское развёртывание предполагает, что прокси аутентифицирует клиентов и передаёт заголовки Authorization, X-AD-User и X-AD-Password без изменений. Удалённый участок WinRM отдельный: используйте use_ssl / порт 5986, когда хоп до Windows-хоста должен быть шифрованным, и держите WINRIG_ALLOW_INSECURE_TLS=false, если самоподписанный сертификат не является намеренным.

Поверх открытого HTTP этот участок WinRM шифрован лишь частично. winrm-rs запечатывает SOAP-тела ключом сессии NTLM, но ключа не существует, пока не завершится рукопожатие, поэтому первый запрос на каждом новом соединении несёт своё тело открытым текстом рядом с сообщением Type 3; запечатаны только последующие запросы на этом keep-alive соединении. Для winrig первое тело — это shell Create, а не скрипт, — но хост, отвечающий на незашифрованное сообщение пустым HTTP 500 (AllowUnencrypted=false, умолчание Windows), отвергнет этот первый запрос сразу. Порт 5986 снимает и экспозицию, и отказ.

Настройка клиента

Есть две формы запроса. С токеном профиля секрет — это токен, а идентичность берётся из профиля, поэтому X-AD-User не нужен. С общим секретом запрос обязан нести WINRIG_AUTH_TOKEN и X-AD-User; токен проверяется прежде, чем X-AD-User получает доверие, потому что этот заголовок — ключ кэша паролей и сессий в памяти.

WINRIG_AUTH_TOKEN обязателен только на пути по заголовкам. X-AD-Password необязателен на уровне HTTP, но нужен, чтобы открыть сессию, если пароль не даёт профиль: winrig не запрашивает пароли через elicitation, потому что спецификация MCP исключает из неё секреты, а ревизия протокола 2026-07-28 убирает elicitation целиком (см. docs/adr/0006-password-header-and-confirmation.md).

Пути ниже — пользовательские, записываемые --scope global; при --scope project та же запись уходит в проектный файл, перечисленный в «Быстром старте».

opencode (~/.config/opencode/opencode.json)

Пишется setup --write-config opencode --scope global; токен подставляется из приватного файла:

{
  "mcp": {
    "winrig": {
      "type": "local",
      "command": ["/path/to/winrig", "stdio", "--profile", "corp"],
      "environment": { "WINRIG_TOKEN": "{file:~/.config/opencode/winrig-token}" },
      "disabled": false
    }
  }
}

Claude Code

Пишется setup --write-config claude-code --scope global в блок mcpServers файла ~/.claude.json. Эквивалент через CLI:

claude mcp add winrig -- /path/to/winrig stdio --profile corp

Codex (~/.codex/config.toml)

Пишется setup --write-config codex --scope global:

[mcp_servers.winrig]
command = "/path/to/winrig"
args = ["stdio", "--profile", "corp"]

[mcp_servers.winrig.env]
WINRIG_TOKEN = "<токен из setup>"

Cursor (~/.cursor/mcp.json)

Пишется setup --write-config cursor --scope global в блок mcpServers. HTTP-форма работает одинаково для любого клиента: направьте его на streamable-HTTP эндпоинт и передайте Authorization: Bearer <token>.

Любой другой MCP-клиент работает так же: либо используйте stdio-определение, напечатанное setup, либо направьте клиент на HTTP-эндпоинт с токеном профиля в качестве bearer.

Подтверждения на клиентах без elicitation

Модифицирующие инструменты подтверждаются через MCP elicitation и отказывают (fail-closed), когда клиент не может спросить. opencode 1.18.31 объявляет только roots, поэтому инструменты записи отказываются там работать и говорят об этом, вместо того чтобы действовать без подтверждения; инструменты только для чтения работают нормально. Замена каналу (input_required, SEP-2322) отслеживается в docs/ROADMAP.md и docs/QUESTIONS.md Q-10.

Журналирование

WINRIG_LOG_DIR хранит winrig.log и аудит winrig-audit.log; каталог создаётся 0700, файлы 0600, права переприменяются при каждой ротации.

Аудит записывает каждый вызов с текстом PowerShell и выдержкой из его вывода. Поскольку в этом выводе могут быть содержимое файлов, данные реестра, списки учётных записей и сертификаты, по умолчанию пишутся только первые WINRIG_AUDIT_MAX_OUTPUT_CHARS символов — агент всё равно получает полный ответ. Задайте WINRIG_AUDIT_LOG_BODY=0, чтобы писать только метаданные вызова.

В stdio-режиме stdout несёт только JSON-RPC: журнал сервера и аудит уходят в stderr и в каталог состояния профиля, поэтому клиент, запускающий winrig stdio, никогда не видит строк журнала, подмешанных в протокол.

Разработка

cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --check
cargo deny check
cargo build --release

Закреплённый тулчейн лежит в rust-toolchain.toml; CI выполняет те же команды плюс cargo-audit и сборку на MSRV (rust-version в Cargo.toml). Живого Windows-хоста в окружении разработки нет. Тесты работают на фиктивном WinRmTransport, который записывает переданные ему команды, и сети не касаются; tests/http_gate.rs проверяет реальную обвязку axum+rmcp /mcp, а tests/stdio_mode.rs запускает настоящий бинарь поверх stdio. Канон проекта, требования, ADR и цикл ревью живут в AGENTS.md и docs/.

Релизы

Релиз ставится так: поднять version в Cargo.toml, добавить соответствующую запись в CHANGELOG.md и отправить тег vX.Y.Z. Тег запускает .github/workflows/release.yml: GitHub Release создаётся из записи changelog, а бинарь собирается под пять таргетов и прикладывается с контрольной суммой sha256. Workflow отказывает, если тег и версия в Cargo.toml расходятся.

Workflow Триггер Что делает
ci.yml каждый push и pull request fmt, clippy, test, release-сборка, сборка на MSRV, cargo-audit, cargo-deny
release.yml тег vX.Y.Z пишет GitHub Release и загружает архивы платформ с контрольными суммами

Лицензия

MIT — см. LICENSE.

from github.com/fgbm/winrig

Installing Winrig

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/fgbm/winrig

FAQ

Is Winrig MCP free?

Yes, Winrig MCP is free — one-click install via Unyly at no cost.

Does Winrig need an API key?

No, Winrig runs without API keys or environment variables.

Is Winrig hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Winrig in Claude Desktop, Claude Code or Cursor?

Open Winrig on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Winrig with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All development MCPs