AIHawk
OfficialServer Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| AIHAWK_MODEL | No | An OpenRouter model id. Defaults to z-ai/glm-5.3-flash. | z-ai/glm-5.3-flash |
| STEALTHFOX_BINARY | No | An engine binary you already have. It must be the build the seal pins, or startup refuses: this skips the download, not the version check. | |
| OPENROUTER_API_KEY | Yes | Your OpenRouter API key. Can also be set with the --openrouter-key flag or in a .env file. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| browser_openA | Open
Called on a browser that is already up, this REOPENS it with the settings given, and what it held is gone. seed the identity; same seed, same fingerprint. Left out, one is drawn.
profile a directory keeping cookies, logins and the seed between opens;
"" means none.
proxy the exit, |
| browser_closeA | Close one browser and free what it was holding. The page it had is gone with it. The other browser is not touched. Closing FORGETS who that browser was: opening it again is a new stranger, not the same person resumed. That is deliberate - a browser somebody shut down should not come back wearing its old identity. |
| browser_listA | Which of the two browsers are open, where each one is, and which one the commands that name none go to. Answers JSON: Starts nothing: it reports what is running, so asking is free. |
| browser_statusA | Who is browsing right now: the identity, the exit, the profile and the page. Ask whenever you need to know which person the browser currently is, or
from where its traffic leaves. The seed is what you would pass to
It starts nothing. If no browser is running yet it says so, because until one is running there is no identity to report.
|
| browser_navigateA | Go to a url in this browser's page, opening it if none exists. Answers with the HTTP status the server gave and the url actually landed on, which is not always the one asked for: a redirect to a login wall or a regional domain shows up here. Read the status before trusting the page - a 404 or a 403 still has a document, and reading it as content is the mistake this reply exists to prevent. wait_until is "domcontentloaded" by default, which returns as soon as the markup is parsed. Use "load" when the page needs its images and stylesheets, or "networkidle" for a single-page app that fetches its content after load.
|
| browser_read_textA | The visible text of an element, with the markup gone. The cheapest way to read a page. Narrow the selector when you know where the answer is; use browser_read_html instead when the structure matters, or browser_snapshot when you need something to click. Long text is cut at max_chars (6000 by default) and the cut is marked in what comes back, so text that ends without that marker is the whole thing.
|
| browser_snapshotA | Title, url, and the interactive elements that are actually visible. Each element carries a Elements with no Not the accessibility tree: on a real sign-up page a single country
|
| browser_read_htmlA | The page's HTML, cleaned down to what is worth reading. Use this when the STRUCTURE matters - a form and its labels, a table, what
a control is wired to. mode="form" keeps the interactive surface and the text explaining it, mode="text" returns the prose alone, mode="full" keeps the structure with the noise and the attribute soup removed. Unlike browser_read_text this is NOT capped: it returns the whole reduced page, tens of thousands of characters on a large one. Cutting markup in the middle leaves tags that mean nothing, so it is not cut - but the answer can be long. Reach for browser_snapshot when you only need something to click.
|
| browser_take_screenshotB | One screenshot of this browser's page, on demand.
|
| browser_watchA | The whole browser window as a person at the machine sees it: tab strip, address bar, the page and the pointer, from a live capture kept running on that page. For watching the work, not for acting on it: the picture is window pixels, so do not feed its coordinates to browser_click_at; use browser_take_screenshot for that. Starts nothing. A browser that is not running has no window, so this refuses rather than opening one to photograph: a look is not a command, and the live panes call this many times a second.
|
| browser_clickA | Click the first element matching a CSS selector. Scrolls it into view and waits for it to be clickable. When no selector can describe the target, use browser_click_at with coordinates from browser_snapshot.
|
| browser_click_atA | Click (or press-and-hold) a raw viewport coordinate instead of a selector - for targets a selector cannot reliably reach: a slider track, a canvas-drawn captcha, a precise point inside a wider element. Moves the pointer there first (no teleport), then down, then up, holding first if hold_seconds is set. Returns a screenshot taken right after release. Coordinates are relative to the VIEWPORT, not to the page, so the ones in a
snapshot go stale the moment anything scrolls. Nothing raises when that
happens: the click lands on whatever is at that spot now. Take a fresh
snapshot after anything that could have moved the page, and prefer
browser_click with the element's
|
| browser_typeA | Fill a field, replacing whatever it holds. This sets the value rather than typing key by key, so it will not fire the per-keystroke handlers an autocomplete needs. For those, click the field and use browser_press_key.
|
| browser_select_optionA | Choose an option in a dropdown ( Use this rather than clicking the dropdown and pressing arrow keys: a click plus arrows cannot tell you which row it landed on, and setting the value through browser_evaluate changes it without the page seeing a real interaction.
|
| browser_press_keyA | Press a key on whatever has focus: "Enter", "Tab", "Escape", "ArrowDown", "Control+a", or a single character.
|
| browser_evaluateA | READ from the page with JavaScript and get the result as JSON. For what the other tools cannot see: a computed style, a value held in a framework's state, the length of a list. Acting on the page is refused, and the refusal names the tool to use.
Assigning to The refusal catches the obvious spellings, not every possible one. A script that slips past it is still the wrong way to do the thing: report it in your answer rather than using it.
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 16 tools
Most tools have clearly distinct purposes (click vs click_at, type vs press_key, select_option vs evaluate), and descriptions actively steer callers between near-neighbors. The reading trio (read_text/read_html/snapshot) and the pair (browser_list vs browser_status) overlap somewhat, but the descriptions draw sharp boundaries and recommend when to use each.
Every tool uses the identical browser_ prefix followed by a clear verb or verb_noun (open, close, navigate, click, click_at, type, press_key, select_option). No convention mixing; names are fully predictable.
16 tools is slightly heavy but each maps to a genuine, non-redundant browser capability spanning lifecycle, navigation, reading, and interaction. Nothing feels padded, though a few read tools could plausibly be merged.
The surface covers lifecycle (open/close/list/status), navigation, multiple read modes, and the key interaction primitives (click, click_at, type, select_option, press_key, evaluate). Minor gaps exist: no tab/page switching despite multi-page support, and no file upload, waiting, or back/forward/refresh helpers.