Skip to content

Latest commit

 

History

History
814 lines (589 loc) · 76.7 KB

File metadata and controls

814 lines (589 loc) · 76.7 KB
title Tool Hooks
description Block dangerous commands, lint after edits, and set up your environment

Tool hooks are experimental. Expect breaking changes while we iterate.

**The easiest way to set up tool hooks is to ask Mux.** Just tell Mux what you want (e.g., "lint Python files after edits" or "block force pushes") and it will create the hook scripts for you.

Tool hooks let you run your own scripts before and after Mux tool executions.

What do you want to do?

Prevent force pushes, rm -rf, etc. Run ruff, eslint, tsc after changes direnv, nvm, virtualenv

Block dangerous commands

Create .mux/tool_pre to validate commands before they run. Exit non-zero to block:

#!/usr/bin/env bash
# .mux/tool_pre - runs before every tool

if [[ "$MUX_TOOL" == "bash" ]]; then
  script="$MUX_TOOL_INPUT_SCRIPT"

  if echo "$script" | grep -q 'push.*--force'; then
    echo "❌ Force push blocked" >&2
    exit 1
  fi

  if echo "$script" | grep -q 'rm -rf /'; then
    echo "❌ Dangerous rm blocked" >&2
    exit 1
  fi
fi

exit 0  # Allow tool to run
chmod +x .mux/tool_pre

The agent sees your error message and can adjust its approach.


Lint after file edits

Create .mux/tool_post to run validation after tools complete:

#!/usr/bin/env bash
# .mux/tool_post - runs after every tool
set -euo pipefail

[[ "$MUX_TOOL" == file_edit_* ]] || exit 0
file="${MUX_TOOL_INPUT_FILE_PATH:-}"
[[ -n "$file" ]] || exit 0

case "$file" in
  *.py)
    ruff check "$file"
    ;;
  *.ts|*.tsx)
    npx tsc --noEmit "$file"
    ;;
esac
chmod +x .mux/tool_post
Minimal formatter example (Go)
#!/usr/bin/env bash
# .mux/tool_post - runs after every tool
set -euo pipefail

[[ "$MUX_TOOL" == file_edit_* ]] || exit 0
file="${MUX_TOOL_INPUT_FILE_PATH:-}"
[[ "$file" == *.go ]] || exit 0

gofmt -w "$file"

Lint errors appear in hook_output and the agent can fix them.

`hook_output` is only shown in the UI when the hook produces output. For a cleaner experience, only print output when the hook has an effect—e.g., skip "Formatted: file" messages if the file was already formatted.

Set up environment

Create .mux/tool_env to configure your shell environment. This file is sourced before every bash tool call:

# .mux/tool_env - sourced before bash commands

# direnv
eval "$(direnv export bash 2>/dev/null)" || true

# nvm
# export NVM_DIR="$HOME/.nvm"
# [ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"

# Python virtualenv
# source .venv/bin/activate 2>/dev/null || true
Unlike hooks, `tool_env` doesn't need to be executable—it's sourced, not run. It only affects `bash` tools.

Reference

All hooks receive these environment variables:

Variable Description
MUX_TOOL Tool name: bash, file_edit_replace_string, file_read, etc.
MUX_WORKSPACE_ID Current workspace identifier
MUX_TOOL_INPUT_PATH Path to file containing full tool input (always set)

Mux flattens the tool input into MUX_TOOL_INPUT_<...> environment variables (see the appendix below). Fields longer than 8KB are omitted—use MUX_TOOL_INPUT_PATH for full access.

Post-hook only (tool_post):

Variable Description
MUX_TOOL_RESULT_PATH Path to file containing full tool result

Flattened result fields are available as MUX_TOOL_RESULT_<...>. Fields longer than 8KB are omitted—use MUX_TOOL_RESULT_PATH for full access.

Exit Code tool_pre behavior tool_post behavior
0 Tool executes normally Success, output shown to agent
Non-zero Tool blocked, error shown to agent Failure, error shown in hook_output

Mux searches for each hook file in this order:

  1. Project-level: .mux/<hook>
  2. User-level: ~/.mux/<hook>

This applies to tool_pre, tool_post, and tool_env.

For SSH workspaces, hooks execute on the remote machine.

Hooks must complete within 10 seconds or they're terminated. Long-running tools (builds, tests) don't count against this—only hook execution time.

Keep hooks fast—if you need longer operations, consider running them asynchronously or in the background.

Feature .mux/tool_pre .mux/tool_post .mux/tool_env
Purpose Block dangerous commands Lint/validate results Environment setup
Runs Before tool After tool Sourced in bash shell
Applies to All tools All tools bash tool only
Use case Block force-push Run ruff/eslint direnv, nvm, virtualenv

Mux also provides flattened tool input env vars so hook scripts can stay compact.

  • Scalars become MUX_TOOL_INPUT_<FIELD>
  • Nested objects become MUX_TOOL_INPUT_<PARENT>_<CHILD>
  • Arrays also include ..._COUNT and per-index variables like ..._<INDEX>

If a value is too large for the environment, it may be omitted (not set). Mux also caps the number of flattened env vars and array elements to keep hook execution reliable.

{/* BEGIN TOOL_HOOK_ENV_VARS */}

advisor (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_QUESTION question string
agent_report (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_REPORT_MARKDOWN reportMarkdown string
MUX_TOOL_INPUT_TITLE title string
agent_skill_delete (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_CONFIRM confirm boolean Must be true to confirm deletion
MUX_TOOL_INPUT_FILE_PATH filePath string Relative file path within the skill directory to delete. Required when target is 'file'
MUX_TOOL_INPUT_NAME name string Skill name to delete
MUX_TOOL_INPUT_TARGET target enum Deletion target: 'file' to delete a specific file, 'skill' to remove the entire skill directory (defaults to file)
agent_skill_list (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_INCLUDE_UNADVERTISED includeUnadvertised boolean When true, includes skills with advertise: false
agent_skill_read (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_NAME name string Skill name (directory name under the skills root)
agent_skill_read_file (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_FILE_PATH filePath string Path to the file within the skill directory (relative)
MUX_TOOL_INPUT_LIMIT limit number Number of lines to return from offset (optional, returns all if not specified)
MUX_TOOL_INPUT_NAME name string Skill name (directory name under the skills root)
MUX_TOOL_INPUT_OFFSET offset number 1-based starting line number (optional, defaults to 1)
agent_skill_write (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_CONTENT content string File content to write
MUX_TOOL_INPUT_FILE_PATH filePath string Relative path within skill directory. Defaults to SKILL.md
MUX_TOOL_INPUT_NAME name string Skill name (directory name under the global skills root)
analytics_query (6)
Env var JSON path Type Description
MUX_TOOL_INPUT_SQL sql string DuckDB SQL query to execute
MUX_TOOL_INPUT_TITLE title string Optional chart title
MUX_TOOL_INPUT_VISUALIZATION visualization enum Optional visualization type for rendering the query result
MUX_TOOL_INPUT_X_AXIS x_axis string Optional column name for the visualization X axis
MUX_TOOL_INPUT_Y_AXIS_<INDEX> y_axis[<INDEX>] string Optional column name(s) for the visualization Y axis
MUX_TOOL_INPUT_Y_AXIS_COUNT y_axis.length number Number of elements in y_axis (Optional column name(s) for the visualization Y axis)
ask_user_question (8)
Env var JSON path Type Description
MUX_TOOL_INPUT_ANSWERS_<KEY> answers[<KEY>] string
MUX_TOOL_INPUT_QUESTIONS_<INDEX>_HEADER questions[<INDEX>].header string Short label shown in the UI (keep it concise)
MUX_TOOL_INPUT_QUESTIONS_<INDEX>_MULTI_SELECT questions[<INDEX>].multiSelect boolean
MUX_TOOL_INPUT_QUESTIONS_<INDEX>_OPTIONS_<INDEX>_DESCRIPTION questions[<INDEX>].options[<INDEX>].description string
MUX_TOOL_INPUT_QUESTIONS_<INDEX>_OPTIONS_<INDEX>_LABEL questions[<INDEX>].options[<INDEX>].label string
MUX_TOOL_INPUT_QUESTIONS_<INDEX>_OPTIONS_COUNT questions[<INDEX>].options.length number Number of elements in questions[<INDEX>].options
MUX_TOOL_INPUT_QUESTIONS_<INDEX>_QUESTION questions[<INDEX>].question string
MUX_TOOL_INPUT_QUESTIONS_COUNT questions.length number Number of elements in questions
attach_file (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_FILENAME filename string Optional filename override to present to the model.
MUX_TOOL_INPUT_MEDIA_TYPE mediaType string Optional media type override when the filename/extension is ambiguous.
MUX_TOOL_INPUT_PATH path string The path to the file to attach (absolute or relative)
bash (5)
Env var JSON path Type Description
MUX_TOOL_INPUT_DISPLAY_NAME display_name string Human-readable name for the process (e.g., 'Dev Server', 'TypeCheck Watch'). Required for all bash invocations since any process can be sent to background.
MUX_TOOL_INPUT_MODEL_INTENT model_intent string Optional. Short user-facing purpose for this command, shown next to the command in collapsed chat. Use a present-participle phrase in plain English, under 100 characters. Do not repeat the command or include duration, because Mux appends those. Examples: 'Running the unit tests', 'Checking repository state', 'Inspecting build output'.
MUX_TOOL_INPUT_RUN_IN_BACKGROUND run_in_background boolean Run this command in the background without blocking. Use for processes running >5s (dev servers, builds, file watchers). Do NOT use for quick commands (<5s), interactive processes (no stdin support), or processes requiring real-time output (use foreground with larger timeout instead). Returns immediately with a taskId (bash:<processId>) and backgroundProcessId. Read output with task_await (returns only new output since last check). Terminate with task_terminate using the taskId. List active tasks with task_list. Process persists until timeout_secs expires, terminated, or workspace is removed. For long-running tasks like builds or compilations, prefer background mode to continue productive work in parallel. Raw background bash does not automatically wake the parent workspace when it prints output or exits; use task_await when you need output, or wrap the script in a background task/workflow monitor when wake-on-condition behavior is required. Do not call task_await in the same parallel tool-call batch; wait for the returned taskId first. When you actually need the output, read it with task_await; do not poll task_await just because the process is still running.
MUX_TOOL_INPUT_SCRIPT script string The bash script/command to execute
MUX_TOOL_INPUT_TIMEOUT_SECS timeout_secs number Timeout in seconds. For foreground: max execution time before kill. For background: max lifetime before auto-termination. Start small and increase on retry; avoid large initial values to keep UX responsive
bash_background_terminate (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_PROCESS_ID process_id string Background process ID to terminate
bash_output (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_FILTER filter string Optional regex to filter output lines. By default, only matching lines are returned. When filter_exclude is true, matching lines are excluded instead. Non-matching lines are permanently discarded and cannot be retrieved later.
MUX_TOOL_INPUT_FILTER_EXCLUDE filter_exclude boolean When true, lines matching 'filter' are excluded instead of kept. Key behavior: excluded lines do NOT cause early return from timeout - waiting continues until non-excluded output arrives or process exits. Use to avoid busy polling on progress spam (e.g., filter='⏳|waiting|...' with filter_exclude=true lets you set a long timeout and only wake on meaningful output). Requires 'filter' to be set.
MUX_TOOL_INPUT_PROCESS_ID process_id string The ID of the background process to retrieve output from
MUX_TOOL_INPUT_TIMEOUT_SECS timeout_secs number Seconds to wait for new output. If no output is immediately available and process is still running, blocks up to this duration. Returns early when output arrives or process exits. Only use long timeouts (>15s) when no other useful work can be done in parallel.
code_execution (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_CODE code string JavaScript code to execute in the PTC sandbox
complete_goal (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_GOAL_ID goalId string Optional optimistic-concurrency token. Pass the goalId returned by get\_goal to ensure the completion is rejected with a typed conflict error if the user clears or replaces the goal mid-stream.
MUX_TOOL_INPUT_SUMMARY summary string Required 1-2 sentence justification for completing the current goal.
desktop_click (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_BUTTON button enum Optional mouse button to click. Defaults to left.
MUX_TOOL_INPUT_X x number Target X coordinate in screen pixels.
MUX_TOOL_INPUT_Y y number Target Y coordinate in screen pixels.
desktop_double_click (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_BUTTON button enum Optional mouse button to double-click. Defaults to left.
MUX_TOOL_INPUT_X x number Target X coordinate in screen pixels.
MUX_TOOL_INPUT_Y y number Target Y coordinate in screen pixels.
desktop_drag (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_END_X endX number Ending X coordinate in screen pixels.
MUX_TOOL_INPUT_END_Y endY number Ending Y coordinate in screen pixels.
MUX_TOOL_INPUT_START_X startX number Starting X coordinate in screen pixels.
MUX_TOOL_INPUT_START_Y startY number Starting Y coordinate in screen pixels.
desktop_key_press (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_KEY key string Key or key combination to press on the desktop.
desktop_move_mouse (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_X x number Target X coordinate in screen pixels.
MUX_TOOL_INPUT_Y y number Target Y coordinate in screen pixels.
desktop_screenshot (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_SCALED_HEIGHT scaledHeight number Optional scaled height hint in pixels for downstream consumers.
MUX_TOOL_INPUT_SCALED_WIDTH scaledWidth number Optional scaled width hint in pixels for downstream consumers.
desktop_scroll (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_DELTA_X deltaX number Optional horizontal scroll delta in pixels.
MUX_TOOL_INPUT_DELTA_Y deltaY number Vertical scroll delta in pixels.
MUX_TOOL_INPUT_X x number Target X coordinate in screen pixels.
MUX_TOOL_INPUT_Y y number Target Y coordinate in screen pixels.
desktop_type (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_TEXT text string Text to type into the active desktop target.
file_edit_insert (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_CONTENT content string The content to insert
MUX_TOOL_INPUT_INSERT_AFTER insert_after string Anchor text to insert after. Content will be placed immediately after this substring.
MUX_TOOL_INPUT_INSERT_BEFORE insert_before string Anchor text to insert before. Content will be placed immediately before this substring.
MUX_TOOL_INPUT_PATH path string Path to the file to edit (absolute or relative to the current workspace)
file_edit_replace_lines (7)
Env var JSON path Type Description
MUX_TOOL_INPUT_END_LINE end_line number 1-indexed end line (inclusive) to replace
MUX_TOOL_INPUT_EXPECTED_LINES_<INDEX> expected_lines[<INDEX>] string Optional safety check. When provided, the current lines in the specified range must match exactly.
MUX_TOOL_INPUT_EXPECTED_LINES_COUNT expected_lines.length number Number of elements in expected_lines (Optional safety check. When provided, the current lines in the specified range must match exactly.)
MUX_TOOL_INPUT_NEW_LINES_<INDEX> new_lines[<INDEX>] string Replacement lines. Provide an empty array to delete the specified range.
MUX_TOOL_INPUT_NEW_LINES_COUNT new_lines.length number Number of elements in new_lines (Replacement lines. Provide an empty array to delete the specified range.)
MUX_TOOL_INPUT_PATH path string Path to the file to edit (absolute or relative to the current workspace)
MUX_TOOL_INPUT_START_LINE start_line number 1-indexed start line (inclusive) to replace
file_edit_replace_string (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_NEW_STRING new_string string The replacement text
MUX_TOOL_INPUT_OLD_STRING old_string string The exact text to replace (must be unique in file if replace_count is 1). Include enough context (indentation, surrounding lines) to make it unique.
MUX_TOOL_INPUT_PATH path string Path to the file to edit (absolute or relative to the current workspace)
MUX_TOOL_INPUT_REPLACE_COUNT replace_count number Number of occurrences to replace (default: 1). Use -1 to replace all occurrences. If 1, old_string must be unique in the file.
file_read (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_LIMIT limit number Number of lines to return from offset (optional, returns all if not specified)
MUX_TOOL_INPUT_OFFSET offset number 1-based starting line number (optional, defaults to 1)
MUX_TOOL_INPUT_PATH path string The path to the file to read (absolute or relative)
heartbeat (5)
Env var JSON path Type Description
MUX_TOOL_INPUT_ACTION action enum Operation to perform: "get" reads the current heartbeat, "set" enables or configures it, and "unset" removes this workspace's heartbeat settings.
MUX_TOOL_INPUT_CONTEXT_MODE contextMode enum set: context preparation for heartbeat turns: "normal" uses current context, "compact" compacts first, and "reset" appends a reset boundary first. Omit to preserve the current mode.
MUX_TOOL_INPUT_ENABLED enabled boolean set: whether scheduled heartbeats are enabled. Omit to preserve the current value; when creating new settings, omitted means "enabled".
MUX_TOOL_INPUT_INTERVAL_MS intervalMs number set: heartbeat interval in milliseconds (300000–86400000). Omit to preserve the current interval or use the global default for new settings.
MUX_TOOL_INPUT_MESSAGE message string set: optional custom instruction body appended after the fixed idle-workspace lead-in. Pass an empty string to clear the custom message.
memory (11)
Env var JSON path Type Description
MUX_TOOL_INPUT_COMMAND command enum The memory operation to perform.
MUX_TOOL_INPUT_FILE_TEXT file_text string create: full contents of the new file.
MUX_TOOL_INPUT_INSERT_LINE insert_line number insert: line number to insert after (0 = top of file).
MUX_TOOL_INPUT_INSERT_TEXT insert_text string insert: text to insert.
MUX_TOOL_INPUT_LIMIT limit number view on a file: number of lines to return from offset (optional).
MUX_TOOL_INPUT_NEW_PATH new_path string rename: new virtual path (same scope).
MUX_TOOL_INPUT_NEW_STR new_str string str_replace: replacement text.
MUX_TOOL_INPUT_OFFSET offset number view on a file: 1-based starting line number (optional).
MUX_TOOL_INPUT_OLD_PATH old_path string rename: current virtual path.
MUX_TOOL_INPUT_OLD_STR old_str string str_replace: exact text to replace (must be unique in the file).
MUX_TOOL_INPUT_PATH path string Virtual memory path (e.g. /memories/global/notes.md). Required for every command except rename.
mux_agents_write (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_CONFIRM confirm boolean Must be true to apply the write. The agent should ask the user for confirmation first.
MUX_TOOL_INPUT_NEW_CONTENT newContent string The full new contents of the AGENTS.md file
mux_config_read (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_FILE file enum Which configuration file to read
MUX_TOOL_INPUT_PATH_<INDEX> path[<INDEX>] string Optional path segments to read a specific nested value. If omitted, returns the full config.
MUX_TOOL_INPUT_PATH_COUNT path.length number Number of elements in path (Optional path segments to read a specific nested value. If omitted, returns the full config.)
mux_config_write (7)
Env var JSON path Type Description
MUX_TOOL_INPUT_CONFIRM confirm boolean Must be true to apply the write. Ask the user for confirmation first.
MUX_TOOL_INPUT_FILE file enum Which configuration file to write
MUX_TOOL_INPUT_OPERATIONS_<INDEX>_OP operations[<INDEX>].op literal
MUX_TOOL_INPUT_OPERATIONS_<INDEX>_PATH_<INDEX> operations[<INDEX>].path[<INDEX>] string
MUX_TOOL_INPUT_OPERATIONS_<INDEX>_PATH_COUNT operations[<INDEX>].path.length number Number of elements in operations[<INDEX>].path
MUX_TOOL_INPUT_OPERATIONS_<INDEX>_VALUE operations[<INDEX>].value unknown
MUX_TOOL_INPUT_OPERATIONS_COUNT operations.length number Number of elements in operations (Operations to apply to the config document)
notify (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_MESSAGE message string Optional notification body with more details (max 200 chars). Keep it brief - users may only see a preview.
MUX_TOOL_INPUT_TITLE title string Short notification title (max 64 chars). Should be concise and actionable.
review_pane_update (4)
Env var JSON path Type Description
MUX_TOOL_INPUT_HUNKS_<INDEX>_COMMENT hunks[<INDEX>].comment string Short note (~1 sentence) telling the user what to look at and why.
MUX_TOOL_INPUT_HUNKS_<INDEX>_PATH hunks[<INDEX>].path string Filter in path[:range] form, e.g. "src/foo.ts" or "src/foo.ts:42-58". Path is project-relative; use './' or '../' when the path must resolve from the current tool working directory. Range uses new-file line numbers (inclusive).
MUX_TOOL_INPUT_HUNKS_COUNT hunks.length number Number of elements in hunks (List of hunks to flag for review.)
MUX_TOOL_INPUT_OPERATION operation enum 'replace' overwrites the assisted set; 'add' appends to it.
set_goal (5)
Env var JSON path Type Description
MUX_TOOL_INPUT_BUDGET_CENTS budgetCents number Optional positive budget in cents. Omit/null to apply the effective workspace goal default.
MUX_TOOL_INPUT_EXPECTED_GOAL_ID expectedGoalId string Optimistic-concurrency token required when replacing an active, paused, or budget-limited goal. Use the goalId from get_goal.
MUX_TOOL_INPUT_OBJECTIVE objective string Concrete, measurable objective to pursue over automatic goal continuations.
MUX_TOOL_INPUT_REPLACE_EXISTING_GOAL replaceExistingGoal boolean Set true only when the user explicitly asked to replace the current goal.
MUX_TOOL_INPUT_TURN_CAP turnCap number Optional positive maximum automatic continuation turns. Omit/null to apply the effective workspace goal default.
skills_catalog_read (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_OWNER owner string GitHub owner from the search result (e.g. 'vercel-labs')
MUX_TOOL_INPUT_REPO repo string GitHub repository name from the search result (e.g. 'agent-skills')
MUX_TOOL_INPUT_SKILL_ID skillId string Skill ID from the search result
skills_catalog_search (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_LIMIT limit number Maximum number of results to return (default: 10)
MUX_TOOL_INPUT_QUERY query string Search query to find skills in the catalog
task (18)
Env var JSON path Type Description
MUX_TOOL_INPUT_AGENT_ID agentId string
MUX_TOOL_INPUT_ISOLATION isolation enum Workspace isolation for the sub-agent. "fork" (the default) runs it in an isolated copy of this workspace created from committed state. "none" runs it directly in this workspace's checkout, sharing the working tree (including uncommitted changes) and skipping the fork + init overhead. Use "none" only for read-only analysis (e.g. the explore agent) or when you instruct the sub-agent to avoid editing shared files, since it can otherwise modify the same files concurrently. Omit to fork.
MUX_TOOL_INPUT_KIND kind enum Task kind. Omit or use "subagent" for the existing child-workspace sub-agent flow; use "workspace" to start a normal full workspace turn.
MUX_TOOL_INPUT_MODEL model string Optional model override for the sub-agent, parsed with the same alias logic as the UI (an alias or a full 'provider:model' string). Omit this unless the user explicitly instructed a specific model — by default the sub-agent inherits the parent's model. Do not assume any particular model is available.
MUX_TOOL_INPUT_N n number Optional best-of count. Use n when several agents should try the same prompt independently. Mutually exclusive with variants; omit both for a single task. Only use grouped runs for sub-agents without interfering side effects, such as read-only agents like explore.
MUX_TOOL_INPUT_PROMPT prompt string
MUX_TOOL_INPUT_RUN_IN_BACKGROUND run_in_background boolean
MUX_TOOL_INPUT_SUBAGENT_TYPE subagent_type string
MUX_TOOL_INPUT_THINKING thinking string Optional thinking/reasoning-level override for the sub-agent. Accepts a level name (off, low, medium, high, xhigh, max) or a numeric index (resolved against the chosen model). Omit this unless the user explicitly instructed a specific thinking level — by default the sub-agent inherits the parent's thinking level.
MUX_TOOL_INPUT_TITLE title string
MUX_TOOL_INPUT_VARIANTS_<INDEX> variants[<INDEX>] string Optional labels for sibling runs of the same prompt template. Use variants when the task should be repeated across labeled lanes such as issue numbers, commit windows, or frontend/backend/tests/docs review lanes. Mutually exclusive with n. When provided, Mux launches one sibling per label and substitutes ${variant} in the prompt.
MUX_TOOL_INPUT_VARIANTS_COUNT variants.length number Number of elements in variants (Optional labels for sibling runs of the same prompt template. Use variants when the task should be repeated across labeled lanes such as issue numbers, commit windows, or frontend/backend/tests/docs review lanes. Mutually exclusive with n. When provided, Mux launches one sibling per label and substitutes ${variant} in the prompt.)
MUX_TOOL_INPUT_WORKSPACE_BRANCH_NAME workspace.branchName string
MUX_TOOL_INPUT_WORKSPACE_DISPOSABLE workspace.disposable boolean
MUX_TOOL_INPUT_WORKSPACE_MODE workspace.mode enum
MUX_TOOL_INPUT_WORKSPACE_QUEUE_DISPATCH_MODE workspace.queueDispatchMode enum For kind="workspace" + workspace.mode="existing", choose when a follow-up queued while the workspace is busy should dispatch: "tool-end" after the next tool call, or "turn-end" after the current turn.
MUX_TOOL_INPUT_WORKSPACE_TRUNK_BRANCH workspace.trunkBranch string
MUX_TOOL_INPUT_WORKSPACE_WORKSPACE_ID workspace.workspaceId string
task_apply_git_patch (6)
Env var JSON path Type Description
MUX_TOOL_INPUT_DRY_RUN dry_run boolean When true, attempt to apply the patch in a temporary git worktree and then discard it (does not modify the current workspace).
MUX_TOOL_INPUT_EXPECTED_HEAD_SHA expected_head_sha string When provided, refuse to apply unless the target repository HEAD matches this SHA.
MUX_TOOL_INPUT_FORCE force boolean When true, allow apply even if the patch was previously applied (and skip clean-tree checks).
MUX_TOOL_INPUT_PROJECT_PATH project_path string When provided, apply only the patch artifact for this project path.
MUX_TOOL_INPUT_TASK_ID task_id string Child task ID whose patch artifact should be applied
MUX_TOOL_INPUT_THREE_WAY three_way boolean When true, run git am with --3way
task_await (6)
Env var JSON path Type Description
MUX_TOOL_INPUT_FILTER filter string Optional regex to filter bash task output lines. By default, only matching lines are returned. When filter_exclude is true, matching lines are excluded instead. Non-matching lines are discarded and cannot be retrieved later.
MUX_TOOL_INPUT_FILTER_EXCLUDE filter_exclude boolean When true, lines matching 'filter' are excluded instead of kept. Requires 'filter' to be set.
MUX_TOOL_INPUT_MIN_COMPLETED min_completed number Number of awaited tasks that must complete before this call returns. Defaults to 1, so by default task_await returns as soon as the FIRST awaited task completes, letting you act on it while the rest keep running. The result still includes every task complete at that moment plus current status (running/queued) for the rest. Tasks that have not yet completed keep running and remain re-awaitable on a later task_await call. Raise this (e.g. set it to the total number of awaited tasks) when you genuinely need more before proceeding — for example best-of-N synthesis that must compare every candidate. Clamped to the number of awaited tasks; values above that behave like 'wait for all'.
MUX_TOOL_INPUT_TASK_IDS_<INDEX> task_ids[<INDEX>] string List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, or workflow_run results; never fabricate an ID. task_list can rediscover sub-agent/background bash IDs, but top-level workflow run rediscovery is done by omitting task_ids. When omitted, waits for active descendant tasks and top-level workflow runs of the current workspace, excluding workflow-owned sub-agents/background bash tasks because those results are consumed through parent workflow runs.
MUX_TOOL_INPUT_TASK_IDS_COUNT task_ids.length number Number of elements in task_ids (List of task IDs or workflow run IDs to await — use only real IDs returned by prior task, bash, or workflow_run results; never fabricate an ID. task_list can rediscover sub-agent/background bash IDs, but top-level workflow run rediscovery is done by omitting task_ids. When omitted, waits for active descendant tasks and top-level workflow runs of the current workspace, excluding workflow-owned sub-agents/background bash tasks because those results are consumed through parent workflow runs.)
MUX_TOOL_INPUT_TIMEOUT_SECS timeout_secs number Maximum time to wait in seconds for each task. For bash tasks, this waits for NEW output (or process exit). If exceeded, the result returns status=queued|starting|running|awaiting_report (task is still active). Defaults to 600 seconds (10 minutes) if not specified. Set to 0 for a non-blocking status check.
task_list (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_INCLUDE_ARCHIVED includeArchived boolean Whether to include archived child workspace tasks. Defaults to false, hiding archived non-actionable child workspace work.
MUX_TOOL_INPUT_STATUSES_<INDEX> statuses[<INDEX>] enum Task statuses to include. Defaults to active tasks: queued, starting, running, awaiting_report, pending, backgrounded. Pass ['interrupted', 'failed'] to discover workflow runs that may be resumable via workflow_resume.
MUX_TOOL_INPUT_STATUSES_COUNT statuses.length number Number of elements in statuses (Task statuses to include. Defaults to active tasks: queued, starting, running, awaiting_report, pending, backgrounded. Pass ['interrupted', 'failed'] to discover workflow runs that may be resumable via workflow_resume.)
task_terminate (2)
Env var JSON path Type Description
MUX_TOOL_INPUT_TASK_IDS_<INDEX> task_ids[<INDEX>] string List of task IDs to terminate. Sub-agent task IDs and bash task IDs must belong to descendants of the current workspace; workflow run IDs (wfr_...) must belong to the current workspace and are interrupted (resumable) rather than destroyed.
MUX_TOOL_INPUT_TASK_IDS_COUNT task_ids.length number Number of elements in task_ids (List of task IDs to terminate. Sub-agent task IDs and bash task IDs must belong to descendants of the current workspace; workflow run IDs (wfr_...) must belong to the current workspace and are interrupted (resumable) rather than destroyed.)
todo_write (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_TODOS_<INDEX>_CONTENT todos[<INDEX>].content string Task description with tense matching status: past for completed, present progressive for in_progress, imperative for pending
MUX_TOOL_INPUT_TODOS_<INDEX>_STATUS todos[<INDEX>].status enum Task status
MUX_TOOL_INPUT_TODOS_COUNT todos.length number Number of elements in todos
web_fetch (1)
Env var JSON path Type Description
MUX_TOOL_INPUT_URL url string The URL to fetch (http or https)
workflow_resume (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_MODE mode enum Defaults to 'resume', which continues interrupted or crash-orphaned runs from durable state and never re-executes completed steps. Use 'retry_from_checkpoint' only for failed runs; it re-executes work after the last checkpoint and is rejected when unsafe.
MUX_TOOL_INPUT_RUN_ID run_id string Workflow run ID (wfr_...) to resume. Must belong to the current workspace.
MUX_TOOL_INPUT_RUN_IN_BACKGROUND run_in_background boolean Defaults to false (foreground): waits until the run reaches a terminal status and returns its result. Set true to resume in the background and continue other work; await the runId with task_await when you need the result.
workflow_run (3)
Env var JSON path Type Description
MUX_TOOL_INPUT_ARGS args unknown
MUX_TOOL_INPUT_RUN_IN_BACKGROUND run_in_background boolean Defaults to false. Prefer foreground mode for a single workflow; when the returned status is completed, the result is available directly. Set true only when you will start another workflow/task or do independent work while it runs. If workflow_run returns status=running or status=backgrounded, await the returned runId with task_await before using the result.
MUX_TOOL_INPUT_SCRIPT_PATH script_path string Explicit workflow script path, such as "skill://deep-research/workflow.js" or "./workflows/research.js".

{/* END TOOL_HOOK_ENV_VARS */}


More examples

#!/usr/bin/env bash
# .mux/tool_post

if [[ "$MUX_TOOL" == file_edit_* ]]; then
  file="$MUX_TOOL_INPUT_FILE_PATH"
  prettier --write --log-level silent "$file" 2>/dev/null || true
fi
#!/usr/bin/env bash
# .mux/tool_post

# Tool results are available via MUX_TOOL_RESULT_* if needed.
echo "$(date '+%H:%M:%S') $MUX_TOOL completed" >> /tmp/mux-tools.log
#!/usr/bin/env python3
# .mux/tool_pre

import os, sys

tool = os.environ.get('MUX_TOOL', '')
script = os.environ.get('MUX_TOOL_INPUT_SCRIPT', '')

if tool == 'bash':
    if 'rm -rf /' in script:
        print("❌ Blocked dangerous command", file=sys.stderr)
        sys.exit(1)

sys.exit(0)  # Allow