# wait_for_text

Source: https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/

> Wait for NEW output in a tmux pane, then return.

tool MCPstable

MCP is in development

Server behavior and tool contracts may change. Tool availability depends on the server configuration.

* **wait_for_text**( [interval](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Finterval)?: [number](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"), [match_case](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fmatch_case)?: [boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"), [pane_id](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fpane_id)?: [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), [patterns](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fpatterns)?: [Array](https://json-schema.org/understanding-json-schema/reference/array "array (JSON Schema)")<[string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)")> | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), [regex](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fregex)?: [boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"), [session_id](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fsession_id)?: [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), [session_name](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fsession_name)?: [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), [socket_name](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fsocket_name)?: [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), [stop](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fstop)?: [Array](https://json-schema.org/understanding-json-schema/reference/array "array (JSON Schema)")<[string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)")> | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), [timeout](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Ftimeout)?: [number](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"), [window_id](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fwindow_id)?: [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"), )

  tool \[[source](https://github.com/tmux-python/libtmux-mcp/blob/4daddc0dfca96c43bf521d818bf91564e1434760/src/libtmux_mcp/tools/pane_tools/__init__.py#L153)][¶](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text)

  Wait for NEW output in a tmux pane, then return.

  Polls until one of `patterns` appears on a line written *after* this call starts, one of `stop` appears (immediate failure exit), or the timeout expires. Pass `patterns=null` to wait for any new output at all. Use this instead of polling [`capture_pane`](https://libtmux.org/en/py/stable/mcp/tools/capture_pane/) in 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`](https://libtmux.org/en/py/stable/mcp/tools/run_command/) (returns exit status) or compose [`; tmux wait-for -S <channel>`](https://libtmux.org/en/tmux/latest/manual/wait-for/) with [`wait_for_channel`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_channel/) instead, 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.

  `stop` is 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 reports `effective_timeout`.

  * MCP request method

    `tools/call` Send `wait_for_text` as the tool name, with the arguments below.

  ## Arguments[#](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.parameters)

  * **[`interval`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Finterval)**? = `0.05` ([number](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Seconds between polls. Default 0.05 (50ms). Minimum 0.01.

  * **[`match_case`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fmatch_case)**? = `false` ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    Whether to match case. Default False (case-insensitive).

  * **[`pane_id`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fpane_id)**? = `null` ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Pane ID (e.g. ‘%1’).

  * **[`patterns`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fpatterns)**? = `null` ([Array](https://json-schema.org/understanding-json-schema/reference/array "array (JSON Schema)")<[string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)")> | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Success patterns; the first one to match ends the wait. Literal text unless `regex=True`. Omit or pass `null` to wait for any new output.

  * **[`regex`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fregex)**? = `false` ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    Interpret `patterns` and `stop` as regular expressions. Default False (literal text).

  * **[`session_id`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fsession_id)**? = `null` ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Session ID (e.g. ‘$1’) for pane resolution.

  * **[`session_name`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fsession_name)**? = `null` ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Session name for pane resolution.

  * **[`socket_name`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fsocket_name)**? = `null` ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    tmux socket name.

  * **[`stop`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fstop)**? = `null` ([Array](https://json-schema.org/understanding-json-schema/reference/array "array (JSON Schema)")<[string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)")> | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Failure patterns. A hit ends the wait immediately with `outcome="stopped"` and `found=false`; `matched_index` says which entry fired.

  * **[`timeout`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Ftimeout)**? = `8` ([number](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Requested seconds to wait. Default 8.0. Clamped by server policy; see `effective_timeout` in the result.

  * **[`window_id`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.input%2Fproperties%2Fwindow_id)**? = `null` ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Window ID for pane resolution.

  No other arguments are accepted.

  ## Result[#](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.result)

  Returns [object](https://json-schema.org/understanding-json-schema/reference/object "object (JSON Schema)")

  * **[`alternate_screen`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Falternate_screen)**? = `false` ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    True when the pane was on the terminal’s alternate screen at any point during the wait.

  * **[`effective_timeout`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Feffective_timeout)** ([number](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Seconds actually enforced. Server policy caps the requested `timeout`; compare against what you passed to see a clamp.

  * **[`elapsed_seconds`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Felapsed_seconds)** ([number](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Time spent waiting in seconds

  * **[`found`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Ffound)** ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    True when a `patterns` entry matched new output, or, with `patterns=null`, when any new output appeared.

  * **[`matched_at_entry`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Fmatched_at_entry)**? = `false` ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    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.

  * **[`matched_index`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Fmatched_index)**? = `null` ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)") | [null](https://json-schema.org/understanding-json-schema/reference/null "null (JSON Schema)"))

    Zero-based index into `patterns`, or into `stop` when `outcome` is `stopped`. Null otherwise.

  * **[`matched_lines`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Fmatched_lines)**? ([Array](https://json-schema.org/understanding-json-schema/reference/array "array (JSON Schema)")<[string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)")>)

    Newly-written lines that matched (empty on timeout).

  * **[`outcome`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Foutcome)** ("matched" | "any_output" | "stopped" | "alternate_screen" | "timeout")

    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](https://libtmux.org/en/py/stable/mcp/tools/snapshot_pane/) instead of retrying. `timeout`: nothing matched in the budget.

  * **[`pane_id`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Fpane_id)** ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"))

    Pane ID that was polled

  * **[`saw_new_output`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Fsaw_new_output)**? = `false` ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    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`.

  * **[`tail`](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.output%2Fproperties%2Ftail)**? ([Array](https://json-schema.org/understanding-json-schema/reference/array "array (JSON Schema)")<[string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)")>)

    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[#](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.annotations)

  * [`destructiveHint`](https://libtmux.org/en/py/stable/mcp/reference/glossary/#destructiveHint)

    `true`

  * [`idempotentHint`](https://libtmux.org/en/py/stable/mcp/reference/glossary/#idempotentHint)

    `false`

  * [`openWorldHint`](https://libtmux.org/en/py/stable/mcp/reference/glossary/#openWorldHint)

    `true`

  * [`readOnlyHint`](https://libtmux.org/en/py/stable/mcp/reference/glossary/#readOnlyHint)

    `false`

  ## Protocol data[#](https://libtmux.org/en/py/stable/mcp/tools/wait_for_text/#mcp.tool.wait_for_text.schemas)

  Use the complete advertised contract for validation and client integration.

  Input schema

  ```json
  {
    "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

  ```json
  {
    "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"
  }
  ```
