Skip to main content
Glama
QiuwenZheng

interminal

by QiuwenZheng

Interminal

Lightweight MCP server that gives AI assistants terminal access — SSH and local shells — with support for interactive and long-running commands.

Installation

# Run directly, no install needed (recommended)
uvx mcp-interminal

# Or install permanently
pip install mcp-interminal

Requires Python ≥ 3.11.

Related MCP server: Terminal MCP

MCP Client Configuration

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "interminal": {
      "command": "uvx",
      "args": ["mcp-interminal"]
    }
  }
}

Cursor / other clients: same command + args format above.

Tools

Tool

Description

connect_ssh

Connect to an SSH server; returns session_id and welcome banner

execute

Run a command locally (no session needed) or over SSH; returns output or status=partial + command_id

read_output

Poll a running command for new output without sending input

respond

Send text input to a command waiting at a prompt

send_control

Send control keys: ctrl+c, ctrl+z, arrow keys, F-keys, etc.

disconnect

Close an SSH session and release all resources

Persistent State

Each execute call runs in an isolated channel — there is no persistent shell between calls. For simple tasks, chaining with && works.

For multi-step workflows (project development, debugging, deployment), a terminal multiplexer (like Zellij) provides persistent state that survives across calls. The AI agent can create a persistent session where cd, environment variables, virtual environments, and long-running processes carry over naturally.

Key Behaviors

  • Stateless execute — each call is an isolated channel; cd /foo does not persist. Simple tasks: chain with &&. Multi-step workflows: use a terminal multiplexer.

  • Long-running commands return status="partial" with a command_id; poll with read_output or send input with respond

  • SSH PTY is 500×200 xterm-256color so multiplexer sessions render at your actual terminal size

Optional Dependencies

pip install "mcp-interminal[pty]"       # Windows PTY support (pywinpty)
pip install "mcp-interminal[ansi]"      # ANSI escape rendering (pyte)
pip install "mcp-interminal[pty,ansi]"  # both

Available Tools

6 tools
connect_sshA
Opens a persistent SSH connection and returns a session_id for use with
`execute`. The connection stays open until `disconnect`. Host keys are
auto-accepted. For local commands, call `execute` directly — no session needed.

PARAMETER GUIDANCE: Reuse session_id across multiple execute calls —
each connect_ssh opens a new TCP connection. key_filepath is tried
first when both key and password are provided; password acts as
fallback. With neither, SSH agent and system defaults are used. The
username defaults to the OS user if omitted. host is resolved at
connect time; unresolvable names raise an error. banner_timeout
controls MOTD capture — if exceeded, banner returns "" (not an error);
set to 0 to skip capture entirely.

SIDE EFFECTS: Opens a TCP socket with a 30-second keepalive. Leaks
the socket if `disconnect` is never called.

ERRORS: Raises on auth failure, unresolvable host, refused connection,
or network timeout.

RETURNS: {"session_id": str, "banner": str}
ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesHostname or IP of the SSH server (e.g. '192.168.1.10', 'example.com')
portNoSSH port number, 1–65535
passwordNoPassword for password-based auth; omit for key-based auth
usernameNoLogin user for authentication; omit to use SSH agent or OS default
key_filepathNoAbsolute path to a private key file (e.g. '/home/user/.ssh/id_rsa')
banner_timeoutNoMax seconds to capture the MOTD/welcome banner after login

TDQS

A5/5.0
Behavior5/5

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

Discloses side effects (TCP socket with keepalive, leak if disconnect not called), errors (auth, unresolvable host, etc.), and behaviors like host resolution and banner capture. Adds context beyond annotations.

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?

Well-structured with sections: overview, parameter guidance, side effects, errors, returns. Front-loaded purpose. No wasted words; each sentence adds value.

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?

Complete for a complex tool: covers all 6 parameters, side effects, error conditions, and return format. No gaps in information needed for correct invocation.

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 100%, but the description adds valuable guidance: key_filepath tried first, password fallback, username defaults, banner_timeout behavior (0 skips). Adds meaning beyond 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 it opens a persistent SSH connection and returns a session_id for use with 'execute'. It distinguishes from sibling tools like 'execute' (for local commands) and 'disconnect'.

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?

Explicit guidance: 'For local commands, call execute directly — no session needed.' Details parameter precedence, default behavior, banner timeout, and the lifecycle (connect, execute, disconnect).

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

disconnectA
DestructiveIdempotent
Close an SSH session and release all associated resources. NOT needed
for local commands — those clean up automatically.

SESSION_ID LIFECYCLE: The id is an opaque UUID created by connect_ssh,
used with execute, and retired by this call. Each connect_ssh produces
a unique id — reconnecting the same host gives a new one. After
disconnect, execute() with the old id raises ValueError. Calling
disconnect on an already-closed or unknown id is a safe no-op
(idempotent), so cleanup logic never needs to guard against double-close.

SIDE EFFECTS: Terminates all running commands on this session (their
command_ids become invalid), closes SSH channels and TCP socket.

WHEN NOT TO USE: To stop a single command without closing the session,
use send_control with "ctrl+c" instead.

RETURNS: true (always succeeds).
ParametersJSON Schema
NameRequiredDescriptionDefault
session_idYesSSH session identifier obtained from connect_ssh

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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

Annotations already indicate destructive and idempotent behavior. The description adds detailed transparency by explaining that calling disconnect on an already-closed or unknown id is a safe no-op, that it terminates all running commands, invalidates command_ids, and closes channels and sockets. No contradictions with annotations.

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 well-structured with clear sections for lifecycle, side effects, when-not-to-use, and returns. It is front-loaded with the main purpose and every sentence adds value. Despite length, it is efficient and not verbose.

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 complexity and annotations, the description covers all necessary aspects: lifecycle, side effects, alternatives, idempotency, return value, and parameter semantics. It is fully complete for an agent to use correctly.

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?

The schema covers the session_id parameter with a basic description. The description adds substantial meaning: it explains that the id is an opaque UUID from connect_ssh, is used with execute, and is retired by disconnect. It also clarifies that each connect_ssh produces a unique id, and reconnecting the same host yields a new one.

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 the verb 'Close an SSH session and release all associated resources.' It distinguishes from sibling tools by explicitly noting it is not needed for local commands and that for stopping a single command, send_control should be used.

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 provides explicit when-to-use and when-not-to-use guidance. It states that disconnect is for closing SSH sessions, not for local commands, and advises using send_control to stop a single command. It also explains the session lifecycle, making usage context clear.

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

executeA
Destructive
Execute a command locally or over SSH in an isolated channel.

PARAMETER RELATIONSHIPS & VALIDATION:
- `session_id` vs `shell`: `session_id` determines the execution environment. If provided (must be a valid active session), it runs over SSH and `shell` is completely ignored. If omitted, it runs locally, and `shell` (e.g., 'powershell.exe', '/bin/bash') is used.
- `pause_timeout` vs `total_timeout`: These interact to manage execution time. `pause_timeout` (must be > 0) triggers an early return if the command goes silent for that many seconds. `total_timeout` (must be >= `pause_timeout`) sets a hard wall-clock limit even if output is constantly streaming. To wait longer for a quiet command (e.g., a build), increase `pause_timeout`.
- Both timeouts accept floats but invalid ranges (e.g., pause_timeout <= 0, or total_timeout < pause_timeout) or an unknown `session_id` will raise a ValueError.

WHEN NOT TO USE: 
Do not use this to send input to an existing command (`respond`), send control keys (`send_control`), or poll a running command (`read_output`).

SIDE EFFECTS: 
Spawns a new, stateless process. `cd` or environment variables do NOT persist between calls. For persistent state, start a terminal multiplexer in the foreground. Never use `&` to background TUI apps.

RETURNS:
- {"status": "completed", "output": str, "exit_code": int}
- {"status": "partial", "output": str, "command_id": str}
ParametersJSON Schema
NameRequiredDescriptionDefault
shellNoShell for local execution (e.g. 'powershell.exe', '/bin/bash'); ignored for SSH
commandYesShell command to run (stateless — cd does not persist between calls)
session_idNoSSH session_id from connect_ssh; omit for local execution
pause_timeoutNoSeconds of silence before returning a partial result (> 0, ≤ total_timeout)
total_timeoutNoHard cap on call duration in seconds (≥ pause_timeout)

TDQS

A5/5.0
Behavior5/5

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

Discloses statelessness, non-persistence of cd/env, and warnings about backgrounding. Annotations provide destructiveHint and readOnlyHint, and description adds context beyond annotations.

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?

Well-structured with clear sections: purpose, parameter relationships, when not to use, side effects, returns. Every sentence adds value; no fluff.

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?

Covers all aspects: purpose, usage guidance, behavioral traits, parameter details, return types. No gaps given the tool's complexity and absence of output schema.

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 100%, and description adds significant extra semantics: parameter relationships (session_id vs shell, pause_timeout vs total_timeout), validation (ValueError on invalid ranges), and defaults.

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?

Clear verb+resource+context: 'Execute a command locally or over SSH in an isolated channel.' Distinguishes from sibling tools like respond, send_control, read_output.

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?

Explicit 'WHEN NOT TO USE' section listing alternatives. Also explains parameter relationships and validation, guiding when to use local vs SSH.

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

read_outputA
Read-only
Poll new output from a running command without sending input. Use after
execute returns status="partial" for non-interactive commands (builds,
training loops, long searches).

Each call returns only output produced since the last read. When the
command finishes, status changes to "completed" and the command_id is
retired — further calls raise ValueError.

WHEN NOT TO USE: If the command expects input, use respond. If you
need to interrupt or send keys, use send_control.

PARAMETER GUIDANCE: pause_timeout is the primary dial — it controls
how long to wait when the command is silent. total_timeout only caps
actively streaming output and has no effect during silence.

ERRORS: Raises ValueError if command_id is invalid or already completed.

RETURNS:
- {"status": "partial", "output": str, "command_id": str}
- {"status": "completed", "output": str, "exit_code": int}
ParametersJSON Schema
NameRequiredDescriptionDefault
command_idYesThe command_id from a status='partial' response. Raises ValueError if invalid or already completed
pause_timeoutNoSeconds of silence before returning. Primary dial for polling — raise it (e.g. 30, 60) for quiet jobs instead of total_timeout. Must be > 0 and ≤ total_timeout
total_timeoutNoHard cap on call duration in seconds. Only binds while output is streaming — silent polls return at pause_timeout. Must be ≥ pause_timeout

TDQS

A5/5.0
Behavior5/5

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

Discloses key behaviors beyond readOnlyHint: incremental output (each call returns new output since last read), command lifecycle (retired on completion, future calls raise ValueError), and error conditions. No contradiction with readOnlyHint or openWorldHint.

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?

Well-structured with sections like 'WHEN NOT TO USE', 'PARAMETER GUIDANCE', 'ERRORS', 'RETURNS'. Every sentence adds value; no filler. Concise yet comprehensive.

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?

Despite no output schema, the description fully documents return types with structure and meaning. Covers error scenarios, lifecycle, polling semantics. Complete for a polling tool of moderate complexity.

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 100% (baseline 3), but the description adds significant value by explaining the roles of pause_timeout vs total_timeout: 'pause_timeout is the primary dial... total_timeout only caps actively streaming output.' This clarifies behavior beyond schema comments.

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 starts with a clear verb+resource: 'Poll new output from a running command without sending input.' It distinguishes itself from siblings like 'respond' and 'send_control' by specifying when to use each.

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?

Provides explicit when-to-use: 'Use after execute returns status="partial" for non-interactive commands.' Also includes a 'WHEN NOT TO USE' section with direct alternatives (respond, send_control), guiding the agent clearly.

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

respondA
Destructive
Write text to a running command's stdin. Works for prompts (y/n,
passwords), shell input, or any text the process expects.

PARAMETER GUIDANCE: text auto-appends \n if missing. For control
keys use send_control — AI frameworks strip control bytes. Raise
pause_timeout (not total_timeout) for slow responses after input.
Raises ValueError if command_id is invalid or completed.

WHEN NOT TO USE: Inside zellij, prefer multiplexer CLI via execute.

SIDE EFFECTS: Writes to stdin; may trigger output, state change, or exit.

RETURNS:
- {"status": "partial", "output": str, "command_id": str}
- {"status": "completed", "output": str, "exit_code": int}
ParametersJSON Schema
NameRequiredDescriptionDefault
textYesText to write to stdin (e.g. 'y', a password, a shell command)
command_idYesThe command_id from a status='partial' response. Raises ValueError if invalid or already completed
pause_timeoutNoSeconds of silence before returning (> 0, ≤ total_timeout)
total_timeoutNoHard cap on call duration in seconds (≥ pause_timeout)

TDQS

A5/5.0
Behavior5/5

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

Discloses side effects (writes to stdin, may trigger output/state change/exit), auto-appends newline, and raises ValueError for invalid/closed commands. Complements annotations (destructiveHint=true) with actionable behavioral details.

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?

Well-structured with labeled sections (parameter guidance, when not to use, side effects, returns). Every sentence adds necessary information without 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?

Despite no output schema, description fully explains return values with status/output/exit_code structure. Covers error conditions and parameter interactions thoroughly.

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?

Adds value beyond 100% schema coverage by explaining auto-appending newline, recommending send_control for control codes, and clarifying pause_timeout/total_timeout usage. Each parameter gets contextual usage guidance.

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?

Description clearly states 'Write text to a running command's stdin' with specific verb and resource. Distinguishes from sibling send_control for control keys and execute for starting commands.

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?

Explicitly provides 'WHEN NOT TO USE' clause (inside zellij) and guidance for parameter adjustments (pause_timeout vs total_timeout). Clearly contrasts with send_control for alternative input methods.

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

send_controlA
Destructive
Send a control key or escape sequence to a running command. Use for
interrupts (ctrl+c), TUI navigation (arrows, F-keys), or any
non-printable input. Prefer this over `respond` for control keys —
AI frameworks strip raw control bytes from string arguments.

SIGNAL HANDLING: The signal parameter accepts any key name from the
supported list (case-insensitive, whitespace-tolerant — "Ctrl + C"
works). Common signals: ctrl+c (SIGINT/interrupt), ctrl+z (SIGTSTP/
suspend), ctrl+d (EOF), ctrl+\ (SIGQUIT). Local non-PTY subprocesses
only react to ctrl+c, ctrl+z, ctrl+\; SSH and PTY channels accept all.

SIDE EFFECTS: The signal may terminate the command (e.g. ctrl+c),
making the command_id invalid on the next read.

TIMEOUT INTERACTION: pause_timeout controls how long to wait for
output after the signal. Raise it for slow TUI repaints over
high-latency SSH; total_timeout only binds during active streaming.

ERRORS: Raises ValueError if command_id is invalid, already completed,
or signal name is unrecognized.

RETURNS: Same format as execute —
{"status": "completed"|"partial", "output": str, ...}
ParametersJSON Schema
NameRequiredDescriptionDefault
signalYesCase-insensitive key name. Values: ctrl+a..ctrl+z, ctrl+[/]/^/_/\, esc, tab, enter, return, space, backspace, up/down/left/right, home, end, pageup, pagedown, insert, delete, f1..f12, backtab, alt+<char>. Raises ValueError if unrecognized
command_idYesThe command_id from a status='partial' response. Must be an active command. Raises ValueError if invalid or already completed
pause_timeoutNoSeconds of output silence after sending the key before returning. Raise for slow TUI repaints (e.g. over high-latency SSH). Must be > 0 and ≤ total_timeout
total_timeoutNoHard cap on total call duration in seconds. Only binds while output is actively streaming. Must be ≥ pause_timeout

TDQS

A5/5.0
Behavior5/5

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

Beyond annotations (destructiveHint=true, idempotentHint=false), the description explains side effects (signal may terminate command, making command_id invalid), timeout interaction, and error handling. No contradiction with annotations.

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 well-structured with sections (signal handling, side effects, timeout interaction, errors, returns). Every sentence adds value, and the information is front-loaded with key usage guidance.

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 4 parameters (2 required), no output schema, and the open-world/destructive annotations, the description fully covers behavior, return format, errors, and edge cases. It is complete for an agent to use the tool correctly.

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?

With 100% schema coverage, the description adds value by explaining signal case-insensitivity, common signals, and when to raise pause_timeout or total_timeout. It enriches understanding 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 the tool sends control keys or escape sequences to a running command, listing specific use cases (interrupts, TUI navigation, non-printable input) and explicitly distinguishes it from sibling 'respond' by noting that AI frameworks strip raw control bytes.

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?

Explicit guidance is provided: 'Prefer this over respond for control keys.' It also details when to use different signals, how to adjust timeout for slow TUI repaints, and error conditions, giving clear context on when and when not to use the tool.

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. 1 tool updatev1.0.17
    • Changedsend_control2 fields changed
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of silence after sending the key before returning (> 0, ≤ total_timeout)"New value: +"Seconds of output silence after sending the key before returning. Raise for slow TUI repaints (e.g. over high-latency SSH). Must be > 0 and ≤ total_timeout"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap on call duration in seconds (≥ pause_timeout)"New value: +"Hard cap on total call duration in seconds. Only binds while output is actively streaming. Must be ≥ pause_timeout"
  2. 1 tool updatev1.0.15
    • Changedsend_control2 fields changed
      • removedInput schema / properties / signal / default
        Removed value: -"ctrl+c"
      • changedInput schema / required
        Previous value: -[
        -  "command_id"
        -]New value: +[
        +  "command_id",
        +  "signal"
        +]
  3. 1 tool updatev1.0.12
    • Changedrespond4 fields changed
      • changedInput schema / properties / command_id / description
        Previous value: -"The command_id from a status='partial' response. Must be an active (not yet completed) command. Raises ValueError if invalid or already finished"New value: +"The command_id from a status='partial' response. Raises ValueError if invalid or already completed"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence before returning. Raise this (not total_timeout) when the command is slow to respond after receiving input. Must be > 0 and ≤ total_timeout"New value: +"Seconds of silence before returning (> 0, ≤ total_timeout)"
      • changedInput schema / properties / text / description
        Previous value: -"Text to write to the command's stdin (e.g. 'y', a password, a shell command). A trailing newline is auto-appended if missing. For control keys (Ctrl+C, arrows, etc.) use send_control instead — AI frameworks strip control bytes from strings"New value: +"Text to write to stdin (e.g. 'y', a password, a shell command)"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap on total call duration in seconds. Only binds while output is actively streaming. Must be ≥ pause_timeout"New value: +"Hard cap on call duration in seconds (≥ pause_timeout)"
  4. 5 tool updatesv1.0.11
    • Changedconnect_ssh6 fields changed
      • changedInput schema / properties / banner_timeout / description
        Previous value: -"Max seconds to capture the MOTD/welcome banner after login. If exceeded, banner returns '' (not an error). Increase for slow hosts; set to 0 to skip banner capture entirely"New value: +"Max seconds to capture the MOTD/welcome banner after login"
      • changedInput schema / properties / host / description
        Previous value: -"Hostname or IP of the SSH server (e.g. '192.168.1.10', 'example.com'). DNS resolution happens at connect time; unresolvable hosts raise an error"New value: +"Hostname or IP of the SSH server (e.g. '192.168.1.10', 'example.com')"
      • changedInput schema / properties / key_filepath / description
        Previous value: -"Absolute path to a private key file (e.g. '/home/user/.ssh/id_rsa'). Must be readable by the server process. Preferred over password for non-interactive use"New value: +"Absolute path to a private key file (e.g. '/home/user/.ssh/id_rsa')"
      • changedInput schema / properties / password / description
        Previous value: -"Password for password-based auth. If both password and key_filepath are provided, key is tried first, password is the fallback"New value: +"Password for password-based auth; omit for key-based auth"
      • changedInput schema / properties / port / description
        Previous value: -"SSH port, 1–65535. Most servers listen on 22; non-standard ports are common for hardened hosts"New value: +"SSH port number, 1–65535"
      • changedInput schema / properties / username / description
        Previous value: -"Login user for authentication. If omitted, falls back to SSH agent or OS default user. Required when the remote user differs from the local one"New value: +"Login user for authentication; omit to use SSH agent or OS default"
    • Changeddisconnect1 field changed
      • changedInput schema / properties / session_id / description
        Previous value: -"The session_id returned by connect_ssh. After this call, the session_id becomes invalid — further execute() calls with it raise ValueError. Safe to call multiple times: disconnecting an already-closed or unknown session_id silently returns true (idempotent)"New value: +"SSH session identifier obtained from connect_ssh"
    • Changedexecute5 fields changed
      • changedInput schema / properties / command / description
        Previous value: -"Shell command to run. Each call is stateless — `cd /foo` does NOT persist. Chain with && for multi-step (e.g. 'cd /foo && ls'), or use a Zellij/tmux session for persistent state"New value: +"Shell command to run (stateless — cd does not persist between calls)"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence before returning. Controls how long to wait for a quiet command — raise this (not total_timeout) for slow-starting jobs. Must be > 0 and ≤ total_timeout"New value: +"Seconds of silence before returning a partial result (> 0, ≤ total_timeout)"
      • changedInput schema / properties / session_id / description
        Previous value: -"SSH session_id from connect_ssh. Omit (or null) for local execution. Raises ValueError if the session_id is invalid or was already disconnected"New value: +"SSH session_id from connect_ssh; omit for local execution"
      • changedInput schema / properties / shell / description
        Previous value: -"Shell for local execution (e.g. 'powershell.exe', '/bin/bash'). Only used when session_id is null — ignored for SSH. Defaults to cmd.exe on Windows, /bin/bash on Unix"New value: +"Shell for local execution (e.g. 'powershell.exe', '/bin/bash'); ignored for SSH"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap on total call duration in seconds. Only binds while output is actively streaming — a silent command returns at pause_timeout, not total_timeout. Must be ≥ pause_timeout"New value: +"Hard cap on call duration in seconds (≥ pause_timeout)"
    • Changedread_output3 fields changed
      • changedInput schema / properties / command_id / description
        Previous value: -"The command_id from a status='partial' response. Must be an active command. Raises ValueError if invalid or already completed"New value: +"The command_id from a status='partial' response. Raises ValueError if invalid or already completed"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence before returning. This is the primary dial for polling quiet jobs — raise it (e.g. 30, 60) instead of total_timeout. Must be > 0 and ≤ total_timeout"New value: +"Seconds of silence before returning. Primary dial for polling — raise it (e.g. 30, 60) for quiet jobs instead of total_timeout. Must be > 0 and ≤ total_timeout"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap on total call duration in seconds. Only binds while output is actively streaming — a silent poll returns at pause_timeout regardless. Must be ≥ pause_timeout"New value: +"Hard cap on call duration in seconds. Only binds while output is streaming — silent polls return at pause_timeout. Must be ≥ pause_timeout"
    • Changedsend_control2 fields changed
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence after sending the key before returning. Raise for slow TUI repaints (e.g. over high-latency SSH). Must be > 0 and ≤ total_timeout"New value: +"Seconds of silence after sending the key before returning (> 0, ≤ total_timeout)"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap on total call duration in seconds. Only binds while output is actively streaming. Must be ≥ pause_timeout"New value: +"Hard cap on call duration in seconds (≥ pause_timeout)"
  5. 1 tool updatev1.0.10
    • Changeddisconnect1 field changed
      • changedInput schema / properties / session_id / description
        Previous value: -"The session_id returned by connect_ssh. Becomes invalid after this call — further execute() calls with it raise ValueError. Raises ValueError if already disconnected or unrecognized"New value: +"The session_id returned by connect_ssh. After this call, the session_id becomes invalid — further execute() calls with it raise ValueError. Safe to call multiple times: disconnecting an already-closed or unknown session_id silently returns true (idempotent)"
  6. 6 tool updatesv1.0.9
    • Changedconnect_ssh6 fields changed
      • changedInput schema / properties / banner_timeout / description
        Previous value: -"The timeout in seconds to wait for the MOTD/welcome banner after the connection opens"New value: +"Max seconds to capture the MOTD/welcome banner after login. If exceeded, banner returns '' (not an error). Increase for slow hosts; set to 0 to skip banner capture entirely"
      • changedInput schema / properties / host / description
        Previous value: -"The hostname or IP address of the SSH server to connect to (e.g., '192.168.1.10' or 'example.com')"New value: +"Hostname or IP of the SSH server (e.g. '192.168.1.10', 'example.com'). DNS resolution happens at connect time; unresolvable hosts raise an error"
      • changedInput schema / properties / key_filepath / description
        Previous value: -"Optional absolute path to a private key file for key-based auth; must be readable by the server process. If both this and password are supplied, the key is attempted first"New value: +"Absolute path to a private key file (e.g. '/home/user/.ssh/id_rsa'). Must be readable by the server process. Preferred over password for non-interactive use"
      • changedInput schema / properties / password / description
        Previous value: -"Optional password for password-based authentication. Omit if using key-based authentication"New value: +"Password for password-based auth. If both password and key_filepath are provided, key is tried first, password is the fallback"
      • changedInput schema / properties / port / description
        Previous value: -"The port number of the SSH server (default is 22)"New value: +"SSH port, 1–65535. Most servers listen on 22; non-standard ports are common for hardened hosts"
      • changedInput schema / properties / username / description
        Previous value: -"Optional username for authentication. If omitted, the connection will use SSH agent or system defaults"New value: +"Login user for authentication. If omitted, falls back to SSH agent or OS default user. Required when the remote user differs from the local one"
    • Changeddisconnect1 field changed
      • changedInput schema / properties / session_id / description
        Previous value: -"The SSH session_id returned by connect_ssh that you want to close"New value: +"The session_id returned by connect_ssh. Becomes invalid after this call — further execute() calls with it raise ValueError. Raises ValueError if already disconnected or unrecognized"
    • Changedexecute5 fields changed
      • changedInput schema / properties / command / description
        Previous value: -"The shell command to execute. Each call is stateless; for persistent state (cd, venv, env vars), drive a Zellij session instead of chaining &&"New value: +"Shell command to run. Each call is stateless — `cd /foo` does NOT persist. Chain with && for multi-step (e.g. 'cd /foo && ls'), or use a Zellij/tmux session for persistent state"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence to wait before returning a partial response (default is 9.0)"New value: +"Seconds of output silence before returning. Controls how long to wait for a quiet command — raise this (not total_timeout) for slow-starting jobs. Must be > 0 and ≤ total_timeout"
      • changedInput schema / properties / session_id / description
        Previous value: -"SSH session_id returned by connect_ssh. Omit for local commands — no session needed"New value: +"SSH session_id from connect_ssh. Omit (or null) for local execution. Raises ValueError if the session_id is invalid or was already disconnected"
      • changedInput schema / properties / shell / description
        Previous value: -"Shell for local execution (e.g. 'powershell.exe', '/bin/bash'). Ignored when session_id is provided. Defaults to cmd.exe on Windows, /bin/bash on Unix"New value: +"Shell for local execution (e.g. 'powershell.exe', '/bin/bash'). Only used when session_id is null — ignored for SSH. Defaults to cmd.exe on Windows, /bin/bash on Unix"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap in seconds on the maximum duration of this call (default is 20.0)"New value: +"Hard cap on total call duration in seconds. Only binds while output is actively streaming — a silent command returns at pause_timeout, not total_timeout. Must be ≥ pause_timeout"
    • Changedread_output3 fields changed
      • changedInput schema / properties / command_id / description
        Previous value: -"The active command_id returned in a partial status response"New value: +"The command_id from a status='partial' response. Must be an active command. Raises ValueError if invalid or already completed"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence to wait before returning (default is 9.0)"New value: +"Seconds of output silence before returning. This is the primary dial for polling quiet jobs — raise it (e.g. 30, 60) instead of total_timeout. Must be > 0 and ≤ total_timeout"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap in seconds on the maximum duration of this call (default is 20.0)"New value: +"Hard cap on total call duration in seconds. Only binds while output is actively streaming — a silent poll returns at pause_timeout regardless. Must be ≥ pause_timeout"
    • Changedrespond4 fields changed
      • changedInput schema / properties / command_id / description
        Previous value: -"The active command_id returned in a partial status response that is waiting for input"New value: +"The command_id from a status='partial' response. Must be an active (not yet completed) command. Raises ValueError if invalid or already finished"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence to wait before returning (default is 9.0)"New value: +"Seconds of output silence before returning. Raise this (not total_timeout) when the command is slow to respond after receiving input. Must be > 0 and ≤ total_timeout"
      • changedInput schema / properties / text / description
        Previous value: -"The text input to send to the command (e.g. 'y' for prompts, passwords, etc.). Newline is auto-appended"New value: +"Text to write to the command's stdin (e.g. 'y', a password, a shell command). A trailing newline is auto-appended if missing. For control keys (Ctrl+C, arrows, etc.) use send_control instead — AI frameworks strip control bytes from strings"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap in seconds on the maximum duration of this call (default is 20.0)"New value: +"Hard cap on total call duration in seconds. Only binds while output is actively streaming. Must be ≥ pause_timeout"
    • Changedsend_control4 fields changed
      • changedInput schema / properties / command_id / description
        Previous value: -"The active command_id returned in a partial status response"New value: +"The command_id from a status='partial' response. Must be an active command. Raises ValueError if invalid or already completed"
      • changedInput schema / properties / pause_timeout / description
        Previous value: -"Seconds of output silence to wait before returning (default is 9.0)"New value: +"Seconds of output silence after sending the key before returning. Raise for slow TUI repaints (e.g. over high-latency SSH). Must be > 0 and ≤ total_timeout"
      • changedInput schema / properties / signal / description
        Previous value: -"The control signal or key to send. Supported values: 'ctrl+c', 'ctrl+z', 'ctrl+d', arrow keys, enter, f1-f12, etc."New value: +"Case-insensitive key name. Values: ctrl+a..ctrl+z, ctrl+[/]/^/_/\\, esc, tab, enter, return, space, backspace, up/down/left/right, home, end, pageup, pagedown, insert, delete, f1..f12, backtab, alt+<char>. Raises ValueError if unrecognized"
      • changedInput schema / properties / total_timeout / description
        Previous value: -"Hard cap in seconds on the maximum duration of this call (default is 20.0)"New value: +"Hard cap on total call duration in seconds. Only binds while output is actively streaming. Must be ≥ pause_timeout"
  7. 4 tool updatesv1.0.8
    • Removedcreate_local
    • Changeddisconnect1 field changed
      • changedInput schema / properties / session_id / description
        Previous value: -"The unique session identifier returned by connect_ssh or create_local that you want to close"New value: +"The SSH session_id returned by connect_ssh that you want to close"
    • Changedexecute6 fields changed
      • addedInput schema / properties / session_id / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • addedInput schema / properties / session_id / default
        Added value: +null
      • changedInput schema / properties / session_id / description
        Previous value: -"The unique session identifier returned by connect_ssh or create_local"New value: +"SSH session_id returned by connect_ssh. Omit for local commands — no session needed"
      • removedInput schema / properties / session_id / type
        Removed value: -"string"
      • addedInput schema / properties / shell
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Shell for local execution (e.g. 'powershell.exe', '/bin/bash'). Ignored when session_id is provided. Defaults to cmd.exe on Windows, /bin/bash on Unix",
        +  "title": "Shell"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "session_id",
        -  "command"
        -]New value: +[
        +  "command"
        +]
    • Removedlist_sessions
  8. 1 tool updatev1.0.7
    • Changedconnect_ssh2 fields changed
      • changedInput schema / properties / key_filepath / description
        Previous value: -"Optional absolute path to a private key file (SSH key) for key-based authentication"New value: +"Optional absolute path to a private key file for key-based auth; must be readable by the server process. If both this and password are supplied, the key is attempted first"
      • changedInput schema / properties / password / description
        Previous value: -"Optional password for password-based authentication. If using key-based authentication, this can be omitted"New value: +"Optional password for password-based authentication. Omit if using key-based authentication"
  9. 1 tool updatev1.0.5
    • Changedexecute1 field changed
      • changedInput schema / properties / command / description
        Previous value: -"The shell command to execute (e.g., 'ls -la' or 'npm run build'). Can chain multiple commands with && or ;"New value: +"The shell command to execute. Each call is stateless; for persistent state (cd, venv, env vars), drive a Zellij session instead of chaining &&"
  10. 7 tool updatesv1.0.3
    • Changedconnect_ssh6 fields changed
      • addedInput schema / properties / banner_timeout / description
        Added value: +"The timeout in seconds to wait for the MOTD/welcome banner after the connection opens"
      • addedInput schema / properties / host / description
        Added value: +"The hostname or IP address of the SSH server to connect to (e.g., '192.168.1.10' or 'example.com')"
      • addedInput schema / properties / key_filepath / description
        Added value: +"Optional absolute path to a private key file (SSH key) for key-based authentication"
      • addedInput schema / properties / password / description
        Added value: +"Optional password for password-based authentication. If using key-based authentication, this can be omitted"
      • addedInput schema / properties / port / description
        Added value: +"The port number of the SSH server (default is 22)"
      • addedInput schema / properties / username / description
        Added value: +"Optional username for authentication. If omitted, the connection will use SSH agent or system defaults"
    • Changedcreate_local1 field changed
      • addedInput schema / properties / shell / description
        Added value: +"Optional absolute path or executable name of the shell to use (e.g., 'powershell.exe', '/bin/bash', '/bin/zsh'). If omitted, defaults to cmd.exe on Windows or /bin/bash on Unix/macOS."
    • Changeddisconnect1 field changed
      • addedInput schema / properties / session_id / description
        Added value: +"The unique session identifier returned by connect_ssh or create_local that you want to close"
    • Changedexecute4 fields changed
      • addedInput schema / properties / command / description
        Added value: +"The shell command to execute (e.g., 'ls -la' or 'npm run build'). Can chain multiple commands with && or ;"
      • addedInput schema / properties / pause_timeout / description
        Added value: +"Seconds of output silence to wait before returning a partial response (default is 9.0)"
      • addedInput schema / properties / session_id / description
        Added value: +"The unique session identifier returned by connect_ssh or create_local"
      • addedInput schema / properties / total_timeout / description
        Added value: +"Hard cap in seconds on the maximum duration of this call (default is 20.0)"
    • Changedread_output3 fields changed
      • addedInput schema / properties / command_id / description
        Added value: +"The active command_id returned in a partial status response"
      • addedInput schema / properties / pause_timeout / description
        Added value: +"Seconds of output silence to wait before returning (default is 9.0)"
      • addedInput schema / properties / total_timeout / description
        Added value: +"Hard cap in seconds on the maximum duration of this call (default is 20.0)"
    • Changedrespond4 fields changed
      • addedInput schema / properties / command_id / description
        Added value: +"The active command_id returned in a partial status response that is waiting for input"
      • addedInput schema / properties / pause_timeout / description
        Added value: +"Seconds of output silence to wait before returning (default is 9.0)"
      • addedInput schema / properties / text / description
        Added value: +"The text input to send to the command (e.g. 'y' for prompts, passwords, etc.). Newline is auto-appended"
      • addedInput schema / properties / total_timeout / description
        Added value: +"Hard cap in seconds on the maximum duration of this call (default is 20.0)"
    • Changedsend_control4 fields changed
      • addedInput schema / properties / command_id / description
        Added value: +"The active command_id returned in a partial status response"
      • addedInput schema / properties / pause_timeout / description
        Added value: +"Seconds of output silence to wait before returning (default is 9.0)"
      • addedInput schema / properties / signal / description
        Added value: +"The control signal or key to send. Supported values: 'ctrl+c', 'ctrl+z', 'ctrl+d', arrow keys, enter, f1-f12, etc."
      • addedInput schema / properties / total_timeout / description
        Added value: +"Hard cap in seconds on the maximum duration of this call (default is 20.0)"

TDQS

A5/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose: connect_ssh opens sessions, disconnect closes them, execute runs commands, read_output polls output, respond sends text, send_control sends control keys. There is no overlap or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb or verb_noun pattern (connect_ssh, disconnect, execute, read_output, respond, send_control). No mixed conventions or irregular naming.

Tool Count5/5

Six tools perfectly cover the core operations of a terminal server (session management, command execution, I/O, and control) without extraneous or missing tools.

Completeness5/5

The tool surface covers the full lifecycle of SSH sessions and local command execution: connect, execute, interact (input, control, output), and disconnect. There are no obvious gaps for the stated purpose.

Maintenance

ActivitySlowing
ResponsivenessResponsive

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

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    A secure and pluggable MCP server to run terminal commands on your local machine or cloud server — remotely, safely, and with LLMs or agentic clients.
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables management of visible, interactive terminal sessions across platforms (macOS, Windows, Linux, WSL). Supports creating, executing commands, capturing output, and managing multiple terminal windows simultaneously.
    5
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP 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.
    6
    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/QiuwenZheng/interminal'

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