# run_shell_command

Source: https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/

> Run a shell command in a pane with your user's permissions. Run a shell command in a pane, wait for it to finish, and report its exit status and output. Prefer this over send_keys plus capture_pane: it frames the command so a pane's echo of what you typed can never be mistaken for what the command printed, and it knows when the command actually ended rather than guessing from the screen. The command runs in a subshell, so cd and export do not persist to a later call. A pane is effectively single-writer: this server reserves it until the command settles, but another process with the same tmux socket can still write into it.

tool MCPlatest

MCP concept example

A working example of the core library. It can change without notice.

[What concept means](https://libtmux.org/en/meta/support/#concept-and-alpha)

* **run_shell_command**( [command](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2Fcommand): [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"), [force](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2Fforce)?: [boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"), [maxLines](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2FmaxLines)?: [integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"), [paneId](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2FpaneId): [string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"), [timeoutMs](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2FtimeoutMs)?: [integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"), )

  tool \[[source](https://github.com/libtmux/libtmux-ts/blob/46cccfef2a546de55ce8b308249b8c76339089a0/packages/mcp/src/tools/input.ts#L304)][¶](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command)

  Run a shell command in a pane with your user’s permissions. Run a shell command in a pane, wait for it to finish, and report its exit status and output. Prefer this over [send_keys](https://libtmux.org/en/ts/latest/mcp/tools/send_keys/) plus [capture_pane](https://libtmux.org/en/ts/latest/mcp/tools/capture_pane/): it frames the command so a pane’s echo of what you typed can never be mistaken for what the command printed, and it knows when the command actually ended rather than guessing from the screen. The command runs in a subshell, so cd and export do not persist to a later call. A pane is effectively single-writer: this server reserves it until the command settles, but another process with the same tmux socket can still write into it.

  * MCP request method

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

  ## Arguments[#](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.parameters)

  * **[`command`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2Fcommand)** ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"))

    The shell command to run.

  * **[`force`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2Fforce)**? ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    Allow writing to the pane this server itself was called from, which is otherwise refused. It does not override the refusal to write to a pane a person is watching — a pane an attached client has on screen is still refused with force.

  * **[`maxLines`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2FmaxLines)**? ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Keep at most this many lines, from the end. Defaults to the server limit.

    * maximum

      `9007199254740991`

    * exclusiveMinimum

      `0`

  * **[`paneId`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2FpaneId)** ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"))

    Stable pane id, e.g. %1.

    * pattern

      `"^%\\d+$"`

  * **[`timeoutMs`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.input%2Fproperties%2FtimeoutMs)**? ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    How long to wait. Clamped by the server ceiling; the result says what was used.

    * maximum

      `9007199254740991`

    * exclusiveMinimum

      `0`

  ## Result[#](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.result)

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

  * **[`droppedLines`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FdroppedLines)** ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Lines of output withheld by maxLines. The text half says so in a notice; a caller reading only the structured half would otherwise take the tail for the whole.

    * minimum

      `-9007199254740991`

    * maximum

      `9007199254740991`

  * **[`effectiveTimeoutMs`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FeffectiveTimeoutMs)** ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    The timeout actually enforced.

    * minimum

      `-9007199254740991`

    * maximum

      `9007199254740991`

  * **[`exitStatus`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FexitStatus)** ([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)"))

    The command’s exit status; null if it did not finish.

    Matches one or more variants.

    * **[Variant 1](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FexitStatus%2FanyOf%2F0)** ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

      * minimum

        `-9007199254740991`

      * maximum

        `9007199254740991`

  * **[`foreignOutputSuspected`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FforeignOutputSuspected)** ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    Another writer printed into this pane while the command ran. Output that could be attributed to them was removed; what is left may still include theirs. False means no foreign marker was seen, not that the output is certainly this command’s.

  * **[`missedBytes`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FmissedBytes)** ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Output that fell out of the pane’s buffer before this read reached it. Nonzero means the command printed more than was kept, so the output here starts partway through it.

    * minimum

      `-9007199254740991`

    * maximum

      `9007199254740991`

  * **[`omittedBytes`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FomittedBytes)** ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    Output bytes omitted by the result ceiling.

    * minimum

      `-9007199254740991`

    * maximum

      `9007199254740991`

  * **[`outcome`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2Foutcome)** ("completed" | "timed_out" | "pane_died" | "cancelled")

    Why this returned. Read it rather than inferring from the text.

  * **[`output`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2Foutput)** ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"))

    The bounded tail of the command’s output.

  * **[`outputComplete`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FoutputComplete)** ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    False when capture or result limits omitted any command output.

  * **[`paneId`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FpaneId)** ([string](https://json-schema.org/understanding-json-schema/reference/string "string (JSON Schema)"))

    Stable pane id, e.g. %1.

    * pattern

      `"^%\\d+$"`

  * **[`returnedBytes`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FreturnedBytes)** ([integer](https://json-schema.org/understanding-json-schema/reference/numeric "numeric (JSON Schema)"))

    UTF-8 output bytes returned.

    * minimum

      `-9007199254740991`

    * maximum

      `9007199254740991`

  * **[`stillRunning`](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.output%2Fproperties%2FstillRunning)** ([boolean](https://json-schema.org/understanding-json-schema/reference/boolean "boolean (JSON Schema)"))

    Whether the command may still be running after this call returned.

  No other properties are accepted.

  ## Annotations[#](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.annotations)

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

    `true`

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

    `false`

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

    `true`

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

    `false`

  ## Protocol data[#](https://libtmux.org/en/ts/latest/mcp/tools/run_shell_command/#mcp.tool.run_shell_command.schemas)

  Use the complete advertised contract for validation and client integration.

  Input schema

  ```json
  {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "properties": {
      "command": {
        "description": "The shell command to run.",
        "type": "string"
      },
      "force": {
        "description": "Allow writing to the pane this server itself was called from, which is otherwise refused. It does not override the refusal to write to a pane a person is watching — a pane an attached client has on screen is still refused with force.",
        "type": "boolean"
      },
      "maxLines": {
        "description": "Keep at most this many lines, from the end. Defaults to the server limit.",
        "exclusiveMinimum": 0,
        "maximum": 9007199254740991,
        "type": "integer"
      },
      "paneId": {
        "description": "Stable pane id, e.g. %1.",
        "pattern": "^%\\d+$",
        "type": "string"
      },
      "timeoutMs": {
        "description": "How long to wait. Clamped by the server ceiling; the result says what was used.",
        "exclusiveMinimum": 0,
        "maximum": 9007199254740991,
        "type": "integer"
      }
    },
    "required": [
      "command",
      "paneId"
    ],
    "type": "object"
  }
  ```

  Output schema

  ```json
  {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "additionalProperties": false,
    "properties": {
      "droppedLines": {
        "description": "Lines of output withheld by maxLines. The text half says so in a notice; a caller reading only the structured half would otherwise take the tail for the whole.",
        "maximum": 9007199254740991,
        "minimum": -9007199254740991,
        "type": "integer"
      },
      "effectiveTimeoutMs": {
        "description": "The timeout actually enforced.",
        "maximum": 9007199254740991,
        "minimum": -9007199254740991,
        "type": "integer"
      },
      "exitStatus": {
        "anyOf": [
          {
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          {
            "type": "null"
          }
        ],
        "description": "The command's exit status; null if it did not finish."
      },
      "foreignOutputSuspected": {
        "description": "Another writer printed into this pane while the command ran. Output that could be attributed to them was removed; what is left may still include theirs. False means no foreign marker was seen, not that the output is certainly this command's.",
        "type": "boolean"
      },
      "missedBytes": {
        "description": "Output that fell out of the pane's buffer before this read reached it. Nonzero means the command printed more than was kept, so the output here starts partway through it.",
        "maximum": 9007199254740991,
        "minimum": -9007199254740991,
        "type": "integer"
      },
      "omittedBytes": {
        "description": "Output bytes omitted by the result ceiling.",
        "maximum": 9007199254740991,
        "minimum": -9007199254740991,
        "type": "integer"
      },
      "outcome": {
        "description": "Why this returned. Read it rather than inferring from the text.",
        "enum": [
          "completed",
          "timed_out",
          "pane_died",
          "cancelled"
        ],
        "type": "string"
      },
      "output": {
        "description": "The bounded tail of the command's output.",
        "type": "string"
      },
      "outputComplete": {
        "description": "False when capture or result limits omitted any command output.",
        "type": "boolean"
      },
      "paneId": {
        "description": "Stable pane id, e.g. %1.",
        "pattern": "^%\\d+$",
        "type": "string"
      },
      "returnedBytes": {
        "description": "UTF-8 output bytes returned.",
        "maximum": 9007199254740991,
        "minimum": -9007199254740991,
        "type": "integer"
      },
      "stillRunning": {
        "description": "Whether the command may still be running after this call returned.",
        "type": "boolean"
      }
    },
    "required": [
      "effectiveTimeoutMs",
      "droppedLines",
      "missedBytes",
      "omittedBytes",
      "foreignOutputSuspected",
      "exitStatus",
      "outcome",
      "output",
      "outputComplete",
      "paneId",
      "returnedBytes",
      "stillRunning"
    ],
    "type": "object"
  }
  ```
