Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
start_sessionA

Start a browser testing session and navigate to the given URL.

Args: url: The URL to test (e.g. http://localhost:3000) headless: Run browser without visible window (default True) viewport_width: Browser viewport width in pixels viewport_height: Browser viewport height in pixels include_observation: Return the initial page observation in this call. review_mode: exploratory, visual, or regression.

observeA

Observe the current target — page, app, or screen. Read this first.

Returns the URL/window, the visible text, every interactive element keyed by description (no integer indices), feedback messages, counts, and any list-shaped repeating content. After every action, observe() again and reason about what changed before acting.

The agent decides what's a bug from this output. Argus does not auto-flag content quality, validation behaviour, or visual issues here — that's your judgment to make.

click_whatA

Click the element best matching the natural-language description.

Examples: "Login button", "Add Task", "the email field", "Delete near Buy groceries". Argus matches against visible text, aria-label, placeholder, name, id, and the parent context. Trailing kind hints ("button" / "field" / "link" / "dropdown") narrow the candidate pool.

If the description is ambiguous, this returns the top candidates with their distinguishing properties so you can rephrase. It does not guess and click — that's how testers misclick.

type_intoA

Type text into the input element best matching description.

Examples: type_into("email", "alice@x.com"), type_into("confirm password", "...") , type_into("the search box", "buy"). Resolution rules are the same as click_what — see that tool for ambiguity behaviour.

select_into

Select value in the dropdown best matching description.

hover_whatA

Hover the mouse over the element best matching description.

Real :hover (not synthetic): triggers tooltips, dropdown-on-hover menus, hover-only action buttons. Use after the element shows up in observe — for divs that observe filters out (figures, plain <div>s with :hover rules), introspect via inspect_element or fall back to eval_js.

press_keyA

Press a keyboard key — the web-mode equivalent testers reach for constantly.

key is a Playwright key name: "Escape" (dismiss a modal/overlay), "Enter" (submit a focused field), "Tab" / "Shift+Tab" (keyboard navigation / focus order), "ArrowDown"/"ArrowUp"/"ArrowLeft"/"ArrowRight" (menus, sliders, listboxes), "Backspace", "Delete", "PageDown", "Home", or a chord like "Control+a". Optionally pass description to focus that element first (e.g. press ArrowRight on "the volume slider"); omit it to press at the page level (e.g. Escape to close whatever modal is open).

Real users hit keys — a modal you can only close with Esc, a form that submits on Enter, arrow-key menu nav, focus-order bugs — none of which click/type can exercise. After it, observe() to see what changed.

resizeA

Resize the viewport mid-session to test RESPONSIVE layouts.

Real users are on phones, tablets and desktops, and mobile-only bugs (a hamburger that never appears, content that doesn't reflow, an overlay that covers the page, tap targets that overlap) are exactly the class scripted E2E misses. Unlike opening a fresh session at a mobile width, this keeps your current state (logged in, cart filled, form typed) so you can compare the SAME page across breakpoints and test the transition itself. Common widths: 375 (mobile), 414 (large phone), 768 (tablet), 1280/1440 (desktop). After it, observe() to see the reflowed layout.

emulate_deviceA

Re-open the current page as a real MOBILE DEVICE — touch, mobile user-agent, device-pixel-ratio, and viewport — not just a viewport resize.

resize() only changes width/height; many mobile bugs need the full device identity: touch-only interactions, mobile-only nav, content gated on a mobile UA, or a broken viewport-meta layout. Session state (cookies/login) carries over, so you can log in on desktop then switch to mobile. Common device names: "iPhone 13", "iPhone SE", "Pixel 5", "iPad Pro 11", "Galaxy S9+". Use resize() for a plain breakpoint sweep; use this for true device emulation. observe() after to see the mobile layout.

upload_fileA

Attach one or more local files to the file <input> matching description.

Wraps Playwright's set_input_files — works on both visible and hidden file inputs (most modern UIs hide the real input behind a styled label). For drag-drop upload zones that don't have an underlying <input type=file>, this won't work; use drop_file.

Args: description: Match the file input. "file", "upload", or the visible label text. paths: List of absolute paths to files to attach. Single file: pass a one-element list.

inspect_element

Get computed styles, ARIA metadata, and outerHTML for any visible element.

Use this when you suspect a visual / a11y / truncation bug on a specific surface and observe()'s summary doesn't tell you enough. Returns:

  • rendered styles (color, background, font-size/weight, display, visibility, opacity, position, z-index, overflow, cursor, etc.)

  • bounding rect + whether it's in the viewport

  • whether the element is visually truncated by CSS (scrollWidth > clientWidth with overflow: hidden / text-overflow: ellipsis)

  • aria-label / aria-describedby / aria-hidden / role / title

  • associated text(s)

  • disabled / readonly / focused state

  • first 1.5 KB of outerHTML

Argus does not auto-judge anything from this output. You read it and decide whether anything you see warrants record_bug.

check_layout

Inspect responsive layout signals without enabling arbitrary eval_js.

Returns raw evidence for horizontal overflow, clipped text, undersized interactive targets, and fixed/sticky overlays. These are leads for visual review, not automatically-recorded bugs.

capsule_save

Snapshot the current logged-in / seeded state as a named, restorable capsule.

Captures cookies + localStorage + sessionStorage + the current URL. Mint the state through the REAL UI first (sign up, create data) and THEN save — that keeps it honest (if onboarding is broken, you felt it). Pass a liveness_marker: text visible ONLY while the capsule is still valid (e.g. the logged-in user's name) so a later restore can tell live from stale.

Args: name: Capsule name to save under (per-origin). liveness_marker: Text that proves the restored state is still valid.

capsule_restoreA

Restore a saved capsule onto this session and verify it is still live.

Sets the cookies + storage, navigates to the captured URL, then checks the saved liveness marker. Returns whether the restored state is LIVE or STALE. A STALE capsule (the server session expired) cannot be trusted — any bug you record afterwards is flagged unreliable until you re-mint the state.

Args: name: Capsule name to restore (looked up for the current origin).

navigate

Navigate to a specific URL.

Args: url: The URL to navigate to

go_back

Go back to the previous page.

scroll_down

Scroll the page down to reveal more content.

screenshotA

Capture a screenshot — full viewport, full page, or one element.

Use this whenever something looks visually off and you want evidence for a record_bug call, or when you want a before/after pair to feed into screenshot_diff.

Args: name: Filename label (no extension). element: Optional element description (same syntax as click_what). If given, crops the screenshot to that element's bounds. Use for visual hierarchy / truncation / contrast checks. full_page: If True, capture the entire scrollable page rather than just the viewport. Ignored when element is set.

screenshot_diffA

Compare two screenshots and produce a third image with changed regions highlighted in red, so you can see what visually changed between two states.

Useful for detecting layout shifts, content updates that should not have happened, focus-ring changes after a click, modal overlays appearing, theme switches, etc. Argus does not auto-judge whether a diff is a bug — you read the side-by-side and decide.

Args: before: Path or filename of the earlier screenshot (returned from a previous screenshot() call). after: Path of the later screenshot. name: Label for the output diff image. threshold: 0-255 per-channel pixel difference above which a pixel is considered "changed". Default 25 (mild). Lower = more sensitive.

get_errors

Drain captured browser events (console errors, HTTP 4xx/5xx) since the last call.

These two channels are not visible to you through page state, so Argus captures them as Bug records automatically. Use this after any action that might have triggered a JS error or backend failure.

For everything else (visual issues, copy problems, missed validation, cross-page inconsistency), read the page state yourself and call record_bug when you've confirmed something is a real bug.

record_bugA

Record a confirmed bug you have identified during testing.

Call this only after you have observed something that meets the bug bar: reproducible, user-affecting, persistent. Do not record speculation or polish nits. The session report is built from these records — be specific.

Args: title: One-line headline, specific. Bad: "Form has issues." Good: "Login form accepts any password — no authentication." severity: "critical" | "high" | "medium" | "low" | "info". HIGH = data loss / security / payment / blocked flow. MEDIUM = workflow friction / confusing UX / cross-page bug. LOW = polish / suggestion-grade. verify: Optional reproduction clause. When the bug has a machine-checkable symptom (something present/absent on a fresh page load), pass it and Argus will INDEPENDENTLY re-load the page and confirm the symptom before recording — turning the bug into a verified, reproducible finding instead of your unverified say-so. This is Argus's anti-false-positive guard; use it whenever the symptom is text-checkable. Shape: {"expect": "present"|"absent", "target_text": "the text that proves the bug", "at_url": "/path"} # optional, defaults to current page Examples: - Fake delete (item survives): {"expect":"present", "target_text":"Buy groceries","at_url":"/tasks"} - Save didn't persist (new value missing): {"expect":"absent", "target_text":"EDITED-XYZ","at_url":"/tasks/1/edit"} IMPORTANT — the target must PROVE the symptom, not a nearby fact. target_text has to be the exact string whose presence/absence ALONE is the bug. For a COUNT or LOGIC inconsistency ("7 pending + 2 done != 8 total") no single text check establishes it — verifying that "8 total" merely EXISTS does not confirm the inconsistency and would stamp a misleading VERIFIED on tangential evidence. Record those as observation-based (omit verify), or verify the specific wrong value that should not be there. For a broken URL or API response whose HTTP status is the proof, use {"expect_status": 404, "at_url": "/missing"} instead of matching error-page copy. Status verification and text verification are alternatives and cannot be combined in one clause. For a MULTI-STEP bug (the symptom only appears after a journey), add "replay": true — Argus re-drives the recorded action trace (click_what/type_into/select_into/navigate) in a fresh cold context and checks the symptom there, giving a stronger "reproduced by replaying N steps from a cold start" receipt (or INCONCLUSIVE if a step no longer resolves). Shape: {"replay": true, "expect": "present"|"absent", "target_text": "the text that proves the bug"} CAUTION: replay re-EXECUTES the journey's steps against the live backend, so any Save/Delete/Add/checkout in the trace runs a second time (real side effect; the receipt reports writes_replayed). Use the plain clean-load verify (no replay) for destructive flows, or accept the re-run. Add "minimize": true to also narrow a confirmed reproduction to the minimal sufficient steps ("you don't need all 7 — 2 and 5 suffice"). Minimization runs ONLY for a write-free journey (it re-runs subsets, which would repeat any writes); it is skipped with a note otherwise. Omit verify entirely for visual/layout/UX-judgment bugs that no single text check captures — those record as observation-based. evidence: Optional dict with extra context. Recommended keys: description (str): Longer explanation including user impact. Default = same as title. steps (list[str]): Reproduction steps. Default = current session step log (everything you did so far). url (str): Page or screen URL. Default = current page URL. screenshot (str): One of "auto" (default — take one now and attach), "skip" (no screenshot), or a label to use as the screenshot filename. Pre-existing screenshot paths are also accepted. bug_type (str): A category for the report. Default "ux_issue". One of: console_error, network_error, visual_anomaly, ux_issue, crash, broken_link, form_error, state_verification, misleading_success, count_mismatch, text_anomaly, broken_image, seo_issue, accessibility, performance, mixed_content. Pick the SPECIFIC type, not the generic ux_issue: a "Saved!" / success toast that lied -> misleading_success; a delete or edit that did not persist -> state_verification; a wrong/inconsistent count or total -> count_mismatch; a JS exception or dead page -> crash; a form losing data / rejecting valid input -> form_error. Reserve ux_issue for genuine usability friction with no better fit — a data-loss or persistence bug labeled "ux_issue" reads as cosmetic next to its HIGH severity.

record_observationA

Record a qualitative review note without classifying it as a bug.

Use this for visual polish, hierarchy, readability, content, responsive, or usability observations that are useful evidence but do not meet the reproducible user-affecting bug bar.

Args: title: Short, specific observation headline. evidence: What is visible and why it matters. category: visual, usability, content, responsive, or accessibility. screenshot: "auto", "skip", an existing image path, or a screenshot label.

verify_persistenceA

Force a fresh page load and report whether target_text is present or absent — your tool for catching the "Saved!" toast that lied.

After any destructive or persistence-changing action (delete, edit, save, submit, toggle, payment, etc.), the success toast is not proof. Only a fresh GET on the relevant page is. This tool does that GET and reports presence — you decide whether the result matches what you expected.

Examples: verify_persistence("absent", "Buy groceries", "/tasks") — after deleting "Buy groceries", confirm it's gone from the list. verify_persistence("present", "EDITED-VALUE-XYZ", "/tasks/1/edit") — after editing, confirm the new value reloads.

Argus does not auto-record a bug here. If presence does not match your expectation, call record_bug.

Args: expect: "present" or "absent" — what state the target_text should be in after the fresh page load. target_text: The text or value you're checking for. after_url: Page to load and inspect. Defaults to the current URL. clear_storage: When True, wipe localStorage/sessionStorage before the reload so you test TRUE server persistence — a "Save" that only wrote client storage will read absent (data would be lost on another device/browser). Default False keeps client storage (proves server-backed truth without logging out). Use True when the feature is supposed to persist to a server/account. If clearing logs the app out, the result is unreliable — re-check without it.

check_links

Probe every internal link on the current page (HEAD with GET fallback) and return raw status-code results.

Argus does not auto-record bugs here. You read the dead-link list and decide. A handful of dead anchor links is rarely shippable; the severity depends on context. Call record_bug for the ones that matter.

check_performanceA

Read raw performance metrics from the browser's Performance API (load time, TTFB, request count, large resources).

Argus does not auto-record bugs here — Lighthouse already owns the performance-audit space. Only call record_bug if the page is so slow or so heavy that it materially blocks a real user (multi-second TTFB on a primary flow, multi-MB hero asset, etc).

test_action

Click an element and observe the diff in one round-trip — optionally predicting the outcome so Argus can catch the SURPRISE for you.

Captures the state before and after a click on the element matching target, computes a structural diff, drains console/network events, and screenshots the result.

Pass expect to commit a machine-checkable prediction in user-observable terms; Argus reports each as MATCH or SURPRISE against the real diff. This is the senior-tester move — a SURPRISE on something nobody scripted is a bug lead (fake delete, off-by-one count). It is an in-session OBSERVATION, not a reproduced finding: to bank it, call record_bug with a verify clause.

Args: target: Natural-language description of the element to click, same syntax as click_what ("Login button", "Add Task"). expectation: Optional human note (informational, shown in the diff). expect: Optional bounded prediction dict, any of: {"count": {"label": "tasks", "delta": 1}} count delta (or "value") {"gains": "Buy milk"} / {"removes": "Buy milk"} list membership {"text_present": "Saved"} / {"text_absent": "Buy milk"} {"toast": "Saved"} a new toast appeared {"url_changed": true} Multiple keys may be combined; all must hold.

test_form

Fill a set of form fields and submit, in one call. Description-keyed.

Each key in form_fields is matched to an input via the same natural-language resolver used by type_into / select_into. Use descriptions that match the field's label, name, or placeholder: {"email": "alice@x.com", "password": "abc12345", "confirm": "abc12345"}.

Argus reports what happened (URL change, new feedback messages, captured browser events, structural diff). It does NOT label the outcome as success / failure — your job is to read the result and call record_bug if you've confirmed a real bug.

Args: form_fields: Dict {field_description: value}. submit: How to submit. "auto" (default) finds the most likely submit button by text. "enter" presses Enter on the last filled field. Otherwise, treated as a description for click_what to resolve (e.g. "Save Changes" or "Register").

regression_checkA

Re-test previously-recorded findings for this site against the CURRENT build — "did my fix land, and did anything I'd fixed come back?".

Findings with a clean-load verify clause are journaled at end_session (per origin). This re-runs each one's INDEPENDENT clean-load check now and classifies it: STILL-PRESENT (the bug is still there), NO-LONGER-REPRODUCES (the symptom is gone — likely fixed; confirm the surface still exists), or INCONCLUSIVE. Each carried finding is treated as a hypothesis and re-checked from scratch — nothing is trusted from the prior run. Read-only (clean GETs); replay-mode findings are not auto-re-driven (that would re-execute writes).

end_sessionA

End the testing session, close the browser, and generate an HTML error report.

Returns the path to the generated report and a summary of findings.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

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/chriswu727/argus'

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