PowerShellHome

Choose documentation 2

latest

Current version

latest
English

Early release libtmux is released, and its APIs may still change between releases. This site's structure and URLs may change too.

libtmux for PowerShell

PowerShell-based tmux client

tmux client library for PowerShell. Control tmux, connect to and create servers, navigate sessions, windows, and panes, send keys, watch for changes via control mode, capture pane contents

Product

Start with PowerShell

Example details
$ErrorActionPreference = 'Stop'
Import-Module "$PSScriptRoot/modules/LibTmux/0.1.0/LibTmux.psd1"
$socket = 'libtmux-home-' + [Guid]::NewGuid().ToString('N')
$server = New-TmuxServer -SocketName $socket -ConfigurationFile /dev/null
$session = $server | New-TmuxSession `
-Name demo -WindowName editor -Command 'exec /bin/cat'
$pane = $session | Get-TmuxPane
$null = $pane | Split-TmuxPane -Horizontal -Command 'exec /bin/cat'
$null = $session | New-TmuxWindow -Name logs -Command 'exec /bin/cat'
$captured = ($server | Get-TmuxSnapshot).Sessions |
Select-TmuxSession -Criteria @{ Name = 'demo' } -ExactlyOne
foreach ($window in $captured.Windows) {
'{0}: {1}' -f $window.Name, ($window.Panes.Id -join ', ')
}
$ErrorActionPreference = 'Stop'
Import-Module "$PSScriptRoot/modules/LibTmux/0.1.0/LibTmux.psd1"
try {
$socket = 'libtmux-home-' + [Guid]::NewGuid().ToString('N')
$server = New-TmuxServer -SocketName $socket -ConfigurationFile /dev/null
$session = $server | New-TmuxSession `
-Name demo -WindowName editor -Command 'exec /bin/cat'
$pane = $session | Get-TmuxPane
$null = $pane | Split-TmuxPane -Horizontal -Command 'exec /bin/cat'
$null = $session | New-TmuxWindow -Name logs -Command 'exec /bin/cat'
$captured = ($server | Get-TmuxSnapshot).Sessions |
Select-TmuxSession -Criteria @{ Name = 'demo' } -ExactlyOne
foreach ($window in $captured.Windows) {
'{0}: {1}' -f $window.Name, ($window.Panes.Id -join ', ')
}
} catch {
$failure = [InvalidOperationException]::new(
"tmux quickstart failed: $($_.Exception.Message)", $_.Exception)
throw $failure
}
$ErrorActionPreference = 'Stop'
Import-Module "$PSScriptRoot/modules/LibTmux/0.1.0/LibTmux.psd1"
$session = $null
$failure = $null
try {
$socket = 'libtmux-home-' + [Guid]::NewGuid().ToString('N')
$server = New-TmuxServer -SocketName $socket -ConfigurationFile /dev/null
$session = $server | New-TmuxSession `
-Name demo -WindowName editor -Command 'exec /bin/cat'
$pane = $session | Get-TmuxPane
$null = $pane | Split-TmuxPane -Horizontal -Command 'exec /bin/cat'
$null = $session | New-TmuxWindow -Name logs -Command 'exec /bin/cat'
$captured = ($server | Get-TmuxSnapshot).Sessions |
Select-TmuxSession -Criteria @{ Name = 'demo' } -ExactlyOne
foreach ($window in $captured.Windows) {
'{0}: {1}' -f $window.Name, ($window.Panes.Id -join ', ')
}
} catch {
$failure = $_.Exception
throw
} finally {
if ($session) {
$cleanupErrors = @()
$session | Remove-TmuxSession -Confirm:$false `
-ErrorAction SilentlyContinue -ErrorVariable cleanupErrors
if ($cleanupErrors) {
if ($failure) {
$errors = @($failure) + $cleanupErrors.Exception
throw [AggregateException]::new(
'tmux operation and cleanup failed.',
[Exception[]]$errors)
}
throw $cleanupErrors[0]
}
}
}
$ErrorActionPreference = 'Stop'
Import-Module "$PSScriptRoot/modules/LibTmux/0.1.0/LibTmux.psd1"
$session = $null
$failure = $null
try {
$socket = 'libtmux-home-' + [Guid]::NewGuid().ToString('N')
$server = New-TmuxServer -SocketName $socket -ConfigurationFile /dev/null
$session = $server | New-TmuxSession `
-Name demo -WindowName editor -Command 'exec /bin/cat'
$pane = $session | Get-TmuxPane
$null = $pane | Split-TmuxPane -Horizontal -Command 'exec /bin/cat'
$null = $session | New-TmuxWindow -Name logs -Command 'exec /bin/cat'
$captured = ($server | Get-TmuxSnapshot).Sessions |
Select-TmuxSession -Criteria @{ Name = 'demo' } -ExactlyOne
foreach ($window in $captured.Windows) {
'{0}: {1}' -f $window.Name, ($window.Panes.Id -join ', ')
}
} catch {
$failure = [InvalidOperationException]::new(
"tmux quickstart failed: $($_.Exception.Message)", $_.Exception)
throw $failure
} finally {
if ($session) {
$cleanupErrors = @()
$session | Remove-TmuxSession -Confirm:$false `
-ErrorAction SilentlyContinue -ErrorVariable cleanupErrors
if ($cleanupErrors) {
if ($failure) {
$errors = @($failure) + $cleanupErrors.Exception
throw [AggregateException]::new(
'tmux operation and cleanup failed.',
[Exception[]]$errors)
}
throw $cleanupErrors[0]
}
}
}
Run this example

PowerShell 7.4.20 with PSResourceGet 1.1.1, POSIX shell and tmux on Linux.

Save the program above as quickstart.ps1 in a new directory, along with the files below.

Cleanup is omitted; the private tmux server and its temporary files may remain. Select Cleanup to remove them when the program finishes. The program stops its private tmux server and removes any temporary files it created when it finishes. Error handling adds diagnostics; every version checks required results and deadlines.

Setup and run

pwsh -NoLogo -NoProfile -Command '
$ErrorActionPreference = "Stop"
$null = New-Item -ItemType Directory -Path ./modules -Force
Save-PSResource -Name LibTmux -Version 0.1.0 `
-Path ./modules -TrustRepository
'
unset TMUX TMUX_PANE
export ENV=/dev/null BASH_ENV=/dev/null SHELL=/bin/sh
pwsh -NoLogo -NoProfile -File quickstart.ps1

Expected output

editor: %0, %1
logs: %2

Library revision: 2c30121b7733.

Core Library documentation →More PowerShell examples →

Install LibTmux

Install-Module -Name LibTmux

Requires PowerShell 7.4 or later and tmux on the same Unix host.

Install-PSResource -Name LibTmux

Requires PowerShell 7.4 or later and tmux on the same Unix host.

MCP

PowerShell has no MCP package of its own. It uses the C# port's LibTmux.Mcp.

The C# server lets an agent work with tmux through 45 tools, grouped as Inspect, Manage, Execute and Teardown.

Install LibTmux.Mcp

Choose your client and configuration scope, then run the command or paste the configuration.

$ claude mcp add tmux -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.claude.json (this project)

$ claude mcp add tmux --scope user -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.claude.json (all projects)

$ claude mcp add tmux --scope project -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: .mcp.json (in repo, version-controlled)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ claude mcp add tmux -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.claude.json (this project)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ claude mcp add tmux --scope user -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.claude.json (all projects)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ claude mcp add tmux --scope project -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: .mcp.json (in repo, version-controlled)

{
    "mcpServers": {
        "tmux": {
            "command": "dnx",
            "args": ["LibTmux.Mcp", "--yes"]
        }
    }
}

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: claude_desktop_config.json

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then use this config:

{
    "mcpServers": {
        "tmux": {
            "command": "libtmux-mcp"
        }
    }
}

Installs the `libtmux-mcp` tool from NuGet.

Config file: claude_desktop_config.json

$ codex mcp add tmux -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.codex/config.toml

Codex's CLI doesn't support project scope yet — paste this into .codex/config.toml at the repo root.

[mcp_servers.tmux]
command = "dnx"
args = ["LibTmux.Mcp", "--yes"]

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: .codex/config.toml (in repo)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ codex mcp add tmux -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.codex/config.toml

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

Codex's CLI doesn't support project scope yet — paste this into .codex/config.toml at the repo root.

[mcp_servers.tmux]
command = "libtmux-mcp"

Installs the `libtmux-mcp` tool from NuGet.

Config file: .codex/config.toml (in repo)

$ gemini mcp add --scope user tmux dnx -- LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.gemini/settings.json

$ gemini mcp add --scope project tmux dnx -- LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: .gemini/settings.json (in repo)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ gemini mcp add --scope user tmux libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.gemini/settings.json

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ gemini mcp add --scope project tmux libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: .gemini/settings.json (in repo)

{
    "mcpServers": {
        "tmux": {
            "command": "dnx",
            "args": ["LibTmux.Mcp", "--yes"]
        }
    }
}

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: .cursor/mcp.json (in repo)

{
    "mcpServers": {
        "tmux": {
            "command": "dnx",
            "args": ["LibTmux.Mcp", "--yes"]
        }
    }
}

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.cursor/mcp.json

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then use this config:

{
    "mcpServers": {
        "tmux": {
            "command": "libtmux-mcp"
        }
    }
}

Installs the `libtmux-mcp` tool from NuGet.

Config file: .cursor/mcp.json (in repo)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then use this config:

{
    "mcpServers": {
        "tmux": {
            "command": "libtmux-mcp"
        }
    }
}

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.cursor/mcp.json

$ grok mcp add --scope user tmux -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.grok/config.toml

$ grok mcp add --scope project tmux -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ./.grok/config.toml (in repo)

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ grok mcp add --scope user tmux -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.grok/config.toml

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ grok mcp add --scope project tmux -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ./.grok/config.toml (in repo)

{
    "mcpServers": {
        "tmux": {
            "command": "dnx",
            "args": ["LibTmux.Mcp", "--yes"]
        }
    }
}

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.gemini/config/mcp_config.json

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then use this config:

{
    "mcpServers": {
        "tmux": {
            "command": "libtmux-mcp"
        }
    }
}

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.gemini/config/mcp_config.json

$ opencode mcp add tmux -- dnx LibTmux.Mcp --yes

Runs the server from NuGet without installing it; needs the .NET 10 SDK. Write LibTmux.Mcp@<version> to pin a version.

Config file: ~/.config/opencode/opencode.jsonc

Build or install the server first:

$ dotnet tool install --global LibTmux.Mcp

Then register:

$ opencode mcp add tmux -- libtmux-mcp

Installs the `libtmux-mcp` tool from NuGet.

Config file: ~/.config/opencode/opencode.jsonc

Embed the server in a program
examples/LibTmux.Examples/Snippets/Mcp.cs
Dictionary<string, string?> environment =
StdioClientTransportOptions.GetDefaultEnvironmentVariables();
environment["LIBTMUX_SOCKET"] = server.ConnectionOptions.SocketName;
environment["TMUX_TMPDIR"] = Environment.GetEnvironmentVariable("TMUX_TMPDIR");
environment["DOTNET_ROOT"] = Environment.GetEnvironmentVariable("DOTNET_ROOT");
environment["LIBTMUX_TOOLSETS"] = "inspect,manage,execute";
environment["LIBTMUX_EXCLUDE_TOOLS"] = "run_shell_command";
var transport = new StdioClientTransport(new StdioClientTransportOptions
{
Name = "tmux",
Command = Environment.GetEnvironmentVariable("LIBTMUX_MCP_COMMAND")
?? "libtmux-mcp",
InheritEnvironmentVariables = false,
EnvironmentVariables = environment,
});
McpClient client = await McpClient.CreateAsync(
transport,
cancellationToken: ct);

Excerpt of examples/LibTmux.Examples/Snippets/Mcp.cs, which dotnet test --project tests/LibTmux.ExampleTests/LibTmux.ExampleTests.csproj runs in the repository's CI (.github/workflows/dotnet.yml).

Workspace Manager

Main-horizontal layout

The main-horizontal layout gives the first pane the top of the window and splits the rest below it.

session_name: test window options
start_directory: '~'
windows:
- layout: main-horizontal
options:
main-pane-height: 5
panes:
- pane
- pane
- pane
window_name: editor
{
"session_name": "test window options",
"start_directory": "~",
"windows": [
{
"layout": "main-horizontal",
"options": {
"main-pane-height": 5
},
"panes": [
"pane",
"pane",
"pane"
],
"window_name": "editor"
}
]
}

Converted from the YAML; the tests load the YAML.

0:editor
Window 0, editor: 3 panes, main-horizontal
layout main-horizontal

Workspace file: tests/fixtures/workspace/tmuxp-v1.74.0-window_options.yaml. Tested by window options fixture (tests/WorkspaceCorpus.Tests.ps1; a test runs the command).

Install LibTmux.Workspace

The workspace package is separate from the core library.

Install-Module -Name LibTmux.Workspace

Installs the matching LibTmux core dependency. Run PowerShell and tmux on the same Unix host.

Install-PSResource -Name LibTmux.Workspace

Installs the matching LibTmux core dependency. Run PowerShell and tmux on the same Unix host.

Build the workspace from a program
examples/Guides.ps1
$workspace = LibTmux.Workspace\Import-TmuxWorkspace -Yaml @'
session_name: readme-workspace-preview
windows:
- window_name: editor
panes:
- shell_command: exec /bin/sh
- shell_command: exec /bin/sh
'@

Excerpt of examples/Guides.ps1, which eng/Test.ps1 -Suite Documentation runs in the repository's CI (.github/workflows/ci.yml).

Packages and integrations

API references

All PowerShell versions and install instructions

Esc

Type to search.

Reference previewOpen reference