Core LibraryGuides

Choose documentation 2

latest

Current version

latest
English

Prerelease This site documents an alpha of libtmux. Its structure, URLs and APIs are subject to change.

Using the .NET MCP server

Use the separate LibTmux.Mcp .NET tool to let an MCP client inspect panes, wait for output and run commands in tmux. It uses the same .NET library as libtmux for PowerShell. It does not import the PowerShell modules or require a PowerShell launcher.

Install and select a server

Install the published alpha.20 tool on the Unix host running tmux:

Terminal window
$ dotnet tool install LibTmux.Mcp \
--tool-path build/mcp \
--version 0.0.0-alpha.20 \
--framework net8.0

For shared .NET source changes, use the optional MCP development setup. A desktop-launched client may need DOTNET_ROOT in its server environment when .NET comes from a version manager.

For clients using an mcpServers configuration, replace these absolute paths with the installed tool, tmux executable and an existing server socket:

{
"mcpServers": {
"tmux": {
"command": "/absolute/tool-directory/libtmux-mcp",
"env": {
"LIBTMUX_TMUX": "/absolute/path/to/tmux",
"LIBTMUX_SOCKET_PATH": "/absolute/path/to/tmux/socket",
"LIBTMUX_TOOLSETS": "inspect"
}
}
}
}

Other clients use different configuration formats; see the .NET MCP client setup. Launch the executable directly: standard input and output carry MCP messages.

Use LIBTMUX_SOCKET for a socket name or LIBTMUX_SOCKET_PATH for an absolute path. Set only one, including inherited environment variables. The choice is fixed at startup; calls cannot switch sockets. Shut down the client connection when finished. The server leaves a borrowed tmux daemon running.

Discover before calling

After initialization, read the server instructions, call tools/list, and read tmux://capabilities. The resource identifies the selected socket, effective tools and observation policy. Tool discovery supplies schemas, descriptions and annotations. Each advertised tool also carries its capability row in _meta["com.git-pull.libtmux-mcp/capability"].

The example selects inspect. Add manage, execute or teardown only for the operations your client needs, then restart it to change the selection. Toolsets shape the interface; they are not an authorization boundary. Commands execute with the tmux user’s authority.

TaskStart with
Find a session, window or panelist_sessions, list_windows, list_panes
Read terminal textcapture_pane; snapshot_pane for structured state
Find text across panessearch_panes
Wait for text that has not appearedwait_for_text with a finite timeout
Read changes across later callscapture_since, retaining its returned cursor
Run your own command and observe its completionrun_shell_command from the execute toolset
Combine independent reads in one requestcall_read_tools_batch; its operations run serially

Input acknowledgement does not prove a shell command finished. Use the completion result of run_shell_command for a command you start; cancellation or timeout can leave that command running in its pane. For a program already running, wait for its output rather than repeatedly capturing the screen.

run_shell_command uses a cooperative completion channel and also probes authenticated run status and pane liveness, starting after 250 ms and backing off to five seconds. This run watchdog is separate from pane text observation and its optional polling fallback.

Pane text waits require control observation by default in alpha.20. Explicitly enabling LIBTMUX_MCP_ALLOW_POLLING_FALLBACK=true allows repeated captures if control observation fails; capabilities disclose the policy and affected results report pollingFallback. Give text waits a finite timeout; the server bounds their returned tail. For captures, select maxLines. Inspect eventsDropped and truncation fields before treating observed output as complete.

A capture_since cursor tracks observation between calls; it is not a background job. Progress notifications and optional MCP Tasks are separate protocol features, available only where the discovered tool declares them. Read the installed server’s schemas and capability rows for those contracts.

Inspect a pane and wait for readiness

After discovery, select a session from list_sessions. These are tools/call parameter objects: replace $0 and %0 with IDs returned by your server. The inspect toolset includes all three calls.

List the selected session’s panes:

{
"name": "list_panes",
"arguments": { "session": "$0" }
}

The response’s structuredContent.result contains pane records with paneId, windowId, sessionId, dimensions and the current command. Select one pane and read its rendered screen:

{
"name": "capture_pane",
"arguments": { "paneId": "%0", "maxLines": 64 }
}

For this object result, read structuredContent.content.lines directly. content.truncated, content.droppedLines and content.droppedBytes disclose output omitted to fit the budget. A list result has the result wrapper; object results do not. Check isError before interpreting either shape.

If the application prints Service ready, wait for that whole line:

{
"name": "wait_for_text",
"arguments": {
"paneId": "%0",
"patterns": ["^Service ready$"],
"timeoutSeconds": 1,
"ignoreCase": false
}
}

An existing line returns structuredContent.outcome = "PresentAtEntry"; a later line returns "Matched". matchedPattern identifies the condition, and tail contains bounded rendered text. Stop-pattern, timeout and pane-death outcomes remain distinct. A ready-line match is an application-specific condition; it does not establish shell exit status or continuing health.

The official SDK client reads these three request examples, substitutes discovered IDs and executes them against an installed tool. Its owned fixture prints the ready line before the calls, then checks capture, PresentAtEntry, an untruncated tail, no polling or event drops, stdio shutdown and preservation of the borrowed tmux state.

Use a finite server timeout even when your client can cancel. With the pinned SDK 2.2.0, cancelling a local token does not reliably send notifications/cancelled; it can leave the remote wait running until its timeout. A client that knows its request ID can explicitly send that notification. For negotiated MCP Tasks, cancel the task with tasks/cancel using its returned task ID. Neither cancellation stops the application in the pane. Task records are temporary and disappear on expiry or restart.

Check the client workflow from this checkout

After building the discovery probe, set MCP_COMMAND to the installed executable’s absolute path and MCP_VERSION to its exact version. Select the desired tmux on PATH, then run:

Terminal window
$ pwsh -NoLogo -NoProfile -File eng/Test.ps1 \
-Suite Mcp \
-McpCommand "$MCP_COMMAND" \
-McpVersion "$MCP_VERSION"

The official SDK client source initializes the installed tool, compares discovery with capabilities, then executes list_sessions and the three request examples above. The suite checks that the session and pane survive MCP shutdown, then removes the owned fixture. It neither imports the PowerShell modules nor builds, installs or downloads anything during the test. Broader task, cancellation, loss and concurrent-wait acceptance belongs to the .NET protocol suite.

Esc

Type to search.

Reference preview Open reference