All plugins

webmint

Turn a website into a deterministic tool: a real browser captures the page once, the host's own model writes a declarative extraction spec, two runs must agree (same field set, >=50% fill per field) before it is saved, and every later call runs that spec with no model in the loop (~2.7s). Five tools: setup, mint, run, list, remove. Disclosure — needs Node >= 18 and Playwright; on first mint the plugin installs Playwright and Chromium into its own directory (~120 MB, opt out with WEBMINT_NO_AUTO_SETUP=1). Capture runs in a fresh signed-out browser: actions may fill, click and submit forms, and http specs replay the captured GET or POST (Cookie and Authorization headers are never replayed). Public http(s) URLs only — file:, loopback/private and link-local/metadata addresses are refused, with private/loopback behind WEBMINT_ALLOW_PRIVATE_URLS=1 or the host's security.allow_private_urls. Headless Chromium is refused by some bot-protected sites.

DECRUX98121Webv0.1.4Updated 2 days ago

About

Turn a website into a deterministic tool: a real browser captures the page once, the host's own model writes a declarative extraction spec, two runs must agree (same field set, >=50% fill per field) before it is saved, and every later call runs that spec with no model in the loop (~2.7s). Five tools: setup, mint, run, list, remove. Disclosure — needs Node >= 18 and Playwright; on first mint the plugin installs Playwright and Chromium into its own directory (~120 MB, opt out with WEBMINT_NO_AUTO_SETUP=1). Capture runs in a fresh signed-out browser: actions may fill, click and submit forms, and http specs replay the captured GET or POST (Cookie and Authorization headers are never replayed). Public http(s) URLs only — file:, loopback/private and link-local/metadata addresses are refused, with private/loopback behind WEBMINT_ALLOW_PRIVATE_URLS=1 or the host's security.allow_private_urls. Headless Chromium is refused by some bot-protected sites.

webmint

webmint — learn a site once, prove the spec twice, then never browse it again

Turn a website into a deterministic, verified tool — using whatever model your agent already runs.

No OpenAI key. No cloud. No sandbox. The artifact is a JSON file you own.

hermes plugins install DECRUX9812/webmint

That's it. The first mint provisions its own browser if needed; webmint_setup does it
explicitly if you'd rather pre-install.


Why

Every agent demo ends the same way: it opens a browser, reads the screen, and guesses.
Tomorrow the page moves and the agent guesses differently.

webmint learns the page once, turns it into a declarative spec, proves the spec twice,
and then runs it as plain data — no model in the loop, ~3.5 s per call, same fields every time.

browser agent:  open browser → load → read pixels → parse → hope      (~31 s, shape varies)
webmint tool:   run_website_tool(query="...") → [{title, price}]      (~3.5 s, typed)

What makes it different

| | |
|---|---|
| Model-agnostic | The mint calls the host's own ctx.llm. Whatever provider/model your agent is on does the work — DeepSeek, Gemini, a local model. Nothing is hardcoded to one vendor. |
| Verified, not vibes | A tool is saved only if it runs twice, returns rows both times, and every declared field is non-empty in most rows. A spec that returns 25 rows of null is rejected and repaired, not shipped. |
| You own the artifact | tool.json — readable, editable by hand, committable. No service holds your integrations. |
| Signed-out by design | Every capture uses a fresh browser with no cookies or saved logins, and minted specs never replay Cookie/Authorization. Capture actions can fill, click and press keys on the page, and an http spec replays the captured request (GET or POST). Only public http(s) URLs are opened; loopback/private hosts need WEBMINT_ALLOW_PRIVATE_URLS=1. |

Tools

| tool | what it does |
|---|---|
| webmint_setup | Check/provision Node, Playwright and Chromium (about 120 MB once). Idempotent. |
| webmint_mint | Capture a URL → the model writes a spec → run twice → save only if both runs agree |
| webmint_run | Execute a minted spec with new inputs (no model) |
| webmint_list | List minted tools with site, kind and verified state |
| webmint_remove | Delete a tool and its capture |

Ask your agent:

Mint a tool for https://news.ycombinator.com/from?site=github.com that lists posts with title and url.

Then:

Use it for rust-lang.org.

Requirements

  • Node >= 18 — found automatically ($WEBMINT_NODE, ~/.local/node24/bin/node, PATH,
    /usr/local/bin, /usr/bin; version checked).
  • Playwright + Chromium — found in $WEBMINT_PW_MODULES, the plugin's own node_modules,
    an existing Pomerado install, or the global npm root. If none is present, webmint_mint
    provisions it automatically (set WEBMINT_NO_AUTO_SETUP=1 to opt out).
  • URL policy — the mint URL, goto actions, minted url_templates and every redirect must be
    public http(s). Inside Hermes the host's URL safety check decides (honours
    security.allow_private_urls); standalone, set WEBMINT_ALLOW_PRIVATE_URLS=1 to reach
    loopback/private hosts. Link-local and cloud-metadata addresses are always refused.
  • Everything else is stdlib Python.

Artifact

$HERMES_HOME/webmint/tools/<name>/
├── tool.json     the spec (hand-editable; hand-written specs are first-class)
├── meta.json     provenance: model, runs, fill rates, timing, example input
└── capture/      the recording it was built from

A spec:

{
  "name": "letterboxd_films",
  "kind": "dom",
  "url_template": "https://letterboxd.com/search/films/{query}/",
  "item_selector": "ul.results > li.search-result",
  "fields": {"title": "a.film-title", "year": "small.metadata a", "url": "a@href"},
  "input_schema": {"properties": {"query": {"type": "string"}}, "required": ["query"]},
  "limit": 20
}

Field expressions: "css", "css@attr", "+ .x" (next sibling), "^ .x" (parent) — the last
two exist because real pages split one record across sibling elements (arXiv's <dt>/<dd>).

kind: "http" replays a captured JSON endpoint instead (method, headers, body_template,
items_path, field_paths).

Measured

Six tools, eight sites, minted with deepseek-v4.1-flash (2026-10-26):

| tool | mint | run | rows | field fill |
|---|---|---|---|---|
| wikipedia_search | 28.3 s | 3.1 s | 20 | 100% |
| arxiv_recent | 64.2 s (1 repair) | 2.7 s | 25 | 100% |
| github_trending | 29.5 s | 4.0 s | 14 | 93% lang |
| books_scrape | 15.4 s | 2.7 s | 19 | 100% |
| hn_github_posts | 18.8 s | 2.5 s | 30 | 100% |
| letterboxd_films | 32.4 s | 4.9 s | 20 | 100% |

mean mint 31.4 s · mean run 3.5 s · 6 of 8 sites mintable · break-even ≈ 10 runs

Honest limits

  • Bot walls. Headless Chromium gets 403 on some sites (Chewy, eBay) and an empty page on
    others (DuckDuckGo). Two of eight test sites failed this way. No prompt fixes a fingerprint —
    that needs your own browser profile, which is not in v0.1.
  • Not strictly read-only. It never logs in or uses your cookies, but capture actions can
    fill and submit page forms, and an http spec replays the captured request, POST included.
  • Selectors rot. meta.json records when a tool was verified; re-mint when a run starts
    returning zero rows. A repair cron is not included.
  • Weak models produce worse specs. The verifier turns that into a visible failure rather
    than a silent one, which is the most that can be promised.

Tests

python3 -m pytest tests/ -q     # 13 tests: validation, store, verifier gates, real browser fixtures

Two tests launch Chromium against a local HTML fixture — the extractor and the sibling
prefix are covered without touching the network.

Credits

Pomerado — github.com/Pomerado/pomerado, MIT — made the case that a
website should be learned once and replayed instead of re-reasoned every run. webmint is an independent
implementation of that idea for Hermes Agent: the same shape (capture → spec → verify → tool), rebuilt so the
learning step runs on whatever model you already have, with the artifact as a JSON spec you own rather than
generated source. Their Guardian/authority model and job contract are worth reading; nothing is copied here.

The conversation this came from — @Gamma_950 ("your browser agent re-reasons every page on every run"),
@sreecharantwts ("browser use being slow and flaky is the real tax on agents"), @stretchcloud (structure loss in
markdown flattening), @pamelafox (WebMCP as the endgame). Those posts are the reason the pitch is about
verification, not speed.

License

MIT © Ritesh Patel

README from the reviewed commit 5b7fa61; it updates when the author re-pins.

More by DECRUX9812

5 plugins by DECRUX9812 in the catalog.

DECRUX9812gameforgeGame development toolkit: sound effects, music loops with MIDI, NPC voices, pixel-art sprite sheets and autotiling tilesets, low-poly and AI 3D models (.glb); 4 playable web genres (topdown, platformer, arena, roguelike), Godot 4 and Unity builds; headless Blender and Unreal pipelines; an automated playtester that plays each genre and reports crashes, stuck spots and boring stretches; one-click PWA, itch.io, single-HTML and Capacitor export. Offline by default. Disclosure — runs local Chrome/Chromium for playtests, and Godot, Unity, Blender, UnrealEditor-Cmd, ffmpeg, xvfb-run or butler only when a call asks for them; blender action=script runs a bpy file the caller names. Network only when asked: fal.ai, Tripo or Meshy (FAL_KEY / TRIPO_API_KEY / MESHY_API_KEY, prompt and image sent), ElevenLabs (ELEVENLABS_API_KEY, SFX prompt), Edge TTS when edge-tts is installed (dialogue text), Godot export templates from GitHub (~1 GB, target=godot_templates), itch.io via butler (target=itch with an explicit itch_target). Writes only inside the game project directory, plus a temporary browser profile. No telemetry.Communitytools45DECRUX9812typesafe-skill-routerTypeSafe (Jev) skill routing: the request is routed before the model call and the one skill from the live roster that fits it is named in a single <skill_relevance> line on the user message — nothing is injected when nothing fits.Communityautomation15DECRUX9812office-deskGuarded Word, PowerPoint and Excel editing: tracked Word changes and comments, slide and deck edits, and Excel edits with LibreOffice recalc. Every write gets a backup and a revertible receipt, and you review it all on a Desk page in the Desktop app. Settings are in Settings > Plugins. Disclosure: reads any Office file the agent is pointed at but writes only inside folders the user puts on the Desk (backups and receipts live in the plugin's own data dir). xlsx_recalc runs the user's installed LibreOffice (soffice, headless) on a temporary copy. The Desk page reads the session store read-only to show a workstream's chat. No network calls, telemetry, credentials or background processes. Depends on the paper-docx, paper-pptx and paper-xlsx forks. They provide the docx, pptx and openpyxl import names, so they must not share an environment with python-docx, python-pptx or openpyxl.Communitytools14DECRUX9812handflowManus-style planning flow — the agent plans in steps and marks them as it works, with a live desktop pane.Communityautomation4