Skip to main content
Glama

apic

Компилятор из приложения в API. Укажите ему веб-приложение, у которого нет API для агентов. Агент, работающий с компьютером, исследует UI, проверяет найденное, выполняя это, и выдаёт типизированный MCP-сервер для приложения.

Playwright MCP интерпретирует приложение при каждом вызове. apic компилирует его один раз.

Создано в одиночку за один день на {Tech: Europe} × VEED Hackathon, Лондон, 22 августа 2026.

apic-ui.vercel.app — там демо-видео, решения каждой модели-партнёра и результаты замеров компилятора.

Публичные потребительские сайты

apic --read https://example.com компилирует публичную, доступную только для чтения поверхность любого потребительского сайта в MCP-инструменты. Он начинает с этого сайта (плюс необязательные стартовые URL того же сайта), находит поисковые поля, фильтры и повторяющиеся карточки результатов, а затем выдаёт только те инструменты, чьи «строки» переживают чистый перезапуск. Он не исходит из предположения о маршрутах Deliveroo, ресторанной лексике, аккаунте, корзине или оформлении заказа.

Для известной страницы коллекции/товара передайте её явно как прямой стартовый URL того же сайта: APIC_READ_DIRECT_URL=https://example.com/catalog/item apic --read https://example.com. URL, предоставляемые агентом, ограничены тем origin, который был скомпилирован в рецепт.

Один запрос без целевого URL

Когда APIC подключён к MCP-серверу, для обычного пользовательского вопроса используйте fulfill_request вместо compile_app:

{ "request": "Find me the cheapest pizza near 17 & 18 Clere Street" }

Сервер использует Tavily для поиска публичных кандидатных сервисов, OpenAI — для выбора и выполнения скомпилированного сценария, h — для приоритизации неоднозначных контролов чтения, Pioneer — для классификации того, дали ли пробные проверки осмысленные результаты, а fal — только там, где этой классификации нужна визуальная арбитражная проверка. Он пробует небольшой резервный набор из других origins, если кандидат защищён вызовом или не имеет воспроизводимого публичного сценария. Он никогда не входит в систему, не делает заказ, не завершает покупку и не обходит вызов. Выжившие инструменты чистым способом проверяются, возвращаются в качестве подтверждения и регистрируются на том же MCP-сервере для последующих вызовов.


Related MCP server: mcp-apps-demo-engine

Демонстрация

Смотрите на сайте: apic-ui.vercel.app — две минуты, без монтажа: компиляция, появление сгенерированных инструментов, в живую сессию и watcher, который сам замечает изменение UI.

На том же сайте — цифры, о которых говорится в этом README, разбивка по партнёрам и фрагмент для установки для каждого MCP-клиента.

Проблема

Агенты, работающие с компьютером, экономически не масштабируются. Каждый запуск заново извлекает из пикселей одни и те же знания: модель совершает круг за шагом, снимок страницы за шагом заполняет контекстное окно, а надёжность падает с каждым звеном цепочки. Именно поэтому их беспрерывно показывают в демо, но редко внедряют.

Программное обеспечение, которым агентам нужно управлять сильнее всего, — это как раз ПО, которое с наименьшей вероятностью когда-либо получит API: внутренние инструменты, legacy-системы, всё, от чего исчез вендор. Нельзя прочесть сетевую вкладку, в которой ничего нет, и нельзя попросить корпоративное приложение 2011 года внедрить новый протокол.

apic использует дорогого агента один раз, чтобы написать интерфейс. После этого — это просто вызов функции.

Как это работает

Этап

Задача

Технология

Ground

Читает документацию целевого сайта и усваивает существительные этого приложения, чтобы словарь не был захардкожен под Vikunja

Tavily + OpenAI, кэш по хосту — только CLI-путь

Explore

Управляет приложением, ранжирует возможности так, чтобы действия создания шли первыми, открывает формы и отправляет их

Playwright + h (уровень эскалации для контролов, которые словарь не может назвать)

Perceive

Определяет, изменилось ли что-то значимое

DOM-сравнение, обостряет эскалацией до fal на CLI-пути

Synthesise

Превращает траекторию в типизированную схему инструмента

детерминированно — без обращения к модели

Verify

Холодно повторяет инструмент с аргументами, которых приложение никогда не видел

нижняя граница — diff без ключей, затем дообученный судья Pioneer, с OpenAI в резерве

Emit

Создаёт запускаемый MCP-сервер, его схемы и доказательства

Watch

Повторно прогоняет тесты через интервал

Heal

Красный («упавший») инструмент повторно входит в discovery на собственном фиде

Путь восстановления — тот же путь, что и путь построения. «Лечение» не патчит селектор — оно заново про googles discovery, которое первоначально создало инструмент, и сопоставляет по имени, которое выдаёт синтез. Переименованная кнопка по-прежнему даёт createProject.

Инструмент существует только тогда, когда приложение подтвердило запись

Подсчёт узлов DOM даёт правдоподобный инструмент для каждой кнопки на странице. apic выпускает инструмент только тогда, когда само приложение подтверждает, что состояние изменилось, — через три сигнала, отражающих три разных типа поведения приложения:

Поведение

Пример

Сигнал

announce-and-stay

создание метки

баннер успеха в области статуса

announce-and-navigate

создание проекта

баннер переживает смену URL

silent-append

быстрое добавление в канбан

введённое значение появляется как отрисованный контент

relocation

перетаскивание карточки между колонками

карточка сменила контейнер

Перемещение важно, потому что у сервер no banner and no echo — the card already existed. The change of container is the proof; no decorative re-render can produce it.

Рецепты привязаны к идентификации, а не к местоположению

Vikunja на каждой загрузке страницы заново генерирует DOM-идентификаторы, поэтому сохранённый селектор мёртв с самого начала. Рецепт фиксирует, чем поле является — его подпись, placeholder, name — и при воспроизведении повторно резолвит его вживую, в числу it: стабильную селекторную «цепочку» (name → стабильный id → placeholder → and last the generated id).

Результаты

Скомпилировано из интерфейса. Спецификация OpenAPI, предоставленная сайтом, никогда не читается во время компиляции — она используется только как истина-эталон для оценки, поэтому число полноты, которое здесь называется, «до».

День знаменатель, before the unexam: 18 — это все операции записи (POST/PUT/DELETE) по /projects, /tasks and /labels в спецификации OpenAPI самого Vikunja, за минусом того, что не является жестом доски: teams, project-level permissions, sharing by link, attachments, task relationships, duplication, bulk endpoints and read receipts. Vikunja publishes a total of 105 write operations; 18 — this is a subset that a person can perform on a Kanban board, and each emitted tool may pretend to hold at most one of them, so the accuracy cannot be inflated by vague matching.

RECALL     8/18    of the board write-ops in the target's own API
PRECISION  9/9     emitted tools that map to a real operation
VERIFIED   9/9     survived a cold replay with arguments never seen before

Девять инструменты нашли, девять были показаны. Отклонённые инструменты не удаляются — они остаются в tools.json с verified: false, потому что отброшенный инструмент — это evidence about the compiler, not garbage.

markTask is flavky, and that's more valuable than the 9/9. Two consecutive verifying runs over same build, with no changes in between, gave 8/9 and then 9/9: it failed with "observed mutation but nothing confirmed a write", and then passed with "Success — the task was saved successfully." The probable cause is the state of the seed: if the agent starts from an already completed task, the control reads as MARK THE UNDONE and confirms it differently. It takes no parameters, so it cannot disambiguate by an argument either.

Это — живое проявление проблемы flake-vs-drift, которая ниже перечислена как нерешённая: watch посчитал бы этот сбой дрейфом и вызвал было бы heal, хотя дрейф ничем не.

Непрекращающаяся проверка в течение живого дня:

327 checks · 118 breaks · 3 automatic repairs · MTTR 20s

(out/watch-stats.json, 38head from 11:33, still running when playing — counters keep moving.)

Смотрите на этот счётчик числа просто провалов. stats.breaks++ срабатывает на каждый красный повтор в каждомы цикле, поэтому три инструмента с, остававшихся красными все 38 циклов, читаются как ~114 провалов — это счётчик «красный инструмент × цикл», а не 118 отдельных событий дрейфа. А этот watcher был запущен в 11:12, до того как поправить heal(), который возвращал восстановленный рецепт без свежисего provenance, по которому реально кликает гарантия replay(); поэтому базовый инструмент, у которого переименовали контрл, причём действовал с большинством циклов and didn't get green in none. Именно это даёт большую часть 6/9. It was fixed in the code, and was not re-run on an equivalent window.

Партнёрские технологии

У каждой есть свой этап, и каждая деградирует, а не блокирует: весь pipeline пашет вообще без API-ключ, с reduced accuracy. Именно поэтому компилятор был in the assembled before any account appeared arrived — and it is also why an integration can be disconnected without the compile noticing; it is the status column and notes it.

Технология

Этап

Почему она заслуживает своего места

Статус

OpenAI

Verify

Независимый вердикт о том, произошёл ли прогнозируемый эффект, поверх бесключевого diff-уровня. Может подтвердить отклонение, но никогда не отменить его

в использовании — она вынесла решение по единственному инструменту, который verify отклонил

fal

Perceive

Быстрая VLM для оценки «значимое против косметического», подключается только когда DOM-diff неоднозначен

в использовании — 4/4 эскалированных шагов оценены при последней компиляции, 2 из них признаны косметическими. Только через CLI; compile_app не эскалирует

Pioneer

Verify, Distil

Энкодер GLiNER2, дообученный на собственных verify-данных apic, заменяет судью GPT-4.1-mini — и превосходит его на отложенных инструментах (ниже). Также классификатор diff-текста в distill.js

в использованииPIONEER_JUDGE_MODEL задан: живой проход verify выше был оценён дообученным энкодером, 8/9, каждый вердикт за 106–183 мс

h

Explore

Читает страницу и называет действия записи, которые бесключевой словарь отказался распознавать

в использовании — запускается один раз на сид по остаткам; называет 0 из 3 на Vikunja, корректно

Tavily

Ground

Документация приложения → доменный словарь, поэтому инструменты называются createIssue, а не btn_submit_2

в использованииground.js запускается перед первым сидом; дополняет встроенную таблицу, кэшируется по хосту, только через CLI

Двухуровневое разделение — это тезис самого продукта, применённый к нему же: fal — это дешёвый высокочастотный слой восприятия, OpenAI — дорогой низкочастотный слой рассуждений. Эскалируй при сбое, а не при каждом вызове.

Как каждая из них реально вызывается

h — holo3-1-35b-a3b, api.hcompany.ai/v1 (совместим с OpenAI). gesture() сопоставляет видимый текст элемента управления с парой <глагол, ресурс> через регулярные выражения и возвращает null для всего остального. Этот null — ворота точности, и именно здесь теряется полнота: кнопка только с иконкой, элемент управления без ведущего глагола или приложение, чью формулировку словарь не предвидел, отбрасывается, как бы явно она ни была написана. h — это уровень эскалации именно для такого набора — discover.js classify() отправляет JPEG страницы и отклонённые элементы управления, один раз на сид, и спрашивает, какие из них выполняют запись.

Три вещи не дают этому стоить точности. Ответы проверяются по закрытому словарю — шесть глаголов, четыре ресурса — через plan.gestureFrom(), поэтому выдуманный глагол не может назвать инструмент. Элементы вне среза не предлагаются, а удерживаются, потому что исключение ADD TO FAVORITES — это решение о границах, а не пробел, который должна заполнять модель. И классифицированный элемент управления всё равно должен заставить приложение подтвердить запись, как и любой другой кандидат.

Измерено на компиляции, о которой сообщает этот README: h читает три элемента управления, которые словарь оставляет нерешёнными на странице задач Vikunja, и называет один из них — элемент только с иконкой, который регулярные выражения отбрасывают полностью:

! h read 3 unresolved controls, named 1
! h: "Kanban bucket: To-Do" -> move task (Pencil icon allows changing task status)

Это уровень эскалации, выполняющий свою работу: элемент управления без ведущего глагола и без полезного текста, восстановленный по иконке и сопоставленный с закрытым словарём.

Он не добавил инструмент, и мы не утверждаем, что добавил. move task к тому моменту уже был найден дважды — один раз перетаскиванием на доске (Move card between columns), один раз выпадающим списком корзины на странице задачи (Kanban bucket: Doing) — поэтому ответ h дедуплицировался в moveTask, который дало перетаскивание. На этой цели h — это подтверждение, а не полнота: третий независимый путь к действию, которого уже достигли два других пути. Более ранняя редакция этого файла утверждала, что h никогда не срабатывал и ничего не называл; оба утверждения были неверны.

Добавляет ли h полноту — здесь не проверено, потому что записи Vikunja необычно хорошо подписаны. Случай, для которого он создан — приложение с кнопками-иконками — это ровно тот случай, которого эта цель не представляет. Без ключа компиляция теряет это подтверждение и ничего больше.

fal — google/gemini-2.5-flash-lite через fal-ai/any-llm/vision. DOM-differ говорит, изменилась ли страница. Он не может оценить изменение, которое текст не описывает — карточку, переместившуюся между колонками, элемент управления, который просто подсветился. perceive.js adjudicate() эскалирует эти шаги, и только их, к пикселям.

Измерено на последней полной компиляции: vision: 4/4 эскалированных шагов оценены fal, 1 перетаскивание подтверждено, 2 признаны косметическими. Два косметических вердикта — самая интересная половина — fal удаляет кандидатов, которые иначе были бы проверены как записи. Он запускается из cli.js; компиляция через compile_app на MCP-сервере не эскалирует.

OpenAI — gpt-4.1-mini, структурированный вывод. verify.js воспроизводит каждый выпущенный инструмент на холодную с аргументами, которых приложение никогда не видело, и оценивает результат дважды: сначала детерминированный diff-уровень, затем модель. Модель может подтвердить отклонение и никогда не отменить его — инструмент, который diff не смог подтвердить, остаётся отклонённым, как бы уверен ни был судья.

Измерено: на прогоне, где markTask не сработал, его запись гласит openai/gpt-4.1-mini disagreed but cannot overturn a rejection. Эта асимметрия намеренная: судья, который может продвигать собственные догадки, — это утечка точности.

Pioneer — GLiNER2 (fastino/gliner2-base-v1), один POST /inference на шаг. distill.js отправляет diff-текст каждого шага отдельным запросом и получает класс изменения состояния, флаг деструктивности и доменные существительные при пороге уверенности выше 0.6. Раньше он отправлял всю траекторию пакетом, и именно о пакетной обработке третий тяжёлый урок ниже: один и тот же текст получил creation 0.777 в одиночку, creation 1.000 на позиции 0 и DELETION 0.600 на позиции 2 перевёрнутого пакета — неверная метка, прошедшая порог. Идентификатор завершённого тренировочного задания в PIONEER_MODEL заменяет базовый энкодер на чекпоинт, дообученный на собственных метках apic — система, компилирующая собственный слой восприятия — и больше ничего не меняется.

Pioneer — дообученный verify-судья. Это запись в побочном испытании Pioneer: дообучить модель, которая превосходит или заменяет вызов универсального LLM API. Вызов, который она заменяет, — это judgeModel() в verify.js — GPT-4.1-mini, системный промпт на 200 слов, структурированный вывод, один вопрос на каждый воспроизведённый инструмент: учитывая этот DOM-diff, произошло ли прогнозируемое действие записи наглядно? Это двухклассовая текстовая классификация, замаскированная под чат-завершение.

pioneer-train.js строит замену из собственных выхлопов продукта, без ручной разметки:

  1. collect — воспроизвести каждый скомпилированный инструмент шесть раз со свежими аргументами через verifyAll(), записывая доказательства и вердикт, который дал штатный судья (diff-уровень + GPT). 54 реальных строки.

  2. dataset — получить негативы, удалив доказательства, на которые опирается уровень (баннер исчез, эхо переместилось в поле ввода, которое его набрало, аргумент не заполнен, воспроизведение выбросило ошибку, ничего не изменилось), и позитивы, сохраняющие метку (порядок узлов перевёрнут, добавлены несвязанные узлы, аргументы переименованы в значения, которые ввёл бы человек). Каждая производная строка переразмечается тем же детерминированным уровнем. 788 строк; отложены по инструментам, поэтому бенчмарк измеряет инструменты, которых энкодер никогда не видел.

  3. upload / trainPOST /felix/datasets/upload/url → presigned PUT → POST /felix/training-jobs, fastino/gliner2-base-v1, LoRA, 12 эпох. Обучается примерно за четыре минуты.

  4. bench — отложенные строки через обоих судей. LLM вызывается через неизменённый judgeModel(), поэтому видит ровно то же, что и в продакшене.

судья

точность

precision

recall

ложные срабатывания

ложные пропуски

мс/строка

Pioneer GLiNER2 fine-tune (задание 91370379…)

94.4%

100%

87.6%

0

12

150

OpenAI GPT-4.1-mini

89.3%

84.3%

93.8%

17

6

890

215 отложенных строк, два инструмента (createTask, assignLabel) отсутствуют в обучении. Энкодер жертвует частью полноты ради нуля ложных срабатываний — правильный обмен для этого судьи, который по замыслу может подтвердить отклонение, но никогда не продвинуть догадку. Установите PIONEER_JUDGE_MODEL на идентификатор задания, и verify будет использовать его; OpenAI остаётся в резерве как запасной вариант, а без ключей вовсе уровень всё равно работает.

Три урока, усвоенных на горьком опыте, все проверены вживую и записаны в коде: multi_label/top_k внутри спецификации классификации заставляют единый путь /inference возвращать categories: [] для любого текста (именно это, а не кредиты, было причиной молчания этапа distil всё утро); GLiNER2 обучается только как LoRA — training_type: "full" принимается и падает внутри Modal без единой строки в логе; и пакетный вывод (text: [...]) на дообученной модели возвращает метки, не совпадающие с входами, поэтому судья отправляет один текст на запрос.

Tavily — api.tavily.com/search, пять результатов, с ответом. ground.js запускается перед первым сидом. plan.js поставляется с существительными Vikunja — bucket, task, label, project — и при обращении к чему-либо ещё gesture() получает вопросы о задачах и репозиториях от таблицы, которая о них никогда не слышала, возвращает null, и элемент управления отбрасывается. Tavily получает документацию самой цели; OpenAI структурирует этот текст в закрытый набор существительных по строгой схеме; каждый термин проверяется на /^[a-z][a-z-]{1,18}$/, ограничен 12 элементами и сливается во встроенную таблицу, а не заменяет её, поэтому grounding может добавить словарь и никогда не может отнять словарь Vikunja. Кэшируется по хосту в .apic/, так что повторная компиляция ничего не тратит, а демо не зависит от wi-fi площадки.

Он деградирует в три шага — нет ключа Tavily, нет доказательств; нет ключа OpenAI, доказательства нельзя структурировать; ничего не проходит валидацию — и каждый шаг логируется и оставляет встроенную таблицу на месте. Как и fal, он запускается из cli.js: compile_app на MCP-сервере использует встроенный словарь.

Таким образом, показатели полноты выше получены без ключей, с fal на эскалированных шагах восприятия и судьёй OpenAI на проходе verify. Это не демонстрация полного стека партнёров, и этот README не будет притворяться иначе.

Настройка

git clone https://github.com/brwbo/apic && cd apic
npm install && npx playwright install chromium
cp .env.example .env      # fill in keys; .env is gitignored
npm run setup             # starts the target app, checks every credential

Целевое приложение (самохостимое, одноразовое — никогда не направляйте это на продукт третьей стороны):

docker volume create vikunja-files
docker run --rm -v vikunja-files:/data alpine sh -c "chown -R 1000:0 /data"
docker run -d --name vikunja -p 3456:3456 -v vikunja-files:/app/vikunja/files \
  -e VIKUNJA_SERVICE_PUBLICURL=http://localhost:3456 \
  -e VIKUNJA_DATABASE_PATH=/app/vikunja/files/vikunja.db \
  -e VIKUNJA_RATELIMIT_ENABLED=false \
  vikunja/vikunja:latest

Команда

Что делает

npm run doctor

Какие учётные данные работают, какие цели доступны

npm run compile

Исследовать → синтезировать → выдать

npm run verify

Воспроизвести каждый инструмент на холодную; обслуживаются только выжившие

npm run watch

Непрерывная проверка с автоматическим восстановлением

npm run score

Полнота и точность относительно реального API цели

npm run serve

Запустить сам apic как MCP-сервер — см. ниже

Каждая команда читает одни и те же две переменные, поэтому весь запуск можно направить на альтернативный пакет, не трогая рабочий:

APIC_OUT_DIR=out/rescue APIC_APP=vikunja npm run verify

Переменная

По умолчанию

Значение

APIC_OUT_DIR

generated

Где хранятся скомпилированные пакеты. APIC_GENERATED принимается как псевдоним

APIC_APP

vikunja

Какой пакет внутри него

TARGET_URL

http://localhost:3456

Приложение, которое компилируется

TARGET_USER / TARGET_PASS

apic / —

Учётные данные для цели

TARGET_LOGIN_PATH

обнаружен

Нужно только если форма входа не находится по пути в стиле /login

APIC_SEEDS

/projects,/labels

Страницы, с которых начинается исследование

Семена и цель управляются окружением — ничто в компиляторе не знает маршрутов Vikunja:

APIC_APP=gitea TARGET_URL=http://localhost:3001 APIC_SEEDS=/repo/create,/issues npm run compile

Сгенерированный вывод

generated/vikunja/ — сервер, схемы и доказательства для каждого инструмента. Ничто в этом каталоге не было написано человеком.

Использование в качестве MCP-сервера

claude mcp add apic -- node /path/to/apic/src/server.js

src/server.js начинается с одного инструмента, compile_app. Укажите ему URL, и он запустит конвейер в процессе, выдаст generated/<app>/, зарегистрирует скомпилированные инструменты на себе и отправит notifications/tools/list_changed — так что они вызываются по тому же соединению без перезапуска. С холодного старта:

[apic] ready - 0 compiled tools + compile_app
BEFORE compile, tools/list = [ 'compile_app' ]
compile_app returned in 22.1s
list_changed notification: YES
AFTER compile = [compile_app, createProject, createLabel, updateLabel, createTask]
createLabel -> {"ok":true,"effect":"creation","expected":"creation"}

Компилятор, который требует перезапуска того, что он только что расширил, — это этап сборки. Тот, который не требует, — это живой компилятор. Заметки о совместимости с клиентами и полные стенограммы: docs/mcp-client.md.

Оба тупика получают ответ, а не сообщение

Клиент встречается с apic только в тот момент, когда чего-то не хватает, и оба этих момента раньше заканчивали разговор.

Несуществующий инструмент возвращает компиляцию, которая его создаст:

unknown tool: createIssue

No compiled tool exposes that action (compiled so far: vikunja). If the app has no API for it, make one:

    compile_app { "url": "http://localhost:3456", "goal": "createIssue" }

Инструмент, который приложение вытащило из-под ног, восстанавливается на пути вызова — watch лечит по таймеру, сервер лечит по требованию, через тот же heal(). Инструмент становится красным, компилятор заново исследует это одно действие, исправление записывается обратно в tools.json, и вызов повторяется до того, как вызывающий увидит сбой:

[apic] createLabel is red (no control matched "ADD LABEL (RENAMED)") - re-exploring to heal it
[apic] createLabel healed in 13.6s (click "…" -> "create label"; selectors re-resolved); retry passed
{ "ok": true, "effect": "creation", "healed": { "ms": 13589, "persisted": true } }

Здоровый инструмент не затрагивается ничем из этого: тот же вызов, 4,4 с, без повторного исследования.

Связанные работы и чем это отличается

Проект

Что делает

Разница

Playwright MCP

Автоматизация браузера как типизированные MCP-инструменты

Общие глаголы (click(ref)) против специфичных для приложения существительных (createTask(title)). Время выполнения против времени компиляции

Apify MCP Server

Автоматически генерирует типизированные инструменты из входных схем Actor

Акторы написаны людьми — он генерирует обёртку из контракта, написанного человеком

Apify AI Web Scraper

URL + простой английский → структурированные данные

Возвращает данные, а не интерфейс, и перезапускает LLM при каждом вызове

cli-printing-press

URL/HAR/OpenAPI → CLI + MCP-сервер, с проверочными шлюзами

Перехватывает сетевой трафик — у приложения уже должен быть API. apic управляет интерфейсом

Easy MCP

Спецификация OpenAPI → MCP-инструменты

Требует, чтобы API уже существовал

Alita

Агент генерирует и переиспользует MCP для каждой задачи

Генерирует инструменты, ища в интернете. apic выводит их, управляя программным обеспечением

WebMCP

Страницы объявляют свои собственные инструменты на JavaScript

Требует, чтобы разработчики приложения приняли его

Voyager

Напишите навык, проверьте его, сохраните, переиспользуйте

Предок цикла «проверь, затем сохрани»

Цикл не нов — ново то, откуда берётся возможность. Alita читает интернет, чтобы создавать инструменты; cli-printing-press читает сеть; Easy MCP читает спецификацию. apic читает приложение.

Что пока не работает

Сказано прямо, потому что компилятор, скрывающий свои режимы отказа, — не компилятор.

  • h находится в пути и ничего не даёт для этой цели. Он читает элементы управления, которые отказался обрабатывать словарь, и правильно не называет ни один из них, потому что срез доски Vikunja уже покрыт регулярными выражениями. Эскалация реальна и измерена; выигрыш здесь нулевой, и цель, чьи элементы управления являются иконками, а не глагольными фразами, — это случай, который это покажет.

  • compile_app выполняет сокращённый конвейер. compile.js — это внутрипроцессная компиляция, которую вызывает MCP-сервер, и это cli.js минус пять вещей: обоснование (Tavily/OpenAI), обнаружение семян, специальный зонд страницы формы, семя деталей задачи и перетаскивание Kanban, а также уровень зрения fal — adjudicate() запускается только из cli.js. Он сохраняет обнаружение, персистентность, дистилляцию Pioneer, синтез и выдачу. Вот почему в приведённой выше стенограмме показано четыре инструмента, тогда как npm run compile даёт девять: демо живого компилятора и пакет из 9 инструментов — это два разных пути, и только CLI-путь описывается цифрами полноты.

  • Pioneer выглядел недоступным всё утро — сначала 403 payment_method_required, а после нового ключа categories: [] при каждом вызове, что код воспринимал как «нет мнения» и переходил к эвристике. Второе было ошибкой формы запроса (multi_label/top_k), а не API. Каждая интеграция была написана так, чтобы деградировать молча, и каждая так и делала — деградация является предполагаемым поведением; не замечать её целое утро — нет.

  • Тонко настроенный судья видел одно приложение. Его 788 обучающих строк — все из Vikunja. Отложенный сплит сделан по инструментам, а не по приложениям; стенд Gitea или ParaBank — следующий честный тест, и collect по второй цели — способ его получить.

  • Вторая цель компилируется тонко. Gitea теперь компилируется от начала до конца — createRepository и createIssue, оба проверены, 2/13 по срезу задач против swagger.v1.json. Для обнаружения не потребовалось изменений: два исправления были классом подтверждения (Gitea подтверждает запись, обслуживая результат по новому URL, несущему отправленное значение, а шлюз искал только баннеры и эхо тела) и переносом шаблонов URL контейнера/элемента из cli.js в конфигурацию, где уже жил APIC_SEEDS. Действия с метками и комментариями всё ещё пропускаются: они находятся за элементами управления, которые словарь не называет, и h не назвал ни одного из 14 переданных ему.

  • 8/18 полноты на Vikunja. Отсутствуют: создание корзин, комментарии, связи и вложения.

  • markTask выходит из строя примерно в одном запуске из двух (см. Результаты). Эффект реален и наблюдаем; подтверждает ли его что-либо, зависит от текущего состояния задачи. Любой живой npm run verify должен ожидаемо выводить 8/9 или 9/9.

  • Параллельные запуски конфликтуют. Каждая команда использует одну сохранённую сессию в .apic/session.json, поэтому компиляция и проверка, запущенные вместе, могут уничтожить контекст браузера друг друга в середине выполнения (Error setting storage state: Execution context was destroyed). Передайте отдельный APIC_SESSION для каждого запуска в качестве обходного пути; настоящее исправление — файл сессии для каждого запуска по умолчанию.

  • Watch рассматривает каждый сбой как дрейф. Настоящей классификации «флейк против дрейфа» не существует. Три класса ложных срабатываний были исправлены вручную — ограничение скорости, истечение токена и упавшая страница — но общая проблема остаётся.

  • Семантическое изменение не обнаруживается и опасно. Если deleteProject начнёт архивировать вместо удаления, исцеление селектора — неправильный ответ. Проверка проверяет, что эффект произошёл, а не то, что это тот же эффект.

  • Нет обратных действий, поэтому набор загрязняет собственный фикстур. Повторные запуски ухудшают цель, пока она не будет сброшена.

  • Аутентификация обходится стороной. Один вход, один пользователь, без областей разрешений — а это самая сложная часть проблемы в реальном корпоративном ПО.

Декларация о предыдущей работе

Написано с нуля на хакатоне. Никакого готового кода не приносилось; репозиторий был создан пустым утром мероприятия. Playwright, MCP SDK и клиенты OpenAI и fal — единственные зависимости.

Лицензия

MIT

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

  • Read-only MCP server for the WebAssembly spec: instructions, types, sections, search, proposals.

View all MCP Connectors

Latest Blog Posts

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/brwbo/apic'

If you have feedback or need assistance with the MCP directory API, please join our Discord server