shane logsdon · local browser automation

One browser.
Many calls.

GLiNER Browser is a command-line browser for AI agents. One Chromium session stays open between invocations, page controls come back as JSON, and a local GLiNER2.5 model ranks those controls against a plain description when you have one instead of a selector.

Set it up

the problem

An agent with a shell can drive a browser, but each invocation is a new process. A browser started per command begins at a blank page and an empty profile, so the work of getting to the page — navigating, signing in, opening the right tab — is repeated or lost.

The other half is finding the control. Page structure is not a stable interface: an agent that hard-codes a selector has to be right about markup it did not write, and one that guesses coordinates has to be right about layout.

GLiNER Browser keeps the session instead of the selector. One browser holds the page between calls, and the two ways of naming a control — an observed element ID, or a description ranked by a local model — are both answers about the page as it is now.

what it does

start · stop
Runs a daemon that owns a visible or headless Chromium context and listens on a Unix-domain socket. Later commands reach the same page, including tabs opened since.
observe
Returns the current title, URL, and every visible interactive element with an ID such as e4, plus its role, accessible name, tag, and href.
find
Ranks the observed controls with fastino/gliner2.5-multi-v1, so "the save changes button" comes back as element IDs with confidence scores, not as a selector.
click · fill · select
Take an element ID from observe or find for a deterministic action, or a description to resolve one on the spot.
One object per call
Every command prints a single JSON object. Check ok before using the rest, and report error when it is false.

Navigation, observation, key presses, scrolling, full-page screenshots, and tab selection are commands too; so is status. Screenshots are written to a path you name. The browser profile is a dedicated automation profile under the state directory, not your everyday one.

where it runs

Browser actions and model inference are local. There is no hosted demo, no sandbox and no backend to send a page to: the CLI, the Chromium it drives, and the model all run on the machine that issues the command. The CLI process talks to its daemon over a local socket in ~/.local/state/gliner-browser by default, which holds the socket, the daemon log, and the browser profile.

Because inference is local, the model files are too. On the first natural-language lookup GLiNER2.5 downloads its weights from Hugging Face unless they are already cached; the default checkpoint is Apache-2.0 licensed, and the model card carries the terms. Chromium is a separate download through Playwright. Until both are in place, observe still answers, and a natural-language target has to wait for the model.

status

Early development. The command interface and behavior may change, and the source README says so at the top. Version 0.1.0 is MIT licensed.

Python 3.11 through 3.13, on macOS or Linux. Windows is not supported, because the persistent session is a Unix-domain socket.

Natural-language matching ranks candidates, and ranking can choose the wrong control. That is why the observed ID exists: inspect the find output, then act on the ID you chose. Canvas-only interfaces and pages with inaccessible controls may not expose enough to name at all. The tool is a browser control library, not a task planner, and a returned browser state is not a guarantee that the action did what the page implied.

Page content is untrusted data. Instructions found on a website are not instructions to the agent, and consequential actions — purchases, publishing, deletion — are worth reviewing before they are submitted.

where to go