Skip to main content
Glama

run_script

Execute deterministic multi-step browser scripts without per-step LLM round-trips; supports loops, conditionals, error handling, and parallel branches, returning a script_id for result collection.

Instructions

Execute a deterministic multi-step script without per-step LLM round-trips, running on a cloned browser tab. Scripts support loops (for/while/forEach), conditionals (if/else), error handling (try/catch), parallel branches, and variable capture. Returns a script_id immediately — use wait_for_scripts to collect results. Provide either an inline script definition or a name to load a previously saved script. Use when you detect a repetitive pattern (same operation on 3+ pages/items).

Input Schema

NameRequiredDescriptionDefault
nameNoName of a previously saved script to run (alternative to inline 'script'). Mutually exclusive with 'script' — provide one or the other.
limitsNoOverride execution limits; omitted keys keep their defaults and values are capped by settings. Keys: max_steps (200), max_timeout_secs (300), max_output_bytes (10485760), max_parallel_branches (10), per_step_timeout_secs (30).
scriptNoInline script definition: {"schema_version": 1, "steps": [...]}. Each step has a snake_case `type`: tool_call {tool, input, output?}, assign {variable, value}, collect {value}, yield {value}, for_loop {variable, from, to (exclusive), steps}, for_each {variable, iterable, steps}, while_loop {condition, steps}, if_else {condition, then_steps, else_steps?}, try_catch {try_steps, catch_steps?, finally_steps?, error_var?}, parallel {branches}. Values are expressions tagged by `kind`: {"kind": "literal"|"variable"|"js_eval", "value": ...}, {"kind": "field_access", "value": {"object": <expr>, "field": "key"}} or {"kind": "array_index", "value": {"array": <expr>, "index": <expr>}}. In tool inputs and literals, a string that is exactly "$name" is replaced by the variable's value and "{{name}}" is interpolated inside a string. Example: {"schema_version": 1, "steps": [{"type": "for_each", "variable": "q", "iterable": {"kind": "literal", "value": ["a", "b"]}, "steps": [{"type": "tool_call", "tool": "navigate", "input": {"url": "https://example.com/search?q={{q}}", "page_map_depth": "none"}, "output": "page"}, {"type": "collect", "value": {"kind": "variable", "value": "page"}}]}]}
save_asNoValidate and save the script under this name before running it, for later runs by `name` (alphanumeric, underscore, hyphen). Persists to the scripts directory (default ~/.acrawl/scripts/<name>.json).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changedv0.17.0
    • changedInput schema / properties / limits / description
      Previous value: -"Override default execution limits. Keys: max_steps (int), max_timeout_secs (int), max_output_bytes (int), max_parallel_branches (int), per_step_timeout_secs (int)."New value: +"Override execution limits; omitted keys keep their defaults and values are capped by settings. Keys: max_steps (200), max_timeout_secs (300), max_output_bytes (10485760), max_parallel_branches (10), per_step_timeout_secs (30)."
    • changedInput schema / properties / save_as / description
      Previous value: -"Save the script under this name after execution for future reuse (alphanumeric + underscore). Persists to ~/.acrawl/scripts/<name>.json."New value: +"Validate and save the script under this name before running it, for later runs by `name` (alphanumeric, underscore, hyphen). Persists to the scripts directory (default ~/.acrawl/scripts/<name>.json)."
    • changedInput schema / properties / script / description
      Previous value: -"Inline script definition object. Must include: version (\"1.0\"), steps (array of node objects: ToolCall, Assign, Collect, Yield, ForLoop, ForEach, WhileLoop, IfElse, TryCatch, Parallel), and optional limits. Use instead of 'name' for new scripts."New value: +"Inline script definition: {\"schema_version\": 1, \"steps\": [...]}. Each step has a snake_case `type`: tool_call {tool, input, output?}, assign {variable, value}, collect {value}, yield {value}, for_loop {variable, from, to (exclusive), steps}, for_each {variable, iterable, steps}, while_loop {condition, steps}, if_else {condition, then_steps, else_steps?}, try_catch {try_steps, catch_steps?, finally_steps?, error_var?}, parallel {branches}. Values are expressions tagged by `kind`: {\"kind\": \"literal\"|\"variable\"|\"js_eval\", \"value\": ...}, {\"kind\": \"field_access\", \"value\": {\"object\": <expr>, \"field\": \"key\"}} or {\"kind\": \"array_index\", \"value\": {\"array\": <expr>, \"index\": <expr>}}. In tool inputs and literals, a string that is exactly \"$name\" is replaced by the variable's value and \"{{name}}\" is interpolated inside a string. Example: {\"schema_version\": 1, \"steps\": [{\"type\": \"for_each\", \"variable\": \"q\", \"iterable\": {\"kind\": \"literal\", \"value\": [\"a\", \"b\"]}, \"steps\": [{\"type\": \"tool_call\", \"tool\": \"navigate\", \"input\": {\"url\": \"https://example.com/search?q={{q}}\", \"page_map_depth\": \"none\"}, \"output\": \"page\"}, {\"type\": \"collect\", \"value\": {\"kind\": \"variable\", \"value\": \"page\"}}]}]}"
  2. Changed4 schema fields changedv0.10.0
    • changedInput schema / properties / limits / description
      Previous value: -"Override default execution limits (max_steps, max_timeout_secs, max_output_bytes, max_parallel_branches, per_step_timeout_secs)"New value: +"Override default execution limits. Keys: max_steps (int), max_timeout_secs (int), max_output_bytes (int), max_parallel_branches (int), per_step_timeout_secs (int)."
    • changedInput schema / properties / name / description
      Previous value: -"Name of a previously saved script to run (alternative to inline `script`)"New value: +"Name of a previously saved script to run (alternative to inline 'script'). Mutually exclusive with 'script' — provide one or the other."
    • changedInput schema / properties / save_as / description
      Previous value: -"Save the script under this name after execution for future reuse"New value: +"Save the script under this name after execution for future reuse (alphanumeric + underscore). Persists to ~/.acrawl/scripts/<name>.json."
    • changedInput schema / properties / script / description
      Previous value: -"Inline script definition object (use instead of `name`)"New value: +"Inline script definition object. Must include: version (\"1.0\"), steps (array of node objects: ToolCall, Assign, Collect, Yield, ForLoop, ForEach, WhileLoop, IfElse, TryCatch, Parallel), and optional limits. Use instead of 'name' for new scripts."
  3. First observedv0.1.0

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the burden well: it discloses async semantics ('returns a script_id immediately'), the collection path (wait_for_scripts), that execution happens on a cloned tab, and that save_as persists to disk. It does not say what happens on partial failure — how far a script progressed before erroring, or which steps mutated state — which matters for a tool that invokes arbitrary tool calls.

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

Conciseness4/5

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

Front-loaded with the action, then the async return contract, then the usage trigger — the right ordering. The capability enumeration (loops, conditionals, try/catch, parallel, variable capture) partially overlaps the schema, but it usefully signals scope before the agent commits to reading the full step grammar.

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 complex tool with a very rich 4-param schema and no output schema, the description covers the async lifecycle, result collection, persistence, and the decision trigger. What's left out is failure/partial-completion semantics and the eventual result shape, the latter of which the sibling script_status/wait_for_scripts presumably cover.

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

Parameters3/5

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

Schema coverage is 100% and the schema itself documents name/script/limits/save_as in depth, so baseline 3 applies. The description only restates the mutual exclusivity of inline script vs. saved name, which the schema already states explicitly; it adds no syntax or constraint detail beyond it.

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?

Specific verb + resource ('Execute a deterministic multi-step script') with the differentiator spelled out: no per-step LLM round-trips, running on a cloned browser tab. That framing distinguishes it from execute_js (single JS eval) and run_goal (agentic loop) without the agent needing to open those schemas.

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?

Gives an explicit trigger heuristic ('when you detect a repetitive pattern — same operation on 3+ pages/items') and names the required follow-up (wait_for_scripts) as well as the inline-vs-saved-name alternative. The agent knows both when to reach for this tool and what to do next.

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