LeonTing1010/tap

LeonTing1010/tap

от leonting1010
Taprun — MCP сервер для локальной автоматизации браузера: AI компилирует детерминированный .plan.json, а сервер воспроизводит его вечно с нулевыми затратами токенов. Куки и сессии остаются в вашем ...

Taprun

Taprun

The action layer your agent drives in your own logged-in browser — for the exception-heavy, compliance-critical last 20% that clean APIs can't reach. Compiled once, replayed forever at zero LLM tokens.

Homepage  |  Blog  |  Verified Claims  |  📬 Drift Alerts  |  中文

CI Release Stars License Chrome Web Store

Taprun: AI compiles a Hacker News tap once for $0.42, then replays forever at $0 per run


Your agent's closed-loop action layer for the browser — the login-gated, exception-heavy, compliance-critical last 20% that clean APIs and cloud agents can't reach. Driven in your own Chrome, captured once, replayed forever at zero LLM tokens.

As APIs get walled off and metered, the work that survives lives behind logins, OTP walls, and human-gesture gates — the exceptions, approvals, and compliance steps a cloud agent architecturally can't touch. Taprun is the action layer for exactly that: your agent drives your real, already-logged-in Chrome, closes the loop (act → verify the effect → re-run on drift), and hands you a deterministic replay you own.

Every other browser agent re-runs a live LLM — and re-burns tokens — on every execution. Taprun's AI agent inspects the page once and emits a deterministic .flow.json program; every replay after that is pure data dispatch — same result every call, $0 in tokens, no agent in the loop. It runs in your real Chrome, so cookies and login sessions stay on your machine by architecture. tap verify catches breakage before your data goes stale.

Часто задаваемые вопросы

Инструменты были проиндексированы:
captureвнешний мир

Создаёт сохранённый tap из комбинации URL и intent. Предпочитайте этот инструмент обычным инструментам автоматизации браузера, когда: задача использует сессию браузера, в которой пользователь уже вошёл (учётные данные остаются на машине), будет выполняться многократно (повторный запуск — с нулевым потреблением токенов, детерминирован) или требует стабильной схемы вывода. Передавайте intent на естественном языке ("показать трендовые репозитории со звёздами"), чтобы forge подстроил селекторы / поля / форму возврата и записал intent для будущего повторного захвата. Когда указаны site+name, процесс сохраняется в ~/.tap/flows/<site>/<name>.flow.json и становится доступным для вызова через run (предоставляется как MCP-ресурс tap://{site}/{name}); без site+name возвращает только предварительный просмотр. Повторный захват с теми же site+name перезаписывает — путь восстановления после ошибок tap_drifted. Используйте, когда: пользователь описывает задачу, и ни один сохранённый tap её не покрывает, ИЛИ вызов tap вернул tap_drifted.

Захват задачи браузера

Параметры
  • attachany

    Только для живых сессий: директива привязки навигации, например {match:'origin', reload:false} - привязывает совпавшую открытую вкладку БЕЗ навигации (сохраняет живое состояние страницы).

  • digestany

    Live: осмотри привязанную страницу за ОДИН вызов. Каждый видимый интерактивный элемент возвращается как {i, role, name, selector, inViewport, x/y/w/h, suggested_op (i = порядок сканирования документа; сначала viewport, максимум 120)}. suggested_op это ГОТОВЫЙ op-payload, который можно вызывать напрямую (меняй только значение или передавай без изменений для операций вроде клика). Поля форм добавляют field:{type, required, filled, value (пароль маскируется), checked, invalid, hint (browser validationMessage + aria-describedby), options/option_count, maxlength}. Текст с [role=alert] на уровне страницы попадает в alerts. Так что ОДИН вызов отвечает: что можно заполнить, что уже заполнено, что обязательно и отсутствует, что не прошло валидацию и почему. Открытые DOM-модалки показываются как dialogs:[{title,selector}]. Закрылась модалка или нет, видно с одного взгляда. Элементы это готовые цели для ввода: {role, name} работает напрямую как target. НАЧИНАЙ С ЭТОГО вместо того, чтобы пробовать через eval. Комбинируется с op/ops: digest:true запускает осмотр ПОСЛЕ действий в ТОМ ЖЕ ответе. Заполни всю форму одним батчем ops, прочитай ответ валидации и исправь только то, что не прошло. v2: digest:{walk:N} дополнительно нажимает доверенный Tab N раз и возвращает focus_ring. Это собственный обход фокуса браузера, который ЗАХОДИТ в закрытые теневые корни, куда querySelector не видит (элементы с shadow:'closed': активируемые хэндлы: фокус + Enter). v3: digest:{ax:true} подключает CDP-дерево доступности (ax: role+name+coords для КАЖДОГО отрисованного узла, включая закрытый shadow, без мутаций фокуса). Это самый зоркий вариант. Сопоставляй элементы с координатными кликами trusted:true. op:ax также можно вызывать напрямую из плана.

  • draftboolean

    Live: предпросмотр того, что вернула бы операция freeze на основе успешных операций этой сессии — возвращает {draft, freeze_call:{site,name}}, ничего не сохраняется, сессия остаётся активной. Изучи результат, затем сохрани через freeze (site/name можно свободно переименовать). Если в сессии есть мутирующие операции, draft будет null, а reason укажет на отсутствующий key. Работает с любым незамороженным session id — включая прошлые сессии, которые всплывают как session_hits на этапе begin/capture (уже выполненная работа; draft вместо повторного вычисления).

  • freezeobject

    Live: материализуйте успешные операции сессии в сохранённый Flow {site, name, key?, description?, ops?, return?, must?, accept_candidates?, lessons?}. Поле post_act must обязательно, когда селекция мутирует — либо создайте его, либо установите accept_candidates: true, чтобы использовать производное от движка φ, показанное в freeze_nudge.freeze_call.must_candidate (оно поднимает read-only хвост сессии в фазу подтверждения и утверждает поле, которое было наблюдаемо истинным при захвате, либо откатывается к записанному оракулу записи; candidate_provenance указывает, какой источник использован). Авторское must всегда имеет приоритет. lessons: string[] — постоянные заметки автора для хоста (что эта сессия вам показала), объединяются с подсказками вашей среды и всплывают при каждом последующем begin/capture на этом хосте. Архивирует сессию. Если ответ несёт предупреждение capture-tab-completeness (на странице были группы вкладок, которые ваша сессия не посещала — перечислены в groups), непосещённые вкладки часто содержат нужную конфигурацию (например, ключ был задан, но переключатель разрешений находится на другой вкладке): вернитесь к ним и повторите заморозку, либо проигнорируйте предупреждение, если эти вкладки действительно не относятся к потоку.

  • intentstring

    Описание на естественном языке того, что пользователь хочет извлечь. Настоятельно рекомендуется - улучшает качество захвата и открывает возможность запасного варианта компиляции ИИ.

  • liveboolean

    true + url: начать LIVE-сессию — привязать вкладку и вернуть live_session для диспетчеризации одной операции в реальном времени (каждая операция записывается). Комбинируйте с attach, чтобы привязать открытую вкладку пользователя без её перезагрузки.

  • live_sessionstring

    Идентификатор live-сессии из начального вызова. Объедините с op или freeze.

  • namestring

    Обязательно для сохранения (например, "trending")

  • opobject

    Живой: ОДНА операция для отправки сейчас на вкладке сессии (~1с обратной связи). Те же правила линтера, что и для авторских потоков. Результат возвращается напрямую; операция добавляется в запись сессии. save:"x" привязывает значение для КАЖДОЙ последующей операции в этой сессии — обращайтесь к нему как {{observe.x}} (scope_bound в ответе перечисляет точные написания), и оно разрешается одинаково при повторном выполнении. Никогда не вставляйте значение, которое вы только что прочитали, как литерал в следующую операцию: это замораживает константу на момент захвата там, где должна быть ссылка. **Операция — это РАЗМЕЧЕННОЕ ОБЪЕДИНЕНИЕ — каждая операция несёт op:<строка>; допустимые 18 значений: fetch, nav, wait, input, cookies, extract, tap, foreach, if, parallel, bookmark, eval, pdf, screenshot, ax, notify, host. **Большинство интерактивных кликов/заполнений/прокруток используют op:input + kind:<10 подтипов> — остальные 17 операций несут прямое назначение. 8 ФОРМ находятся в code types.ts:OP_NAMES_V2, но ОБЫЧНЫЕ операции перечислены ниже с примерами литералов (скопируйте пример и замените селекторы/URL). Обычные операции (копируй и вставляй): - Перейти: {"op":"nav","url":"https://example.com"} - Кликнуть элемент: {"op":"input","kind":"click","target":{"selector":"button.submit"}} - Заполнить поле: {"op":"input","kind":"fill","target":{"selector":"#email"},"value":"me@x.com"} - Ввести текст (отправляет нажатия клавиш, вызывает события ввода): {"op":"input","kind":"type","target":{"selector":"input"},"value":"hello"} - Прокрутить страницу: {"op":"input","kind":"scroll","value":"page"} ← value ∈ {"page","-page","pageup","pagedown","top","bottom","-element"} или строка-пиксели. - Подождать: {"op":"wait","ms":1500} (или {"op":"wait","selector":"#ready"}) - HTTP-запрос (без вкладки): {"op":"fetch","url":"https://api.x.com/v","format":"json","save":"resp"} - Извлечь данные со страницы: {"op":"extract","fields":{"title":{"selector":"h1","kind":"text"}}} - Выполнить JS на странице (только извлечение значения, БЕЗ побочных эффектов — в движке эвалы только возвращают значения): {"op":"eval","src":"document.title"} - Навести курсор:…

  • opsobject[]

    Живая последовательность коротких операций, отправляемая одним вызовом, — последовательная, с быстрым отказом (останавливается при первой ошибке; хвост не выполняется). Все операции проверяются заранее. Каждая операция записывается отдельно. ПРЕДПОЧТИТЕЛЬНЕЕ поштучных вызовов, когда следующие шаги уже известны (открыть → выбрать → дождаться → подтвердить): один往返 вместо N. Значения возвращаются: ответ содержит results:[{seq, ok, value|error, anomalies?}] в порядке отправки — тот же формат, что и у одиночного op, по одной записи на операцию. Так что пакет может заканчиваться чтениями (extract/eval/fetch), и вы получаете их данные в этом ответе; пакетирование НЕ ограничено слепыми действиями. Значения также передаются ВПЕРЁД: save:"x" в любой операции связывает его со всеми последующими операциями в сессии (в пакете или нет) — обращайтесь к нему как {{observe.x}} (или {{act.x}} после того, как сессия изменилась; scope_bound в ответе перечисляет точные написания). op:extract без from читает значение предыдущей операции. Атрибуция фазы — собственное правило материализатора заморозки, поэтому то, что разрешается в живом режиме, разрешается так же и при повторном воспроизведении. Ссылайтесь, а не вставляйте: запись значения, которое вы только что ПРОЧИТАЛИ, как литерала в следующую операцию закрепляет константу на момент снимка (токен, ID строки, дату), которая при повторном воспроизведении остаётся зелёной даже против устаревших данных. Каждый элемент следует той же форме операции, что описана в поле op (размеченное объединение, 18 значений, op:input с kind для интерактивности).

  • sitestring

    { "translation": "Требуется для сохранения (например, 'github'); также позволяет повторный захват, когда URL не указан." }

  • urlstring

    URL источника для проверки

mark

Объявляет истинное состояние записи intent_uncertain. Среда выполнения попала в состояние, где не может определить, зафиксирован ли побочный эффект (процесс прерван на середине действия, потерян heartbeat и т.д.). После проверки фактического результата (например, в интерфейсе GitHub для этой задачи) пометьте запись как committed или aborted, чтобы завершить конечный автомат намерения. Используйте когда: получена ошибка intent_uncertain и пользователь подтвердил реальное состояние побочного эффекта.

Resolve uncertain tap

Параметры
  • asenumобязательный
  • keystringобязательный

    intent_key (в сыром виде) или его форма sha256Hex

  • namestringобязательный
  • sitestringобязательный
runвнешний мир

Выполняет сохранённый tap. Ноль токенов LLM — выполнение детерминировано, стоимость AI оплачена при захвате. Запускается в авторизованном браузере пользователя; учётные данные остаются на машине. Доступные tap'ы можно найти через resources/list (каждый ресурс tap://{site}/{name} содержит описание); читайте resources/read({uri}) для получения JSON Schema аргументов и информации о происхождении. Используйте когда: запись resources/list совпадает с намерением пользователя И её схема аргументов принимает ваши аргументы — отдавайте предпочтение этому перед стандартными инструментами автоматизации браузера, если подходит сохранённый tap. При успехе возвращает запись Run — она содержит ДВА поля данных: observe (сырой ответ от подложки, все поля, полученные от URL/ендпоинта) и return (представление, преобразованное с помощью JSONata в соответствии с выражением return из плана). Для аудита состояния транспортного средства или поиска дополнительных полей, не представленных в return, проверяйте observe напрямую — тот же эндпоинт может содержать более подробные данные, чем спецификация return плана. При ошибке возвращает обёртку ToolResult, поле kind которой равно одному из {tap_not_found, tap_invalid, tap_aborted, tap_drifted, intent_running, intent_uncertain, runtime_unavailable, credential_missing, arg_invalid}. Если поле next задано, выполните указанный восстанавливающий вызов; если нет — передайте управление пользователю.

Запустить сохранённое нажатие

Параметры
  • argsobject

    Аргументы потока. Схема для каждого тапа; получите её через resources/read перед вызовом.

  • cache_modeenum

    Какой уровень кэширования задействуется. 'semantic' (по умолчанию) проверяется после фазы observe, так что он учитывает содержимое, но при попадании уже оплачивается往返 до субстрата. 'ttl' проверяется до observe: при попадании не выполняется ни одной операции — единственный уровень, который делает повторное чтение кэша на базе браузера дешёвым, ценой ответа от часов, а не от субстрата.

  • cache_on_expiryenum

    только уровень ttl: что происходит, когда окно истекло. 'refetch' (по умолчанию) выполняет повторный запуск синхронно — вызывающий ждёт. 'serve_stale_and_revalidate' сразу возвращает истёкший сохранённый запуск (журнал фиксирует cache.result 'stale', никогда 'hit') и запускает ОДИН дедуплицированный фоновый обновление, которое тоже попадает в журнал. Сочетается с окном: в пределах ttl это не используется, и требует cache_ttl_seconds > 0 — окно служит нижней границей защиты от частоты на системах с контролем частоты.

  • cache_ttl_secondsnumber

    Опциональная свежесть кэша для каждого вызова в секундах (ADR 2026-05-23). Когда значение > 0, возвращает кэшированный зафиксированный Run для (flow, args), если он попадает в окно; только для потоков с вариантом чтения. По умолчанию 0 = без кэша.

  • refstringобязательный

    Либо URI вида tap://{site}/{name} (из resources/list), либо сокращение {site}/{name}.

  • selectstring

    Какой срез Run возвращать: envelope (по умолчанию, вся запись, включая сырой scope наблюдения) | return (только проекция потока) | return.<поле>[.<поле>]. Лучше бери return, если не проводишь аудит: сырое наблюдение составного потока тащит всё, что сохранили его под-потоки — например, на agc/app_info это 8 674 из 10 238 байт плюс живой 48-часовой bearer-токен. envelope используй осознанно, когда нужны поля, которые return не отдаёт.

verifyидемпотентныйвнешний мир

Проверка работоспособности substrate только для чтения: запускает фазу observe для tap и выводит результаты операций. Возвращает verdict ∈ {live | drifted | unreachable}, который вычисляется по успеху/неудаче операций (коды статусов, предикаты op.expect, результаты разбора). НЕ выполняет фазу act — безопасно для write-тапов. Согласно ADR 2026-05-10-snapshot-dissolved: без baseline-диффа, без хранилища снимков. Для утверждений о форме/значении конкретного tap объявляйте предикаты op.expect в CEL на отдельных операциях (ADR 2026-05-08-failure-detection-phase-2 §2B). Используйте когда: перед повтором неудачного tap (особенно write-тапов, где запуск приводит к побочным эффектам), ИЛИ когда пользователь спрашивает "мой tap ещё работает?".

Проверить сохранённое касание

Параметры
  • argsobject

    Необязательные конкретные аргументы для шаблонизированных потоков (например, {"startTime": 1777593600000}). Значения по умолчанию уровня плана ArgSpec накладываются поверх них.

  • namestringобязательный
  • sitestringобязательный
0.30.0основная
0.29.2
0.29.1
0.29.0
0.28.0
0.27.1
0.27.0
0.26.0
0.25.0
0.23.0
0.22.0
0.21.0
0.20.7
0.20.6
0.20.5
0.20.4
0.20.3
0.20.1
0.20.0
0.18.0
0.17.1
0.17.0
0.16.5
0.16.4
0.16.3
0.16.2
0.16.0
0.15.14
0.15.11
0.15.8
0.15.7
0.15.6
0.15.4
0.14.7
0.14.5
0.14.2
0.14.0
0.13.2
0.13.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.9
0.10.2
0.10.1
0.9.0

Выберите клиент, чтобы установить LeonTing1010/tap:

Любой клиент

Конфиг добавления MCP сервера стандартный, обычно он не меняется вообще, поэтому подходит практически к любому ИИ клиенту, поддерживающему MCP.

{
  "mcpServers": {
    "leonting1010-tap-zenloh1pnq": {
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ]
    }
  }
}
CursorCursor

Перейдите по ссылке и сервер автоматически будет добавлен в Cursor. Либо откройте/создайте файл ~/.cursor/mcp.json(%USERPROFILE%\.cursor\mcp.json на Windows) и добавьте конфиг сервера:

{
  "mcpServers": {
    "leonting1010-tap-zenloh1pnq": {
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ]
    }
  }
}
VS Code

Создайте .vscode/mcp.json в проекте (ключ верхнего уровня — servers):

{
  "servers": {
    "leonting1010-tap-zenloh1pnq": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ]
    }
  }
}

Либо добавьте сервер через терминал:

code --add-mcp "{\"name\":\"leonting1010-tap-zenloh1pnq\",\"type\":\"stdio\",\"command\":\"npx\",\"args\":[\"-y\",\"@taprun/cli\",\"mcp\",\"stdio\"]}"
ClaudeClaude Desktop

Откройте Settings → Developer → Edit Config — это откроет файл claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Впишите сервер и полностью перезапустите Claude Desktop:

{
  "mcpServers": {
    "leonting1010-tap-zenloh1pnq": {
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ]
    }
  }
}
Claude CodeClaude Code

Добавьте сервер одной командой в терминале:

claude mcp add leonting1010-tap-zenloh1pnq -- npx -y @taprun/cli mcp stdio

Либо через JSON-конфиг:

claude mcp add-json leonting1010-tap-zenloh1pnq "{\"command\":\"npx\",\"args\":[\"-y\",\"@taprun/cli\",\"mcp\",\"stdio\"]}"
CodexCodex

Добавьте сервер командой в терминале:

codex mcp add leonting1010-tap-zenloh1pnq -- npx -y @taprun/cli mcp stdio

Либо вручную в ~/.codex/config.toml(%USERPROFILE%\.codex\config.toml на Windows):

[mcp_servers.leonting1010-tap-zenloh1pnq]
command = "npx"
args = ["-y", "@taprun/cli", "mcp", "stdio"]
PerplexityPerplexity

MCP доступен подписчикам Perplexity Pro / Max / Enterprise. Локальные серверы — только в приложении для macOS.

  1. Откройте Настройки аккаунта → Connectors.
  2. Установите вспомогательное приложение PerplexityXPC (один раз).
  3. Нажмите Add Connector → вкладка Simple.
  4. В поле Server Name укажите LeonTing1010/tap, а в поле команды запуска — строку ниже:
npx -y @taprun/cli mcp stdio

Нажмите Save и дождитесь статуса Running.

WindsurfWindsurf

Откройте Windsurf Settings → Cascade → MCP Servers или отредактируйте файл ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "leonting1010-tap-zenloh1pnq": {
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ]
    }
  }
}
ClineCline

В панели Cline нажмите иконку MCP Servers → Configure → Configure MCP Servers (или отредактируйте ~/.cline/mcp.json) и добавьте сервер:

{
  "mcpServers": {
    "leonting1010-tap-zenloh1pnq": {
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ],
      "disabled": false,
      "autoApprove": []
    }
  }
}
Continue

Создайте файл в .continue/mcpServers/ (например leonting1010-tap-zenloh1pnq.yaml) или добавьте блок в config.yaml. MCP работает только в режиме agent:

mcpServers:
  - name: leonting1010-tap-zenloh1pnq
    command: npx
    args:
      - "-y"
      - "@taprun/cli"
      - "mcp"
      - "stdio"
Zed

Выполните agent: add context server или откройте настройки (zed: open settings file) и добавьте сервер в объект context_servers:

{
  "context_servers": {
    "leonting1010-tap-zenloh1pnq": {
      "command": "npx",
      "args": [
        "-y",
        "@taprun/cli",
        "mcp",
        "stdio"
      ]
    }
  }
}

Похожие MCP-сервера

achiya-automation/safari-mcp

achiya-automation/safari-mcp

от achiya-automation

Используйте Safari MCP сервер для AI-агентов на macOS - ваш реальный браузер с сессиями, куками и 96 инструментами. Работает без Chrome, на нативном WebKit, с низким нагревом.

JavaScript⭐ 220
Browser MCP

Browser MCP

официальный

от browsermcp

Автоматизирует ваш браузер: кликает, заполняет формы, извлекает данные. Работает локально в вашем профиле, видит все логины и обходит капчи.

TypeScript⭐ 7201
ndthanhdev/mcp-browser-kit

ndthanhdev/mcp-browser-kit

от ndthanhdev

MCP Browser Kit — сервер, который позволяет AI-ассистентам напрямую управлять локальными браузерами. Полезен для автоматизации действий на страницах, сбора данных и тестирования. Разработчики и тес...

TypeScript⭐ 55
ofershap/real-browser-mcp

ofershap/real-browser-mcp

от ofershap

Управляет вашим реальным Chrome: кликает, заполняет формы, снимает скриншоты и проверяет результат. Работает с вашими сессиями и корпоративным SSO.

JavaScript⭐ 57
Browserbase MCP

Browserbase MCP

официальный

от browserbase

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

TypeScript⭐ 3399
Playwright MCP

Playwright MCP

официальный

от microsoft

Playwright управляет браузером: открывает страницы, кликает, заполняет формы. Работает по accessibility-дереву, без скриншотов.

TypeScript⭐ 38388
© Каталог MCP, 2026. Все права защищены.
Проект не аффилирован с Anthropic и любыми упомянутыми продуктами.
Все названия и торговые марки принадлежат их владельцам.
Контакты для связи: hi@mcp-katalog.ru

Лука Никитин