Skip to main content
Glama
gilberth

mcp-ssh-multi

by gilberth

mcp-ssh-multi

MCP server for managing multiple SSH servers through AI assistants. Provides 11 tools for remote command execution, file operations, and system monitoring.

Current version: 0.4.0

Features

  • Multi-server management — Configure and manage multiple SSH servers from a single YAML file

  • Connection pooling — Automatic connection reuse with per-server locks and retry on stale connections

  • Bounded command output — Streams stdout/stderr with a configurable combined memory limit

  • Timeout cleanup — Terminates timed-out remote processes and explicitly closes their SSH channels

  • 11 MCP tools — Execute commands, transfer files, read/write files, tail logs, list processes

  • Two transports — stdio (for local MCP clients) and streamable-http (for web/remote)

  • Cloudflare Tunnel compatible — Deploy behind a tunnel for remote access

  • MCP tool annotations — Hints for destructive, read-only, idempotent, and open-world operations

  • MCP resourcesssh://servers resource for listing configured servers

  • Pagination — Directory listings support limit/offset for large directories

  • Input validation — Path and filter sanitization to prevent command injection

  • Structured errors — Consistent error responses with codes, messages, and suggestions

Related MCP server: R-Shell

Installation

uv tool install mcp-ssh-multi

Using pip

pip install mcp-ssh-multi

Using uvx (one-shot)

uvx --from mcp-ssh-multi ssh-mcp

From source

git clone https://github.com/gilberth/mcp-ssh-multi.git
cd mcp-ssh-multi
uv sync

Configuration

1. SSH Servers (ssh_servers.yaml)

Create a ssh_servers.yaml file with your server definitions:

servers:
  proxmox:
    host: 192.168.1.100
    port: 22
    username: root
    key_file: ~/.ssh/id_rsa
    description: "Proxmox VE hypervisor"

  truenas:
    host: 192.168.1.101
    port: 22
    username: root
    password: "my-password"  # or use key_file
    description: "TrueNAS storage server"

2. Environment Variables (.env)

Copy .env.example to .env and customize:

cp .env.example .env

Variable

Default

Description

SSH_SERVERS_FILE

ssh_servers.yaml

Path to servers config

SSH_TIMEOUT

30

Default command timeout (seconds)

SSH_MAX_OUTPUT_BYTES

16777216

Combined stdout/stderr retention limit per command

LOG_LEVEL

INFO

Logging level

MCP_PORT

8086

HTTP server port

MCP_SECRET_PATH

/mcp

HTTP endpoint path

Usage

stdio mode (local MCP clients)

ssh-mcp

Or with uvx:

uvx --from mcp-ssh-multi ssh-mcp

HTTP mode (web/remote MCP clients)

ssh-mcp-web

The server will listen on http://0.0.0.0:8086/mcp by default.

MCP Client Configuration

Add to your MCP client config (e.g., Claude Desktop):

{
  "mcpServers": {
    "ssh": {
      "command": "uvx",
      "args": ["--from", "mcp-ssh-multi", "ssh-mcp"],
      "env": {
        "SSH_SERVERS_FILE": "/path/to/ssh_servers.yaml"
      }
    }
  }
}

For HTTP mode:

{
  "mcpServers": {
    "ssh": {
      "url": "http://localhost:8086/mcp"
    }
  }
}

Tool Reference

Connection Management

Tool

Description

ssh_list_servers

List all configured servers with connection status

ssh_disconnect

Disconnect from a specific server

Command Execution

Tool

Description

ssh_execute

Execute a shell command on a remote server

ssh_execute streams stdout and stderr concurrently and retains at most SSH_MAX_OUTPUT_BYTES bytes across both streams. If the limit is exceeded, the remote process is terminated and the response includes "truncated": true. Commands which exceed their timeout are terminated, escalated to a kill when necessary, and have their SSH process channel explicitly closed.

File Operations

Tool

Description

ssh_upload

Upload a local file to a remote server

ssh_download

Download a file from a remote server

ssh_file_exists

Check if a file/directory exists on a server

ssh_list_dir

List contents of a remote directory (supports pagination with limit/offset)

ssh_read_file

Read a text file from a remote server

ssh_write_file

Write content to a file on a remote server

System Monitoring

Tool

Description

ssh_tail_log

Tail a log file on a remote server

ssh_process_list

List running processes (optionally filtered)

MCP Resources

The server exposes the following MCP resources:

Resource URI

Description

ssh://servers

List of all configured SSH servers with connection status

Changelog

v0.4.0

  • Bounded command outputssh_execute reads stdout and stderr concurrently in chunks and enforces the combined SSH_MAX_OUTPUT_BYTES limit

  • Timeout process cleanup — Timed-out commands are terminated, escalated to kill() when necessary, and their SSH channels are explicitly closed

  • Truncation reporting — Command responses expose truncated when output exceeds the configured limit

  • Robust transport cleanup — Connections which fail to close gracefully are aborted and invalidated instead of being returned to the pool

  • Memory-efficient pagination — SFTP directory pagination retains only the requested page while still reporting the total entry count

  • Reproducible dependency ranges — FastMCP, MCP, and AsyncSSH are constrained to the audited major versions

v0.2.0

  • Per-server connection locks — Replaced global lock with per-server async locks for better concurrency

  • Connection retry — Automatic single retry on stale/lost SSH connections

  • MCP tool annotations — Added destructiveHint, readOnlyHint, idempotentHint, openWorldHint to all tools

  • MCP resource — Added ssh://servers resource endpoint

  • Directory paginationssh_list_dir now supports limit and offset parameters

  • Input validation — Path sanitization for ssh_tail_log and filter validation for ssh_process_list

  • Structured errors — Consistent error format with ErrorCode enum across all tools

  • Dynamic versioning — Version sourced from importlib.metadata instead of hardcoded strings

  • Test suite — Added tests for pagination, retry logic, input validation, and version consistency

v0.1.1

  • Initial public release with 11 SSH tools, stdio and HTTP transports

Production Deployment (LXC + Cloudflare Tunnel)

Full deployment guide for running mcp-ssh-multi as a systemd service behind a Cloudflare Tunnel on a Proxmox LXC container.

Prerequisites

  • A Proxmox LXC container (Debian 12/13)

  • A Cloudflare account with a domain

  • uv and cloudflared installed on the LXC

1. Install dependencies

# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install cloudflared
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb \
  -o cloudflared.deb && dpkg -i cloudflared.deb

2. Create SSH servers config

mkdir -p /ssh-mcp
cat > /ssh-mcp/ssh_servers.yaml << 'EOF'
servers:
  my-server:
    host: 192.168.1.100
    port: 22
    username: root
    password: "my-password"  # or use key_file
    description: "My server"
EOF

3. Create the Cloudflare Tunnel

# Login to Cloudflare (opens browser)
cloudflared tunnel login

# Create the named tunnel
cloudflared tunnel create ssh-mcp

# Route DNS to your domain
cloudflared tunnel route dns ssh-mcp ssh-mcp.yourdomain.com

4. Configure the tunnel

The tunnel create command outputs the tunnel UUID (e.g. 2687c640-38df-40f9-...) and creates a credentials file at /root/.cloudflared/<TUNNEL-ID>.json. If you need to find it later, run cloudflared tunnel list.

# Replace <TUNNEL-ID> with the UUID from "cloudflared tunnel create" output
cat > /root/.cloudflared/config.yml << 'EOF'
tunnel: <TUNNEL-ID>
credentials-file: /root/.cloudflared/<TUNNEL-ID>.json

ingress:
  - hostname: ssh-mcp.yourdomain.com
    service: http://localhost:8086
  - service: http_status:404
EOF

5. Create systemd services

mcp-ssh-multi service:

cat > /etc/systemd/system/mcp-ssh-multi.service << 'EOF'
[Unit]
Description=MCP SSH Multi Server
After=network.target

[Service]
Type=simple
Environment=SSH_SERVERS_FILE=/ssh-mcp/ssh_servers.yaml
Environment=MCP_SECRET_PATH=/your-secret-path
ExecStart=/root/.local/bin/uvx --from mcp-ssh-multi@latest ssh-mcp-web
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

cloudflared service:

cloudflared service install

Enable and start both:

systemctl daemon-reload
systemctl enable --now mcp-ssh-multi
systemctl enable --now cloudflared

6. Verify

# Check services
systemctl status mcp-ssh-multi
systemctl status cloudflared

# Test the endpoint
curl -s -X POST "https://ssh-mcp.yourdomain.com/your-secret-path" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'

7. Configure your MCP client

{
  "mcpServers": {
    "ssh": {
      "type": "remote",
      "url": "https://ssh-mcp.yourdomain.com/your-secret-path"
    }
  }
}

Service management

# View logs
journalctl -u mcp-ssh-multi -f
journalctl -u cloudflared -f

# Restart services
systemctl restart mcp-ssh-multi
systemctl restart cloudflared

Environment Variables

Variable

Default

Description

SSH_SERVERS_FILE

ssh_servers.yaml

Path to servers config

SSH_TIMEOUT

30

Default command timeout (seconds)

SSH_MAX_OUTPUT_BYTES

16777216

Combined stdout/stderr retention limit per command

LOG_LEVEL

INFO

Logging level

MCP_PORT

8086

HTTP server port

MCP_SECRET_PATH

/mcp

HTTP endpoint path (use a secret value)

Development

# Install with dev dependencies
uv sync --group dev

# Run linting
uv run ruff check src/ tests/ --fix
uv run ruff format src/ tests/

# Run type checking
uv run mypy src/

# Run tests
uv run pytest tests/ -v

License

MIT

Available Tools

11 tools
ssh_disconnectA
Idempotent

Disconnect from a specific SSH server.

Closes the active SSH connection to the named server. The connection will be re-established automatically on next command.

EXAMPLES:

  • Disconnect: ssh_disconnect("proxmox")

ParametersJSON Schema
NameRequiredDescriptionDefault
server_nameYesServer name to disconnect from (from ssh_list_servers)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

Annotations indicate idempotentHint and openWorldHint. The description adds that the connection is closed and auto-reconnected, which aligns with annotations. It does not contradict and adds useful behavioral context.

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 concise, front-loaded with the purpose, and includes an example. Every sentence provides value without redundancy.

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

Completeness4/5

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

Given the tool's simplicity, annotations, and schema coverage, the description is sufficiently complete. The output schema exists but is not shown; however, the behavior is clearly described.

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

Parameters3/5

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

Schema coverage is 100%, so the description adds no extra meaning beyond the schema. The parameter is clearly described in the schema as 'server_name' with a description.

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 'Disconnect from a specific SSH server' and explains it closes the active connection. It distinguishes from sibling tools like ssh_execute, ssh_read_file, etc., which are for other operations.

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

Usage Guidelines4/5

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

The description mentions that the connection will be re-established automatically on the next command, providing implicit guidance on when to disconnect. It doesn't explicitly state when not to use or compare with alternatives, but the context is clear.

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

ssh_downloadA

Download a file from a remote server to the local machine via SFTP. Use this tool (NOT scp via ssh_execute) to transfer files FROM a remote SSH server TO the local machine.

ParametersJSON Schema
NameRequiredDescriptionDefault
local_pathYesLocal destination path
remote_pathYesRemote file path to download
server_nameYesSource server name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior3/5

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

The description does not contradict the 'openWorldHint' annotation. However, it lacks additional behavioral details such as whether the local file is overwritten, authentication requirements, or error handling. Given the annotation, the burden is lower, but the description could still be more transparent about potential 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.

Conciseness5/5

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

The description consists of two concise sentences. The first states the primary function, and the second provides crucial usage guidance. No superfluous information is present, achieving both brevity and effectiveness.

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

Completeness4/5

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

Given the tool's complexity (3 required parameters, no nested objects, output schema exists), the description covers the main action and usage context adequately. It could be more complete by mentioning overwrite behavior or error scenarios, but it is already sufficient for typical use.

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

Parameters3/5

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

Schema description coverage is 100% with each parameter described (server_name, remote_path, local_path). The description does not add extra meaning beyond the schema; it only reinforces the direction of transfer. Baseline 3 is appropriate.

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 explicitly states 'Download a file from a remote server to the local machine via SFTP', which clearly identifies the verb (download), resource (file), and method (SFTP). It also distinguishes itself from the sibling tool 'scp via ssh_execute' by specifying the direction 'FROM a remote SSH server TO the local machine'.

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 usage guidance: 'Use this tool (NOT scp via ssh_execute) to transfer files FROM a remote SSH server TO the local machine.' This clearly states when to use this tool and which alternative to avoid, leaving no ambiguity.

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

ssh_executeA
Destructive

Execute a command on a remote SSH server.

Runs the given shell command on the specified server and returns stdout, stderr, and exit code. Connections are established automatically and reused.

EXAMPLES:

  • Run command: ssh_execute("proxmox", "uptime")

  • With timeout: ssh_execute("truenas", "zpool status", timeout=60)

ParametersJSON Schema
NameRequiredDescriptionDefault
commandYesShell command to execute
timeoutNoCommand timeout in seconds (default: 30)
server_nameYesServer name to execute on (from ssh_list_servers)

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

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

The description adds details about automatic connection reuse, which is beyond annotations. It aligns with destructiveHint=true (command execution can modify server state). No contradictions found.

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

Conciseness4/5

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

The description is concise, front-loads the purpose, and includes useful examples. Every sentence adds value, though the phrase 'Connections are established automatically and reused' could be slightly more precise.

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 (3 parameters, output schema exists), the description adequately covers execution behavior, parameter roles, and connection management. No gaps remain for the agent.

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

Parameters3/5

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

Schema coverage is 100%, and the description does not add significant additional meaning beyond what is in the parameter descriptions (server_name, command, timeout). The examples illustrate usage but do not deepen semantic understanding.

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 'Execute' and the resource 'command on a remote SSH server', with specific details on returning stdout, stderr, and exit code. It distinguishes from sibling tools that focus on file operations.

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

Usage Guidelines3/5

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

The description provides examples but does not explicitly state when to use this tool versus alternatives like ssh_read_file, nor does it include when-not-to-use guidance. Usage is implied through context.

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

ssh_file_existsA
Read-only

Check if a file or directory exists on a remote server.

Returns existence status, type (file/directory), size, and permissions.

EXAMPLES:

  • ssh_file_exists("proxmox", "/etc/pve/qemu-server/100.conf")

ParametersJSON Schema
NameRequiredDescriptionDefault
remote_pathYesRemote path to check
server_nameYesServer name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations provide readOnlyHint=true and openWorldHint=true. Description adds valuable context: returns existence status, type, size, and permissions. No contradictions, and description enriches behavioral understanding 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?

Description is three sentences with a clear front-loaded purpose and an illustrative example. No wasted words; every 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?

For a simple existence check tool, the description adequately covers purpose, return values (existence, type, size, permissions), and an example. Output schema is present, so return format is covered externally. Complete for the task.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents both parameters. Description does not add new semantic information beyond the schema (e.g., formatting, constraints). Example shows usage but no additional parameter details. Baseline 3 is appropriate.

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 action ('Check if a file or directory exists') and specifies the resource ('remote server'). It distinguishes from siblings like ssh_list_dir and ssh_read_file by focusing on existence and metadata.

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

Usage Guidelines3/5

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

The purpose is implied, but there is no explicit guidance on when to use this tool versus alternatives (e.g., ssh_list_dir for listing contents). The example provides usage context but no when-not scenarios.

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

ssh_list_dirA
Read-only

List contents of a remote directory.

Returns file names, types, sizes, and permissions. Supports pagination with limit/offset for large directories.

EXAMPLES:

  • ssh_list_dir("truenas", "/mnt/data")

  • ssh_list_dir("proxmox") # lists home directory

  • ssh_list_dir("proxmox", "/var/log", limit=50, offset=100)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMax entries to return, 0 for all (default: 200)
offsetNoNumber of entries to skip (default: 0)
remote_pathNoRemote directory path (default: home directory).
server_nameYesServer name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true, so the read-only nature is known. The description adds pagination support but omits prerequisites like the need for an existing SSH connection or server configuration.

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 extremely concise: three sentences plus examples. Every part is relevant and front-loaded with the core purpose.

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

Completeness4/5

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

Given the rich annotations and output schema, the description adequately covers return values and pagination. It could mention connection prerequisites, but this is implied by the sibling tools context.

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

Parameters3/5

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

The input schema provides full coverage with descriptions. The description adds example usage but no additional semantics beyond what the schema already states.

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 lists remote directory contents and specifies what is returned (names, types, sizes, permissions). This distinguishes it from siblings like ssh_read_file or ssh_download.

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

Usage Guidelines3/5

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

The description implies usage for listing directory contents via examples, but does not explicitly contrast with siblings or provide when-not-to-use guidance.

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

ssh_list_serversA
Read-only

List all configured SSH servers with connection status.

Returns server names, hosts, usernames, descriptions, and whether each server currently has an active connection.

EXAMPLES:

  • List all servers: ssh_list_servers()

ParametersJSON Schema
NameRequiredDescriptionDefault
_placeholderNoPlaceholder. Always pass true.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already provide readOnlyHint=true and openWorldHint=true. The description adds context about returning connection status and specific fields, which is valuable beyond annotations. No contradictory information.

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 concise (two sentences plus an example), front-loaded with the primary purpose, and every sentence provides 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?

For a simple list tool with output schema and clear annotations, the description adequately covers purpose, returned fields, and usage example. No gaps identified.

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

Parameters3/5

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

Schema coverage is 100% with a single placeholder parameter described in the schema. The description does not add any additional meaning or usage guidance for the parameter, meeting the baseline expectation.

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 lists all configured SSH servers with connection status, specifying exact returned fields. It distinguishes from sibling tools (e.g., ssh_execute, ssh_disconnect) which perform different actions.

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

Usage Guidelines3/5

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

The description implies usage for viewing server status and details before connecting, but does not explicitly state when to use vs. alternatives or when not to use. No exclusions or alternative tools are mentioned.

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

ssh_process_listA
Read-only

List running processes on a remote server.

Returns process list sorted by CPU usage. Optionally filter by name.

EXAMPLES:

  • ssh_process_list("proxmox")

  • ssh_process_list("truenas", filter_name="zfs")

ParametersJSON Schema
NameRequiredDescriptionDefault
filter_nameNoOptional: filter processes by name (grep pattern)
server_nameYesServer name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate read-only (readOnlyHint=true). The description adds that results are sorted by CPU usage and optionally filterable, providing behavioral context beyond the 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 very concise: three lines of text plus two examples. Every sentence is informative without redundancy.

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

Completeness4/5

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

Given the simple tool with two parameters and an output schema, the description covers purpose, output ordering, and filtering. It lacks error handling or prerequisites but is adequate for a list operation.

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

Parameters4/5

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

With 100% schema coverage, the baseline is 3. The description adds value through concrete examples showing server names and filter usage, clarifying parameter usage beyond schema descriptions.

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's purpose: 'List running processes on a remote server' and mentions output sorting by CPU usage, distinguishing it from sibling tools like ssh_execute.

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

Usage Guidelines3/5

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

The description implies usage for listing processes via examples but does not explicitly state when to use this tool versus alternatives like ssh_execute or when not to use it.

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

ssh_read_fileA
Read-only

Read a text file from a remote server.

Returns the file contents as a string. For binary or large files, use ssh_download instead.

EXAMPLES:

  • ssh_read_file("proxmox", "/etc/hostname")

  • ssh_read_file("truenas", "/var/log/messages", max_size=5000000)

ParametersJSON Schema
NameRequiredDescriptionDefault
max_sizeNoMax file size in bytes (default: 1MB)
remote_pathYesRemote file path to read
server_nameYesServer name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already indicate read-only and open world. Description adds value by specifying return type (string) and default max_size. No contradictions; behavior is well-disclosed 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?

Very concise: three sentences plus examples. Front-loaded with the main action. No redundant information; every sentence contributes to clarity.

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

Completeness4/5

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

Given the tool's simplicity, the description is mostly complete. It covers purpose, usage, and limitations. Could optionally mention encoding or error handling, but not necessary for typical use.

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

Parameters3/5

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

Schema coverage is 100% with clear descriptions for all parameters. The description adds minimal extra meaning: examples show expected values, but no new semantics 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 reads a text file from a remote server, using a specific verb and resource. It differentiates from sibling ssh_download by noting binary/large file handling, which avoids confusion.

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 advises to use ssh_download for binary or large files, providing clear alternative. Examples illustrate typical usage, making it easy for the agent to decide when to use this tool.

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

ssh_tail_logA
Read-only

Tail a log file on a remote server.

Returns the last N lines of the specified log file.

EXAMPLES:

  • ssh_tail_log("proxmox")

  • ssh_tail_log("truenas", "/var/log/messages", lines=100)

ParametersJSON Schema
NameRequiredDescriptionDefault
linesNoNumber of lines to tail (default: 50)
log_pathNoPath to log file (default: /var/log/syslog)/var/log/syslog
server_nameYesServer name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true. The description adds that it returns last N lines, which is standard behavior. No disclosure of error handling or edge cases, but bar is lower with annotations present.

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?

Extremely concise: two sentences and three examples. No fluff, front-loaded with purpose and example usage, making it easy to parse.

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

Completeness4/5

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

Covers core functionality and provides examples. Has output schema so return values don't need explanation. Minor gaps: no mention of behavior if file doesn't exist or permissions issues, but overall complete for a simple tail tool.

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

Parameters4/5

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

Schema covers 100% of parameters with descriptions and defaults. The description adds value with concrete examples showing usage patterns (e.g., default path, overriding parameters), which aids 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 tails a log file and returns the last N lines. It distinguishes from sibling tools like ssh_read_file (reads entire file) and ssh_execute (executes commands), as 'tail' is a specific operation.

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

Usage Guidelines3/5

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

No explicit guidance on when to use vs. alternatives. While the purpose is clear, it does not mention when not to use or provide alternatives, which is a gap given the many sibling tools.

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

ssh_uploadA
Destructive

Upload a local file to a remote server via SFTP. Use this tool (NOT scp via ssh_execute) to transfer files FROM the local machine TO a remote SSH server. For server-to-server transfers, download from source first, then upload to destination.

ParametersJSON Schema
NameRequiredDescriptionDefault
local_pathYesLocal file path to upload
remote_pathYesRemote destination path
server_nameYesTarget server name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already indicate destructiveHint and openWorldHint. Description adds that it uses SFTP and specifies direction, but doesn't mention overwrite behavior or authentication requirements, which would be helpful context.

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

Conciseness5/5

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

Two sentences, no wasted words. First sentence defines verb and protocol; second sentence provides usage boundaries and alternatives. Front-loaded and efficient.

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

Completeness4/5

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

Given the simple tool with 3 parameters, full schema coverage, and annotations, the description covers purpose and usage well. It lacks details on whether files are overwritten or if directories are created, but output schema likely handles return values.

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

Parameters3/5

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

Schema description coverage is 100% with clear descriptions for all three parameters. The description does not add additional semantics beyond what the schema provides, so baseline score applies.

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 explicitly states 'Upload a local file to a remote server via SFTP' with clear verb+resource and direction. It distinguishes from sibling tools like ssh_download (reverse direction) and ssh_execute (for SCP).

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 guidance: 'Use this tool (NOT scp via ssh_execute)' and explains when to use each direction. Also advises on server-to-server transfers, giving a clear workflow.

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

ssh_write_fileA
Destructive

Write content to a file on a remote server.

Creates or overwrites the file with the given content.

EXAMPLES:

  • ssh_write_file("proxmox", "/tmp/test.txt", "Hello World")

ParametersJSON Schema
NameRequiredDescriptionDefault
contentYesContent to write to the file
remote_pathYesRemote file path to write
server_nameYesServer name

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

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

Annotations already declare destructiveHint=true and openWorldHint=true. The description reiterates overwriting behavior but adds no new behavioral context beyond what annotations provide.

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 two sentences plus a concise example. It is front-loaded with the core action, and each part serves a purpose without redundancy.

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

Completeness4/5

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

Given the simple tool with full schema and annotations, the description adequately explains the operation. However, it omits edge cases like directory creation or error conditions, which could be inferred but are not explicit.

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

Parameters3/5

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

Schema coverage is 100% with descriptive parameter names. The description does not add semantic depth beyond the schema; the example provides concrete values but no additional constraints or formatting details.

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 writes content to a file on a remote server, specifying verb and resource. It contrasts with siblings like ssh_read_file and ssh_file_exists, and includes an example that demonstrates usage.

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

Usage Guidelines3/5

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

The description implies usage for creating or overwriting files, but lacks explicit guidance on when to use versus alternatives like ssh_upload or prerequisites (e.g., existing SSH connection). The example provides context but no conditional rationale.

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. 11 tool updatesv0.2.3
    • First observedssh_disconnect
    • First observedssh_download
    • First observedssh_execute
    • First observedssh_file_exists
    • First observedssh_list_dir
    • First observedssh_list_servers
    • First observedssh_process_list
    • First observedssh_read_file
    • First observedssh_tail_log
    • First observedssh_upload
    • First observedssh_write_file

TDQS

A4.2/5.0
Disambiguation5/5

Each tool has a clearly distinct action (execute, download, upload, read, write, list, etc.) with no overlapping purposes. The descriptions further clarify when to use which, e.g., ssh_download for binary files vs ssh_read_file for text.

Naming Consistency5/5

All tools follow a consistent 'ssh_verb_noun' snake_case pattern (e.g., ssh_execute, ssh_list_servers, ssh_read_file). No mixing of styles or verbs.

Tool Count5/5

With 11 tools covering connection management, command execution, file transfer, directory listing, process listing, and log tailing, the count is well-scoped for a comprehensive SSH management server.

Completeness4/5

The tool set covers core SSH operations but lacks direct tools for file deletion, directory creation, or server-to-server copy. However, these can be accomplished via ssh_execute, so minor gaps exist.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives AI assistants full SSH/SFTP remote operations — session management, command execution, interactive shells, file transfers, port forwarding, and system diagnostics.
    2
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP 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.
    4
    MIT
  • A
    license
    C
    quality
    A
    maintenance
    An MCP server that enables AI agents to establish and manage persistent SSH sessions with smart command execution, async support, and file operations.
    21
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server that enables AI assistants to perform development operations on remote servers via SSH, including executing commands, managing files, and browsing directories.
    1
    MIT

Latest Blog Posts

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gilberth/mcp-ssh-multi'

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