run_program
-
Run a program in a new pane of its own with your user’s permissions. Run a program in a pane of its own and wait for it; returns its output and exit status. No shell parses argv and nothing is typed into its pane, so the output holds no command line or echo. Check outcome and outputComplete before trusting output. The pane is removed before this returns unless keep is set. A program still running at the timeout, capped by the server’s wait ceiling, is ended: run longer ones with start_program. Commands come from this MCP server’s PATH, and one not found or not executable fails the call before anything runs. stdin is input when given, else the terminal. PAGER and GIT_PAGER are cat. Use startDirectory in place of cd, [“sh”, “-c”, …] for pipes, and run_shell_command for a command that needs an existing shell’s state. Requires tmux 3.8 or newer.
- MCP request method
tools/callSendrun_programas the tool name, with the arguments below.
Arguments#
-
The program and its arguments, as given: [“git”, “status”, “—short”]. Put variables first with env: [“env”, “CI=1”, “make”, “test”].
- minItems
1- maxItems
256
-
fromPaneId? (string) #Run beside this pane, in its directory and session, with that session’s tmux environment. Variables the pane’s shell exported come only with inheritShell.
- pattern
"^%\\d+$"
-
Rows of the program’s terminal. Defaults to tmux’s default-size.
- maximum
10000- exclusiveMinimum
0
-
inheritShell? (boolean | Array<string>) #With fromPaneId, first read the variables that pane’s idle shell exported, by typing one env command into it, and run the program with them: true for all, or a list of names, such as [“PATH”, “VIRTUAL_ENV”], for only those. The shell must be a POSIX one at its prompt, as run_shell_command requires. argv[0] is then found on the shell’s PATH, and one missing exits 127.
Matches one or more variants.
-
Text the program reads as its stdin, from a private file, so no shell quotes it and the pane never shows it. Needs the tmux server on this machine.
-
Leave the pane, dead and showing the output, for a person to read and close. Set it only when a person asked to see the run.
-
Keep at most this many lines, from the end. Defaults to the server limit.
- maximum
9007199254740991- exclusiveMinimum
0
-
placement? ("window" | "split") #With fromPaneId: “window”, the default, is a background window of its session; “split” splits that pane, so a person watching it sees the run. Focus stays put.
-
Return what the program writes to stderr apart, as stderr, so output holds stdout alone. Its stderr is then no terminal. Needs the tmux server on this machine, as input does.
-
Directory the program starts in, taken literally. Defaults to the directory this MCP server was started in, or the fromPaneId pane’s. One that cannot be entered fails the call, with the reason, before the program starts.
-
How long to let it run; 30 s by default and clamped by the server ceiling. The result says what was used.
- maximum
9007199254740991- exclusiveMinimum
0
-
Columns of the program’s terminal. A program that formats to its width — ls, ps, git log —graph — lays out to this at the source.
- maximum
10000- exclusiveMinimum
0
Result#
Returns object
-
Lines of output withheld by maxLines.
- minimum
-9007199254740991- maximum
9007199254740991
-
effectiveTimeoutMs(integer) #The timeout enforced.
- minimum
-9007199254740991- maximum
9007199254740991
-
exitStatus(integer | null) #The exit status; null when a signal ended the program (see signal) or the timeout ended it (outcome timed_out).
Matches one or more variants.
-
True when the end may be missing: tmux closed the pane before reading it. Running it again repeats what it did; for one with effects, have it write its output to a file with [“sh”, “-c”, ”… > file”] and read the file.
-
True when the start scrolled past the scrollback limit; pipe a long output into a file, or read it with start_program.
-
Output bytes omitted by the result ceiling.
- minimum
-9007199254740991- maximum
9007199254740991
-
outcome("completed" | "timed_out") #completed: it ended on its own, or by the signal reported, whatever exitStatus says. timed_out: it was ended at the timeout, possibly part way through its work; running it again repeats what it did, so use start_program for one that needs longer.
-
The bounded tail of what the program printed, as its terminal shows it; stderr and stdout share it.
-
False when outcome is timed_out, lostStart or lostEnd is true, or maxLines or the result limit cut the output or stderr.
-
UTF-8 output bytes returned.
- minimum
-9007199254740991- maximum
9007199254740991
-
The signal that ended the program, such as “SIGTERM”; otherwise null. A program that exits 130 on its own reads as SIGINT, as that status means.
-
The bounded tail of what the program wrote to stderr, with separateStderr; otherwise null, and stderr is in output.
No other properties are accepted.
Annotations#
destructiveHinttrueidempotentHintfalseopenWorldHinttruereadOnlyHintfalse
Protocol data#
Use the complete advertised contract for validation and client integration.
Input schema
{"$schema": "http://json-schema.org/draft-07/schema#","properties": {"argv": {"description": "The program and its arguments, as given: [\"git\", \"status\", \"--short\"]. Put variables first with env: [\"env\", \"CI=1\", \"make\", \"test\"].","items": {"type": "string"},"maxItems": 256,"minItems": 1,"type": "array"},"fromPaneId": {"description": "Run beside this pane, in its directory and session, with that session's tmux environment. Variables the pane's shell exported come only with inheritShell.","pattern": "^%\\d+$","type": "string"},"height": {"description": "Rows of the program's terminal. Defaults to tmux's default-size.","exclusiveMinimum": 0,"maximum": 10000,"type": "integer"},"inheritShell": {"anyOf": [{"type": "boolean"},{"items": {"pattern": "^[A-Za-z_][A-Za-z0-9_]*$","type": "string"},"maxItems": 256,"minItems": 1,"type": "array"}],"description": "With fromPaneId, first read the variables that pane's idle shell exported, by typing one env command into it, and run the program with them: true for all, or a list of names, such as [\"PATH\", \"VIRTUAL_ENV\"], for only those. The shell must be a POSIX one at its prompt, as run_shell_command requires. argv[0] is then found on the shell's PATH, and one missing exits 127."},"input": {"description": "Text the program reads as its stdin, from a private file, so no shell quotes it and the pane never shows it. Needs the tmux server on this machine.","type": "string"},"keep": {"description": "Leave the pane, dead and showing the output, for a person to read and close. Set it only when a person asked to see the run.","type": "boolean"},"maxLines": {"description": "Keep at most this many lines, from the end. Defaults to the server limit.","exclusiveMinimum": 0,"maximum": 9007199254740991,"type": "integer"},"placement": {"description": "With fromPaneId: \"window\", the default, is a background window of its session; \"split\" splits that pane, so a person watching it sees the run. Focus stays put.","enum": ["window","split"],"type": "string"},"separateStderr": {"description": "Return what the program writes to stderr apart, as stderr, so output holds stdout alone. Its stderr is then no terminal. Needs the tmux server on this machine, as input does.","type": "boolean"},"startDirectory": {"description": "Directory the program starts in, taken literally. Defaults to the directory this MCP server was started in, or the fromPaneId pane's. One that cannot be entered fails the call, with the reason, before the program starts.","type": "string"},"timeoutMs": {"description": "How long to let it run; 30 s by default and clamped by the server ceiling. The result says what was used.","exclusiveMinimum": 0,"maximum": 9007199254740991,"type": "integer"},"width": {"description": "Columns of the program's terminal. A program that formats to its width — ls, ps, git log --graph — lays out to this at the source.","exclusiveMinimum": 0,"maximum": 10000,"type": "integer"}},"required": ["argv"],"type": "object"}Output schema
{"$schema": "http://json-schema.org/draft-07/schema#","additionalProperties": false,"properties": {"droppedLines": {"description": "Lines of output withheld by maxLines.","maximum": 9007199254740991,"minimum": -9007199254740991,"type": "integer"},"effectiveTimeoutMs": {"description": "The timeout enforced.","maximum": 9007199254740991,"minimum": -9007199254740991,"type": "integer"},"exitStatus": {"anyOf": [{"maximum": 9007199254740991,"minimum": -9007199254740991,"type": "integer"},{"type": "null"}],"description": "The exit status; null when a signal ended the program (see signal) or the timeout ended it (outcome timed_out)."},"lostEnd": {"description": "True when the end may be missing: tmux closed the pane before reading it. Running it again repeats what it did; for one with effects, have it write its output to a file with [\"sh\", \"-c\", \"... > file\"] and read the file.","type": "boolean"},"lostStart": {"description": "True when the start scrolled past the scrollback limit; pipe a long output into a file, or read it with start_program.","type": "boolean"},"omittedBytes": {"description": "Output bytes omitted by the result ceiling.","maximum": 9007199254740991,"minimum": -9007199254740991,"type": "integer"},"outcome": {"description": "completed: it ended on its own, or by the signal reported, whatever exitStatus says. timed_out: it was ended at the timeout, possibly part way through its work; running it again repeats what it did, so use start_program for one that needs longer.","enum": ["completed","timed_out"],"type": "string"},"output": {"description": "The bounded tail of what the program printed, as its terminal shows it; stderr and stdout share it.","type": "string"},"outputComplete": {"description": "False when outcome is timed_out, lostStart or lostEnd is true, or maxLines or the result limit cut the output or stderr.","type": "boolean"},"returnedBytes": {"description": "UTF-8 output bytes returned.","maximum": 9007199254740991,"minimum": -9007199254740991,"type": "integer"},"signal": {"description": "The signal that ended the program, such as \"SIGTERM\"; otherwise null. A program that exits 130 on its own reads as SIGINT, as that status means.","type": ["string","null"]},"stderr": {"description": "The bounded tail of what the program wrote to stderr, with separateStderr; otherwise null, and stderr is in output.","type": ["string","null"]}},"required": ["droppedLines","effectiveTimeoutMs","exitStatus","omittedBytes","outcome","output","lostEnd","lostStart","outputComplete","returnedBytes","signal","stderr"],"type": "object"}