oswright
OSWright
Автоматизация рабочего стола для ИИ-агентов без оплаты скриншота на каждом шаге.
mcp-name: io.github.Ask-812/oswright
Это MCP-сервер, который позволяет LLM управлять реальными настольными приложениями — настольный аналог Playwright MCP. Он сохраняет модель экрана между действиями и повторно считывает только изменившиеся части, поэтому та же работа обходится на порядок дешевле по токенам.

Восемь полей считываются со счёта и вводятся в форму расходов; корректность проверяет само приложение. Та же задача, тот же результат — в 7.4× меньше контекста, чем при возврате скриншота после каждого действия. Каждое число на экране замеряется во время запуска — воспроизведите всё заново с помощью python benchmarks/record_demo.py.
Зачем это нужно
Большинство GUI-агентов заново воспринимают весь экран на каждом шаге: скриншот, OCR, передача изображения модели — и так по кругу. При замерах на живом рабочем столе медианное изменение занимает 0.012% пикселей экрана. Повторное чтение всего экрана делает гораздо больше работы, чем оправдано изменением, и обходится в ~2,800 токенов изображения независимо от того, произошло ли что-нибудь.
OSWright спрашивает у композитора, что изменилось, повторно сканирует только это и отвечает на запросы элементов из самого дешёвого источника, который может. Приведённые ниже утверждения измерены на этой машине и воспроизводимы из benchmarks/ — включая те, которые оказались не в его пользу.
Ключевые возможности
Кроссплатформенность. Windows (Win32 API), Linux (pynput/X11), macOS (pynput/Quartz).
Дерево специальных возможностей. Детерминированный поиск элементов по роли и имени через Windows UI Automation — точность 100%, мгновенно, без модели.
Быстрый OCR. Windows OCR (встроенный, мгновенный) с запасным вариантом EasyOCR для Linux/macOS. Результаты кэшируются автоматически.
Лёгкий на Windows. Без загрузки PyTorch — Windows использует встроенный OCR-движок, поэтому полная установка занимает несколько МБ, а не несколько ГБ.
Сопоставление изображений. Находит элементы по шаблонному изображению с помощью OpenCV.
Управление окнами. Список, фокус, сворачивание, закрытие и снятие скриншотов конкретных окон.
Сравнение скриншотов. Определение изменения экрана с помощью
wait_for_change.Доступ к буферу обмена. Чтение и запись системного буфера обмена для передачи данных.
Запуск приложений. Запуск приложений и ожидание их загрузки.
Автоснимок. Каждое действие возвращает скриншот, поэтому агент всегда видит текущее состояние.
43 MCP-инструмента. Экран, OCR, UIA, мышь, клавиатура, окна, буфер обмена и составные действия.
Инкрементальное восприятие. Повторно сканирует только изменившиеся части экрана и может вернуть изменения вместо полного скриншота — ~21× меньше токенов на шаг.
Память экрана. Распознаёт ранее прочитанные экраны и переиспользует их, проверяя по пикселям — в 89 раз дешевле повторного чтения.
Спекулятивное восприятие. Изучает, что делают действия, и подтверждает ожидаемый результат вместо повторного чтения — в 19–23 раза дешевле, с отчётом
surprise, когда интерфейс ведёт себя неожиданно.Адаптивное ожидание. Ждёт, пока экран действительно установится, а не спит фиксированные 300 мс — экономия 11.9 с за задачу из 50 шагов.
Каскад разрешения запросов. Поиск элементов останавливается на самом дешёвом работающем методе; повторные запросы стоят ~0.05 мс.
Корректность DPI. Координаты везде в физических пикселях, поэтому клики попадают точно на масштабированных дисплеях.
Набор тестов. 237 автоматических тестов; тесты, управляющие рабочим столом, пропускают себя при отсутствии дисплея.
Требования
Python 3.10 или новее
VS Code, Cursor, Windsurf, Claude Desktop или любой другой MCP-клиент
Начало работы
Сначала установите MCP-сервер OSWright в вашем клиенте.
Стандартная конфигурация работает в большинстве инструментов:
{
"mcpServers": {
"oswright": {
"command": "uvx",
"args": ["oswright"]
}
}
}Примечание: Если у вас нет
uvx, можно использоватьpip install oswright, а затем указать"command": "oswright"напрямую.
Следуйте руководству по установке MCP, используйте стандартную конфигурацию выше.
claude mcp add oswright uvx oswrightДобавьте в ваш пользовательский или рабочий settings.json в раздел mcp.servers:
{
"mcp": {
"servers": {
"oswright": {
"command": "uvx",
"args": ["oswright"]
}
}
}
}Или используйте CLI VS Code:
code --add-mcp '{"name":"oswright","command":"uvx","args":["oswright"]}'Перейдите в Cursor Settings -> MCP -> Add new MCP Server. Назовите его oswright, используйте тип command с командой uvx oswright.
Следуйте документации Windsurf MCP. Используйте стандартную конфигурацию выше.
Добавьте в ваш cline_mcp_settings.json:
{
"mcpServers": {
"oswright": {
"type": "stdio",
"command": "uvx",
"args": ["oswright"],
"disabled": false
}
}
}Перейдите в Advanced settings -> Extensions -> Add custom extension. Назовите его oswright, используйте тип STDIO и укажите command как uvx oswright.
Если вы предпочитаете обычную установку через pip:
pip install oswrightЗатем используйте эту конфигурацию:
{
"mcpServers": {
"oswright": {
"command": "oswright"
}
}
}Или запустите напрямую:
python -m oswrightRelated MCP server: AutoFlow
Инкрементальное восприятие
Большинство GUI-агентов заново воспринимают весь экран на каждом шаге: полный скриншот, полный OCR, затем передают модели свежее изображение. При замерах на живом рабочем столе медианное изменение составляет 0.012% пикселей — то есть полное повторное сканирование выполняет примерно в 240 раз больше работы, чем оправдано изменением, а возвращаемый скриншот стоит ~2,800 токенов изображения независимо от того, произошло ли что-то.
OSWright сохраняет модель экрана между наблюдениями и повторно сканирует только те области, которые действительно изменились.
observe() -> {"changed": true,
"added": [{"text": "Saved", "x": 812, "y": 447}],
"removed": ["Unsaved changes"],
"screen_fraction_scanned": 0.015}Замерено на этой машине в цикле агента из 14 шагов:
v0.4.0 (полный OCR + скриншот) | инкрементальный | |
Медианная задержка на шаг | 212 ms | 33 ms |
Токенов на наблюдение | ~2,764 | ~49 |
Токенов за 14 шагов | 38,696 | 1,025 |
Повторное чтение экрана | 100% | 16% |
Чем насыщеннее экран, тем больше разрыв: полный OCR масштабируется от объёма текста на экране, тогда как инкрементальный путь — от того, сколько изменилось. То же сравнение показывает 6.5× на спокойном рабочем столе и 14.3× при открытой плотной веб-странице. Перепроверьте на benchmarks/, а не полагайтесь на эти цифры.
Однако стоимость — это лишь прокси, и более дешёвый путь восприятия, который незаметно ухудшает точность, был бы хуже, чем никакого. Поэтому он проверяется по завершению задач: скриптовые задачи, управляющие реальным интерфейсом в четырёх приложениях, оцениваются по состоянию самого приложения — UI Automation для Calculator и Explorer, заголовок окна для Chrome и VS Code — но никогда по OCR.
Конфигурация | Calculator | File Explorer | Chrome | токены |
стиль v0.4 (полный скриншот) | 9/9 | 3/3 | 3/3 | 118,858 |
только дельта | 9/9 | 3/3 | 3/3 | 5,252 |
дельта + память | 9/9 | 3/3 | 3/3 | 5,099 |
дельта + память + прогнозирование | 9/9 | 3/3 | 3/3 | 7,981 |
Точность идентична во всех конфигурациях, при том что стоимость в токенах падает в 23 раза. Запустите это с помощью python benchmarks/bench_tasks.py.
Почему нужны и пиксели, и специальные возможности
Конструкция исходит из того, что ни один путь восприятия не выигрывает везде. Отключение каждой половины позволяет это измерить, а не просто утверждать:
Конфигурация | Calculator | File Explorer | Chrome |
полный каскад | 9/9 | 3/3 | 3/3 |
только специальные возможности | 9/9 | 0/3 | 0/3 |
только пиксели | 6/9 | 3/3 | 3/3 |
Подход «только специальные возможности» — которого придерживается большинство Windows-GUI-агентов — безупречен на XAML и слеп к представлению списка Win32 и веб-содержимому. При проверке на VS Code он видит 18 элементов — вся IDE является одним узлом с именем Chrome Legacy Window, тогда как OCR считывает 94 элемента, включая все имена файлов.
Подход «только пиксели» не справляется с кнопками Calculator, потому что кнопка, которую человек читает как 7, называется Seven, а Windows OCR вообще не возвращает цифры из Calculator.
Каскад — единственная конфигурация, которая проходит везде.
Каскад разрешения запросов
find_element и click_element останавливаются на первом методе, который может дать ответ, поэтому стоимость зависит от того, насколько нов запрос, а не от размера экрана:
Уровень | Метод | Типичная стоимость |
0 | Уже в модели экрана | ~0.05 ms |
1 | Повторное сканирование только изменений | ~70 ms |
2 | Дерево специальных возможностей (знает, что Button — это кнопка) | ~40 ms |
3 | Собственный текстовый буфер приложения через UIA TextPattern — точные символы | ~400 ms |
4 | Полноэкранный OCR | ~250 ms |
Поиск текста, который модель уже знает, обходится примерно в ~5,000 раз дешевле, чем путь v0.4.0 (0.05 мс против 244 мс). В ответе сообщается, какой уровень ответил, так что вы видите реальную стоимость задачи.
Уровень 3 стоит понять: TextRange.FindText из UIA ищет в собственном текстовом буфере приложения и возвращает точные ограничивающие прямоугольники. Он невосприимчив к шрифту, DPI, сглаживанию и ошибкам OCR. Он находится ниже пиксельных уровней только потому, что сканирование элементов окна для него стоит несколько сотен миллисекунд межпроцессного COM, — это точный уровень, а не быстрый.
Примечание о порядке. Уровни упорядочены по измерениям, а не по теории. Распространённый совет — делать дерево специальных возможностей основным, но в реальных приложениях оно не всегда дешевле: обход дерева Chrome здесь занял 537 мс, что медленнее полноэкранного прохода OCR, а VS Code открыл ему только 18 элементов. Ни пиксели, ни специальные возможности не выигрывают везде, поэтому это каскад, а не выбор.
Спрашиваем композитора вместо просмотра
В Windows композитор рабочего стола уже знает, какие пиксели изменились, и предоставляет их через DXGI Desktop Duplication. Запрос к нему стоит 0.14 мс и не передаёт ни одного пикселя, тогда как захват кадра и обнаружение его идентичности занимают десятки миллисекунд — поэтому в отсутствие изменений наблюдение пропускает захват полностью.
Когда что-то всё же изменилось, композитор остаётся с этим кадром, поэтому его пиксели читаются напрямую с GPU, а не захватываются повторно через другой API, — по замерам здесь это в 1.5–2.3 раза быстрее, чем mss.
Композитор используется только как быстрый отрицательный сигнал для обнаружения изменений. Когда он сообщает об изменении, грязные области по-прежнему получаются хэшированием захваченного кадра: эти два процесса измеряются на слегка разных интервалах, поэтому прямоугольники композитора могут занижать объём относительно реально захваченных пикселей, а заниженная область — это текст, который никогда не будет перечитан. Там, где Desktop Duplication недоступен, механизм незаметно деградирует до хэширования тайлов и обычного захвата.
Включите дельта-наблюдения для инструментов действий с помощью --observation-mode delta. По умолчанию остаётся screenshot для совместимости с существующими клиентами.
Воспроизведите всё это самостоятельно: см. benchmarks/.
Обоснование каждого решения, включая тупиковые варианты, приведено в
docs/ENGINEERING_LOG.md.
Конфигурация
MCP-сервер OSWright поддерживает следующие аргументы. Их можно указать в JSON-конфигурации в составе списка "args":
Option | Description | Переменная окружения |
| Порт для SSE-транспорта. Если не указан, используется stdio (по умолчанию). |
|
| Хост, к которому привязывается HTTP/SSE-сервер. По умолчанию: |
|
| Протокол транспорта: | |
| Языки OCR (по умолчанию: |
|
| Тайм-аут по умолчанию для операций автоматического ожидания (по умолчанию: |
|
| Уменьшает автоматический снимок, возвращаемый после каждого действия. |
|
| Что возвращают инструменты действий: |
|
| Не запоминать экраны между посещениями. |
|
| Не предсказывать исход действий. |
|
| Требуется для привязки к адресу, отличному от loopback. См. Безопасность. | |
| Уровень логирования: |
|
Явный флаг командной строки всегда имеет приоритет над соответствующей переменной окружения.
Пример: многоязычный OCR
{
"mcpServers": {
"oswright": {
"command": "uvx",
"args": ["oswright", "--ocr-languages", "en", "es", "fr"]
}
}
}Автономный MCP-сервер (SSE)
При запуске из рабочего процесса или с другой машины используйте SSE-транспорт:
uvx oswright --port 8931Затем в конфигурации вашего MCP-клиента:
{
"mcpServers": {
"oswright": {
"url": "http://127.0.0.1:8931/sse"
}
}
}Безопасность
OSWright не имеет аутентификации. Любой, кто может подключиться к порту, получает полный контроль над клавиатурой, мышью, экраном и буфером обмена машины — это захват удалённого рабочего стола, а не изолированный API.
Поэтому сервер по умолчанию привязывается к 127.0.0.1 и отказывается запускаться на
адресе, отличном от loopback, если вы не передадите --allow-remote. Чтобы подключиться к нему
с другой машины, предпочтите SSH-туннель открытию порта:
ssh -L 8931:127.0.0.1:8931 user@desktop-hostТранспорт stdio (используемый по умолчанию во всех конфигурациях MCP-клиента выше) вообще не открыт для сети, и это рекомендуемый способ запуска OSWright.
Инструменты, которые могут уничтожить работу, помечены соответствующим образом: close_window отмечен
как разрушительный, а launch_app запускает произвольные программы. Инструменты создания снимков
отказываются перезаписывать существующий save_path.
Примечания о платформах
Platform | Input Backend | OCR Backend | Extra downloads |
Windows | Win32 API (SendInput) | Windows OCR (мгновенный, встроенный) | Нет. PyTorch не нужен. UI Automation включён. |
Linux | pynput (X11) | EasyOCR | PyTorch (~2.5 ГБ). Требуется X11; поддержка Wayland ограничена. |
macOS | pynput (Quartz) | EasyOCR | PyTorch (~2.5 ГБ). Предоставьте разрешения для специальных возможностей в System Settings > Privacy > Accessibility. |
В Windows EasyOCR не устанавливается, потому что встроенный движок Windows OCR быстрее и не требует загрузки модели. Устанавливайте его, только если вам нужен язык, который Windows OCR не поддерживает:
pip install "oswright[easyocr]"Координаты
Все координаты, возвращаемые OCR, сопоставлением изображений и UI Automation, — это абсолютные
физические пиксели экрана, готовые для прямой передачи в mouse_click. Это справедливо для
подобластей и для многомониторных конфигураций, где виртуальный рабочий стол начинается с
отрицательного начала координат. screenshot также сообщает origin_x/origin_y — абсолютную
позицию верхнего левого пикселя изображения, на случай если вы сами считываете координату с
изображения.
Инструменты
screenshot -- Сделать снимок экрана или области. Возвращает изображение как нативное содержимое изображения MCP. При необходимости сохраняет в файл по указанному пути.
Только чтение: true
get_screen_info -- Получить размеры экрана и количество мониторов.
Только чтение: true
find_text_on_screen -- Найти все вхождения текста на экране с помощью OCR. Возвращает совпадения с координатами и уверенностью.
Параметры:
text,exact, границы области,monitorТолько чтение: true
read_screen_text -- Прочитать ВЕСЬ видимый текст на экране с помощью OCR. Возвращает каждый обнаруженный текстовый элемент с позицией.
Параметры: границы области,
monitorТолько чтение: true
find_image_on_screen -- Найти все вхождения шаблонного изображения на экране с помощью сопоставления шаблонов OpenCV.
Параметры:
template_path,threshold,monitorТолько чтение: true
mouse_click -- Кликнуть мышью по координатам или в текущей позиции. Возвращает снимок экрана.
Параметры:
x,y,button,clicks
mouse_double_click -- Дважды кликнуть по координатам или в текущей позиции. Возвращает снимок экрана.
mouse_move -- Переместить курсор мыши в координаты экрана.
mouse_scroll -- Прокрутить колесо мыши. Возвращает снимок экрана.
Параметры:
amount,x,y
mouse_drag -- Перетащить из одной точки в другую. Возвращает снимок экрана.
Параметры:
start_x,start_y,end_x,end_y,button,duration
get_mouse_position -- Получить текущую позицию курсора мыши.
Только чтение: true
type_text -- Ввести текст посимвольно. Возвращает снимок экрана.
Параметры:
text,delay
press_key -- Нажать клавишу или комбинацию, например
Enter,Ctrl+C,Alt+Tab. Возвращает снимок экрана.Параметры:
key
click_text -- Найти текст через OCR и кликнуть по нему. Автоматически повторяет попытки до обнаружения или истечения тайм-аута. Возвращает снимок экрана.
Параметры:
text,exact,button,timeout,poll_interval,monitor
double_click_text -- Найти текст через OCR и дважды кликнуть по нему. Возвращает снимок экрана.
right_click_text -- Найти текст через OCR и кликнуть по нему правой кнопкой мыши. Возвращает снимок экрана.
hover_text -- Найти текст через OCR и навести на него курсор. Возвращает снимок экрана.
fill_field -- Найти метку, кликнуть по ней, очистить её и ввести значение. Возвращает снимок экрана.
Параметры:
target_text,value,exact,timeout,monitor
fill_form -- Заполнить несколько полей за один вызов. Сокращает количество циклов запроса/ответа.
Параметры:
fields(список из{label, value}),timeout,monitor
wait_for_text -- Ждать появления текста на экране. Опрашивает через OCR.
Параметры:
text,exact,timeout,poll_interval,monitorТолько чтение: true
wait_for_text_gone -- Ждать исчезновения текста с экрана.
Параметры:
text,exact,timeout,poll_interval,monitorТолько чтение: true
wait_for_time -- Ждать в течение указанного времени (не более 30 с), затем сделать снимок экрана.
list_windows -- Вывести список всех видимых окон. При необходимости фильтрует по подстроке заголовка.
Параметры:
title_filterТолько чтение: true
focus_window -- Вывести окно на передний план по заголовку. Возвращает снимок экрана.
Параметры:
title
close_window -- Закрыть окно по заголовку (отправляет WM_CLOSE). Возвращает снимок экрана.
Параметры:
title
minimize_window -- Свернуть окно по заголовку. Возвращает снимок экрана.
Параметры:
title
screenshot_window -- Сделать снимок экрана только одного окна.
Параметры:
title,save_pathТолько чтение: true
get_clipboard -- Получить текущее текстовое содержимое системного буфера обмена.
Только чтение: true
set_clipboard -- Скопировать текст в системный буфер обмена.
Параметры:
text
launch_app -- Запустить приложение и при необходимости дождаться его загрузки. Запускает программу напрямую, без использования оболочки.
Параметры:
command,args,wait_text,timeoutСообщает
wait_text_found, чтобы вы могли определить, действительно ли приложение загрузилось.
get_ocr_info -- Получить информацию об активном OCR-бэкенде и доступных бэкендах.
Только чтение: true
observe -- Сообщить, что изменилось на экране с момента последнего наблюдения. Повторно сканирует только области, которые изменились. Для отслеживания состояния предпочитайте этот инструмент
screenshot.Параметры:
force_fullТолько чтение: true
find_element -- Найти текст на экране самым экономичным методом, который может дать ответ. Сообщает, какая ступень каскада ответила.
Параметры:
text,exact,window_titleТолько чтение: true
click_element -- Найти текст через каскад и кликнуть по нему. Экономичная альтернатива
click_text.Параметры:
text,exact,button,window_title
read_model_text -- Прочитать текст с экрана из инкрементальной модели без повторного OCR-сканирования дисплея.
Параметры:
query,limitТолько чтение: true
perception_stats -- Сообщить, сколько работы по восприятию модель помогла избежать.
Только чтение: true
remember_screen -- Запомнить текущий экран, чтобы будущие посещения пропускали его чтение. Сохраняется между сеансами.
Только чтение: true
atlas_stats -- Сообщить, что запомнил атлас экрана и как часто он помогал.
Только чтение: true
get_ui_tree -- Получить дерево специальных возможностей сфокусированного окна. Возвращает все интерактивные элементы с именами, типами, позициями. Детерминированно и мгновенно.
Параметры:
window_title,max_depthТолько чтение: true
click_ui_element -- Нажать элемент интерфейса, используя дерево специальных возможностей. Надёжнее, чем OCR.
Параметры:
name,control_type,automation_id,window_title
fill_ui_element -- Задать значение элемента интерфейса (например, текстового поля). Надёжнее, чем заполнение через OCR.
Параметры:
value,name,automation_id,window_title
get_active_window -- Получить информацию о текущем сфокусированном окне.
Только чтение: true
wait_for_change -- Ожидать визуального изменения экрана. Делает базовый снимок экрана и опрашивает, пока изображение не изменится.
Параметры:
timeout,poll_interval
Python-библиотека
OSWright также работает как самостоятельная Python-библиотека с API в стиле Playwright:
from oswright import OSWright
with OSWright() as ow:
screen = ow.screen()
screen.click(text="Start")
screen.type_text("Hello World")
screen.press("Ctrl+S")
screen.screenshot("desktop.png")Дополнительные примеры см. в каталоге examples/.
Архитектура
oswright/
__init__.py # Package entry point (single source of __version__)
core.py # OSWright class (= Browser)
screen.py # Screen class (= Page)
locator.py # Locator + Assertions (= Locator + expect)
capture.py # Screen capture (mss - cross-platform, thread-safe)
dirty.py # Change detection - which parts of the screen moved
screenmodel.py # Persistent screen model, updated incrementally
cascade.py # Resolution cascade - cheapest method that can answer
atlas.py # Remembers screens across visits and sessions
settle.py # Knowing when the screen has finished responding
speculate.py # Predicting what an action does, instead of looking
textprovider.py # Exact text from the app itself via UIA TextPattern
detect.py # OCR dispatcher with caching (auto-selects best backend)
_ocr_windows.py # Windows OCR backend (instant, built-in)
accessibility.py # Windows UI Automation (deterministic element finding)
cache.py # Screenshot diffing, image hashing, OCR result cache
_dpi.py # Process DPI awareness (keeps every API in physical pixels)
_dxgi_windows.py # Compositor dirty rectangles via DXGI Desktop Duplication
input.py # Platform dispatcher for input backends
_input_windows.py # Windows input backend (Win32 API)
_input_pynput.py # Linux/macOS input backend (pynput)
window.py # Window management (list, focus, close)
clipboard.py # Clipboard read/write (cross-platform)
mcp_server.py # MCP server (43 tools for AI agents)
tests/
conftest.py # Fixtures that skip when no display/OCR is available
test_core.py # Unit tests (no desktop required)
test_perception.py # Incremental perception (stubbed, runs headless)
test_atlas.py # Screen memory and its failure modes (headless)
test_speculate.py # Prediction, settling, and their limits (headless)
test_e2e.py # End-to-end tests against the real desktop (marked `e2e`)Запоминание экранов
Приложения детерминированы — один и тот же диалог каждый раз имеет одинаковую раскладку. OSWright запоминает экраны, которые он уже прочитал, и повторно использует их при следующем посещении, между сеансами: 125 мс холодное чтение → 1.4 мс тёплое воспроизведение (89×).
Запомненному экрану никогда не доверяют только на основании распознавания. Несколько областей выборочно проверяются по пикселям, прежде чем раскладка будет использована повторно, поэтому экран, который изменился, отклоняется, а не используется. Проверка безопасна при сбое: экран с нечем проверять вообще не запоминается.
Отключается флагом --no-atlas. Запомненные экраны хранятся в ~/.oswright/atlas.json.
Предсказание действий вместо их наблюдения
Приложения детерминированы — нажатие кнопки Save каждый раз приводит к одному и тому же диалогу — поэтому после первого наблюдения исход действия уже известен. OSWright изучает, что делают действия, и подтверждает ожидаемый экран, а не читает его заново: в 19–23 раза дешевле, чем наблюдение (2.3 мс против 43–50 мс).
Предсказание должно подтвердиться дважды, прежде чем ему доверят; оно отменяется, если оказывается
неверным, и проверяется теми же двумя способами, что и запомненный экран. Неудачное
предсказание сообщается агенту как surprise — интерфейс сделал
что-то, чего обычно не делает, и об этом стоит знать, а не молча принимать.
Что гарантирует подтверждённое предсказание: раскладку — те же элементы управления на
тех же местах. Не то, что каждый символ идентичен. Изменение одной цифры
затрагивает меньше пикселей, чем мигающий курсор, поэтому никакая проверка всего экрана не может их различить
ни при каком разрешении. Используйте observe(force_full=True), когда важен точный текст.
Отключается флагом --no-speculate.
Ожидание ровно столько, сколько нужно
Раньше инструменты действий спали фиксированные 300 мс, выбранные по самому медленному случаю, поэтому каждое действие платило за худший случай. Композитор знает, когда экран перестаёт меняться, так что теперь ожидание заканчивается, когда интерфейс действительно устаканивается:
Прежний фиксированный сон | 300 мс |
Медианное фактическое ожидание | 61.5 мс |
Сэкономлено за задачу из 50 шагов | 11.9 с |
«Устаканилось» означает отсутствие значительных изменений в последнее время, а не отсутствие изменений вообще: настоящий рабочий стол никогда не стоит на месте — курсор и часы порождают событие изменения каждые ~18 мс, затрагивающее около 32 пикселей, тогда как настоящие изменения интерфейса затрагивают десятки тысяч.
Что ещё не сделано
Внедрение ввода в Wayland, а также macOS
AXTextMarkerкак эквивалент TextPattern.Ступень на основе зрительной модели для поверхностей, которые не являются ни доступными через специальные возможности, ни читаемыми по тексту: игры, холсты, графические редакторы.
Переходы, зависящие не только от предыдущего экрана, для действий, чей результат зависит от состояния, которое не видно.
Что измеряется, а что нет
Стоимость восприятия и успешность выполнения задач измеряются на этой машине и
воспроизводимы через benchmarks/ — на четырёх приложениях более дешёвое восприятие
не стоит точности, и разбиение на пиксели/специальные возможности измерено, а не
декларируется.
Сравнение с Windows-MCP
Те же задачи, четыре сценария, каждый оценивается самим приложением. Ни один инструмент не оценивает себя сам, а Windows-MCP работает с настройками по умолчанию:
Калькулятор | Проводник | Chrome | Chrome, 2 шага | пройдено | токены | |
oswright | 5/5 | 4/5 | 5/5 | 5/5 | 19/20 | 832 |
Windows-MCP, снимок на каждое действие | 5/5 | 5/5 | 5/5 | 5/5 | 20/20 | 14,053 |
Windows-MCP, один снимок | 5/5 | 5/5 | 5/5 | 5/5 | 20/20 | 8,214 |
Честно прочитаем эти цифры: Windows-MCP оказался надёжнее, а oswright — в 16.9 раза дешевле. oswright потерял один клик из двадцати на окне, которое только что открылось.
Разница в стоимости структурная, а не результат настройки. Windows-MCP возвращает
экран агенту — Snapshot представляет дерево специальных возможностей как
(x,y) button "Seven" [action: click] — и принимает координаты обратно, поэтому
описание экрана списывается в контекст модели при каждом действии.
oswright принимает текст и возвращает результат.
Разрыв в надёжности может быть вызван скоростью: oswright распознаёт и кликает за ~100 мс, иногда до того, как только что сфокусированное окно готово к вводу, тогда как более медленный цикл даёт приложению время, которое оно никогда не просило. Это гипотеза, а не вывод — добавление паузы перед действием не дало измеримой разницы за десять попыток, поэтому это зафиксировано, а не исправлено.
Сценарий Chrome, 2 steps существует потому, что все остальные задачи здесь достаточно коротки,
чтобы инструмент мог прочитать экран один раз и повторно использовать эти координаты. Там
первый клик перемещает элементы управления на 325 px вниз по странице, и конфигурации
с одним снимком пришлось перечитать экран — поэтому для задач, чей интерфейс
двигается, её дешёвого показателя не существует, а реальная стоимость — это стоимость одного действия.
Воспроизводится командой python benchmarks/bench_head_to_head.py (настройка в
docstring файла).
Чего это не доказывает: четыре короткие задачи на одном ноутбуке. Ничего о долгой многошаговой работе, восстановлении или зрелости продукта — у Windows-MCP есть OAuth, аналитика, watchdog и установщик; у oswright нет ничего из этого. Его обход дерева специальных возможностей также читает содержимое страниц Chrome, чего собственный уровень специальных возможностей oswright не делает. «Существенно дешевле за действие, ценой небольшой потери надёжности» — вот утверждение. «Лучший продукт» — нет.
Разработка
pip install -e ".[dev]"
pytest tests/ # everything available on this machine
pytest tests/ -m "not e2e" # unit tests only, no desktop needed
ruff check oswright tests # lint
python benchmarks/bench_pipeline.py # reproduce the performance numbers
python benchmarks/bench_tasks.py # task success (opens Calculator repeatedly)Проектные решения, измерения и тупики зафиксированы в
docs/ENGINEERING_LOG.md.
Лицензия
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.
Memory that reasons: continual learning for stateful agents. Better context, fewer tokens.
Codebase intelligence for agents: 152 structured artifacts across 21 programs, one call.
Shared distillation cache for AI agents — every fetch ~73-89% fewer tokens via a shared cache.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI coding agents to automate Windows desktop applications through semantic UI Automation instead of brittle coordinate clicks, with tools for discovering windows, finding controls by stable identifiers, and verifying actions.1MIT
- FlicenseNot gradedqualityDmaintenanceAutoFlow enables AI agents to automate Windows desktop tasks by visually recognizing screen elements and simulating keyboard and mouse actions, with 18 MCP tools for workflow control.
- AlicenseAqualityAmaintenanceEnables AI agents to query Windows process, window, and console information via structured JSON instead of screenshots, reducing token usage by 94-98%.20511MIT
- AlicenseAqualityBmaintenanceEnables low-cost agent models to control Windows applications through a compact, state-safe proxy over Open Computer Use, reducing model-visible context by up to 99.8% with support for record/replay and reusable UI component memory.5MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ask-812/oswright'
If you have feedback or need assistance with the MCP directory API, please join our Discord server