Tools¶
Batch tools¶
Generic MCP tool batching helpers.
-
libtmux_mcp.tools.batch_tools._content_block_to_dict(block)¶libtmux_mcp.tools.batch_tools._content_block_to_dict(block)¶
Return a JSON-ready representation of an MCP content block.
-
libtmux_mcp.tools.batch_tools._result_error_text(result)¶libtmux_mcp.tools.batch_tools._result_error_text(result)¶
Extract a readable error string from a FastMCP
ToolResult.
-
libtmux_mcp.tools.batch_tools._tool_tier(tool_name, tags)¶libtmux_mcp.tools.batch_tools._tool_tier(tool_name, tags)¶
Return the highest recognized safety tier for a registered tool.
-
libtmux_mcp.tools.batch_tools._check_operation_allowed(*, tool_name, tool_tier, max_tier)¶libtmux_mcp.tools.batch_tools._check_operation_allowed(*, tool_name, tool_tier, max_tier)¶
Raise when a nested tool exceeds this batch wrapper’s tier.
-
libtmux_mcp.tools.batch_tools._get_allowed_tool_tier(*, fastmcp, operation, max_tier)¶libtmux_mcp.tools.batch_tools._get_allowed_tool_tier(*, fastmcp, operation, max_tier)¶
Validate that one nested operation targets an allowed tool.
- Parameters:
fastmcp (
FastMCP)operation (
ToolCallOperation)max_tier (
str)
- Return type:
-
libtmux_mcp.tools.batch_tools._ensure_tool_result(tool_name, result)¶libtmux_mcp.tools.batch_tools._ensure_tool_result(tool_name, result)¶
Return
resultas aToolResultor raise a row-level error.
-
libtmux_mcp.tools.batch_tools._batch_response_size(result)¶libtmux_mcp.tools.batch_tools._batch_response_size(result)¶
Return the serialized byte size of FastMCP’s batch response envelope.
- Parameters:
result (
ToolCallBatchResult)- Return type:
-
libtmux_mcp.tools.batch_tools._operation_has_nested_payload(result)¶libtmux_mcp.tools.batch_tools._operation_has_nested_payload(result)¶
Return True when a row still carries payload fields that can be elided.
- Parameters:
result (
ToolCallOperationResult)- Return type:
-
libtmux_mcp.tools.batch_tools._limit_batch_result(result, *, max_bytes=¶
DEFAULT_RESPONSE_LIMIT_BYTES)libtmux_mcp.tools.batch_tools._limit_batch_result(result, *, max_bytes=¶DEFAULT_RESPONSE_LIMIT_BYTES) Elide nested result payloads until the batch envelope fits.
- Parameters:
result (
ToolCallBatchResult)max_bytes (
int)
- Return type:
-
libtmux_mcp.tools.batch_tools._call_one_tool(*, fastmcp, operation, index, max_tier)¶libtmux_mcp.tools.batch_tools._call_one_tool(*, fastmcp, operation, index, max_tier)¶
Call one nested tool and convert its outcome to a batch result row.
- Parameters:
fastmcp (
FastMCP)operation (
ToolCallOperation)index (
int)max_tier (
str)
- Return type:
-
libtmux_mcp.tools.batch_tools._call_tools_batch(*, operations, on_error, max_tier, ctx)¶libtmux_mcp.tools.batch_tools._call_tools_batch(*, operations, on_error, max_tier, ctx)¶
Execute nested MCP tool calls serially through FastMCP.
- Parameters:
operations (
list[ToolCallOperation])on_error (
_OnError)max_tier (
str)ctx (
Context|None)
- Return type:
-
libtmux_mcp.tools.batch_tools.call_readonly_tools_batch(operations, on_error='stop', ctx=None)¶libtmux_mcp.tools.batch_tools.call_readonly_tools_batch(operations, on_error='stop', ctx=None)¶
Call readonly MCP tools serially and return per-tool results.
Use when several read-only observations should be made in one agent turn. Each nested call still goes through FastMCP validation, middleware, and safety checks. Mutating and destructive tools are rejected even if the server process itself is running at a higher safety tier.
- Parameters:
operations (
list[ToolCallOperation])on_error (
_OnError)ctx (
Context|None)
- Return type:
-
libtmux_mcp.tools.batch_tools.call_mutating_tools_batch(operations, on_error='stop', ctx=None)¶libtmux_mcp.tools.batch_tools.call_mutating_tools_batch(operations, on_error='stop', ctx=None)¶
Call readonly or mutating MCP tools serially and return per-tool results.
Use for ordered tmux workflows where every step is still an existing typed MCP tool. Destructive tools are rejected regardless of the process-wide safety tier.
- Parameters:
operations (
list[ToolCallOperation])on_error (
_OnError)ctx (
Context|None)
- Return type:
-
libtmux_mcp.tools.batch_tools.call_destructive_tools_batch(operations, on_error='stop', ctx=None)¶libtmux_mcp.tools.batch_tools.call_destructive_tools_batch(operations, on_error='stop', ctx=None)¶
Call readonly, mutating, or destructive MCP tools serially.
This wrapper preserves the normal per-tool schemas and middleware but its tier permits destructive nested operations. Prefer the narrower readonly or mutating wrappers whenever possible.
- Parameters:
operations (
list[ToolCallOperation])on_error (
_OnError)ctx (
Context|None)
- Return type:
Server tools¶
MCP tools for tmux server operations.
-
libtmux_mcp.tools.server_tools.list_sessions(socket_name=None, filters=None)¶libtmux_mcp.tools.server_tools.list_sessions(socket_name=None, filters=None)¶
List tmux sessions (terminal workspaces) on a tmux server.
Use for tmux multiplexer sessions — ‘this session’, ‘my workspace’, ‘the dev session’ — not login sessions or HTTP sessions. The starting point for discovery — call this before targeting specific sessions, windows, or panes.
- Parameters:
socket_name (
str,optional) – tmux socket name. Defaults to LIBTMUX_SOCKET env var.filters (
dict or str, optional) – Django-style filters as a dict (e.g.{"session_name__contains": "dev"}) or as a JSON string. Some MCP clients require the string form.
- Returns:
List of session objects.
- Return type:
-
libtmux_mcp.tools.server_tools.create_session(session_name=None, window_name=None, start_directory=None, x=None, y=None, environment=None, socket_name=None, *, suppress_persistent_history=False)¶libtmux_mcp.tools.server_tools.create_session(session_name=None, window_name=None, start_directory=None, x=None, y=None, environment=None, socket_name=None, *, suppress_persistent_history=False)¶
Create a new tmux session.
Check list_sessions first to avoid name conflicts. A new session starts with one window and one pane. Values in
environmentare stored in the tmux session environment, so future panes inherit them too.- Parameters:
session_name (
str,optional) – Name for the new session.window_name (
str,optional) – Name for the initial window.start_directory (
str,optional) – Working directory for the session.x (
int,optional) – Width of the initial window.y (
int,optional) – Height of the initial window.environment (
dict or str, optional) – Environment variables to store in the session environment. Accepts either a dict of env vars or a JSON-serialized string of the same — the latter is the cursor-composer-1 workaround described inlibtmux_mcp._utils._coerce_dict_arg(). Each item appears in the tmux client argv as one-eKEY=VALUEelement and may be visible to host process inspection during launch. tmux retains the values in tmux session state, whereshow-environmentcan reveal them. They reach the initial and future child environments unless a later spawn overrides them. MCP audit redaction does not hide these surfaces. Pass credential references, not literal credentials.socket_name (
str,optional) – tmux socket name. Defaults to LIBTMUX_SOCKET env var.suppress_persistent_history (
bool) – Whether to suppress persistent history for the spawned shell. Defaults to False for MCP and direct Python calls. This per-call option does not inherit LIBTMUX_SUPPRESS_HISTORY. Startup files may override these controls.
- Returns:
The created session.
- Return type:
-
libtmux_mcp.tools.server_tools.kill_server(socket_name=None)¶libtmux_mcp.tools.server_tools.kill_server(socket_name=None)¶
Kill the tmux server and all its sessions.
Destroys ALL sessions, windows, and panes on this server. Use kill_session to remove a single session instead. Self-kill protection prevents killing the server running this MCP process.
-
libtmux_mcp.tools.server_tools.get_server_info(socket_name=None)¶libtmux_mcp.tools.server_tools.get_server_info(socket_name=None)¶
Get information about the tmux server.
Use to verify the tmux server is running before other operations. For session-level details, use list_sessions instead.
- Parameters:
socket_name (
str,optional) – tmux socket name. Defaults to LIBTMUX_SOCKET env var.- Returns:
Server information.
- Return type:
-
libtmux_mcp.tools.server_tools._is_tmux_socket_live(path)¶libtmux_mcp.tools.server_tools._is_tmux_socket_live(path)¶
Return True if a tmux socket has a listener accepting connections.
Uses a UNIX-domain
connect()with a short timeout rather than shelling out totmux.$TMUX_TMPDIR/tmux-$UID/routinely accumulates thousands of stale socket inodes from past servers — probing each one withtmux -L <name> lswould makelist_servers()O(sockets * tmux-spawn-cost), easily tens of seconds on well-aged machines. Socket connect is kernel-fast (sub millisecond) and returnsECONNREFUSEDimmediately for dead inodes.
-
libtmux_mcp.tools.server_tools._probe_server_by_path(socket_path)¶libtmux_mcp.tools.server_tools._probe_server_by_path(socket_path)¶
Return a
ServerInfofor a live socket atsocket_path.Mirrors
get_server_info()’s serialization but keys the Server bysocket_path(-S) rather than socket name (-L) so callers can probe arbitrarytmux -S /path/...daemons that live outside$TMUX_TMPDIR. ReturnsNonewhen the path is not a socket, has no listener, or the server cannot be queried. Probe failures are logged at debug level so operators can surface “why isn’t my custom socket appearing?” via verbose logging.- Parameters:
socket_path (
Path)- Return type:
-
Tools that intentionally do NOT accept
socket_namebecause they either discover sockets themselves or coordinate nested tools whose arguments carry their own targeting. Read bytest_registered_tools_accept_socket_nameto enforce the agent-facing contract advertised inlibtmux_mcp.server._BASE_INSTRUCTIONS. When you add a new discovery-style tool, append it here AND update the prose in_BASE_INSTRUCTIONSso the two stay in lockstep.
-
libtmux_mcp.tools.server_tools.list_servers(extra_socket_paths=None)¶libtmux_mcp.tools.server_tools.list_servers(extra_socket_paths=None)¶
Discover live tmux servers under the current user’s
$TMUX_TMPDIR.Scans
${TMUX_TMPDIR:-/tmp}/tmux-<uid>/for socket files — the canonical location where tmux creates per-server sockets (see tmux.c’sexpand_paths+TMUX_SOCKtemplate). Only sockets with a live listener are reported; stale inodes (a common case on long-running systems where$TMUX_TMPDIRcan carry thousands of orphans) are silently filtered.Scope caveat: custom
tmux -S /some/path/...servers that live OUTSIDE$TMUX_TMPDIRare not returned by the scan alone — there is no canonical registry for arbitrary socket paths. Supply known paths viaextra_socket_pathsto include them in the result, or pass the path to other tools via theirsocket_name/socket_pathparameters once known.- Parameters:
extra_socket_paths (
list of str, optional) – Additional filesystem paths to probe alongside the$TMUX_TMPDIRscan. Each path is checked for liveness (UNIXconnect()) and queried for server metadata. Paths that do not exist, are not sockets, or have no listener are silently skipped.- Returns:
One entry per live tmux server found. Canonical-directory results come first, followed by successful
extra_socket_pathsprobes in the supplied order. Empty when nothing lives under$TMUX_TMPDIRand no extras are supplied or reachable.- Return type:
Session tools¶
MCP tools for tmux session operations.
-
libtmux_mcp.tools.session_tools.list_windows(session_name=None, session_id=None, socket_name=None, filters=None)¶libtmux_mcp.tools.session_tools.list_windows(session_name=None, session_id=None, socket_name=None, filters=None)¶
List tmux windows (terminal tabs) in a session, or across the server.
Use for tmux windows — ‘current window’, ‘this tab’ (when terminal- contextual) — not browser tabs or desktop windows. Only searches window metadata (name, index, layout); to search the actual visible terminal text, use search_panes.
- Parameters:
session_name (
str,optional) – Session name to look up. If omitted along with session_id, returns windows from all sessions.session_id (
str,optional) – Session ID (e.g. ‘$1’) to look up.socket_name (
str,optional) – tmux socket name. Defaults to LIBTMUX_SOCKET env var.filters (
dict or str, optional) – Django-style filters as a dict (e.g.{"window_name__contains": "dev"}) or as a JSON string. Some MCP clients require the string form.
- Returns:
List of serialized window objects.
- Return type:
-
libtmux_mcp.tools.session_tools.get_session_info(session_id=None, session_name=None, socket_name=None)¶libtmux_mcp.tools.session_tools.get_session_info(session_id=None, session_name=None, socket_name=None)¶
Return metadata for a single tmux session (ID, name, window count, activity).
Use this instead of list_sessions + filter when you only need one session’s info. Resolves by session_id first; falls back to session_name.
- Parameters:
- Returns:
Serialized session metadata.
- Return type:
-
libtmux_mcp.tools.session_tools.create_window(session_name=None, session_id=None, window_name=None, start_directory=None, attach=False, direction=None, socket_name=None, *, environment=None, suppress_persistent_history=False)¶libtmux_mcp.tools.session_tools.create_window(session_name=None, session_id=None, window_name=None, start_directory=None, attach=False, direction=None, socket_name=None, *, environment=None, suppress_persistent_history=False)¶
Create a new window in a tmux session.
Creates a window with one pane. Use split_window to add more panes afterward.
- Parameters:
session_name (
str,optional) – Session name to look up.session_id (
str,optional) – Session ID (e.g. ‘$1’) to look up.window_name (
str,optional) – Name for the new window.start_directory (
str,optional) – Working directory for the new window.attach (
bool,optional) – Whether to make the new window active.direction (
str,optional) – Window placement direction.socket_name (
str,optional) – tmux socket name. Defaults to LIBTMUX_SOCKET env var.environment (
dict or str, optional) – Per-process environment as a mapping or JSON object string. Values do not modify the tmux session environment. Each item becomes a tmux-elaunch option. Values may be visible to host process inspection in the tmux client argv during launch and in the child environment afterward; MCP audit redaction does not hide either surface. Pass credential references, not literal credentials.suppress_persistent_history (
bool) – Whether to suppress persistent history for the spawned shell. Defaults to False for MCP and direct Python calls. This per-call option does not inherit LIBTMUX_SUPPRESS_HISTORY. Startup files may override these controls.
- Returns:
Serialized window object.
- Return type:
-
libtmux_mcp.tools.session_tools.rename_session(new_name, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.session_tools.rename_session(new_name, session_name=None, session_id=None, socket_name=None)¶
Rename a tmux session.
Use when a session’s purpose has changed. Existing pane_id references remain valid after renaming.
- Parameters:
- Returns:
Serialized session object.
- Return type:
-
libtmux_mcp.tools.session_tools.kill_session(session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.session_tools.kill_session(session_name=None, session_id=None, socket_name=None)¶
Kill a tmux session.
Destroys the session and all its windows and panes. Use kill_window to remove a single window instead. Self-kill protection prevents killing the session containing this MCP process.
-
libtmux_mcp.tools.session_tools.select_window(window_id=None, window_index=None, direction=None, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.session_tools.select_window(window_id=None, window_index=None, direction=None, session_name=None, session_id=None, socket_name=None)¶
Select (focus) a tmux window by ID, index, or direction.
Use to navigate between windows. Provide window_id or window_index for direct selection, or direction for relative navigation.
- Parameters:
window_id (
str,optional) – Window ID (e.g. ‘@1’) for direct selection.window_index (
str,optional) – Window index for direct selection.direction (
str,optional) – Relative direction: ‘next’, ‘previous’, or ‘last’.session_name (
str,optional) – Session name for resolution.session_id (
str,optional) – Session ID for resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
The now-active window.
- Return type:
Window tools¶
MCP tools for tmux window operations.
-
libtmux_mcp.tools.window_tools.list_panes(session_name=None, session_id=None, window_id=None, window_index=None, socket_name=None, filters=None)¶libtmux_mcp.tools.window_tools.list_panes(session_name=None, session_id=None, window_id=None, window_index=None, socket_name=None, filters=None)¶
List tmux panes (terminal multiplexer splits) in a window, session, or server.
Use for terminal panes — including ‘this pane’, ‘current pane’, ‘split pane’, ‘the bottom shell’ — not editor splits or browser panes. Only searches pane metadata (current command, title, working directory); to search the actual visible terminal text, use search_panes.
- Parameters:
session_name (
str,optional) – Session name. If given without window params, lists all panes in the session.session_id (
str,optional) – Session ID. If given without window params, lists all panes in the session.window_id (
str,optional) – Window ID (e.g. ‘@1’). Scopes to a single window.window_index (
str,optional) – Window index within the session. Scopes to a single window.socket_name (
str,optional) – tmux socket name.filters (
dict or str, optional) – Django-style filters as a dict (e.g.{"pane_current_command__contains": "vim"}) or as a JSON string. Some MCP clients require the string form.
- Returns:
List of serialized pane objects.
- Return type:
-
libtmux_mcp.tools.window_tools.get_window_info(window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.window_tools.get_window_info(window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶
Return metadata for a single tmux window (ID, name, layout, dimensions).
Use this instead of list_windows + filter when you only need one window’s info. Resolves the window by window_id first; falls back to window_index within a session if window_id is not given.
- Parameters:
window_id (
str,optional) – Window ID (e.g. ‘@1’).window_index (
str,optional) – Window index within the session. Requires session_name or session_id to disambiguate.session_name (
str,optional) – Session name for window_index lookup.session_id (
str,optional) – Session ID for window_index lookup.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized window metadata.
- Return type:
-
libtmux_mcp.tools.window_tools.split_window(pane_id=None, session_name=None, session_id=None, window_id=None, window_index=None, direction=None, size=None, start_directory=None, shell=None, socket_name=None, *, environment=None, suppress_persistent_history=False)¶libtmux_mcp.tools.window_tools.split_window(pane_id=None, session_name=None, session_id=None, window_id=None, window_index=None, direction=None, size=None, start_directory=None, shell=None, socket_name=None, *, environment=None, suppress_persistent_history=False)¶
Split a tmux window to create a new pane.
Creates a new pane by splitting an existing one. Use direction to choose above/below/left/right. Returns the new pane’s info including its pane_id.
- Parameters:
pane_id (
str,optional) – Pane ID to split from. If given, splits adjacent to this pane.session_name (
str,optional) – Session name.session_id (
str,optional) – Session ID (e.g. ‘$1’).window_id (
str,optional) – Window ID (e.g. ‘@1’).window_index (
str,optional) – Window index within the session.direction (
str,optional) – Split direction.size (
str or int, optional) – Size of the new pane. Use a string with ‘%%’ suffix for percentage (e.g. ‘50%%’) or an integer for lines/columns.start_directory (
str,optional) – Working directory for the new pane.shell (
str,optional) – Shell command to run in the new pane.socket_name (
str,optional) – tmux socket name.environment (
dict or str, optional) – Per-process environment as a mapping or JSON object string. Values do not modify the tmux session environment. Each item becomes a tmux-elaunch option. Values may be visible to host process inspection in the tmux client argv during launch and in the child environment afterward; MCP audit redaction does not hide either surface. Pass credential references, not literal credentials.suppress_persistent_history (
bool) – Whether to suppress persistent history for the spawned shell. Defaults to False for MCP and direct Python calls. This per-call option does not inherit LIBTMUX_SUPPRESS_HISTORY. Startup files may override these controls.
- Returns:
Serialized pane object.
- Return type:
-
libtmux_mcp.tools.window_tools.rename_window(new_name, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.window_tools.rename_window(new_name, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶
Rename a tmux window.
Use when a window’s purpose has changed. Existing window_id references remain valid after renaming.
- Parameters:
- Returns:
Serialized window object.
- Return type:
-
libtmux_mcp.tools.window_tools.kill_window(window_id, socket_name=None)¶libtmux_mcp.tools.window_tools.kill_window(window_id, socket_name=None)¶
Kill (close) a tmux window. Requires exact window_id (e.g. ‘@3’).
Destroys the window and all its panes. Use kill_pane to remove a single pane instead. Self-kill protection prevents killing the window containing this MCP process.
-
libtmux_mcp.tools.window_tools.select_layout(layout, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.window_tools.select_layout(layout, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶
Set the layout of a tmux window.
Choose from: even-horizontal, even-vertical, main-horizontal, main-vertical, or tiled. Rearranges all panes in the window.
- Parameters:
layout (
str) – Layout name or custom layout string. Built-in layouts: ‘even-horizontal’, ‘even-vertical’, ‘main-horizontal’, ‘main-horizontal-mirrored’, ‘main-vertical’, ‘main-vertical-mirrored’, ‘tiled’.window_id (
str,optional) – Window ID (e.g. ‘@1’).window_index (
str,optional) – Window index within the session.session_name (
str,optional) – Session name.session_id (
str,optional) – Session ID.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized window object.
- Return type:
-
libtmux_mcp.tools.window_tools.resize_window(window_id=None, window_index=None, session_name=None, session_id=None, height=None, width=None, socket_name=None)¶libtmux_mcp.tools.window_tools.resize_window(window_id=None, window_index=None, session_name=None, session_id=None, height=None, width=None, socket_name=None)¶
Resize a tmux window.
Use to adjust the window dimensions. This affects all panes within the window.
- Parameters:
window_id (
str,optional) – Window ID (e.g. ‘@1’).window_index (
str,optional) – Window index within the session.session_name (
str,optional) – Session name.session_id (
str,optional) – Session ID.height (
int,optional) – New height in lines.width (
int,optional) – New width in columns.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized window object.
- Return type:
-
libtmux_mcp.tools.window_tools.move_window(window_id=None, window_index=None, session_name=None, session_id=None, destination_index='', destination_session=None, socket_name=None)¶libtmux_mcp.tools.window_tools.move_window(window_id=None, window_index=None, session_name=None, session_id=None, destination_index='', destination_session=None, socket_name=None)¶
Move a window to a different index or session.
Reorder windows within a session or move a window to another session.
- Parameters:
window_id (
str,optional) – Window ID (e.g. ‘@1’).window_index (
str,optional) – Window index within the session.session_name (
str,optional) – Source session name.session_id (
str,optional) – Source session ID.destination_index (
str) – Target window index. Default empty string (next available).destination_session (
str,optional) – Target session name or ID. Default is current session.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized window after move.
- Return type:
Pane tools¶
Pane-level MCP tools, organised by domain.
The package is structured by operation kind (io, wait, search,
copy_mode, layout, lifecycle, pipe, meta). Consumers can continue to
import libtmux_mcp.tools.pane_tools — re-exports below preserve
the historical flat namespace so existing tests and typed imports
keep working.
-
libtmux_mcp.tools.pane_tools.capture_pane(pane_id=None, session_name=None, session_id=None, window_id=None, start=None, end=None, max_lines=CAPTURE_DEFAULT_MAX_LINES, socket_name=None)¶libtmux_mcp.tools.pane_tools.capture_pane(pane_id=None, session_name=None, session_id=None, window_id=None, start=None, end=None, max_lines=CAPTURE_DEFAULT_MAX_LINES, socket_name=None)¶
Capture the visible contents of a tmux pane (terminal scrollback).
Use for tmux pane output — ‘capture the build log’, ‘what did the server print’ — not editor file contents. The tool for reading what is displayed in a terminal; use search_panes to search across multiple panes at once.
Output is tail-preserved: when the capture exceeds
max_linesthe oldest lines are dropped and the returned string is prefixed with a single[... truncated K lines ...]header line so the agent can tell truncation occurred and re-request with a narrowerstart/endwindow or a largermax_linesif needed. Passmax_lines=Noneto disable truncation entirely.- Parameters:
pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.start (
int,optional) – Start line number. 0 is the first visible line. Negative values reach into scrollback history (e.g. -100 for last 100 lines).end (
int,optional) – End line number.max_lines (
int or None) – Maximum number of lines to return. Defaults toCAPTURE_DEFAULT_MAX_LINES. PassNoneto return the full capture with no truncation.socket_name (
str,optional) – tmux socket name.
- Returns:
Captured pane content as text. When truncated, the first line is a
[... truncated K lines ...]marker.- Return type:
-
libtmux_mcp.tools.pane_tools.capture_since(cursor=None, pane_id=None, session_name=None, session_id=None, window_id=None, max_lines=CAPTURE_SINCE_DEFAULT_MAX_LINES, max_bytes=CAPTURE_SINCE_DEFAULT_MAX_BYTES, socket_name=None)¶libtmux_mcp.tools.pane_tools.capture_since(cursor=None, pane_id=None, session_name=None, session_id=None, window_id=None, max_lines=CAPTURE_SINCE_DEFAULT_MAX_LINES, max_bytes=CAPTURE_SINCE_DEFAULT_MAX_BYTES, socket_name=None)¶
Capture new tmux terminal scrollback since the previous cursor.
Use for observation-first workflows: tailing a shell, watching a long-running command, or repeatedly checking a tmux workspace pane without re-sending the same visible screen every turn. The first call with
cursor=Nonereturns the current visible pane and an opaque cursor. Later calls pass that cursor back and receive only rows written or rewritten after the cursor, as long as tmux still retains the required scrollback history.If tmux history was cleared or trimmed before the cursor anchor, the tool returns the current visible pane with
lines_missed=Trueand a fresh cursor. Malformed cursors, cursors for a different pane, pane death, and pane respawn fail withExpectedToolErrorso agents do not accidentally observe the wrong process.- Parameters:
cursor (
str,optional) – Opaque cursor returned by a priorcapture_sincecall. When omitted, the tool captures the current visible screen and starts a new cursor.pane_id (
str,optional) – Pane ID (e.g. ‘%1’). Optional whencursoris supplied; the cursor carries the original pane id.session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.max_lines (
int or None) – Maximum number of lines to return. Defaults toCAPTURE_SINCE_DEFAULT_MAX_LINES. PassNoneto disable line truncation.max_bytes (
int or None) – Maximum UTF-8 bytes to return acrosslines. Defaults toCAPTURE_SINCE_DEFAULT_MAX_BYTES. PassNoneto disable byte truncation.socket_name (
str,optional) – tmux socket name.
- Returns:
Structured lines, cursor, elapsed time, and truncation/loss metadata.
- Return type:
-
libtmux_mcp.tools.pane_tools.clear_pane(pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.clear_pane(pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Clear the contents of a tmux pane.
Use before a fresh run_command call or raw-input observation workflow when prior scrollback would make the result harder to inspect.
- Parameters:
- Returns:
Confirmation message.
- Return type:
-
libtmux_mcp.tools.pane_tools.display_message(format_string, pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.display_message(format_string, pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Evaluate a tmux format string against a target and return the expanded value.
Read-only introspection tool — expands any tmux format variable against a target pane and returns the substituted text. Use this when no dedicated tool covers the field you want, e.g. ‘#{window_zoomed_flag}’, ‘#{pane_dead}’, ‘#{client_activity}’.
- Parameters:
format_string (
str) – tmux format string (e.g. ‘#{cursor_x} #{cursor_y}’).pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID for pane resolution.window_id (
str,optional) – Window ID for pane resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
Expanded format string result.
- Return type:
-
libtmux_mcp.tools.pane_tools.enter_copy_mode(pane_id=None, scroll_up=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.enter_copy_mode(pane_id=None, scroll_up=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Enter copy mode in a tmux pane, optionally scrolling up.
Use to navigate scrollback history. After entering copy mode, use snapshot_pane to read the scroll_position and content.
- Parameters:
pane_id (
str,optional) – Pane ID (e.g. ‘%1’).scroll_up (
int,optional) – Number of lines to scroll up immediately after entering copy mode.session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID for pane resolution.window_id (
str,optional) – Window ID for pane resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized pane info.
- Return type:
-
libtmux_mcp.tools.pane_tools.exit_copy_mode(pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.exit_copy_mode(pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Exit copy mode in a tmux pane.
Returns the pane to normal mode. Use after scrolling through scrollback history.
- Parameters:
- Returns:
Serialized pane info.
- Return type:
-
libtmux_mcp.tools.pane_tools.find_pane_by_position(corner, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.find_pane_by_position(corner, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶
Find the pane occupying a corner of a tmux window.
Composes the four
pane_at_*predicates so callers can target a layout-relative position (e.g. “the bottom-right pane”) in one round-trip instead of listing every pane and computing the geometry. Resolves the window the same way as the other window-scoped tools.- Parameters:
corner (
str) – One of'top-left','top-right','bottom-left','bottom-right'.window_id (
str,optional) – Window ID (e.g. ‘@1’).window_index (
str,optional) – Window index. Requires session_name or session_id.session_name (
str,optional) – Session name.session_id (
str,optional) – Session ID.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized pane occupying the requested corner.
- Return type:
- Raises:
ExpectedToolError– If no pane satisfies both edge predicates for that corner — in practice only possible for layouts tmux itself produced via custom layout strings; the built-in layouts always have a pane at every corner.
-
libtmux_mcp.tools.pane_tools.get_pane_info(pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.get_pane_info(pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Get detailed information about a tmux pane.
Use this for metadata (PID, path, dimensions) without reading terminal content. To read what is displayed in the pane, use capture_pane instead.
- Parameters:
- Returns:
Serialized pane details.
- Return type:
-
libtmux_mcp.tools.pane_tools.kill_pane(pane_id, socket_name=None)¶libtmux_mcp.tools.pane_tools.kill_pane(pane_id, socket_name=None)¶
Kill (close) a tmux pane. Requires exact pane_id (e.g. ‘%5’).
Use to clean up panes no longer needed. To remove an entire window and all its panes, use kill_window instead.
-
libtmux_mcp.tools.pane_tools.paste_text(text, pane_id=None, bracket=True, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.paste_text(text, pane_id=None, bracket=True, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Paste multi-line text into a pane using tmux paste buffers.
Uses tmux’s load-buffer and paste-buffer for clean multi-line input, avoiding the issues of sending text line-by-line via send_keys. Supports bracketed paste mode for terminals that handle it.
When to use this vs. load_buffer + paste_buffer:
paste_textis the fire-and-forget path — the buffer is created, pasted, and deleted in one call. Useload_buffer+paste_bufferwhen you need to stage content first, paste it into multiple panes, or inspect it withshow_bufferbefore pasting.- Parameters:
text (
str) – The text to paste.pane_id (
str,optional) – Pane ID (e.g. ‘%1’).bracket (
bool) – Whether to use bracketed paste mode. Default True. Bracketed paste wraps the text in escape sequences that tell the terminal “this is pasted text, not typed input”.session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID for pane resolution.window_id (
str,optional) – Window ID for pane resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
Confirmation message.
- Return type:
-
libtmux_mcp.tools.pane_tools.pipe_pane(pane_id=None, output_path=None, append=True, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.pipe_pane(pane_id=None, output_path=None, append=True, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Log a pane’s live output to a file (or stop an active log).
Streams everything written to the pane (stdout plus terminal control sequences) into a file on disk — the common use is
output_path="/tmp/pane.log"to capture scrollback continuously while the agent watches for errors. Whenoutput_pathis given, starts logging; whenoutput_pathis None, stops any active pipe for the pane.Warning
This tool writes to arbitrary filesystem paths chosen by the MCP client. There is no allow-list; the server will create files anywhere the server process has write access. Treat this as elevated-risk even though it sits in the
mutatingsafety tier — it is the broadest-reach tool in that tier. If you run libtmux-mcp on untrusted input, considerLIBTMUX_SAFETY=readonlyor run the server under a user with a scoped home directory. See Safety tiers for the full footgun list.- Parameters:
pane_id (
str,optional) – Pane ID (e.g. ‘%1’).output_path (
str,optional) – File path to write output to. None stops piping.append (
bool) – Whether to append to the file. Default True. If False, overwrites.session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID for pane resolution.window_id (
str,optional) – Window ID for pane resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
Confirmation message.
- Return type:
-
libtmux_mcp.tools.pane_tools.register(mcp)¶libtmux_mcp.tools.pane_tools.register(mcp)¶
Register pane-level tools with the MCP instance.
- Parameters:
mcp (
FastMCP)- Return type:
-
libtmux_mcp.tools.pane_tools.resize_pane(pane_id=None, session_name=None, session_id=None, window_id=None, height=None, width=None, zoom=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.resize_pane(pane_id=None, session_name=None, session_id=None, window_id=None, height=None, width=None, zoom=None, socket_name=None)¶
Resize a tmux pane.
Use when adjusting layout for better readability or to fit content.
- Parameters:
pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.height (
int,optional) – New height in lines.width (
int,optional) – New width in columns.zoom (
bool,optional) – Toggle pane zoom. If True, zoom the pane. If False, unzoom.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized pane object.
- Return type:
-
libtmux_mcp.tools.pane_tools.respawn_pane(pane_id, kill=True, shell=None, start_directory=None, environment=None, socket_name=None, *, suppress_persistent_history=False)¶libtmux_mcp.tools.pane_tools.respawn_pane(pane_id, kill=True, shell=None, start_directory=None, environment=None, socket_name=None, *, suppress_persistent_history=False)¶
Restart a pane’s process in place, preserving pane_id and layout.
Use when a shell wedges (hung REPL, runaway process, bad terminal mode). The alternative — kill_pane + split_window — destroys pane_id references the agent may still be holding, and rearranges the layout. respawn-pane preserves both.
With
kill=True(the default), tmux kills the existing process before respawning. Optionalshellreplaces the command tmux relaunches;start_directorysets the working directory for the new process;environmentsets per-process environment variables for the relaunched command (one-e KEY=VALUEflag per entry).pane_idis required — sibling pane tools accept a hierarchical fallback (session_name/window_id/pane_index) that resolves to “first pane in session/window”, but combined with defaultkill=Truethat fallback could silently kill an unrelated process. The signature deliberately omits the resolver fields so the FastMCP schema rejects them at the framework boundary. Resolve vialist_panesfirst.Tip: call
get_pane_infofirst if you need to capturepane_current_commandbefore respawn — the new process loses its argv. Omittingshellmakes tmux replay the original argv (good default for shells; may differ for processes spawned via custom shell at split time).- Parameters:
pane_id (
str) – Pane ID (e.g. ‘%1’). Required.kill (
bool) – When True (default), pass-kto tmux so the current process is killed before respawning. When False, respawn fails if the pane already has a running process.shell (
str,optional) – Replacement command for tmux to launch. When omitted, tmux replays the original argv (good default for shells; may differ for processes spawned via custom shell at split time). Matches theshellparameter onsplit_window()and the eventual upstreamPane.respawn(shell=)API.start_directory (
str,optional) – Working directory for the relaunched command (maps torespawn-pane -c).environment (
dict or str, optional) – Environment variables to set for the relaunched process. Each item becomes one-e KEY=VALUEflag (tmux’scmd-respawn-pane.csupports the flag repeatedly). Values supplied in a mapping are redacted in the audit log on a per-key basis — keys likeDATABASE_URLremain visible but their values are replaced by{len, sha256_prefix}digests. A JSON object string is redacted as one scalar digest, so its keys are not retained in the audit record. Values may still appear briefly in the OS process table while tmux spawns the new process; do not pass long-lived secrets here when a host-resident agent or other tenant could observeps.socket_name (
str,optional) – tmux socket name.suppress_persistent_history (
bool) – Whether to suppress persistent history for the spawned shell. Defaults to False for MCP and direct Python calls. This per-call option does not inherit LIBTMUX_SUPPRESS_HISTORY. Startup files may override these controls.
- Returns:
Serialized pane metadata after respawn. The pane_id is preserved; pane_pid reflects the new process.
- Return type:
-
libtmux_mcp.tools.pane_tools.run_command(command, pane_id=None, session_name=None, session_id=None, window_id=None, timeout=30.0, max_lines=None, suppress_history=False, socket_name=None)¶libtmux_mcp.tools.pane_tools.run_command(command, pane_id=None, session_name=None, session_id=None, window_id=None, timeout=30.0, max_lines=None, suppress_history=False, socket_name=None)¶
Run a shell command in a pane, wait for completion, and capture output.
Use for the common terminal workflow: run this command, wait until it completes, then report whether it succeeded. The command is sent to the pane’s interactive shell, followed by a private
tmux wait-forsignal and a private pane option carrying the shell exit status. This is the AUTHORED-output path — the command you pass is what the wait synchronizes on. Reservewait_for_textfor output you did not author: another process, a human, or a background job.The command runs in a subshell, so
cd,exportand other shell state changes do not persist to later calls.- Parameters:
command (
str) – Shell command to run in the target pane.pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.timeout (
float) – Maximum seconds to wait for command completion. Capped by the same server wait ceiling aswait_for_text; an over-large value is not an error — the wait returns at the ceiling and the timeout actually enforced is reported onRunCommandResult.effective_timeout.max_lines (
int or None) – Maximum pane output lines to return. Defaults to all captured visible output; pass a small value for a tail-only summary.suppress_history (
bool) – For MCP calls, omission uses the server’s LIBTMUX_SUPPRESS_HISTORY default; an explicit value overrides it. Direct Python calls default to False. Best effort: the shell must honor space-prefixed history suppression. Suppression requires a single-line command; multiline commands remain available when suppression is false.socket_name (
str,optional) – tmux socket name.
- Returns:
Typed command result with exit status, timeout state, and tail-preserved pane output.
- Return type:
-
libtmux_mcp.tools.pane_tools.search_panes(pattern, regex=False, session_name=None, session_id=None, match_case=False, content_start=None, content_end=None, max_matched_lines_per_pane=SEARCH_DEFAULT_MAX_LINES_PER_PANE, limit=SEARCH_DEFAULT_LIMIT, offset=0, socket_name=None)¶libtmux_mcp.tools.pane_tools.search_panes(pattern, regex=False, session_name=None, session_id=None, match_case=False, content_start=None, content_end=None, max_matched_lines_per_pane=SEARCH_DEFAULT_MAX_LINES_PER_PANE, limit=SEARCH_DEFAULT_LIMIT, offset=0, socket_name=None)¶
Search visible terminal text across all tmux panes.
Use when the user asks what panes ‘contain’, ‘mention’, or ‘show’ — e.g. ‘find the pane with the pytest failure’. Searches each pane’s visible terminal scrollback content (not editor or browser text) and returns panes where the pattern is found, with matching lines.
Bounded output contract¶
The result is paginated at the pane level. The matching panes are sorted by
pane_idand then sliced withoffset/limit. Each matching pane’smatched_linesis further tail-truncated to at mostmax_matched_lines_per_paneentries (most-recent lines preserved). Caps apply only to the slow path (pane.capture_pane(join_wrapped=True)+ Python regex); the tmux fast path at#{C:pattern}returns pane IDs only and is already bounded by tmux. The slow path joins wrapped visual rows so long lines can match across the pane’s wrap column. The fast path remains tmux’s native visual-row search, so useregex=Trueor an explicit content range to force the slow path when wrap-spanning text matters.- param pattern:
Text to search for in pane contents. Treated as literal text by default. Set
regex=Trueto interpret as a regular expression.- type pattern:
str
- param regex:
Whether to interpret pattern as a regular expression. Default False (literal text matching).
- type regex:
bool
- param session_name:
Limit search to panes in this session.
- type session_name:
str, optional
- param session_id:
Limit search to panes in this session (by ID).
- type session_id:
str, optional
- param match_case:
Whether to match case. Default False (case-insensitive).
- type match_case:
bool
- param content_start:
Start line for capture. Negative values reach into scrollback.
- type content_start:
int, optional
- param content_end:
End line for capture.
- type content_end:
int, optional
- param max_matched_lines_per_pane:
Per-pane cap on
matched_lines. Defaults toSEARCH_DEFAULT_MAX_LINES_PER_PANE.- type max_matched_lines_per_pane:
int
- param limit:
Maximum matching panes returned on this call. Defaults to
SEARCH_DEFAULT_LIMIT. PassNoneto disable the cap.- type limit:
int or None
- param offset:
Skip this many matching panes from the start. Use with
limitfor pagination.- type offset:
int
- param socket_name:
tmux socket name.
- type socket_name:
str, optional
- returns:
Paginated match list with
truncated/truncated_panes/total_panes_matched/offset/limitfields.- rtype:
SearchPanesResult
-
libtmux_mcp.tools.pane_tools.select_pane(pane_id=None, direction=None, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.select_pane(pane_id=None, direction=None, window_id=None, window_index=None, session_name=None, session_id=None, socket_name=None)¶
Select (focus) a tmux pane by ID or direction.
Use this to navigate between panes. Provide either pane_id for direct selection, or direction for relative navigation within a window.
- Parameters:
pane_id (
str,optional) – Pane ID (e.g. ‘%1’) for direct selection.direction (
str,optional) – Relative direction: ‘up’, ‘down’, ‘left’, ‘right’, ‘last’ (previously active), ‘next’, or ‘previous’.window_id (
str,optional) – Window ID for directional navigation scope.window_index (
str,optional) – Window index for directional navigation scope.session_name (
str,optional) – Session name for resolution.session_id (
str,optional) – Session ID for resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
The now-active pane.
- Return type:
-
libtmux_mcp.tools.pane_tools.send_keys(keys, pane_id=None, session_name=None, session_id=None, window_id=None, enter=True, literal=False, suppress_history=False, socket_name=None)¶libtmux_mcp.tools.pane_tools.send_keys(keys, pane_id=None, session_name=None, session_id=None, window_id=None, enter=True, literal=False, suppress_history=False, socket_name=None)¶
Send keys (commands or text) to a tmux pane.
Use this for raw interactive input: TUI keys, control sequences, partial shell input, or persistent shell state. Use
send_keys_batchwhen you need several ordered raw-input operations.For authored shell commands that need completion, exit status, or captured output, use
run_commandinstead. For custom completion outside that shape, composetmux wait-for -S <channel>into the shell command and callwait_for_channel. For repeated observation after input, prefercapture_since; reservewait_for_textfor output the agent does not author.Do NOT call
capture_paneimmediately — both the read and the pattern-match paths race the pane’s PTY draw.- Parameters:
keys (
str) – The keys or text to send.pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.enter (
bool) – Whether to press Enter after sending keys. Default True.literal (
bool) – Whether to send keys literally (no tmux interpretation). Default False.suppress_history (
bool) – Suppress shell history by prepending a space; only effective where the shell ignores space-prefixed commands. Default False.socket_name (
str,optional) – tmux socket name.
- Returns:
Confirmation message.
- Return type:
-
libtmux_mcp.tools.pane_tools.send_keys_batch(operations, on_error='stop', timeout=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.send_keys_batch(operations, on_error='stop', timeout=None, socket_name=None)¶
Send an ordered batch of raw key/text operations to tmux panes.
Use this for bulk TUI or persistent-shell input where each item is the same kind of low-level terminal interaction as
send_keys(). For authored shell commands that need exit status and captured output, userun_command()instead. For repeated observation after sending input, usecapture_since()with its returned cursor.This tool intentionally does not compose heterogeneous operations such as send → wait → capture. Keeping the batch homogeneous preserves clear per-operation error attribution and avoids embedding a workflow DSL in the MCP tool surface.
- Parameters:
operations (
list of SendKeysOperation) – Ordered raw-input operations to send.on_error (
{“stop”, “continue”}) – Whether to stop at the first failed operation or keep attempting later operations. Default “stop”.timeout (
float,optional) – Maximum time in seconds to allow the batch to run before aborting.socket_name (
str,optional) – tmux socket name.
- Returns:
Per-operation results with success/error counts and stop index.
- Return type:
-
libtmux_mcp.tools.pane_tools.set_pane_title(title, pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.pane_tools.set_pane_title(title, pane_id=None, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Set the title of a tmux pane.
Use titles to label panes for later identification via list_panes or get_pane_info.
- Parameters:
title (
str) – The new pane title.pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.socket_name (
str,optional) – tmux socket name.
- Returns:
Serialized pane object.
- Return type:
-
libtmux_mcp.tools.pane_tools.snapshot_pane(pane_id=None, session_name=None, session_id=None, window_id=None, max_lines=CAPTURE_DEFAULT_MAX_LINES, socket_name=None)¶libtmux_mcp.tools.pane_tools.snapshot_pane(pane_id=None, session_name=None, session_id=None, window_id=None, max_lines=CAPTURE_DEFAULT_MAX_LINES, socket_name=None)¶
Snapshot a tmux pane: visible terminal output, cursor, mode, scroll.
Use for terminal-contents inspection — ‘what’s in my pane’, ‘the current shell output’ — not editor panes or browser viewports. Returns everything
capture_pane()andget_pane_info()return, plus cursor position, copy-mode state, and scroll position — in a single call. Prefer this over separate capture_pane + get_pane_info calls when you need to reason about cursor location or pane mode.The
contentfield is tail-preserved: when the captured pane exceedsmax_lines, the oldest lines are dropped and the result is reported viacontent_truncated/content_truncated_linesfields on the returnedPaneSnapshot. Passmax_lines=Noneto opt out of truncation entirely.- Parameters:
pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.max_lines (
int or None) – Maximum number of content lines to return. Defaults toCAPTURE_DEFAULT_MAX_LINES. PassNoneto return the full capture untrimmed.socket_name (
str,optional) – tmux socket name.
- Returns:
Rich snapshot with content, cursor, mode, and scroll state. When the capture is trimmed,
content_truncatedis True andcontent_truncated_linesgives the number of dropped head lines;contentitself carries no marker header.- Return type:
-
libtmux_mcp.tools.pane_tools.swap_pane(source_pane_id, target_pane_id, socket_name=None)¶libtmux_mcp.tools.pane_tools.swap_pane(source_pane_id, target_pane_id, socket_name=None)¶
Swap the positions of two panes.
Exchanges the visual positions of two panes. Both panes must exist. Use this to rearrange pane layout without changing content.
-
libtmux_mcp.tools.pane_tools.wait_for_text(patterns=None, stop=None, regex=False, pane_id=None, session_name=None, session_id=None, window_id=None, timeout=8.0, interval=0.05, match_case=False, socket_name=None, ctx=None)¶libtmux_mcp.tools.pane_tools.wait_for_text(patterns=None, stop=None, regex=False, pane_id=None, session_name=None, session_id=None, window_id=None, timeout=8.0, interval=0.05, match_case=False, socket_name=None, ctx=None)¶
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.- Parameters:
patterns (
list of str, optional) – Success patterns; the first one to match ends the wait. Literal text unlessregex=True. Omit or passnullto wait for any new output.stop (
list of str, optional) – Failure patterns. A hit ends the wait immediately withoutcome="stopped"andfound=false;matched_indexsays which entry fired.regex (
bool) – Interpretpatternsandstopas regular expressions. Default False (literal text).pane_id (
str,optional) – Pane ID (e.g. ‘%1’).session_name (
str,optional) – Session name for pane resolution.session_id (
str,optional) – Session ID (e.g. ‘$1’) for pane resolution.window_id (
str,optional) – Window ID for pane resolution.timeout (
float) – Requested seconds to wait. Default 8.0. Clamped by server policy; seeeffective_timeoutin the result.interval (
float) – Seconds between polls. Default 0.05 (50ms). Minimum 0.01.match_case (
bool) – Whether to match case. Default False (case-insensitive).socket_name (
str,optional) – tmux socket name.ctx (
fastmcp.Context,optional) – FastMCP context; when injected the tool reports progress to the client. Omitted in tests.
- Returns:
Match outcome, a bounded tail of what the pane printed, and the timeout actually enforced.
- Return type:
Notes
Matching happens in Python, never in tmux. Patterns are never interpolated into a tmux format string: tmux’s format parser treats
#and}structurally, so an ordinary regex quantifier corrupts field parsing and a pattern ending in#swallows the rest of the format. Only fixed literal formats reach tmux.Every tmux call is timeout-bounded. Reads are spawned with
asyncio.create_subprocess_execand bounded against the wait’s own deadline, rather than going through libtmux’s untimedPopen.communicate(). Nothing in this path runs on a worker thread, so a wedged tmux server can neither pin the event loop nor hang interpreter shutdown.Alternate screen / pagers suppress matching. Inside
lessor any full-screen program,capture-panereturns the program’s painted rows, so matching them would report text the program had already drawn. Matching is skipped for as long as the alternate screen lasts and the result comes back asalternate_screenrather thantimeout— read the screen, don’t retry the wait.Scrollback rollover detection is partial. The tool raises when
hsizeshrinks below the entry value (clear-history, and any rollover whose dip is observable between polls). It does not reliably detectgrid_collect_historytrim during continuous output; a runtimectx.warningfires when sampled state enters the trim-risk band. Usewait_for_channelwhen correctness matters more than convenience.
Buffer tools¶
Agent-namespaced tmux paste buffer tools.
Tmux paste buffers are server-global: every buffer lives in a single
flat namespace shared by all clients on that tmux server. If two MCP
agents — or two parallel tool calls from one agent — independently
created a buffer named clipboard they would silently overwrite
each other’s content.
To make buffers safe for concurrent use, every load_buffer call
allocates a unique name of the form:
libtmux_mcp_<uuid4hex>_<logical_name>
and returns the full name in a BufferRef so
the caller can round-trip with
paste_buffer(),
show_buffer(), and
delete_buffer() without ambiguity.
list_buffers is not exposed in the default safety tier —
buffer contents often include the user’s OS clipboard history (passwords,
private snippets), and a blanket enumeration would leak that to the
agent. Callers track the buffers they own via the
BufferRef objects returned from
load_buffer().
-
libtmux_mcp.tools.buffer_tools.SHOW_BUFFER_DEFAULT_MAX_LINES = 500¶libtmux_mcp.tools.buffer_tools.SHOW_BUFFER_DEFAULT_MAX_LINES = 500¶
Default line cap for
show_buffer(). Reuses the scrollback default so agents see one consistent bound across read-heavy tools.
-
libtmux_mcp.tools.buffer_tools._MCP_BUFFER_PREFIX = 'libtmux_mcp_'¶libtmux_mcp.tools.buffer_tools._MCP_BUFFER_PREFIX = 'libtmux_mcp_'¶
Reserved prefix for MCP-allocated buffers. Anything matching this regex is considered agent-owned; anything else is the human user’s buffer (including OS-clipboard sync buffers) and must not be exposed.
-
libtmux_mcp.tools.buffer_tools._BUFFER_NAME_RE = re.compile('^libtmux_mcp_[0-9a-f]{32}_[A-Za-z0-9_.-]{1,64}$')¶libtmux_mcp.tools.buffer_tools._BUFFER_NAME_RE = re.compile('^libtmux_mcp_[0-9a-f]{32}_[A-Za-z0-9_.-]{1,64}$')¶
Full-shape validator for MCP-allocated buffer names. Caller-provided logical names are restricted to a conservative alphabet so the final name is stable and safe to pass to
tmux load-buffer -b.
-
libtmux_mcp.tools.buffer_tools._LOGICAL_NAME_RE = re.compile('^[A-Za-z0-9_.-]{1,64}$')¶libtmux_mcp.tools.buffer_tools._LOGICAL_NAME_RE = re.compile('^[A-Za-z0-9_.-]{1,64}$')¶
Validator for the caller-supplied logical portion of a buffer name. Empty logical names are replaced with
bufto avoid a trailing underscore in the allocated name.
-
libtmux_mcp.tools.buffer_tools._validate_logical_name(name)¶libtmux_mcp.tools.buffer_tools._validate_logical_name(name)¶
Return
nameunchanged if it is a valid logical portion.Empty strings collapse to
"buf"before validation because tmux-side buffer names must contain at least one character after the UUID separator.Examples
>>> _validate_logical_name("my-buffer") 'my-buffer' >>> _validate_logical_name("clipboard.v2") 'clipboard.v2' >>> _validate_logical_name("") 'buf' >>> _validate_logical_name("has space") Traceback (most recent call last): ... libtmux_mcp._utils.ExpectedToolError: Invalid logical buffer name: 'has space' >>> _validate_logical_name("with/slash") Traceback (most recent call last): ... libtmux_mcp._utils.ExpectedToolError: Invalid logical buffer name: 'with/slash'
-
libtmux_mcp.tools.buffer_tools._validate_buffer_name(name)¶libtmux_mcp.tools.buffer_tools._validate_buffer_name(name)¶
Return
nameunchanged if it is a well-formed MCP buffer name.Rejects names outside the MCP namespace so the tool surface cannot be tricked into reading or clobbering buffers the agent did not allocate. This is the main defence against the “clipboard privacy” risk documented at the module level.
Examples
>>> _validate_buffer_name("libtmux_mcp_00112233445566778899aabbccddeeff_buf") 'libtmux_mcp_00112233445566778899aabbccddeeff_buf' >>> _validate_buffer_name("clipboard") Traceback (most recent call last): ... libtmux_mcp._utils.ExpectedToolError: Invalid buffer name: 'clipboard' >>> _validate_buffer_name("libtmux_mcp_shortuuid_buf") Traceback (most recent call last): ... libtmux_mcp._utils.ExpectedToolError: Invalid buffer name: 'libtmux_mcp_...'
-
libtmux_mcp.tools.buffer_tools._allocate_buffer_name(logical_name)¶libtmux_mcp.tools.buffer_tools._allocate_buffer_name(logical_name)¶
Allocate a unique MCP buffer name for a caller’s logical label.
The returned name always has the shape
libtmux_mcp_<32-hex-uuid>_<logical_name>— the prefix defends the tool surface against interacting with buffers it did not create (OS-clipboard sync populates tmux’s server-global namespace too), and the uuid nonce prevents collisions when multiple agents or parallel tool calls allocate buffers at the same time. Whenlogical_nameis empty orNone,"buf"is substituted to avoid a trailing-underscore name.Examples
>>> name = _allocate_buffer_name("clip") >>> name.startswith("libtmux_mcp_") True >>> name.endswith("_clip") True >>> # 32 hex characters between the prefix and the logical suffix. >>> len(name.removeprefix("libtmux_mcp_").rsplit("_", 1)[0]) 32
Empty logical name collapses to
"buf":>>> _allocate_buffer_name("").endswith("_buf") True >>> _allocate_buffer_name(None).endswith("_buf") True
-
libtmux_mcp.tools.buffer_tools.load_buffer(content, logical_name=None, socket_name=None)¶libtmux_mcp.tools.buffer_tools.load_buffer(content, logical_name=None, socket_name=None)¶
Load text into a new agent-namespaced tmux paste buffer.
Each call allocates a fresh buffer name — two concurrent calls will land in distinct buffers even if they pass the same
logical_name. Agents MUST use the returnedbuffer_nameon subsequent paste/show/delete calls.When to use this vs. paste_text:
load_bufferis the stage-then-fire path — you get a handle back and can inspect viashow_buffer, paste into multiple panes viapaste_buffer, or hold the content for later. Usepaste_textfor a simple one-shot paste with no follow-up.- Parameters:
- Returns:
Handle with the allocated
buffer_namethe caller must use on follow-up calls.- Return type:
-
libtmux_mcp.tools.buffer_tools.paste_buffer(buffer_name, pane_id=None, bracket=True, session_name=None, session_id=None, window_id=None, socket_name=None)¶libtmux_mcp.tools.buffer_tools.paste_buffer(buffer_name, pane_id=None, bracket=True, session_name=None, session_id=None, window_id=None, socket_name=None)¶
Paste an MCP-owned buffer into a pane.
- Parameters:
buffer_name (
str) – Must match the full MCP-namespaced form returned byload_buffer(). Non-MCP buffers are rejected so the tool cannot be turned into an arbitrary-buffer reader.pane_id (
str,optional) – Target pane ID.bracket (
bool) – Use tmux bracketed paste mode. Default True.session_name (
optional) – Pane resolution fallbacks.session_id (
optional) – Pane resolution fallbacks.window_id (
optional) – Pane resolution fallbacks.socket_name (
str,optional) – tmux socket name.
- Returns:
Confirmation message naming the target pane.
- Return type:
-
libtmux_mcp.tools.buffer_tools.show_buffer(buffer_name, max_lines=¶
SHOW_BUFFER_DEFAULT_MAX_LINES, socket_name=None)libtmux_mcp.tools.buffer_tools.show_buffer(buffer_name, max_lines=¶SHOW_BUFFER_DEFAULT_MAX_LINES, socket_name=None) Read back the contents of an MCP-owned buffer.
Output is tail-preserved: when the buffer exceeds
max_linesthe oldest lines are dropped andcontent_truncatedis set so the caller can tell truncation happened and opt in to a full read viamax_lines=None. This mirrorscapture_pane— one consistent bounded-output contract across read-heavy tools so a pathologicalload_bufferstaging cannot blow the agent’s context window on a singleshow_buffercall.- Parameters:
buffer_name (
str) – Must match the full MCP-namespaced form.max_lines (
int or None) – Maximum number of lines to return. Defaults toSHOW_BUFFER_DEFAULT_MAX_LINES. PassNonefor no truncation.socket_name (
str,optional) – tmux socket name.
- Returns:
Structured result with
buffer_name,content, and the truncation fields.- Return type:
-
libtmux_mcp.tools.buffer_tools.delete_buffer(buffer_name, socket_name=None)¶libtmux_mcp.tools.buffer_tools.delete_buffer(buffer_name, socket_name=None)¶
Delete an MCP-owned buffer.
-
libtmux_mcp.tools.buffer_tools.register(mcp)¶libtmux_mcp.tools.buffer_tools.register(mcp)¶
Register buffer tools with the MCP instance.
load_bufferis tagged withANNOTATIONS_SHELLbecause itscontentargument is arbitrary user text that may carry interactive-environment side effects (commands about to be pasted into a shell). Other buffer tools are plain mutating ops on the tmux buffer store.- Parameters:
mcp (
FastMCP)- Return type:
Wait-for tools¶
MCP tools for tmux wait-for channel synchronisation.
tmux wait-for exposes named, server-global channels that clients can
signal and block on. These give agents an explicit synchronisation
primitive that’s strictly cheaper than polling pane content: instead of
scraping capture_pane at 50 ms ticks waiting for a sentinel line,
the agent composes the shell command with tmux wait-for -S NAME and
then calls wait_for_channel() which blocks server-side until the
signal fires.
Wait channel safety¶
tmux wait-for without a timeout blocks indefinitely at the OS level.
If the shell command that was supposed to emit the signal crashes
before it ran, the wait would deadlock the MCP server and every agent
connected to it. wait_for_channel() therefore requires a
timeout and runs tmux through
_run_tmux_bounded(), which kills the
child on expiry and on cancellation. That bound is itself capped by
the same server wait ceiling
_wait_ceiling_seconds() publishes for
wait_for_text — an over-large timeout is clamped, not honoured
verbatim. Agents SHOULD use the safe composition pattern:
send_keys("pytest; tmux wait-for -S tests_done")
Shell ; semantics fire wait-for -S whether pytest succeeded
or failed, so the edge-triggered signal never deadlocks the wait. Do
NOT chain exit $status after the signal — in interactive shells
that exits the shell itself, which destroys single-pane sessions and
takes the tmux server down with them. Exit-status preservation in
interactive shells is out-of-scope; inspect the captured output for
command-specific success markers.
-
libtmux_mcp.tools.wait_for_tools._CHANNEL_NAME_RE = re.compile('^[A-Za-z0-9_.:-]{1,128}$')¶libtmux_mcp.tools.wait_for_tools._CHANNEL_NAME_RE = re.compile('^[A-Za-z0-9_.:-]{1,128}$')¶
Allowed characters and length range for channel names. Channels are tmux-server-global and names are passed to
tmux wait-foron the command line — defending against shell-surface escapes / oversized inputs at the MCP boundary is cheaper than relying on libtmux’s argv handling.
-
libtmux_mcp.tools.wait_for_tools._SIGNAL_TIMEOUT_SECONDS = 5.0¶libtmux_mcp.tools.wait_for_tools._SIGNAL_TIMEOUT_SECONDS = 5.0¶
Cap on
signal_channelsubprocess.wait-for -Sis a short server-local operation; 5 s is a generous ceiling that still bounds pathological hangs (e.g. tmux server deadlock).
-
libtmux_mcp.tools.wait_for_tools._LIVENESS_TIMEOUT_SECONDS = 5.0¶libtmux_mcp.tools.wait_for_tools._LIVENESS_TIMEOUT_SECONDS = 5.0¶
Cap on the post-wait liveness re-probe. Same reasoning as
_SIGNAL_TIMEOUT_SECONDS, and it runs at most once per wait.
-
libtmux_mcp.tools.wait_for_tools._server_is_alive(server)¶libtmux_mcp.tools.wait_for_tools._server_is_alive(server)¶
Return whether the tmux server still answers on its socket.
list-sessionsis the probe libtmux’s ownServer.is_aliveuses. It is safe here specifically because it does NOT auto-start a server: against a socket with no server it exits non-zero witherror connecting to <path>, so probing cannot resurrect the thing it is asking about.A
Falsereturn is deliberately treated as fatal by the caller rather than merely logged. There is a narrow race — a script that signals and then immediately tears the server down would report an error for a wait that genuinely succeeded — but that error names a true fact about the server, whereas the alternative is telling the agent a channel was signalled when nothing signalled it.
-
libtmux_mcp.tools.wait_for_tools._validate_channel_name(name)¶libtmux_mcp.tools.wait_for_tools._validate_channel_name(name)¶
Return
nameunchanged if it is a valid channel name.- Parameters:
name (
str) – Candidate channel name.- Returns:
The same string, validated.
- Return type:
- Raises:
ExpectedToolError– Whennameis empty, too long, or contains disallowed characters.
Examples
>>> _validate_channel_name("tests_done") 'tests_done' >>> _validate_channel_name("deploy.prod") 'deploy.prod' >>> _validate_channel_name("ns:ready-2") 'ns:ready-2' >>> _validate_channel_name("has space") Traceback (most recent call last): ... libtmux_mcp._utils.ExpectedToolError: Invalid channel name: 'has space' >>> _validate_channel_name("") Traceback (most recent call last): ... libtmux_mcp._utils.ExpectedToolError: Invalid channel name: ''
-
libtmux_mcp.tools.wait_for_tools.wait_for_channel(channel, timeout=30.0, socket_name=None)¶libtmux_mcp.tools.wait_for_tools.wait_for_channel(channel, timeout=30.0, socket_name=None)¶
Block until a tmux
wait-forchannel is signalled.This is the AUTHORED-output synchronisation primitive: the channel only fires because your own composed shell command signals it. Reserve
wait_for_textfor output you did not author.Agents can compose this with
send_keysto turn shell-side milestones into explicit synchronisation points:send_keys( "pytest; tmux wait-for -S tests_done", pane_id=..., ) wait_for_channel("tests_done", timeout=60)
Shell
;semantics firewait-for -Swhether the command succeeded or failed, so the edge-triggered signal never deadlocks on a crash. Do NOT chainexit $statusafter the signal — in an interactive shell that exits the shell itself, which destroys single-pane sessions. Exit-status preservation in interactive shells is out-of-scope; inspect the captured output for command-specific success markers.- Parameters:
channel (
str) – Channel name. Must match^[A-Za-z0-9_.:-]{1,128}$.timeout (
float) – Maximum seconds to wait. The underlyingtmux wait-forhas no built-in timeout — this wrapper enforces it by killing the tmux child, which also happens if the call is cancelled. Defaults to 30 seconds. Capped by the same server wait ceiling aswait_for_text; an over-large value is not an error, the wait returns at the ceiling and the confirmation message names the timeout that was actually enforced.socket_name (
str,optional) – tmux socket name.
- Returns:
Confirmation message naming the channel and the timeout actually enforced.
- Return type:
- Raises:
ExpectedToolError– On timeout, invalid channel name, tmux error, or when the tmux server disappeared during the wait —tmux wait-forexits 0 for a clean server shutdown exactly as it does for a real signal, so that case is detected by re-probing the server and reported rather than passed off as success.
-
libtmux_mcp.tools.wait_for_tools.signal_channel(channel, socket_name=None)¶libtmux_mcp.tools.wait_for_tools.signal_channel(channel, socket_name=None)¶
Signal a tmux
wait-forchannel, waking any blocked waiters.Signalling an unwaited channel is a no-op that still returns successfully — safe to call defensively.
Hook tools¶
Read-only MCP tools for tmux hook introspection.
Why read-only only¶
Write-hooks (set-hook / unset-hook) are deliberately excluded.
The reason is side-effect leakage: tmux servers outlive the MCP
process, so if an MCP agent installs a hook that runs arbitrary shell
on pane-exited or command-error and then the MCP server is
kill -9’d, OOM’d, or crashes via a C-extension fault, the hook
stays installed in the user’s persistent tmux server and fires
forever.
FastMCP lifespan teardown only runs on graceful SIGTERM/SIGINT, so
a soft “track what we installed and unset on shutdown” registry cannot
close this gap. Three plausible future paths are open:
Install a tmux-side meta-hook on
client-detachedthat self-cleans alllibtmux_mcp_*-namespaced hooks when the MCP client disconnects. Survives hard crashes because tmux enforces it.Require
LIBTMUX_SAFETY=destructivefor write-hooks so leakage is an explicit opt-in with user awareness.Expose
run_hook(one-shot fire) but notset_hook(persistent install) — narrows the risk surface to transient events.
Until one is implemented, the surface here is deliberately visibility only.
-
libtmux_mcp.tools.hook_tools._resolve_hook_target(socket_name, scope, target)¶libtmux_mcp.tools.hook_tools._resolve_hook_target(socket_name, scope, target)¶
Resolve the target object and scope for hook queries.
Mirrors the pattern used by
libtmux_mcp.tools.option_tools, but returnsscope=Nonewhen the resolved object already carries that scope implicitly. tmux’sshow-hookscommand builds different argv depending on whether the scope flag is set, and passing a redundant explicit scope to a Session/Window/Pane object triggers"too many arguments"on some tmux builds.TODO(libtmux upstream):
Session.show_hook(scope=OptionScope.Session)mis-builds the CLI argv and produces"too many arguments"on current tmux builds. ResettingscopetoNoneafter we’ve resolved to a concrete object makes libtmux use the object’s default, which sidesteps the mis-built argv. File upstream once reduced to a minimal repro — the fix belongs in libtmux’sHooksMixin._show_hookargv-assembly path.- Parameters:
- Return type:
-
libtmux_mcp.tools.hook_tools._split_indexed_hook_name(key)¶libtmux_mcp.tools.hook_tools._split_indexed_hook_name(key)¶
Parse
pane-focus-in[0]→('pane-focus-in', 0).show_hooks(plural, enumerating path) returns keys with the tmux-nativeNAME[N]array suffix baked into the dict key, whileshow_hook(singular, name-targeted path) returns a nested{int: str}mapping with a clean name. Splitting the indexed form at the MCP serialization layer normalizes both paths into the sameHookEntryshape so agents don’t have to distinguish them.
-
libtmux_mcp.tools.hook_tools._flatten_hook_value(hook_name, value)¶libtmux_mcp.tools.hook_tools._flatten_hook_value(hook_name, value)¶
Turn a tmux
show_hook/show_hooksvalue into entries.tmux hook values come in four shapes:
None— hook is unset.scalar string / int — single command with no array index.
dict[int, str]— array hook returned byshow_hook(name).SparseArray— array hook returned by some paths.
Both array shapes implement
.items()yielding(int, str), so a singlehasattrcheck handles them uniformly. Scalars flatten into a singleHookEntrywithindex=None. An empty list means “hook is unset”.The
hook_namemay arrive in theNAME[N]form from the plural enumeration path; it’s split into clean name + index here to match the shape the singular name-lookup path emits.
-
libtmux_mcp.tools.hook_tools.show_hooks(scope=None, target=None, global_=False, socket_name=None)¶libtmux_mcp.tools.hook_tools.show_hooks(scope=None, target=None, global_=False, socket_name=None)¶
List configured tmux hooks at the given scope.
scope="server"enumerates hooks installed viatmux set-hook -g .... tmux splits those globals across two options trees by hook category: session-level hooks (session-closed,client-*, etc.) live in the global-session tree enumerated byshow-hooks -g, while pane/window-level hooks (pane-focus-in,window-resized, etc.) live in the global-window tree enumerated byshow-hooks -gw. This tool consults both trees and merges the results so the enumeration matches what a name-targetedshow_hook()call would return.- Parameters:
scope (
str,optional) – Hook scope (server/session/window/pane). Defaults to the calling object’s scope when atargetis given.target (
str,optional) – Target identifier. For session scope: session name. For window scope: window ID. For pane scope: pane ID. Requiresscope.global (
bool) – Pass-gto query global hooks. Default False.socket_name (
str,optional) – tmux socket name.global_ (
bool)
- Returns:
Flat list of hook-name / index / command entries.
- Return type:
-
libtmux_mcp.tools.hook_tools.show_hook(hook_name, scope=None, target=None, global_=False, socket_name=None)¶libtmux_mcp.tools.hook_tools.show_hook(hook_name, scope=None, target=None, global_=False, socket_name=None)¶
Look up a specific tmux hook by name.
Returns a
HookListResultwith zero or moreHookEntryrows — zero if the hook is unset, one if it is a scalar hook, and multiple if it is an array hook with sparse indices.- Parameters:
hook_name (
str) – Hook to look up (e.g."pane-exited").scope (
see) –show_hooks().target (
see) –show_hooks().global (
see) –show_hooks().socket_name (
see) –show_hooks().global_ (
bool)
- Returns:
One or more
HookEntryrows, or empty if unset.- Return type:
Option tools¶
MCP tools for tmux option management.
-
libtmux_mcp.tools.option_tools._resolve_option_target(socket_name, scope, target)¶libtmux_mcp.tools.option_tools._resolve_option_target(socket_name, scope, target)¶
Resolve the target object and scope for option operations.
- Parameters:
- Return type:
-
libtmux_mcp.tools.option_tools.show_option(option, scope=None, target=None, global_=False, socket_name=None)¶libtmux_mcp.tools.option_tools.show_option(option, scope=None, target=None, global_=False, socket_name=None)¶
Show a tmux option value.
Use to check tmux configuration values such as history-limit, mouse support, or status bar settings.
- Parameters:
option (
str) – The tmux option name to query.scope (
str,optional) – Option scope.target (
str,optional) – Target identifier. For session scope: session name (e.g. ‘mysession’). For window scope: window ID (e.g. ‘@1’). For pane scope: pane ID (e.g. ‘%1’). Requires scope.global (
bool) – Whether to query the global option.socket_name (
str,optional) – tmux socket name.global_ (
bool)
- Returns:
Option name and its value.
- Return type:
-
libtmux_mcp.tools.option_tools.set_option(option, value, scope=None, target=None, global_=False, socket_name=None)¶libtmux_mcp.tools.option_tools.set_option(option, value, scope=None, target=None, global_=False, socket_name=None)¶
Set a tmux option value.
Use to change tmux behavior at runtime. Common uses: adjusting history-limit, enabling mouse support, changing status bar format.
- Parameters:
option (
str) – The tmux option name to set.value (
str) – The value to set.scope (
str,optional) – Option scope.target (
str,optional) – Target identifier. For session scope: session name (e.g. ‘mysession’). For window scope: window ID (e.g. ‘@1’). For pane scope: pane ID (e.g. ‘%1’). Requires scope.global (
bool) – Whether to set the global option.socket_name (
str,optional) – tmux socket name.global_ (
bool)
- Returns:
Confirmation with option name, value, and status.
- Return type:
Environment tools¶
MCP tools for tmux environment variable management.
-
libtmux_mcp.tools.env_tools.show_environment(session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.env_tools.show_environment(session_name=None, session_id=None, socket_name=None)¶
Show tmux environment variables.
Use to inspect tmux environment variables that affect child processes.
- Parameters:
- Returns:
Environment variable mapping.
- Return type:
-
libtmux_mcp.tools.env_tools.set_environment(name, value, session_name=None, session_id=None, socket_name=None)¶libtmux_mcp.tools.env_tools.set_environment(name, value, session_name=None, session_id=None, socket_name=None)¶
Set a tmux environment variable.
Use to set variables that will be inherited by new panes and windows. Changes do not affect already-running processes.
Warning
Values set here propagate into every shell tmux later spawns in the targeted scope — including panes the user opens manually, not just panes the agent drives. A caller that writes
PATH,LD_PRELOAD, orAWS_*variables can influence future commands the human user types directly. Treat this as elevated-risk within themutatingsafety tier. The audit log redacts thevalueargument, but the side effects persist on disk/memory until tmux is restarted. Preferenv VAR=value commandviasend_keys()when you only need the override for a single command. See Safety tiers.- Parameters:
- Returns:
Confirmation with variable name, value, and status.
- Return type: