mcp-ssh-tmux
Manages SSH sessions through a persistent tmux multiplexer, enabling AI agents to execute commands, read/write files, and monitor terminal output on remote hosts.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-ssh-tmuxopen session to myserver.com and run ls -la"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-ssh-tmux
A high-performance, persistent Model Context Protocol (MCP) server that manages SSH sessions via a local tmux instance.
Why this exists?
Traditional SSH automation runs individual commands without state tracking between executions. Other implementations rely on complex regex patterns to detect command completion. By using tmux as a persistent terminal multiplexer, this project eliminates that complexity entirely. The AI agent simply "looks" at the screen like a human would - the server provides visual snapshots, and the agent interprets prompts, errors, and output naturally.
Related MCP server: mcp-ssh-interactive
Key Features
Persistence: SSH connections stay alive in
tmuxeven if the MCP server or your AI client restarts.Observability: You can manually run
tmux attach -t mcp-sshto see exactly what the agent is doing in real-time.Reliability: Uses
ssh -Gfor robust config resolution (handles aliases, identity files, etc.).Safety: Built-in command validation to prevent common dangerous operations.
File Transfer: Native tools for reading and writing remote files. Reads prefer a full-file SSH transfer and fall back to the existing PTY when needed.
Installation
Requirements
tmux must be installed on your system
Ubuntu/Debian:
apt install tmuxmacOS:
brew install tmuxArch:
pacman -S tmux
Via uv (Recommended)
uv tool install mcp-ssh-tmuxVia pip
pip install mcp-ssh-tmuxConfiguration
Add this to your mcp.json (e.g., in Claude Desktop, Cursor, or 1mcp):
{
"mcpServers": {
"ssh-tmux": {
"command": "uv",
"args": [
"run",
"mcp-ssh-tmux"
]
}
}
}Note: If you installed via uv tool install, you can just use mcp-ssh-tmux as the command.
Tools
open_session(host, username, port): Opens a new SSH connection in a unique tmux window.send_command(session_id, command, lines, timeout): Sends a command and polls for a prompt/output. Returns only the lastlinesof terminal output/scrollback.timeout(default 2.0s) controls how long to wait — increase for slower commands like package installs.send_keys(session_id, keys): Sends raw keystrokes without Enter. Use for Ctrl+C, Ctrl+D, interactive input, etc.get_snapshot(session_id, lines): Captures the current screen state. Returns only the lastlinesof terminal output/scrollback.read_remote_file(session_id, remote_path, fallback_lines): Reads a remote text file. Prefer this overcatviasend_command()when you need the full file contents.fallback_linescontrols bounded tmux-history capture if direct SSH read is unavailable.write_remote_file(session_id, remote_path, content, append): Writes content to a remote file.list_sessions(): Lists all active SSH windows.cleanup_dead_sessions(max_age_seconds): Kills all windows where the SSH connection has closed. Optionally filters by how long the session has been dead.close_session(session_id): Kills the window and cleans up. WARNING: This terminates any running processes in the session. For long-running tasks, leave the session open and monitor withget_snapshot().
Transport Modes
By default, the server uses stdio for communication with MCP clients. You can switch to the modern Streamable HTTP transport using environment variables:
# Start server in HTTP mode on port 8080
FASTMCP_TRANSPORT=http FASTMCP_PORT=8080 mcp-ssh-tmuxThe server will be available at http://localhost:8080/mcp.
Important Notes
Automatic Cleanup
Background Reaper: The server automatically cleans up sessions that have been dead (disconnected) for more than 24 hours.
Manual Cleanup: Use
cleanup_dead_sessions()to manually clear disconnected sessions at any time.
Reading Files
Use
read_remote_file()for file contents:send_command("cat ...")andget_snapshot()are screen/snapshot tools, so they only return the tail of terminal output.linescontrols snapshot depth: Increaselinesonsend_command()orget_snapshot()when you need more terminal history, but useread_remote_file()for actual file reads.fallback_linescontrols PTY fallback depth: If direct SSH file read is unavailable,read_remote_file()inspects only the lastfallback_linesof tmux history. Increase it when needed, but keep it bounded.Best for text files:
read_remote_file()is intended for configs, source, logs, and similar text content.
Session Management
Do not close sessions with active processes: Closing a session terminates all running commands (builds, downloads, etc.)
Monitor long-running tasks: Use
get_snapshot()to check progress without closing the sessionSessions persist: SSH connections remain alive in tmux even if the MCP server restarts
Manual inspection: Run
tmux attach -t mcp-sshto see what's happening in real-time
Acknowledgments
Built with FastMCP and libtmux.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Star History
If you find this project useful, please consider giving it a star! ⭐
License
MIT
Available Tools
9 toolscleanup_dead_sessionsA
Kill all sessions where the SSH connection has closed.
Args: max_age_seconds: Optional. Only kill sessions that have been dead for at least this many seconds. If omitted, all dead sessions are killed immediately.
| Name | Required | Description | Default |
|---|---|---|---|
| max_age_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of disclosing behavior. It clearly states that the operation kills sessions, defines the target as 'dead' sessions, and explains the optional age threshold and the immediate kill behavior when omitted. It does not discuss reversibility or side effects beyond killing dead sessions, but for this simple destructive cleanup tool, the core behavioral traits are adequately disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long and front-loaded with the primary action and condition. The parameter documentation is tight and directly explains both the optional flag and its default behavior. Every sentence earns its place with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one optional parameter and an output schema exists, so the description need not explain return values. It covers the action, target condition, and parameter semantics. However, it could slightly benefit from noting whether any sessions are affected if none are dead or if it ever touches active sessions, but the 'dead' condition implicitly covers this, making the description functionally complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only defines max_age_seconds as an optional integer/null with a default of null, providing no semantic meaning. The description adds full meaning: it specifies that the parameter filters sessions by how long they have been dead, and explicitly states the behavior when omitted ('all dead sessions are killed immediately'). This fully compensates for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Kill all sessions') and the specific condition ('where the SSH connection has closed'), making the scope explicit. It distinguishes itself from siblings like close_session (single session) and list_sessions (listing only) by targeting only dead sessions for bulk cleanup.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage context is implied by the description: run this when you want to clean up sessions whose SSH connections have closed. However, it does not explicitly mention alternatives or when not to use it, such as preferring close_session for individual active sessions, so guidance is only implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
close_sessionA
Close an active SSH session and return its final screen state.
WARNING: Closing a session will terminate any running processes in that session. For long-running tasks (builds, downloads, etc.), leave the session open until the task completes. You can monitor progress using get_snapshot() without closing.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral disclosure. It warns that closing terminates running processes and highlights the destructive consequence. It also reveals the return value ('final screen state'), which is not otherwise specified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief and front-loaded with purpose, followed by a clear warning and guidance. Every sentence adds value; no filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter destructive tool with an output schema, the description is complete: it states the action, the consequence, the alternative, and the return value. The agent has enough to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter session_id is self-explanatory and the description adds context by referring to an 'active SSH session'. However, schema coverage is 0% and the description does not explain where to get session_id or how invalid sessions are handled. Still, for one obvious parameter, this is adequate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Close') and resource ('active SSH session') and states the outcome ('return its final screen state'). This clearly distinguishes it from siblings like open_session, get_snapshot, and cleanup_dead_sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when NOT to use the tool ('For long-running tasks... leave the session open') and names an alternative ('You can monitor progress using get_snapshot()'). This gives the agent direct decision-making guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_snapshotA
Get the current screen state of a session.
Use this to check on long-running commands without sending new input. The response includes [INFO: ...] hints about detected prompts or interactive states.
Args: session_id: The ID of the session (format: user@host-). lines: Number of lines to capture from the end of the screen and tmux scrollback (default 40).
| Name | Required | Description | Default |
|---|---|---|---|
| lines | No | ||
| session_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full transparency burden. It discloses that the response includes '[INFO: ...] hints' and explains the line capture from 'the end of the screen and tmux scrollback.' The phrase 'without sending new input' signals a non-invasive read operation, though it does not explicitly guarantee that no state is modified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is highly concise: one line for purpose, one for usage, one for response behavior, and a compact Args block. Every sentence adds value and there is no redundant or filler content. The structure front-loads the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers purpose, usage, behavioral hints, and parameter details. An output schema exists, so return-value formatting need not be described. It does not address error cases (e.g., invalid session), but this is a minor gap for a read-only snapshot tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero description coverage, but the Args section fully compensates. It defines the required session_id format as 'user@host-<id>' and explains that lines controls 'Number of lines to capture from the end of the screen and tmux scrollback' with a default. This adds meaningful semantics beyond the raw schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with the specific verb+resource combination 'Get the current screen state of a session,' which immediately identifies the tool's function. The added usage note 'check on long-running commands without sending new input' clearly distinguishes it from sibling tools like send_command and send_keys.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use this to check on long-running commands without sending new input.' This provides clear context and implies that it is for monitoring rather than interacting. It does not enumerate exclusions or alternative tools, but the context sufficiently separates it from input-sending siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sessionsA
List all SSH sessions, including dead ones (SSH connection closed but pane not yet cleaned up).
Dead sessions still have their terminal output available via get_snapshot(). Use close_session() to clean them up.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the non-obvious behavior that dead sessions are listed and still have output available, which is valuable. It also implicitly signals a read-only operation by not mentioning any side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no wasted words. The core purpose is in the first sentence, and the second provides essential context about dead sessions. Each sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless list tool with an output schema, the description adequately covers the main functionality and the critical nuance about dead sessions. It also references sibling tools for follow-up actions, making it self-contained within the toolset.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so there is nothing to document. The baseline is 4 for no-parameter tools, and the description appropriately avoids discussing parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'List all SSH sessions.' It explicitly differentiates from siblings by noting it includes dead sessions, which is a key distinction from session manipulation tools like close_session or send_command.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It doesn't explicitly say 'use this when,' but it clearly implies list_sessions is the entry point for inspecting sessions. It provides next-step guidance: dead sessions can be accessed via get_snapshot() and cleaned up using close_session(). This gives context on when to use the tool relative to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_sessionA
Open a new SSH session in a tmux window. Returns the session_id.
The host can be an SSH config alias or a hostname/IP. The session_id will be in the format 'user@host-'. The initial snapshot is included in the response to verify connection success.
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | ||
| port | No | ||
| username | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It adds useful context by noting the session_id format and that the initial snapshot is included for verification. However, it does not disclose potential side effects such as tmux window lifecycle, failure handling, or required permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured. It front-loads the primary action, then supplies necessary details in two short sentences. Every sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main purpose, return value, and connection verification, which is adequate for a straightforward tool. However, it omits details about optional parameters and potential caveats like connection failures or session cleanup. The presence of an output schema reduces the need to describe the response structure, but broader context remains incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for parameter meaning. It explains the 'host' parameter thoroughly (alias or hostname/IP), but provides no explanation for 'port' or 'username', leaving these parameters underspecified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action and resource: 'Open a new SSH session in a tmux window.' It also specifies the return value (session_id) and distinguishes itself from sibling tools that list, close, or send commands to sessions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context by explaining that the host can be an SSH config alias or hostname/IP and that the session_id format follows 'user@host-<id>'. It implies when to use the tool (to establish a new session), though it does not explicitly mention alternatives or exclusion cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_remote_fileA
Read a file from the remote host using the established session.
Prefer this over running 'cat' via send_command/get_snapshot when you want file contents. send_command() and get_snapshot() only return the last N lines of visible terminal output.
read_remote_file() attempts a direct SSH file read first so agents can get the full file
instead of just the pane tail. If that is not possible, it falls back to reading via the
existing PTY. fallback_lines controls how much tmux history to inspect during that PTY
fallback (default 200). Best for text files such as configs, logs, and source code.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | ||
| remote_path | Yes | ||
| fallback_lines | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries behavioral disclosure. It reveals the attempt to do a direct SSH read first, the fallback to PTY, and the role of fallback_lines in tmux history. It also implies a limitation for non-text files, which is useful context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well structured: a clear opening, a rationale contrasting with alternatives, then fallback details and use cases. Every sentence adds value without padding. It is concise enough while conveying all necessary nuance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (so return format needs no explanation) and the tool's functionality is moderately complex, the description covers the core mechanics, the fallback path, the parameter specifics, and the ideal domain. This is sufficiently complete for an agent to invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must add meaning. It explains fallback_lines in detail ('controls how much tmux history to inspect during that PTY fallback (default 200)'). For session_id and remote_path, the names and the opening sentence make their purpose evident, though not spelled out explicitly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource pair: "Read a file from the remote host using the established session." It also distinguishes itself from siblings by explicitly contrasting with send_command/get_snapshot, making the tool's unique purpose clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: "Prefer this over running 'cat' via send_command/get_snapshot when you want file contents," and explains why, because those alternatives only return the last N lines. It also notes the best use case (text files like configs, logs, source code).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_commandA
Send a command to an active session and return the screen snapshot.
This tool automatically polls waiting for the command to complete. The response includes [INFO: ...] hints about detected prompts or interactive input requests.
For long-running commands (builds, downloads, etc.), use get_snapshot() to check progress periodically. Do NOT close the session while processes are running - they will be terminated.
Args: session_id: The ID of the session (format: user@host-). command: The command to send. lines: Number of lines to capture from the end of the screen and tmux scrollback (default 40). timeout: Max seconds to poll for command completion (default 2.0). Increase for slower commands like package installs.
| Name | Required | Description | Default |
|---|---|---|---|
| lines | No | ||
| command | Yes | ||
| timeout | No | ||
| session_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It explains the automatic polling behavior, the inclusion of [INFO] hints, the warning about closing sessions with running processes, and the default timeout behavior. This is substantial context beyond the schema, though it stops short of detailing error handling or failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a one-sentence summary, followed by behavioral details, guidance for long-running commands, a critical warning, and then a clear Args section. Every sentence provides necessary information, and the format makes it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description is remarkably complete. It covers what the tool does, how it behaves (polling, hints), when to use alternatives, parameter semantics, and a safety warning. No critical aspect is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has no descriptions (0% coverage), so the description fully compensates. Each parameter is explained with format (session_id: 'user@host-<id>'), purpose (command), defaults (lines=40, timeout=2.0), and usage guidance (increase timeout for slow installs). This adds significant value over the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Send a command to an active session and return the screen snapshot.' It uses a specific verb and resource, distinguishing it from siblings like send_keys (keyboard input) and get_snapshot (snapshot only). The wording makes the tool's core purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context, including automatic polling and the ability to increase timeout for slower commands. It explicitly recommends get_snapshot() for long-running commands, offering an alternative. It does not explicitly contrast send_command with send_keys, but the command vs. keystroke distinction is inherent in the wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_keysA
Send raw keystrokes to a session without appending Enter.
Use this for:
Interrupting commands: keys="C-c" (Ctrl+C)
Sending EOF: keys="C-d" (Ctrl+D)
Interactive input: keys="yes" (without submitting)
Special keys: keys="Enter", keys="Tab", keys="BSpace"
Tmux key notation: C-x (Ctrl), M-x (Alt), S-x (Shift). Multiple keys: "C-c Enter" After sending keys, use get_snapshot() to see the result.
Args: session_id: The ID of the session (format: user@host-). keys: Keys to send using tmux notation.
| Name | Required | Description | Default |
|---|---|---|---|
| keys | Yes | ||
| session_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains that keys are sent without appending Enter, covers tmux notation, and advises using get_snapshot() to see results. It doesn't detail potential side effects (e.g., if the session is not open), but for a keystroke-sending tool this is reasonably transparent and goes beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized: a one-sentence purpose, a bulleted list of use cases, a notation explanation, a result-checking tip, and an Args section. It is a bit longer than strictly necessary, but every part contributes useful information. It is front-loaded with the core behavior, so an agent can grasp it quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema is present, so return values don't need to be explained. The description covers the tool's purpose, usage patterns, key notation, and parameter formats. It even suggests the appropriate follow-up action (get_snapshot to see the result). For a tool of this complexity, the description is thorough and leaves no major gaps for an agent to guess about.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate. The 'Args' section provides clear meanings for both parameters: session_id format is 'user@host-<id>' and keys uses tmux notation. It even includes examples like 'C-c' and 'C-c Enter', which adds significant value beyond the bare string types in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Send raw keystrokes to a session without appending Enter.' This clearly distinguishes it from sibling send_command, which presumably sends full commands with Enter. The direct statement of behavior leaves no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit use cases: interrupting commands, sending EOF, interactive input, and special keys. It gives concrete examples and explains tmux key notation. While it doesn't explicitly say 'when not to use' or name an alternative tool like send_command, the 'without appending Enter' phrasing implies the distinction and the context is sufficient for an agent to select this tool appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_remote_fileA
Write content to a file on the remote host using the established session.
Use this tool to write file contents instead of using echo, redirection, or heredocs with send_command. This method handles large files, binary data, and special characters correctly.
| Name | Required | Description | Default |
|---|---|---|---|
| append | No | ||
| content | Yes | ||
| session_id | Yes | ||
| remote_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It adds useful behavioral context by stating the tool 'handles large files, binary data, and special characters correctly,' which distinguishes it from shell-based methods. However, it does not disclose key behaviors like whether existing files are overwritten, how the append parameter affects behavior, or any permission/error expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: first sentence states the primary action, second gives usage direction, third justifies why this tool is preferred. Every sentence earns its place, and the main point is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values are covered. However, the description leaves gaps about file overwrite behavior, append semantics, and session prerequisites (beyond 'established session'). For a mutating tool with no annotations, this is a significant omission, making the description only partially complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, and the description does not compensate. It never explains the parameters, especially 'append,' which is ambiguous. Parameter names like session_id and remote_path are somewhat self-explanatory, but content and append require more detail. The description adds little beyond what the bare schema shows.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Write content to a file on the remote host using the established session.' It clearly distinguishes itself from the sibling send_command by explicitly saying to use this tool instead of echo, redirection, or heredocs with send_command.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear guidance: 'Use this tool to write file contents instead of using echo, redirection, or heredocs with send_command.' It names the alternative and the scenario. It lacks an explicit when-not-to-use clause, but the context is well implied.
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.
9 tool updates
v0.2.8- First observed
cleanup_dead_sessions - First observed
close_session - First observed
get_snapshot - First observed
list_sessions - First observed
open_session - First observed
read_remote_file - First observed
send_command - First observed
send_keys - First observed
write_remote_file
TDQS
Each tool has a clearly distinct purpose: session lifecycle (list, open, close, cleanup), command interaction (send_command, send_keys, get_snapshot), and file transfer (read, write). There is no overlap or ambiguity even between send_command and send_keys, as the former submits a command and waits, while the latter sends raw keystrokes.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., list_sessions, open_session, send_command, write_remote_file). The naming is uniform, predictable, and clearly indicates the action and target.
With 9 tools, the set is well-scoped for an SSH/tmux server. Every tool serves a necessary function in session management, command execution, and file operations, without redundancy or bloat.
The tool surface provides full coverage of the SSH session lifecycle: open, list, close, cleanup, plus command sending, key injection, snapshot viewing, and file read/write. There are no obvious gaps that would prevent an agent from effectively managing remote sessions and files.
Maintenance
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
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Cloud-hosted MCP server for durable AI memory
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for managing multiple SSH servers via AI assistants, offering tools for remote command execution, file operations, and system monitoring.111MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that enables AI agents to run fully interactive SSH sessions (via tmux) and execute commands like a human operator, with persistent sessions and multiple concurrent connections.6MIT
- AlicenseNot gradedqualityAmaintenanceMCP server enabling AI assistants to securely operate remote servers via persistent SSH sessions, with tools for command execution, file transfer, directory listing, and system monitoring.4MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for persistent SSH sessions with tmux integration, port forwarding, and SFTP file writes, built for AI agent workflows.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/devnullvoid/mcp-ssh-tmux'
If you have feedback or need assistance with the MCP directory API, please join our Discord server