Skip to main content
Glama

scout_attach

Attach a browser to a running web app for exploratory UI testing. Controlled by write policies: observe, read-only, safe-write, or destructive.

Instructions

Launch a browser and attach to a running web app. First attach in this conversation and you have read neither the SceneScout skill nor scout_playbook? Call scout_playbook before this. Write policy is enforced at the NETWORK layer: mode='observe' blocks EVERY request that is not a GET (login and token refresh excepted, and POSTs the user named in readPosts) — choose it for a target that holds real data, where even an ordinary form submission would create a record; mode='read-only' (default) blocks destructive-labeled elements AND all PUT/PATCH/DELETE + destructive POSTs, but lets ordinary form POSTs through; mode='safe-write' allows creating data and permits updates/deletes ONLY on resources this session created (use when the user wants create/edit flows tested); mode='destructive' allows everything — ONLY when the user explicitly confirmed a disposable/seeded environment. Pass role to sign in with a login the user saved by scenescout login <url> --role <name>, or a Playwright storage-state JSON as storageStatePath. Pass session to keep MULTIPLE roles alive at once (one browser each, genuinely concurrent) for collaboration testing — target each directly with every tool's session param, or use scout_session to set which one is the default; coverage and findings merge into one project memory.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesBase URL of the running app, e.g. http://localhost:3000
modeNoWrite policy (see tool description). Never choose 'destructive' yourself — user opt-in only.read-only
openNoOpen the live view (on this attach) and/or report.html (when scout_report writes it) in the user's default browser: 'live', 'report', 'both' or 'none'. Default: the SCENESCOUT_OPEN environment variable, else 'both' on a local desktop session (headed or headless) and 'none' in CI, over SSH, or with no display. Pass it only when the user asked for something other than the default.
roleNoSign in as a role whose login was saved with `scenescout login <url> --role <name>` (kept in the project's .scenescout/auth/). Every session given the same role gets its own browser built from that one login. Not with storageStatePath. No saved login for the role: the attach is refused and names the command to run — ask the user to run it, since it opens a window for them to sign in.
taskNoWhat this session is doing right now, shown under its objective from the moment it appears, e.g. Signing in and taking stock. Passed alone it is read as the 2.0 spelling of `objective`. Defaults to a placeholder so a fresh card never reads as idle.
dedupNoHow this run tells a filed finding from one already recorded. Default: the SCENESCOUT_DEDUP environment variable, else 'rule', the store's rule alone. 'judge': the rule first, then, for a filing the rule keeps apart from everything recorded, a model is asked whether it is one of the open findings on its page, and merges it when it says so. It needs ANTHROPIC_API_KEY or OPENAI_API_KEY in the server's environment, and sends each pair's titles, categories and evidence, and the page's path, to that provider — ONLY when the user asked for it. Applies to every session of the project until the run ends.
headedNoShow the browser window
paceMsNoA floor between actions, in milliseconds, for when a person is watching and needs to keep up — following a flow, taking notes, demonstrating. Default 0: as fast as the page allows, which is what a run wants otherwise. Changeable mid-run with scout_session {paceMs}.
recordNoKeep a frame of the page after every action, under .scenescout/recordings/, and show it beside that step in report.html. Default: the SCENESCOUT_RECORD environment variable (on or off), else off: a recording is pictures of the app under test sitting in the project folder. Turn it on for QA work, where the run is evidence and not only a report.
browserNoBrowser to drive. Default: the SCENESCOUT_BROWSER environment variable, else chromium. A build that is not on disk is downloaded on this attach, once, except in CI or with SCENESCOUT_BROWSER_DOWNLOAD=off, where the attach names the command to run. Use firefox or webkit for a cross-browser pass; stay on chromium otherwise.
sessionNoSession name for multi-role runs (e.g. 'admin', 'qa'). Creates/replaces that session's browser and makes it the default. Default: 'default'.
evidenceNoWhat happens to the picture each scout_finding takes of what it is about. 'inline': kept under .scenescout/recordings/, shown in report.html, and returned in the scout_finding result so the conversation shows it. 'file': kept and shown in the report only. 'off': none taken. Default: the SCENESCOUT_EVIDENCE environment variable, else 'inline', or 'file' in a CI job. Pictures are bounded in size and in how many one session returns (see the configuration reference).
objectiveNoThis session's objective: the whole remit you were given, in one sentence ("Admin lane: §2 registers, §7 plan gating", "Approve and reject orders as a manager"). It sits above the task, which is what the session is doing at any moment. Shown to whoever is watching the run; worth setting whenever more than one session is live.
readPostsNoPOST endpoints that only read, e.g. ["POST /api/search", "POST https://api.example.com/reports/query"], which observe mode then lets out — ONLY when the user named them. Never add one yourself, even when the gap ledger lists a refused POST: ask the user. Exact paths; * stands for one path segment. Still refused when the path or body looks destructive or the body is a GraphQL mutation. Observe mode only. Default: the SCENESCOUT_READ_POSTS environment variable, else none.
projectPathNoAbsolute path to the project (memory + report live in .scenescout/ here). Pass it whenever you have a project or working folder. Omitted: the client's workspace folder, else a folder per tested site under the user's documents folder (Documents/SceneScout/<host>/, or SCENESCOUT_PROJECTS_DIR), which the result names — tell the user where it is.
navTimeoutMsNoHow long a page may take to load, in ms. Default: the SCENESCOUT_NAV_TIMEOUT_MS environment variable, else 20000 (crawled pages 15000; a value set here applies to them too). Raise it only when timeouts come from a loaded machine rather than the app.
trustedEmbedsNoOrigins of embedded frames (e.g. "https://pay.example.com") whose writes out of the app may go out — ONLY when the user named them, typically a provider in test mode, and only in safe-write mode. Never add one yourself. Hostile input, repeated-click probes and uploads stay refused in them.
viewportWidthNoViewport width (default 1280); use e.g. 390 for a mobile pass
viewportHeightNoViewport height (default 900)
actionTimeoutMsNoHow long one click, keystroke, hover or pick may take, in ms. Default: the SCENESCOUT_ACTION_TIMEOUT_MS environment variable, else 5000. Raise it only when timeouts come from a loaded machine rather than the app.
storageStatePathNoOptional Playwright storage-state JSON path for authenticated exploration. Not with `role`.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed9 schema fields changedv3.17.0
    • changedInput schema / properties / browser / description
      Previous value: -"Browser to drive. Default: the SCENESCOUT_BROWSER environment variable, else chromium. firefox and webkit must be downloaded first (scenescout install --browser-only --browsers firefox). Use them for a cross-browser pass; stay on chromium otherwise."New value: +"Browser to drive. Default: the SCENESCOUT_BROWSER environment variable, else chromium. A build that is not on disk is downloaded on this attach, once, except in CI or with SCENESCOUT_BROWSER_DOWNLOAD=off, where the attach names the command to run. Use firefox or webkit for a cross-browser pass; stay on chromium otherwise."
    • addedInput schema / properties / dedup
      Added value: +{
      +  "description": "How this run tells a filed finding from one already recorded. Default: the SCENESCOUT_DEDUP environment variable, else 'rule', the store's rule alone. 'judge': the rule first, then, for a filing the rule keeps apart from everything recorded, a model is asked whether it is one of the open findings on its page, and merges it when it says so. It needs ANTHROPIC_API_KEY or OPENAI_API_KEY in the server's environment, and sends each pair's titles, categories and evidence, and the page's path, to that provider — ONLY when the user asked for it. Applies to every session of the project until the run ends.",
      +  "enum": [
      +    "rule",
      +    "judge"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / evidence
      Added value: +{
      +  "description": "What happens to the picture each scout_finding takes of what it is about. 'inline': kept under .scenescout/recordings/, shown in report.html, and returned in the scout_finding result so the conversation shows it. 'file': kept and shown in the report only. 'off': none taken. Default: the SCENESCOUT_EVIDENCE environment variable, else 'inline', or 'file' in a CI job. Pictures are bounded in size and in how many one session returns (see the configuration reference).",
      +  "enum": [
      +    "inline",
      +    "file",
      +    "off"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / open
      Added value: +{
      +  "description": "Open the live view (on this attach) and/or report.html (when scout_report writes it) in the user's default browser: 'live', 'report', 'both' or 'none'. Default: the SCENESCOUT_OPEN environment variable, else 'both' on a local desktop session (headed or headless) and 'none' in CI, over SSH, or with no display. Pass it only when the user asked for something other than the default.",
      +  "enum": [
      +    "live",
      +    "report",
      +    "both",
      +    "none"
      +  ],
      +  "type": "string"
      +}
    • changedInput schema / properties / projectPath / description
      Previous value: -"Absolute path to the project (memory + report live in .scenescout/ here)"New value: +"Absolute path to the project (memory + report live in .scenescout/ here). Pass it whenever you have a project or working folder. Omitted: the client's workspace folder, else a folder per tested site under the user's documents folder (Documents/SceneScout/<host>/, or SCENESCOUT_PROJECTS_DIR), which the result names — tell the user where it is."
    • addedInput schema / properties / readPosts
      Added value: +{
      +  "description": "POST endpoints that only read, e.g. [\"POST /api/search\", \"POST https://api.example.com/reports/query\"], which observe mode then lets out — ONLY when the user named them. Never add one yourself, even when the gap ledger lists a refused POST: ask the user. Exact paths; * stands for one path segment. Still refused when the path or body looks destructive or the body is a GraphQL mutation. Observe mode only. Default: the SCENESCOUT_READ_POSTS environment variable, else none.",
      +  "items": {
      +    "maxLength": 300,
      +    "type": "string"
      +  },
      +  "maxItems": 20,
      +  "type": "array"
      +}
    • removedInput schema / properties / record / default
      Removed value: -false
    • changedInput schema / properties / record / description
      Previous value: -"Keep a frame of the page after every action, under .scenescout/recordings/, and show it beside that step in report.html. Off by default: a recording is pictures of the app under test sitting in the project folder. Turn it on for QA work, where the run is evidence and not only a report."New value: +"Keep a frame of the page after every action, under .scenescout/recordings/, and show it beside that step in report.html. Default: the SCENESCOUT_RECORD environment variable (on or off), else off: a recording is pictures of the app under test sitting in the project folder. Turn it on for QA work, where the run is evidence and not only a report."
    • changedInput schema / required
      Previous value: -[
      -  "url",
      -  "projectPath"
      -]New value: +[
      +  "url"
      +]
  2. Changed4 schema fields changedv3.14.1
    • addedInput schema / properties / actionTimeoutMs
      Added value: +{
      +  "description": "How long one click, keystroke, hover or pick may take, in ms. Default: the SCENESCOUT_ACTION_TIMEOUT_MS environment variable, else 5000. Raise it only when timeouts come from a loaded machine rather than the app.",
      +  "maximum": 120000,
      +  "minimum": 1000,
      +  "type": "integer"
      +}
    • addedInput schema / properties / navTimeoutMs
      Added value: +{
      +  "description": "How long a page may take to load, in ms. Default: the SCENESCOUT_NAV_TIMEOUT_MS environment variable, else 20000 (crawled pages 15000; a value set here applies to them too). Raise it only when timeouts come from a loaded machine rather than the app.",
      +  "maximum": 300000,
      +  "minimum": 1000,
      +  "type": "integer"
      +}
    • addedInput schema / properties / role
      Added value: +{
      +  "description": "Sign in as a role whose login was saved with `scenescout login <url> --role <name>` (kept in the project's .scenescout/auth/). Every session given the same role gets its own browser built from that one login. Not with storageStatePath. No saved login for the role: the attach is refused and names the command to run — ask the user to run it, since it opens a window for them to sign in.",
      +  "maxLength": 40,
      +  "type": "string"
      +}
    • changedInput schema / properties / storageStatePath / description
      Previous value: -"Optional Playwright storage-state JSON path for authenticated exploration"New value: +"Optional Playwright storage-state JSON path for authenticated exploration. Not with `role`."
  3. Changed1 schema field changedv3.9.0
    • addedInput schema / properties / trustedEmbeds
      Added value: +{
      +  "description": "Origins of embedded frames (e.g. \"https://pay.example.com\") whose writes out of the app may go out — ONLY when the user named them, typically a provider in test mode, and only in safe-write mode. Never add one yourself. Hostile input, repeated-click probes and uploads stay refused in them.",
      +  "items": {
      +    "maxLength": 200,
      +    "type": "string"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
  4. Changed4 schema fields changedv3.4.0
    • addedInput schema / properties / objective
      Added value: +{
      +  "description": "This session's objective: the whole remit you were given, in one sentence (\"Admin lane: §2 registers, §7 plan gating\", \"Approve and reject orders as a manager\"). It sits above the task, which is what the session is doing at any moment. Shown to whoever is watching the run; worth setting whenever more than one session is live.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
    • addedInput schema / properties / paceMs
      Added value: +{
      +  "description": "A floor between actions, in milliseconds, for when a person is watching and needs to keep up — following a flow, taking notes, demonstrating. Default 0: as fast as the page allows, which is what a run wants otherwise. Changeable mid-run with scout_session {paceMs}.",
      +  "maximum": 60000,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / record
      Added value: +{
      +  "default": false,
      +  "description": "Keep a frame of the page after every action, under .scenescout/recordings/, and show it beside that step in report.html. Off by default: a recording is pictures of the app under test sitting in the project folder. Turn it on for QA work, where the run is evidence and not only a report.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / task
      Added value: +{
      +  "description": "What this session is doing right now, shown under its objective from the moment it appears, e.g. Signing in and taking stock. Passed alone it is read as the 2.0 spelling of `objective`. Defaults to a placeholder so a fresh card never reads as idle.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
  5. Changed1 schema field changedv1.2.0
    • addedInput schema / properties / browser
      Added value: +{
      +  "description": "Browser to drive. Default: the SCENESCOUT_BROWSER environment variable, else chromium. firefox and webkit must be downloaded first (scenescout install --browser-only --browsers firefox). Use them for a cross-browser pass; stay on chromium otherwise.",
      +  "enum": [
      +    "chromium",
      +    "firefox",
      +    "webkit"
      +  ],
      +  "type": "string"
      +}
  6. Addedv1.1.0

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so richly: it discloses that write policy is enforced at the network layer, exactly what each mode blocks/allows, that readPosts is user-named only, that role attaches are refused without a saved login, and that dedup='judge' sends evidence to a third-party provider. This is behavioral context well beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and prerequisites, and no sentence is pure filler. However the write-policy sentence is an extremely long run-on cramming four modes and their exceptions into one breath, which hurts parseability even though the content is valuable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 21-parameter tool with no annotations and no output schema, the description covers the critical routing decisions (mode, role, session, dedup) thoroughly and leaves the mechanical params to the 100%-covered schema. It does not describe the attach result or what a successful attach returns, which is the main residual gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents parameters and baseline is 3. The description adds meaning on the highest-stakes params: it explains the mode taxonomy (which the schema delegates to it), the role/session interaction and multi-role concurrency, and the readPosts restriction — genuine added value over the enumerated values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Launch a browser and attach to a running web app") and separates itself from siblings like scout_login, scout_navigate and scout_run_plan. An agent can immediately tell this is the entry/attach tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs the agent to call scout_playbook first when new to the conversation, and gives conditional selection rules for every mode: observe for real data, read-only as default, safe-write for create/edit flows, destructive only on user-confirmed disposable envs. Names alternatives (storageStatePath vs role) and preconditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.