Skip to main content
Glama

Project BareMetal-Tmux

A decoupled, stateful, interactive MCP (Model Context Protocol) Tmux tool. It exposes a persistent host tmux session to MCP clients — GitHub Copilot CLI, ForgeCode, VS Code — over the stdio transport. No containers, no network: raw JSON-RPC text streams straight into bare-metal shell execution.

Interactive terminal state survives agent crashes, context compaction reloads, and framework restarts, because the shell lives in a detached tmux session (local_agent_workspace) owned by the host — not by the agent process.

Architecture

Upstream Client (Copilot CLI / ForgeCode / VS Code)
  │  spawns subprocess, speaks JSON-RPC over stdio
  ▼
Local MCP Server  (server.py — Python 3.11+, fastmcp)
  │  validates schemas, applies SR-01 safety checks, strips ANSI
  ▼
Host OS Shell  (persistent detached tmux session, 20k-line scrollback)

Related MCP server: Ryan's Tmux MCP Server

MCP Tools

Tool

Arguments

Purpose

execute_command

command: str, wait_s: float = 0

Dispatch a literal shell command into the persistent pane, followed by a carriage return (C-m). Fire-and-forget by default; pass wait_s > 0 (capped at 30) to sleep then return the trailing buffer in the same call.

read_terminal_buffer

lines: int = 100 (max 20000)

Capture trailing scrollback from the pane, with ANSI/OSC/control sequences stripped so payloads always encode cleanly into JSON-RPC.

send_control_signal

signal: str = "SIGINT"

Send SIGINT (Ctrl+C), SIGTSTP, SIGQUIT, or EOF to break blocking processes without killing the harness.

The session is created lazily on first tool invocation (FR-01) with a 20,000-line history limit.

Safety Guardrails (SR-01)

Execution is un-sandboxed on the host, so the server refuses destructive commands before they reach the tmux buffer:

  • Recursive rm aimed at / or top-level system roots (/usr, /etc, …), including sudo-wrapped and &&/;-chained variants

  • --no-preserve-root, mkfs.*, dd of=/dev/..., redirects onto block devices, fork-bomb signatures

Workspace-scoped destruction (e.g. rm -rf ./build, /tmp/...) passes through.

Requirements

  • Windows host: WSL distro Ubuntu-24.04 with tmux installed (the server runs inside WSL; clients launch it via wsl.exe)

  • Linux/macOS host: just tmux on PATH — drop the wsl.exe wrapper and run uv run python server.py directly

  • uv (installed user-locally, e.g. curl -LsSf https://astral.sh/uv/install.sh | sh)

  • Python ≥ 3.11 (resolved by uv)

Setup

Dependencies are isolated in a uv-managed venv. On WSL, keep the venv on ext4 (not /mnt/c) for speed:

cd /mnt/c/Users/troll/Python/tmux-harness
export UV_PROJECT_ENVIRONMENT="$HOME/.venvs/tmux-harness"
uv sync

Run the smoke test (28 checks: ANSI stripping, SR-01 guardrails, live tmux round-trips against a throwaway session):

TMUX=harness_smoke_test uv run python tests/smoke_test.py

Client Integration

GitHub Copilot CLI

Two options:

  1. Custom agent (recommended).github/agents/tmux.agent.md is a self-contained agent profile: it defines the MCP server in its frontmatter and allowlists only the three harness tools (no shell, no file edits, no web). Use it with:

    /agent                          # pick "tmux" interactively
    copilot --agent=tmux -p "run the test suite and watch for failures"
  2. Global MCP server — merge mcp-config.copilot.json into ~/.copilot/mcp-config.json to expose the harness tools in every session (all built-in tools remain available).

ForgeCode

.mcp.json sits at the project root and is picked up automatically when ForgeCode runs from this directory.

VS Code

Add the same server block from .mcp.json to .vscode/mcp.json.

Configuration

Variable

Default

Effect

TMUX

local_agent_workspace

Name of the persistent tmux session

UV_PROJECT_ENVIRONMENT

.venv in project

Venv location (keep on ext4 under WSL)

Project Layout

server.py                     MCP server (tools, SR-01 checks, ANSI stripping)
pyproject.toml                uv project: mcp[cli] + fastmcp
tests/smoke_test.py           28-check verification suite
.github/agents/tmux.agent.md  Copilot CLI custom agent (harness tools only)
mcp-config.copilot.json       Copilot CLI global MCP config
.mcp.json                     ForgeCode project-root MCP config

Available Tools

3 tools
execute_commandA

Dispatch a raw shell command string into the persistent background workspace pane (FR-02). The text is sent literally, then a carriage return (C-m) is appended to ensure statement completion.

By default output is NOT returned — poll read_terminal_buffer to observe
results. Pass wait_s > 0 to sleep that many seconds (capped at 30.0)
after dispatch and get the trailing buffer back in the same call —
ideal for quick commands. Long jobs should still dispatch, then poll.
ParametersJSON Schema
NameRequiredDescriptionDefault
wait_sNo
commandYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description fully carries the burden. It discloses that output is not returned by default, carriage return appended, wait_s capped at 30s, and the persistent pane. It doesn't mention destructiveness but shell commands inherently imply that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured but slightly verbose. Each sentence adds value: purpose, mechanics, default behavior, and alternatives. Could be trimmed slightly but still clear.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 2 parameters, no annotations, and an output schema (not shown), the description covers behavior, usage patterns, and alternatives. It references the workspace pane and provides complete guidance for using the tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description must compensate. It explains command is sent literally with carriage return, and wait_s allows sleeping and returning trailing buffer, adding meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'Dispatch a raw shell command string into the persistent background workspace pane (FR-02)', using a specific verb and resource. It distinguishes from siblings like read_terminal_buffer (for reading output) and send_control_signal (for signals).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use wait_s (>0 for quick commands) and when to poll (long jobs). It names the alternative tool read_terminal_buffer for observing results, giving clear usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_terminal_bufferA

Capture trailing scrollback from the active tmux pane (FR-03).

Hard-wrapped rows are joined and trailing blank viewport padding is
trimmed before the payload is returned.

Args:
    lines: Number of trailing scrollback lines to capture (default 100,
        max 20000).
ParametersJSON Schema
NameRequiredDescriptionDefault
linesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that hard-wrapped rows are joined, trailing blank viewport padding is trimmed, and the 'lines' parameter has default 100 and max 20000. It lacks statements about auth or rate limits, but as a read operation, the behavior is well-covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very concise: one sentence for purpose, one paragraph for processing details. Every sentence adds value, and it avoids redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one optional parameter, output schema present), the description is fully complete. It covers purpose, processing, parameter meaning, and bounds. No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description adds significant meaning: it explains that 'lines' is the number of trailing scrollback lines to capture, with default 100 and max 20000. This compensates for the schema's minimal information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'capture' and resource 'trailing scrollback from the active tmux pane', clearly distinguishing it from siblings like execute_command and send_control_signal. It also details processing steps (joining rows, trimming padding) for precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool vs alternatives, but the context of siblings (execute_command, send_control_signal) makes usage implied. No explicit when-not or alternatives are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_control_signalA

Issue a control signal keystroke to the persistent pane (FR-04), e.g. SIGINT (Ctrl+C) to break out of a blocking process without killing the harness. Supported: SIGINT, SIGTSTP, SIGQUIT, EOF.

ParametersJSON Schema
NameRequiredDescriptionDefault
signalNoSIGINT

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description solely handles transparency. It lists supported signals and notes that SIGINT avoids killing the harness, but does not disclose that SIGQUIT may cause a core dump or other potential side effects. The description is missing behavioral details like authentication needs or error handling, earning a 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no superfluous words. The first sentence states the action, and the second lists supported signals. The description is perfectly front-loaded and efficiently uses space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool, the description covers the essential aspects: what it does, when to use it, and supported values. It references 'persistent pane (FR-04)' which may be assumed context. An output schema exists, so return values are not required. Minor gaps (e.g., error handling) prevent a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has only one parameter with no description (0% coverage). The description adds value by listing supported signal values and explaining their effects (e.g., Ctrl+C for SIGINT). This compensates for the schema gap, though it could include an explicit allowed values list.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly specifies the action ('issue a control signal keystroke'), the target ('persistent pane (FR-04)'), and provides concrete examples. It distinguishes itself from siblings (execute_command, read_terminal_buffer) by focusing on sending signals rather than executing commands or reading output.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case 'break out of a blocking process without killing the harness', implying when to use it. However, it does not explicitly contrast with alternatives or state when not to use it, but the context with sibling tools makes the distinction clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 3 tool updatesv0.1.0
    • First observedexecute_command
    • First observedread_terminal_buffer
    • First observedsend_control_signal

TDQS

A4.4/5.0
Disambiguation5/5

Each tool addresses a distinct action: sending commands, reading output, and sending control signals. There is no overlap in functionality.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (execute_command, read_terminal_buffer, send_control_signal), with no deviations.

Tool Count5/5

Three tools cover the essential interactions with a tmux pane (write, read, signal). This is well-scoped for a minimal but functional MCP server.

Completeness4/5

The tools cover the core workflow of dispatching commands and retrieving output. Missing operations like pane management or clearing the buffer are minor gaps given the focused scope.

Maintenance

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    MCP server for SSH and local terminal access. Supports interactive commands, long-running processes, and TUI apps like tmux/zellij
    6
    3
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    A comprehensive MCP server for driving tmux sessions, windows, panes, sending keystrokes, and reading pane output locally or over SSH, enabling real-time collaborative pairing with AI.
    71
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/trolleydodger1988/tmux-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server