Skip to main content
Glama

ssh-mcp

ssh-mcp is a local Model Context Protocol server that gives AI agents safe, structured access to remote machines over SSH. Instead of hand-assembling ssh snow "docker ps" commands, the agent calls typed tools like ssh_exec({host: "snow", command: "docker ps"}) and gets back stdout, stderr, exit code, timeout and truncation information.

AI Agent
   │  MCP / stdio
   ▼
ssh-mcp
   │  SSH (connection pool, your OpenSSH config/credentials)
   ▼
Remote machines

The MCP server has essentially the same remote privileges as the SSH identity in use. Only connect it to agents you trust, on machines you are comfortable granting shell access to.

Requirements

  • Node.js >= 20

  • An SSH configuration you already use (~/.ssh/config) with working credentials

Related MCP server: SSH MCP Server

Installation

From npm:

npm install -g @callumbicknell/ssh-mcp

From source:

git clone https://github.com/CallumBicknell/ssh-mcp.git
cd ssh-mcp
pnpm install
pnpm run build

SSH configuration

ssh-mcp discovers hosts from your existing OpenSSH client config — ~/.ssh/config by default, or SSH_CONFIG_PATH if set. Nothing is duplicated: hostnames, users, ports and key paths all come from the file the ssh CLI already uses.

Per host, it resolves: HostName, Port, User, IdentityFile (tried in order), and IdentityAgent/SSH_AUTH_SOCK. Agent auth is preferred when available, then identity files.

MCP client configuration

Local/source usage:

{
  "mcpServers": {
    "ssh": {
      "command": "node",
      "args": ["/path/to/ssh-mcp/dist/index.js"]
    }
  }
}

npm usage:

{
  "mcpServers": {
    "ssh": {
      "command": "npx",
      "args": ["-y", "@callumbicknell/ssh-mcp"]
    }
  }
}

The server speaks MCP on stdio; all logs go to stderr.

Tools

Tool

Purpose

ssh_hosts

List the concrete host aliases available in your SSH config (no secrets)

ssh_exec

Run a remote command; returns stdout/stderr/exit code/timeout/truncation

ssh_read_file

Read a remote text file (size-capped)

ssh_write_file

Atomically write a remote file (temp file + rename; never creates parent dirs)

ssh_list_directory

Compact directory listing with type, size, mode, mtime

ssh_stat

File/dir metadata: type, size, permissions, mtime, uid/gid

ssh_tunnel / ssh_tunnels / ssh_tunnel_stop

Persistent local port-forwards over the pooled SSH connection

ssh_exec result shape

exit code: 0

stdout:
...

stderr:
...
[stdout truncated at 65536 bytes]   ← only when truncated

Non-zero exit codes and stderr are always surfaced as MCP errors/text; timeouts return partial output plus a clear timeout message. On timeout the remote process is sent KILL and the channel is closed.

Configuration

Variable

Default

Meaning

SSH_MCP_MAX_OUTPUT

65536

Max bytes kept per output stream before truncation

SSH_MCP_COMMAND_TIMEOUT

30000

Default ssh_exec timeout (ms)

SSH_MCP_CONNECTION_TIMEOUT

10000

SSH connection timeout (ms)

SSH_MCP_OPERATION_TIMEOUT

30000

Per-operation SFTP timeout (ms)

SSH_MCP_IDLE_TIMEOUT

120000

How long an idle pooled connection is kept (ms)

SSH_CONFIG_PATH

~/.ssh/config

Path to the OpenSSH client config

Timeout semantics: connection timeout bounds establishing the TCP/SSH session; command timeout bounds a single ssh_exec; operation timeout bounds one SFTP read/write/stat/readdir; idle timeout only evicts a connection with no active operations.

SSH compatibility limitations

ssh-mcp uses the ssh2 library plus a parser for ~/.ssh/config. It is not a full OpenSSH client:

Supported

Not supported (or approximate)

HostName, Port, User

ProxyCommand (not honored)

IdentityFile (multiple)

ProxyJump (not honored)

IdentityAgent / SSH_AUTH_SOCK

Match blocks (not evaluated)

Per-host aliases

LocalForward/RemoteForward, ControlMaster, PermitLocalCommand, CertificateFile agent quirks

Agent and publickey auth

Password prompts (no interactive prompting — use keys/agent)

For hosts that require jump hosts or proxy commands, either add direct HostName/Port entries you can reach, or front them with a reachable bastion address in your config. Switching to shelling out to the system ssh binary was evaluated and rejected: it would lose connection pooling, structured results, and make timeout/output control and atomic-write SFTP impossible to guarantee portably.

Security model

  • No command allowlist by design: the server is an administration tool, and a blanket allowlist would make it useless for that purpose. Command-policy/confirmation middleware is a clear extension point.

  • Private keys/passwords are read by ssh2 during auth only; they are never logged or returned.

  • Host identifiers are validated and never interpolated into a local shell.

  • All output is byte-capped; all operations are timeout-bounded.

  • File writes are atomic and do not create parent directories.

Examples

ssh_hosts()
→ snow\nserver01\nfileserver

ssh_exec({host: "snow", command: "docker ps --format '{{.Names}} {{.Status}}'"})
ssh_read_file({host: "snow", path: "/etc/caddy/Caddyfile"})
ssh_write_file({host: "snow", path: "/tmp/deploy.yaml", content: "..."})
ssh_list_directory({host: "snow", path: "~/stacks"})
ssh_stat({host: "snow", path: "/etc/nginx/nginx.conf"})

Quick install (one-liner for an AI agent)

Copy this into any agent that can read URLs and follow instructions:

Read https://raw.githubusercontent.com/CallumBicknell/ssh-mcp/main/AGENT_INSTALL.md and follow it exactly.

Development

pnpm install        # install
pnpm run dev        # rebuild on change (tsc --watch)
pnpm run build      # emit to dist/
pnpm run typecheck  # strict type check
pnpm test           # vitest — no real SSH server required
pnpm start          # run on stdio

Tests mock the SSH/SFTP layer; they validate host parsing, validation, truncation (including UTF-8 edge cases), timeout logic, atomic write failure handling, connection-pool behaviour under concurrency, error formatting, and tool registration. CI runs install/typecheck/test/build on Node 22, 24 and 26.

Publishing

Package name on npm: @callumbicknell/ssh-mcp (the unscoped ssh-mcp name is owned by another project).

npm login
npm publish --access public

prepublishOnly runs typecheck + tests + build automatically. npm pack --dry-run shows that only dist/, README.md and LICENSE ship.

Available Tools

9 tools
ssh_execA

Run a shell command on a remote machine over SSH. host is an alias from your local ~/.ssh/config (see ssh_hosts). The command runs via a non-interactive remote shell; stdout and stderr are captured, truncated at a configured size limit, and reported together with the exit code. Non-zero exit codes are surfaced, not hidden. Default timeout: 30s (override per call with timeout). For long-running jobs, run them in the background remotely and poll.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesSSH config alias of the target host
commandYesCommand to execute on the remote host
timeoutNoTimeout in milliseconds (default: 30000)

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses non-interactive execution, combined stdout/stderr capture, truncation at a size limit, exit-code surfacing (non-zero codes not hidden), and the 30s default timeout. It omits any warning that arbitrary command execution can mutate or destroy remote state and any auth/permission prerequisites.

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?

Four tight sentences, front-loaded with the core verb and host semantics, then behavior, then the timeout and long-running guidance. No filler.

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

Completeness4/5

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

For a three-param tool with no output schema, the description covers what an agent needs on the return side (stdout+stderr+exit code, truncation) and timeout behavior. The remaining gap is the absence of any destructive-capability or permission caveat for arbitrary shell execution.

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 coverage is already 100%, so the baseline is 3, but the description adds real meaning: it explains what a `host` alias resolves to, that the timeout is overridable per call, and reconciles units (30s vs the schema's milliseconds).

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?

States a specific verb and resource ('Run a shell command on a remote machine over SSH') and immediately scopes the host parameter to an alias from local ~/.ssh/config. This clearly separates it from siblings like ssh_read_file and ssh_write_file.

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?

Provides clear context for invocation and explicitly routes the agent to `ssh_hosts` for aliases, plus guidance to background long-running jobs rather than block. It stops short of stating when to prefer ssh_read_file/ssh_write_file over a raw shell command, so there is no explicit alternative-selection rule.

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

ssh_hostsA

List the SSH host aliases available in the local SSH client configuration (~/.ssh/config). Use these aliases as the host argument to the other ssh tools. Does not expose keys, usernames' credentials, or secrets.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does so reasonably: it discloses that no keys, usernames' credentials, or secrets are exposed, which is the key safety fact for an agent deciding whether to call it. It does not state whether it is strictly read-only or how missing/empty configs are handled, so it is not fully transparent.

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?

Three short sentences, front-loaded with the core action and source, then the follow-up usage, then the safety note. Every sentence earns its place with no filler.

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

Completeness4/5

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

For a zero-parameter read tool with no output schema or annotations, the description covers what it returns (aliases), where they come from, and how to use them. A brief note on behavior when the config is absent or unreadable would make it fully complete.

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?

Zero parameters, so the baseline is 4; there is nothing for the description to disambiguate. The mention of the `host` argument applies to sibling tools rather than this one, so it adds no parameter detail here but also creates no confusion.

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?

States a specific verb and resource ('List the SSH host aliases') and names the exact source ('~/.ssh/config'), which distinguishes it from the sibling ssh_tunnel/ssh_tunnels listing tools. An agent can identify this as the discovery tool without opening a schema.

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?

Explicitly tells the agent what to do with the output: use the aliases as the `host` argument to the other ssh tools. That is strong routing guidance. It lacks a when-not clause (e.g., what to do if no config exists), so it stops short of a 5.

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

ssh_list_directoryA

List the contents of a directory on a remote SSH host (defaults to the remote user's home directory). Each entry includes type, size, permission bits and modification time.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesSSH config alias of the target host
pathNoDirectory path (defaults to the remote user's home directory)

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. It discloses what each entry includes (type, size, permission bits, modification time), which is useful, but it doesn't mention error behavior (e.g., if the path doesn't exist), permission requirements, or whether it follows symlinks. For a read-only operation, the safety profile is implied but not stated.

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 concise sentences that front-load the action and scope. Every clause earns its place by adding either the default path or the entry fields, with no 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 two-parameter read operation, no output schema, and 100% schema coverage, the description is nearly complete. It covers default and return fields but lacks any mention of error handling or limitations, which would be helpful for an agent in production 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%, so the schema already documents both parameters (host as SSH config alias, path as directory path with default). The description repeats the default for path but adds no syntax, format, or edge-case details beyond the schema. Baseline 3 is appropriate when schema does the heavy lifting.

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?

States a specific verb and resource ('List the contents of a directory on a remote SSH host') and clarifies the default scope (remote user's home directory). It is clearly distinguishable from siblings like ssh_stat (single file metadata) and ssh_read_file (file contents) without needing to open schemas.

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 implies usage context (listing remote directory contents) and defaults, which helps an agent decide to use this over ssh_stat or ssh_read_file. However, it doesn't explicitly state when not to use it or name alternatives for edge cases (e.g., listing a single file's metadata).

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 the contents of a text file on a remote SSH host. Large files are truncated at a configured size limit; for very large files prefer ssh_exec with head/tail/grep.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesSSH config alias of the target host
pathYesAbsolute or relative path of the file to read

TDQS

A4/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It usefully discloses truncation at a configured size limit, a non-obvious trait, but omits permission/auth failure behavior, encoding assumptions, and how partial content is signaled.

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, front-loaded with the core action, and the fallback guidance follows immediately. Every clause earns its place with no filler.

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

Completeness4/5

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

For a two-parameter read tool with full schema coverage, the description is nearly complete, covering the action and the truncation caveat. With no output schema, a brief note on the return format (e.g., whether truncation is flagged in the response) would close the remaining gap.

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% for both parameters (host alias, file path), so the schema already carries the semantics. The description adds no syntax, format, or path-resolution detail beyond what the schema provides, making the baseline 3 correct.

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?

States a specific verb (Read) and resource (contents of a text file on a remote SSH host), including scope (remote host, text file). It implicitly differentiates from ssh_write_file and ssh_exec by naming the exec alternative that handles large-file slicing.

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?

Explicitly routes the agent to ssh_exec with head/tail/grep for very large files, which is clear conditional guidance with a named alternative. It does not, however, address other edge cases (binary files, error paths) that would justify a 5.

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

ssh_statA

Get metadata about a file or directory on a remote SSH host: type, size, permissions, modification time, owner/group ids.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesSSH config alias of the target host
pathYesPath to inspect

TDQS

A3.6/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. It establishes that the operation targets a remote SSH host and what data comes back, but says nothing about failure modes (missing path, permission denied), symlink following, or whether the path is interpreted relative to the remote user's home.

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?

A single sentence that front-loads the verb and resource and then lists return fields. No filler, no redundancy with the title or schema.

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?

With no output schema, the description compensates reasonably by enumerating the returned metadata fields. For a low-risk read tool this is nearly sufficient; only error/edge-case behavior and symlink semantics are unaddressed.

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% and both parameters are documented there (host as SSH config alias, path as the target). The description adds no syntax, default, or format detail beyond the schema, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb (get) and resource (metadata about a file or directory on a remote SSH host), then enumerates exactly what is returned: type, size, permissions, mtime, owner/group ids. This field list implicitly separates it from ssh_read_file (contents) and ssh_list_directory (listing), but no sibling is named explicitly.

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?

Usage is only implied by the purpose: an agent can infer this is for inspecting a single remote path's metadata. There is no statement of when to prefer it over ssh_list_directory or ssh_read_file, nor any prerequisites such as reachability of the host.

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

ssh_tunnelA

Start a persistent local port-forward through the pooled SSH connection for host, e.g. forward local port 8080 to snow:80. The tunnel stays open until ssh_tunnel_stop is called. Returns the tunnel id and the local URL to use.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesSSH config alias to tunnel through
localHostNoLocal bind address127.0.0.1
localPortYesLocal port to listen on (0 = random)
remoteHostNoDestination host from the SSH server's perspective127.0.0.1
remotePortYesDestination port

TDQS

A4.2/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full behavioral burden. It does disclose the key trait of persistence and what the call returns (tunnel id + local URL), but says nothing about prerequisites (existing pooled connection/host alias), auth, port-collision failures, or resource cleanup on error.

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?

Three short sentences, zero filler, with the lifetime constraint and return value front-loaded. Every sentence earns its place.

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?

There is no output schema, so the description usefully explains the return (tunnel id, local URL) alongside lifetime semantics. Only gap is failure/error behavior, which leaves it slightly short of fully self-contained for a stateful networking 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 coverage is 100%, so the baseline is 3, but the worked example ('forward local port 8080 to snow:80') adds real meaning by showing how host, localPort, and remotePort combine, which is more than the schema's per-field text conveys.

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?

Specific verb+resource: 'Start a persistent local port-forward through the pooled SSH connection for `host`', with a concrete example (local 8080 -> snow:80). An agent can distinguish it from siblings ssh_tunnels (listing) and ssh_tunnel_stop (teardown) directly from the description.

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?

Clearly states the lifecycle condition ('stays open until ssh_tunnel_stop is called'), which routes the agent to the teardown sibling. It does not explicitly say when to prefer this over a one-off ssh_exec or when not to open a tunnel, so the guidance is clear but not exhaustive.

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

ssh_tunnelsB

List currently open SSH port-forward tunnels.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.2/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It indicates a read-only listing of currently open tunnels, which is useful, but does not disclose permissions, return format, pagination, or whether it only shows tunnels opened by the current session.

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 a single, front-loaded sentence with no wasted words. It efficiently communicates the core action and scope.

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

Completeness3/5

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

For a zero-parameter list tool with no output schema, the description is minimally adequate. It states what is listed but omits return format, ordering, or scope limitations that could matter for an SSH tunnel inventory.

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

Parameters4/5

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

The tool takes zero parameters, so parameter semantics are not applicable. The baseline score of 4 is appropriate because there are no parameters to document.

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

Purpose4/5

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

States a specific verb ('List') and resource ('SSH port-forward tunnels') with a clear scope modifier ('currently open'). It clearly distinguishes the operation from sibling tools like ssh_tunnel and ssh_tunnel_stop, but does not explicitly name or contrast with them.

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool versus alternatives such as ssh_tunnel or ssh_tunnel_stop. The implied usage is clear from the verb 'List', but no context or exclusions are provided.

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

ssh_tunnel_stopA

Stop a port-forward tunnel by id (from ssh_tunnel / ssh_tunnels).

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesTunnel id to stop

TDQS

A3.9/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full behavioral burden. It does not say whether the tunnel is killed vs detached, whether the local port is released, whether the call errors on an unknown id, or whether it is idempotent — all things an agent needs before retrying or chaining.

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?

One sentence, front-loaded with the action and resource, with the id provenance tucked into a parenthetical. No filler and nothing to trim.

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

Completeness3/5

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

For a one-param, no-output-schema tool the description covers what is done and where the id comes from, which is the minimum viable. With zero annotations and no output schema, it should still say what happens on an unknown id or whether stopping is idempotent.

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 coverage is 100% and the single 'id' param is documented as 'Tunnel id to stop', so the baseline is 3. The description adds genuine value by telling the agent where that id comes from (ssh_tunnel / ssh_tunnels), which the schema does not.

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?

States a specific verb (Stop) and resource (a port-forward tunnel) scoped by id. It also names the sibling tools (ssh_tunnel / ssh_tunnels) where the id originates, so an agent can place it in the tunnel lifecycle without opening any schema.

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 parenthetical '(from ssh_tunnel / ssh_tunnels)' tells the agent this is the teardown counterpart to tunnel creation, giving clear usage context. It stops short of stating when not to call it (e.g., unknown/already-closed id) or what to do instead.

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

ssh_write_fileB

Write text to a file on a remote SSH host. The write is atomic (temporary file, then rename), so a failed or interrupted write never leaves a partially-written destination. Parent directories are NOT created automatically.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostYesSSH config alias of the target host
pathYesAbsolute or relative path of the file to write
contentYesText content to write

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It usefully discloses atomicity (temp file then rename) and that parent directories are not created, but omits key behaviors such as whether existing files are overwritten, permission requirements, or error handling.

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 three sentences with zero waste, and the core purpose is front-loaded before the atomicity and directory-creation details. Every sentence earns its place.

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

Completeness4/5

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

For a simple three-parameter write tool with no output schema and full schema coverage, the description covers the important non-obvious behaviors (atomic write, parent directory behavior). It is nearly complete, though the omission of overwrite semantics is a minor gap.

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 all three parameters. The description adds no parameter-level semantics beyond what the schema provides, making the baseline 3 appropriate.

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

Purpose4/5

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

The description states a specific verb and resource: 'Write text to a file on a remote SSH host.' It clearly distinguishes from read-oriented siblings like ssh_read_file, but does not explicitly differentiate from ssh_exec, which could also write files via shell commands.

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

Usage Guidelines2/5

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

No when-to-use guidance is given, and no alternatives are mentioned. An agent must infer that this tool is for writing files rather than using ssh_exec, with no explicit conditions or exclusions provided.

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.

  1. 9 tool updatesv0.2.1
    • First observedssh_exec
    • First observedssh_hosts
    • First observedssh_list_directory
    • First observedssh_read_file
    • First observedssh_stat
    • First observedssh_tunnel
    • First observedssh_tunnel_stop
    • First observedssh_tunnels
    • First observedssh_write_file

TDQS

A3.9/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct operation: file read/write, command execution, directory listing, metadata stat, host enumeration, and tunnel start/list/stop. The tunnel trio (ssh_tunnel, ssh_tunnels, ssh_tunnel_stop) is clearly differentiated by verb, and file/metadata tools do not overlap. No realistic misselection risk.

Naming Consistency4/5

All tools use a consistent `ssh_` snake_case prefix, which is strong. Minor deviations exist: some are verb_noun (ssh_read_file, ssh_list_directory), some are bare resource plurals (ssh_hosts, ssh_tunnels), and ssh_tunnel_stop puts the verb last instead of following the verb_noun pattern.

Tool Count5/5

Nine tools is well-scoped for an SSH remote-operations server. Each tool covers a distinct capability (file I/O, exec, directory listing, stat, hosts, tunnel lifecycle) without redundancy or bloat.

Completeness4/5

The surface covers core SSH workflows: read, write, execute, list, stat, host discovery, and tunnel lifecycle. Gaps exist for dedicated delete, mkdir, move, and binary/SCP-style transfer, but most of these are workable via ssh_exec with shell commands.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI coding agents to securely execute shell commands on remote SSH servers with granular per-host permission controls. Automatically discovers hosts from ~/.ssh/config and exposes dedicated tools for each allowed host to ensure proper authorization before remote execution.
    11,976 npm
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to securely execute commands, transfer files, and manage port forwarding on remote servers via SSH.
    145 npm
    37
    Apache 2.0