wait_for_text
-
Wait for NEW output in a tmux pane, then return.
Polls until one of
patternsappears on a line written after this call starts, one ofstopappears (immediate failure exit), or the timeout expires. Passpatterns=nullto wait for any new output at all. Use this instead of pollingcapture_panein a loop.Pre-existing scrollback is never matched, and neither is paint left below the cursor at entry — only rows written after the call began count. If a pattern was already on screen the result says so via
matched_at_entry.Last resort: reserve for output you did not author. Commands you send are AUTHORED — use
run_command(returns exit status) or compose; tmux wait-for -S <channel>withwait_for_channelinstead, both cheaper and exact. For unattributable recurring prompts or background log lines, bracket your own command with a unique sentinel (cmd; echo __WAIT_$RANDOM__) and wait for that.stopis the cheap way to avoid burning the whole budget: pass the failure markers you already know ("error:","FAILED","Traceback") and a failed run returns in milliseconds instead of at the ceiling.The server caps
timeout. An over-large value is not an error — the wait returns at the ceiling and reportseffective_timeout.- MCP request method
tools/callSendwait_for_textas the tool name, with the arguments below.
Arguments#
-
Seconds between polls. Default 0.05 (50ms). Minimum 0.01.
-
match_case? =false(boolean) #Whether to match case. Default False (case-insensitive).
-
pane_id? =null(string | null) #Pane ID (e.g. ‘%1’).
-
patterns? =null(Array<string> | null) #Success patterns; the first one to match ends the wait. Literal text unless
regex=True. Omit or passnullto wait for any new output. -
Interpret
patternsandstopas regular expressions. Default False (literal text). -
session_id? =null(string | null) #Session ID (e.g. ‘$1’) for pane resolution.
-
session_name? =null(string | null) #Session name for pane resolution.
-
socket_name? =null(string | null) #tmux socket name.
-
stop? =null(Array<string> | null) #Failure patterns. A hit ends the wait immediately with
outcome="stopped"andfound=false;matched_indexsays which entry fired. -
Requested seconds to wait. Default 8.0. Clamped by server policy; see
effective_timeoutin the result. -
window_id? =null(string | null) #Window ID for pane resolution.
No other arguments are accepted.
Result#
Returns object
-
alternate_screen? =false(boolean) #True when the pane was on the terminal’s alternate screen at any point during the wait.
-
Seconds actually enforced. Server policy caps the requested
timeout; compare against what you passed to see a clamp. -
Time spent waiting in seconds
-
True when a
patternsentry matched new output, or, withpatterns=null, when any new output appeared. -
matched_at_entry? =false(boolean) #True when
patternsalready matched on-screen text before the wait began and nothing new matched after. The wait holds out for a FRESH occurrence, so re-running a command whose output looks identical still works. Read it as: the text is there, but it predates your call. -
matched_index? =null(integer | null) #Zero-based index into
patterns, or intostopwhenoutcomeisstopped. Null otherwise. -
matched_lines? (Array<string>) #Newly-written lines that matched (empty on timeout).
-
outcome("matched" | "any_output" | "stopped" | "alternate_screen" | "timeout") #How the wait ended.
matched: apatternsentry hit.any_output:patternswas omitted and something — possibly just a prompt repaint — was written; read it as ‘the pane moved’, never as ‘the command finished’.stopped: astopfailure marker hit.alternate_screen: the pane was under a pager, editor, or full-screen TUI, which repaints the whole grid, so matching was suppressed — read the screen with snapshot_pane instead of retrying.timeout: nothing matched in the budget. -
Pane ID that was polled
-
saw_new_output? =false(boolean) #True when content was written on or below the entry cursor row. Read it with
found=false: true means output arrived and did not match — readtailand fix the pattern; false means the pane was quiet — suspect the command never ran, or checkalternate_screen. -
Rows from the entry cursor row down at the final poll, tail-limited by lines and bytes. Includes stale rows excluded from matching, so it shows what the pane looks like, not what matched. On a timeout this usually already contains the answer — read it before retrying with a different pattern.
Annotations#
destructiveHinttrueidempotentHintfalseopenWorldHinttruereadOnlyHintfalse
Protocol data#
Use the complete advertised contract for validation and client integration.
Input schema
{"additionalProperties": false,"properties": {"interval": {"default": 0.05,"description": "Seconds between polls. Default 0.05 (50ms). Minimum 0.01.","type": "number"},"match_case": {"default": false,"description": "Whether to match case. Default False (case-insensitive).","type": "boolean"},"pane_id": {"anyOf": [{"type": "string"},{"type": "null"}],"default": null,"description": "Pane ID (e.g. '%1')."},"patterns": {"anyOf": [{"items": {"type": "string"},"type": "array"},{"type": "null"}],"default": null,"description": "Success patterns; the first one to match ends the wait.\nLiteral text unless ``regex=True``. Omit or pass ``null`` to\nwait for any new output."},"regex": {"default": false,"description": "Interpret ``patterns`` and ``stop`` as regular expressions.\nDefault False (literal text).","type": "boolean"},"session_id": {"anyOf": [{"type": "string"},{"type": "null"}],"default": null,"description": "Session ID (e.g. '$1') for pane resolution."},"session_name": {"anyOf": [{"type": "string"},{"type": "null"}],"default": null,"description": "Session name for pane resolution."},"socket_name": {"anyOf": [{"type": "string"},{"type": "null"}],"default": null,"description": "tmux socket name."},"stop": {"anyOf": [{"items": {"type": "string"},"type": "array"},{"type": "null"}],"default": null,"description": "Failure patterns. A hit ends the wait immediately with\n``outcome=\"stopped\"`` and ``found=false``; ``matched_index``\nsays which entry fired."},"timeout": {"default": 8,"description": "Requested seconds to wait. Default 8.0. Clamped by server\npolicy; see ``effective_timeout`` in the result.","type": "number"},"window_id": {"anyOf": [{"type": "string"},{"type": "null"}],"default": null,"description": "Window ID for pane resolution."}},"type": "object"}Output schema
{"description": "Result of a bounded wait for new pane output.\n\nDeliberately free of inference. Every field is something the tool\nobserved directly — a match, a clock reading, a tmux flag. There is\nno \"likely cause\", no \"next action\", no quiescence verdict: a\nconfidently-wrong diagnosis costs the agent more than an honest\n\"nothing appeared, here is what the pane shows\".\n\nField count is load-bearing. ``outputSchema`` is re-sent on every\nrequest of every session, so a field that no agent branches on is a\npermanent tax. ``outcome`` carries what three separate booleans\ncarried before it.","properties": {"alternate_screen": {"default": false,"description": "True when the pane was on the terminal's alternate screen at any point during the wait.","type": "boolean"},"effective_timeout": {"description": "Seconds actually enforced. Server policy caps the requested ``timeout``; compare against what you passed to see a clamp.","type": "number"},"elapsed_seconds": {"description": "Time spent waiting in seconds","type": "number"},"found": {"description": "True when a ``patterns`` entry matched new output, or, with ``patterns=null``, when any new output appeared.","type": "boolean"},"matched_at_entry": {"default": false,"description": "True when ``patterns`` already matched on-screen text before the wait began and nothing new matched after. The wait holds out for a FRESH occurrence, so re-running a command whose output looks identical still works. Read it as: the text is there, but it predates your call.","type": "boolean"},"matched_index": {"anyOf": [{"type": "integer"},{"type": "null"}],"default": null,"description": "Zero-based index into ``patterns``, or into ``stop`` when ``outcome`` is ``stopped``. Null otherwise."},"matched_lines": {"description": "Newly-written lines that matched (empty on timeout).","items": {"type": "string"},"type": "array"},"outcome": {"description": "How the wait ended. ``matched``: a ``patterns`` entry hit. ``any_output``: ``patterns`` was omitted and something — possibly just a prompt repaint — was written; read it as 'the pane moved', never as 'the command finished'. ``stopped``: a ``stop`` failure marker hit. ``alternate_screen``: the pane was under a pager, editor, or full-screen TUI, which repaints the whole grid, so matching was suppressed — read the screen with snapshot_pane instead of retrying. ``timeout``: nothing matched in the budget.","enum": ["matched","any_output","stopped","alternate_screen","timeout"],"type": "string"},"pane_id": {"description": "Pane ID that was polled","type": "string"},"saw_new_output": {"default": false,"description": "True when content was written on or below the entry cursor row. Read it with ``found=false``: true means output arrived and did not match — read ``tail`` and fix the pattern; false means the pane was quiet — suspect the command never ran, or check ``alternate_screen``.","type": "boolean"},"tail": {"description": "Rows from the entry cursor row down at the final poll, tail-limited by lines and bytes. Includes stale rows excluded from matching, so it shows what the pane looks like, not what matched. On a timeout this usually already contains the answer — read it before retrying with a different pattern.","items": {"type": "string"},"type": "array"}},"required": ["found","outcome","pane_id","elapsed_seconds","effective_timeout"],"type": "object"}