Skip to main content
Glama

scout_attach

Launches a browser and attaches it to a running web app for exploratory UI testing, enforcing a write policy (observe, read-only, safe-write, destructive) that blocks risky requests.

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' lets out only GET, HEAD and OPTIONS, plus signing in, signing out and token refresh, and POSTs the user named in readPosts; every other request is blocked — 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

NameRequiredDescriptionDefault
urlYesBase URL of the running app, e.g. http://localhost:3000
modeNoWrite policy (see tool description). Default 'read-only', or the SceneScout config's maxMode when that is stricter; a mode above the config's maxMode is refused. Never choose 'destructive' yourself — user opt-in 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. It can ask for less, never more: what SCENESCOUT_OPEN leaves out stays shut (SCENESCOUT_OPEN=none shuts both), and with SCENESCOUT_OPEN unset CI, SSH or no display shuts both; the result says what was not opened and why. 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 sends each pair's titles, categories and evidence, and the page's path, to a model provider, so this argument alone does not switch it on: the person running the server does, with SCENESCOUT_DEDUP=judge and ANTHROPIC_API_KEY or OPENAI_API_KEY in the server's environment. 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}.
planIdNoThe guided plan this attach carries out, as its scout_attach call lists it. Once any guided plan is built in this server, an attach above 'observe' without an accepted plan's id is refused, and so is one above the plan's mode or on another site than the plan's, and any attach passing readPosts or trustedEmbeds. A plan's confirmation covers one check: once no session carries the plan, it must be confirmed again. Never leave it out to get round a plan's confirmation.
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; while a guided plan is open in this server, none, and the variable is not read.
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. Changed2 schema fields changedv3.31.0
    • removedInput schema / additionalProperties
      Removed value: -false
    • changedInput schema / properties / open / description
      Previous value: -"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."New value: +"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. It can ask for less, never more: what SCENESCOUT_OPEN leaves out stays shut (SCENESCOUT_OPEN=none shuts both), and with SCENESCOUT_OPEN unset CI, SSH or no display shuts both; the result says what was not opened and why. Pass it only when the user asked for something other than the default."
  2. Changed5 schema fields changedv3.25.0
    • changedInput schema / properties / dedup / description
      Previous value: -"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."New value: +"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 sends each pair's titles, categories and evidence, and the page's path, to a model provider, so this argument alone does not switch it on: the person running the server does, with SCENESCOUT_DEDUP=judge and ANTHROPIC_API_KEY or OPENAI_API_KEY in the server's environment. Applies to every session of the project until the run ends."
    • removedInput schema / properties / mode / default
      Removed value: -"read-only"
    • changedInput schema / properties / mode / description
      Previous value: -"Write policy (see tool description). Never choose 'destructive' yourself — user opt-in only."New value: +"Write policy (see tool description). Default 'read-only', or the SceneScout config's maxMode when that is stricter; a mode above the config's maxMode is refused. Never choose 'destructive' yourself — user opt-in only."
    • addedInput schema / properties / planId
      Added value: +{
      +  "description": "The guided plan this attach carries out, as its scout_attach call lists it. Once any guided plan is built in this server, an attach above 'observe' without an accepted plan's id is refused, and so is one above the plan's mode or on another site than the plan's, and any attach passing readPosts or trustedEmbeds. A plan's confirmation covers one check: once no session carries the plan, it must be confirmed again. Never leave it out to get round a plan's confirmation.",
      +  "maxLength": 20,
      +  "type": "string"
      +}
    • changedInput schema / properties / readPosts / description
      Previous value: -"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."New value: +"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; while a guided plan is open in this server, none, and the variable is not read."
  3. 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"
      +]
  4. 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`."
  5. 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"
      +}
  6. 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"
      +}
  7. 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"
      +}
  8. 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: it discloses that write policy is enforced at the NETWORK layer with per-method rules, that 'destructive' is user-opt-in only, that a missing role login refuses the attach and names the fix, and that multi-session coverage/findings merge into one project memory. That is exactly the enforcement/auth/concurrency context an agent cannot infer.

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?

Purpose is front-loaded and most content is necessary for a 22-parameter, unannotated tool, but the write-policy sentence is a dense run-on with four clauses chained by dashes and semicolons, and the role/session passage lacks structure. Readable but not scannable.

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 session-establishing tool with 22 params, no annotations and no output schema, it covers the high-stakes surfaces (write policy, auth, plan gating, session concurrency) and failure behavior. Lower-stakes knobs (evidence, record, open, browser) are left entirely to the schema, which is acceptable at 100% coverage, but the description never says what the attach itself returns.

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 coverage is 100%, so baseline is 3, but the description adds real meaning the schema defers to — the schema's `mode` description literally says "see tool description," and the description supplies the per-mode request rules. It also explains the `role`/`session` relationship (one browser per role, target via each tool's `session`).

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?

Opens with a concrete verb+resource: "Launch a browser and attach to a running web app." It is clearly distinguishable from sibling action tools (scout_click, scout_navigate) — this is the session-establishing tool — and it names the prerequisite sibling scout_playbook.

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?

It gives explicit selection criteria for every mode: observe for targets with real data, safe-write "when the user wants create/edit flows tested", destructive "ONLY when the user explicitly confirmed a disposable/seeded environment", plus a sequencing rule (call scout_playbook first on a first attach). It also names the alternative path (role vs storageStatePath, scout_session for defaults).

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