Skip to main content
Glama
SSH MCP Server

SSH MCP Server

by YawLabs

@yawlabs/ssh-mcp

npm version License: MIT

AIツールでSSHを機能させる。 SSH環境を管理し、問題があれば診断・修正し、エージェントにあらゆるものへのリモートアクセスを提供するMCPサーバーです。

Yaw Labsによって構築・保守されています。

問題点

AI CLIツールはサブプロセスで実行されますが、そこではSSHが常に壊れています。エージェントが git pull を試みると Permission denied (publickey) が発生します。サーバーにSSH接続しようとするとエージェントソケットが古くなっています。デプロイしようとすると、インスタンスが再作成されたためにホストキーが変わっています。そのたびにAIは何が問題なのか分からず、混乱に陥ります。

これはSSHキーを必要とするあらゆる状況で発生します:

  • Git — clone, pull, push, fetch, submodules, LFS

  • パッケージマネージャー — プライベートリポジトリからの npm install, pip install, go get, cargo, composer

  • サーバーアクセス — SSH, SCP, SFTP, rsync

  • トンネリング — データベースへのポートフォワーディング, SOCKSプロキシ

  • デプロイメント — Ansible, Terraform, Capistrano, デプロイスクリプト

  • クラウド — AWS EC2, GCP, Azure, DigitalOcean, その他VPS

ssh-mcp はこれを解決します。SSHエージェントの管理、キーの読み込み、失敗時のアクション可能な修正コマンドの提示、そしてリモート操作の提供を、すべてAIエージェントが呼び出せるMCPツールとして実現します。

Related MCP server: Scout MCP

クイックスタート

npm install -g @yawlabs/ssh-mcp

MCPクライアントの設定に追加します:

{
  "mcpServers": {
    "ssh": {
      "command": "ssh-mcp"
    }
  }
}

ツール

SSH環境管理

Git、デプロイ、トンネルなどが壊れないように、ローカルのSSH設定を修正するツールです。

ツール

説明

ssh_agent_ensure

ssh-agentが実行されていることを確認します。必要に応じて起動し、セッション用の環境変数を設定します。

ssh_key_list

~/.ssh/ 内のすべてのSSHキーを、タイプ、フィンガープリント、エージェントの状態とともに一覧表示します。

ssh_key_load

実行中のエージェントにキーを読み込みます。最初にエージェントが起動していることを確認します。

ssh_config_lookup

ホストの有効なSSH設定(ホスト名、ユーザー、ポート、プロキシ、IDファイル)を解決します。

ssh_known_hosts_fix

古いホストキーを削除して再スキャンします。「host key verification failed」エラーを修正します。

ssh_git_check

GitHub, GitLab, BitbucketなどへのGit-over-SSH認証をテストします。

ssh_test

タイミングとアクション可能なエラー詳細を含むクイック接続テストです。

診断

ツール

説明

ssh_diagnose

完全なSSH環境診断。エージェント、キー、設定、known_hosts、接続性をチェックします。すべての失敗に対して正確な修正コマンドを返します。

リモート操作

ツール

説明

ssh_exec

リモートホストでコマンドを実行します。stdout、stderr、終了コードを返します。

ssh_read_file

SFTP経由でリモートホストからファイルを読み取ります。

ssh_write_file

SFTP経由でリモートホストのファイルにコンテンツを書き込みます。

ssh_upload

SFTP経由でローカルファイルをリモートホストにアップロードします。

ssh_download

リモートホストからローカルファイルシステムにファイルをダウンロードします。

ssh_ls

リモートホストのディレクトリ内のファイルを一覧表示します。

高度な操作

エージェントがssh_execで構築する一般的なパターンをラップした、より高速でエラーの少ないツールです。

ツール

説明

ssh_multi_exec

複数のホストでコマンドを並列実行します。ホストごとの結果を返します。

ssh_find

構造化されたパラメータ(名前、タイプ、サイズ、深さ)を使用してリモートでファイルを検索します。

ssh_tail

ファイルの最後のN行を読み取ります(grepパターンによるフィルタリングも可能)。

ssh_service_status

systemdサービスのステータス(アクティブ、PID、稼働時間、説明)を確認します。

自動診断

リモート操作が失敗すると、ssh-mcpは自動的に診断を実行し、その結果をエラーレスポンスに含めます。エージェントが個別に ssh_diagnose を呼び出す必要はありません。エラーメッセージ内で何が問題で、どう修正すべきかが直接伝えられます。

接続プーリング

リモート操作はSSH接続を自動的に再利用します。エージェントが同じホストに対して複数回呼び出しを行う場合、最初の呼び出しで接続が確立され、以降の呼び出しでそれが再利用されます。接続は最後の使用から60秒間維持され、その後自動的に閉じられます。

SSH設定のサポート

すべての接続は ~/.ssh/config を尊重します。ホストエイリアス、カスタムポート、ユーザー名、IDファイル、ProxyJump設定が自動的に使用されます。SSH設定で Host myserver が設定されている場合、単に host: "myserver" を渡すだけで、ssh-mcpがすべてを解決します。

ProxyJump / 踏み台サーバー は自動的にサポートされます。SSH設定にホスト用の ProxyJump bastion がある場合、ssh-mcpは透過的に踏み台を経由して接続します。チェーンされたプロキシも機能します。

ホストキー検証

すべてのリモート操作は、サーバーのホストキーを ~/.ssh/known_hosts と照合して検証します:

  • 既知のホスト、キーが一致 — 許可。

  • 既知のホスト、キーが変更されている — 拒否(MITM保護)。

  • 未知のホスト — 初回接続時に許可(TOFU)。将来の不一致検出のためにキーを固定するには ssh_known_hosts_fix を使用してください。

より厳格な環境では、SSH_MCP_STRICT_HOST_KEY=1 を設定して未知のホストを拒否してください。その場合は、事前に ssh_known_hosts_fix で明示的に追加してください。

診断ツール(ssh_test, ssh_diagnose)は、プローブコマンドに StrictHostKeyChecking=no を使用します。これらのプローブは echo SSH_OK を実行するだけで、資格情報やデータは通過しないため、接続テストにおいてこの緩和された設定は安全です。実際の操作は常に hostVerifier を経由します。

Windowsサポート

Windowsでは、ssh-mcpはOpenSSH Authentication Agentサービスを自動的に検出します(\\.\pipe\openssh-ssh-agent 名前付きパイプ経由)。SSH_AUTH_SOCK は不要です。OpenSSHエージェントサービスが実行されていることを確認してください。

認証

すべてのリモート操作は接続パラメータを受け入れます:

パラメータ

説明

デフォルト

host

SSHホスト名またはIP(必須)

—

port

SSHポート

SSH設定または 22

username

SSHユーザー名

SSH設定または現在のユーザー

privateKeyPath

SSH秘密鍵へのパス

自動検出

password

SSHパスワード(鍵を推奨)

—

認証解決順序: ssh-mcpはこのリストから最初の一致を選択し、それ以降の項目にはフォールスルーしません。これにより、認証方法が決定論的で予測可能になります。

  1. 明示的な privateKeyPath

  2. 明示的な password

  3. ssh-agent (Unixでは SSH_AUTH_SOCK、Windowsでは \\.\pipe\openssh-ssh-agent)

  4. ホスト用の ~/.ssh/config からのIDファイル

  5. デフォルトのキーパス (~/.ssh/id_ed25519, id_rsa, id_ecdsa)

ワークフロー例

エージェントがgit pullできない場合

Agent calls ssh_git_check → "Permission denied. Your SSH key is not registered with github.com."
Agent calls ssh_key_list → finds id_ed25519 exists but is not loaded
Agent calls ssh_key_load("~/.ssh/id_ed25519") → "Key loaded"
Agent calls ssh_git_check → "Git SSH authentication to github.com succeeded as username"
Agent runs git pull → works

インスタンス再作成後にホストキーが変更された場合

Agent calls ssh_exec on server → error: "Host key verification failed"
  (auto-diagnostics included in error: "Fix with ssh_known_hosts_fix")
Agent calls ssh_known_hosts_fix("my-server") → "Host key refreshed"
Agent calls ssh_exec → works

新しいサーバーへの初回接続

Agent calls ssh_test("new-server") → "Connection refused at new-server:22"
Agent calls ssh_diagnose("new-server") → full report showing agent running, keys loaded, but host unreachable
Agent reports: "SSH server isn't running on new-server or port 22 is blocked"

プログラムによる使用

import { connect, exec, diagnose, ensureAgent, listSshKeys, checkGitSsh, ConnectionPool } from '@yawlabs/ssh-mcp';

// Fix SSH environment
const agent = ensureAgent();
console.log(agent.message);

// Check git access
const git = checkGitSsh('github.com');
console.log(git.message);

// List available keys
const keys = listSshKeys();
for (const key of keys) {
  console.log(`${key.name} (${key.type}) - ${key.loadedInAgent ? 'loaded' : 'not loaded'}`);
}

// Run a remote command (one-off)
const client = await connect({ host: 'my-server', username: 'deploy' });
const result = await exec(client, 'uptime');
console.log(result.stdout);
client.end();

// Run multiple commands with connection pooling
const pool = new ConnectionPool();
await pool.withConnection({ host: 'my-server' }, async (client) => {
  const r1 = await exec(client, 'uptime');
  console.log(r1.stdout);
});
// Connection stays open for 60s — next call reuses it
await pool.withConnection({ host: 'my-server' }, async (client) => {
  const r2 = await exec(client, 'df -h');
  console.log(r2.stdout);
});
pool.drain(); // close all connections when done

// Diagnose issues
const report = diagnose('my-server');
console.log(report.overall); // "ok" | "warning" | "error"
for (const check of report.checks) {
  console.log(`[${check.status}] ${check.name}: ${check.message}`);
}

要件

  • Node.js 18以上

  • SSHクライアントがインストールされていること(診断および環境管理用)

ライセンス

MIT

Available Tools

21 tools
ssh_agent_ensureA

Ensure ssh-agent is running and reachable. Starts a new agent if needed and sets environment variables so subsequent SSH operations work. Use this FIRST when SSH operations fail with agent-related errors.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

With no annotations, the description must carry the full burden of behavioral disclosure. It reveals that it starts a new agent if needed and sets environment variables, which is the core behavior. However, it does not elaborate on potential side effects (e.g., environment persistence, failure handling, or whether it modifies the current shell or system-wide settings). This is adequate but 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?

The description is two sentences, front-loaded with the primary purpose ('Ensure ssh-agent is running and reachable'), followed by a concise explanation and usage trigger. No wasted words; every sentence adds necessary information.

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 tool with no parameters and no output schema, the description fully covers what it does and when to use it. It explains the action (starting agent, setting env vars) and the trigger condition. There are no missing details that an agent would need to correctly select and call this 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?

The tool has zero parameters, so the baseline is 4. The description adds no parameter-specific detail (none needed), and the schema already has full coverage with an empty properties object. No additional semantic clarification is required.

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: ensuring ssh-agent is running and reachable, starting a new agent if needed, and setting environment variables. The verb 'ensure' and resource 'ssh-agent' are specific, and it distinguishes from sibling tools that focus on file operations, execution, or diagnostics.

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

Usage Guidelines4/5

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

The description provides an explicit trigger condition: 'Use this FIRST when SSH operations fail with agent-related errors.' This gives clear context for when to invoke the tool, though it does not explicitly mention when not to use it or suggest alternatives (e.g., other diagnostics).

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

ssh_config_lookupA
Read-only

Resolve the effective SSH configuration for a host. Shows hostname, user, port, identity files, proxy settings, and all other options from ~/.ssh/config. Use this to understand how SSH will connect to a host.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address

TDQS

A3.7/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds real information beyond them: the data source (~/.ssh/config) and the fact that it reports the *effective* merged configuration, which tells the agent it is a local, non-mutating resolution rather than a live connection test.

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?

Three short sentences, front-loaded with the action and the returned fields. The trailing 'and all other options from ~/.ssh/config' is slightly redundant after the enumeration, but nothing is bloat.

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?

A single-parameter, read-only, no-output-schema tool; the description plus annotations plus fully documented schema cover what an agent needs to call it correctly. Only the alias-vs-hostname resolution semantics are unstated.

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% for the single required `host` parameter, so baseline is 3. The description does not clarify whether `host` must be a literal Host alias from config or can be an arbitrary hostname/IP subject to wildcard matching — the one semantic point that would add value here.

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 and resource ('Resolve the effective SSH configuration for a host') and enumerates the returned fields (hostname, user, port, identity files, proxy settings), which separates it from the exec/file-oriented siblings. It does not, however, explicitly distinguish itself from the closest conceptual neighbor, ssh_diagnose.

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?

'Use this to understand how SSH will connect to a host' gives an implied context but largely restates the purpose sentence. There is no when-not guidance and no mention of ssh_diagnose or ssh_test as alternatives for connection problems.

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

ssh_deleteA
Destructive

Delete a file or empty directory on a remote host via SFTP. Auto-detects the path type and calls the right SFTP op (unlink for files/symlinks, rmdir for empty dirs). Recursive directory delete is intentionally NOT supported -- for that, use ssh_exec with rm -rf explicitly so the destructive intent is visible in the tool trace. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting. NOT gated by SSH_MCP_COMMAND_WHITELIST / SSH_MCP_COMMAND_BLACKLIST: command policy applies only to ssh_exec and ssh_multi_exec, so a blacklist such as ^rm does NOT block this tool.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
pathYesAbsolute path of the file or empty directory to delete. Must start with /.
portNoSSH port (default: 22)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and openWorldHint=true, and the description adds context annotations cannot express: path-type auto-detection, the deliberate refusal to recurse, and the 30s pool-wait behavior when SSH_MCP_MAX_POOL_SIZE is exhausted. The only gap is that it does not say what happens on failure (e.g., whether a non-empty directory is rejected with a specific error), so a 4 rather than 5.

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?

Front-loaded with the core action, then the failure-mode caveat, then the routing alternative, then the operational footnote. Every sentence carries non-redundant information an agent needs: none is filler, and length is justified by the number of distinct behavioral traits disclosed.

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?

There is no output schema, so the description must carry the full behavioral picture for a destructive SFTP operation, and it does: what is deleted, what is refused, where to go for recursion, pool-wait behavior, and policy exemption. Nothing an agent needs to call it safely and correctly is missing.

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% -- host, path, port, username, password, and privateKeyPath are all documented with defaults and security warnings in the schema itself. The description adds only that the path type is auto-detected, which mildly supplements the `path` param but does not restate or extend the others. Baseline 3 applies when the schema carries this much detail.

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 ('Delete') and resource ('a file or empty directory on a remote host via SFTP') and immediately distinguishes itself from siblings by naming ssh_exec as the recursive-delete path and enumerating the exact SFTP ops used (unlink vs rmdir). An agent can separate this from ssh_mkdir, ssh_write_file, and ssh_exec without opening the schema.

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?

Gives an explicit when/when-not pair: use this for files and empty dirs, do NOT use it for recursive deletes -- use ssh_exec with `rm -rf` instead. It also clarifies the scope of command policy (whitelist/blacklist apply only to ssh_exec and ssh_multi_exec), which prevents the agent from wrongly assuming a blacklist guards this call.

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

ssh_diagnoseA
Read-only

Diagnose SSH connectivity issues. Checks ssh-agent status, loaded keys, known_hosts, SSH config, and attempts a test connection. Use this BEFORE attempting SSH operations if you suspect connectivity issues, or AFTER a failed SSH operation to understand why it failed.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
portNoSSH port (default: 22)

TDQS

A4/5.0
Behavior4/5

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

Annotations declare readOnlyHint=true and openWorldHint=true; the description is consistent with that, disclosing that it opens a live connection ("attempts a test connection") and enumerates every probe it runs, which is real value beyond the annotations. It does not say whether the tool always returns diagnostics rather than erroring on a failed connection, nor whether it has notable latency from the network probe.

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: the first names the purpose, the second enumerates what is checked, the third gives the when-to-use conditions. The intent is front-loaded and no sentence is wasted.

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 only two parameters, one required, and a clear enumeration of probes, the description is sufficient to call it correctly. The one gap is that no output schema exists, so the agent is not told the shape of the diagnostics (per-check pass/fail vs. free-form) nor what is returned when the test connection fails.

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 (host, port) are documented with defaults in the schema, so the schema carries the burden. The description adds no host/port semantics such as whether to pass a hostname from config or whether the port affects all checks, so 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 and resource ("Diagnose SSH connectivity issues") and enumerates the concrete checks performed (agent status, keys, known_hosts, config, test connection), so an agent knows exactly what it does. It does not, however, distinguish itself from overlapping siblings such as ssh_test, ssh_agent_ensure, ssh_config_lookup, or ssh_known_hosts_fix, which cover a subset of the same ground.

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 gives both timing conditions: use BEFORE SSH operations when connectivity is suspect, or AFTER a failure to diagnose. That is a clear, actionable trigger. It stops short of naming alternatives (e.g. "use ssh_test for a single quick reachability check; use ssh_agent_ensure if you only need the agent running").

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 host to local filesystem via SFTP. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
portNoSSH port (default: 22)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
localPathYesLocal path to save the downloaded file
remotePathYesAbsolute path to the remote file. Must start with /.
privateKeyPathNoPath to SSH private key

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations provided, the description carries the full burden. It usefully discloses connection pool behavior: waiting up to 30s when the pool is full and honoring SSH_MCP_MAX_POOL_SIZE. However, it does not disclose other important behavioral traits such as whether an existing local file is overwritten, authentication requirements beyond the schema, or failure/error behavior.

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 with no filler. The core purpose is front-loaded, and the operational detail about pool wait behavior is separated cleanly. Every sentence earns its place.

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?

Given no output schema and no annotations, the description should cover key operational behavior. It covers purpose and pool waiting, and the schema handles parameter semantics, but it omits what happens on local file conflicts, return values, and explicit guidance for choosing between download and read/upload alternatives. This leaves moderate gaps for an agent deciding how to invoke it correctly.

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 7 parameters including defaults, required fields, the absolute path constraint for remotePath, and the password plaintext warning. The description adds no parameter-level detail beyond indicating the source and destination, so the baseline score of 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 states a precise action: 'Download a file from a remote host to local filesystem via SFTP.' It specifies both direction (remote to local) and transport (SFTP), which clearly distinguishes it from siblings like ssh_upload, 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 Guidelines3/5

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

The description implies when to use the tool—whenever a file needs to be downloaded from a remote host—but provides no explicit guidance about alternatives or when not to use it. It does not mention that ssh_read_file or ssh_exec might be better for reading file contents without copying to local disk.

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

ssh_execA

Execute a command on a remote host via SSH. The command is interpreted by the remote login shell — pipes, redirects, globs, and other shell metacharacters work as expected. Returns up to three content blocks in this order: the status ([exit code: N], plus the signal and any truncation), then [stderr], then [stdout]. Status comes first so a proxy that cuts long results (Yaw MCP keeps about 100 KB) never drops the exit code; for big output, filter or page on the remote (head, tail, grep). Use env to set environment variables for this call without modifying the command string. Subject to SSH_MCP_COMMAND_WHITELIST / SSH_MCP_COMMAND_BLACKLIST if configured (policy is checked against the env-prefixed command).

NameRequiredDescriptionDefault
envNoEnvironment variables to set for this command. Injected as a `KEY='value' ...` prefix; works on any sshd regardless of AcceptEnv config. VALUES are POSIX-single-quoted, so any byte is safe in a value. KEYS cannot be quoted (a shell assignment prefix requires a bare name), so each key must match /^[A-Za-z_][A-Za-z0-9_]*$/ (the POSIX name grammar) — a key outside that grammar is rejected and the call fails before anything is sent to a host. Command policy is checked against the PREFIXED command, so a `^`-anchored whitelist pattern stops matching once this is set.
hostYesSSH hostname or IP address
portNoSSH port (default: 22)
commandYesShell command to execute on the remote host (interpreted by the remote login shell)
timeoutNoCommand timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately.
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4/5.0
Behavior5/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 so well: it discloses the exact three-block return ordering, the rationale for status-first (proxy truncation near 100 KB), and that SSH_MCP_COMMAND_WHITELIST/BLACKLIST may reject the call. These are non-obvious behaviors an agent cannot get from schema or annotations.

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?

Front-loaded with the core action, then layered with return format, truncation rationale, and policy notes — each sentence adds information. Slightly dense with implementation-specific detail (the ~100 KB Yaw MCP figure) that could be trimmed.

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 an 8-parameter, nested-object tool with no output schema and no annotations, the description covers what an agent needs: execution semantics, return block layout, truncation behavior, output-size mitigation, env injection, and policy enforcement. Nothing critical to a correct call is missing.

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 host, port, timeout, password, and the env quoting/grammar rules in detail. The description only adds the note that policy is checked against the env-prefixed command, which is largely duplicative of the env property's own text.

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 and resource ("Execute a command on a remote host via SSH") and clarifies that the remote login shell interprets metacharacters. It never names a sibling, so an agent must infer that ssh_read_file/ssh_write_file/ssh_ls are the narrower alternatives for those 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?

Usage guidance is implied rather than explicit: it recommends remote-side filtering (head, tail, grep) for large output and explains `env` for per-call variables, but never says when to prefer ssh_exec over ssh_multi_exec, ssh_read_file, or ssh_tail. The agent gets operational hints but no routing rules.

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

ssh_findB
Read-only

Search for files on a remote host. Wraps the find command with structured parameters so you don't have to construct find syntax manually.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
nameNoFilename pattern with wildcards (e.g. '*.log', 'config.*')
pathYesDirectory to search in (e.g. /var/log, /home/user)
portNoSSH port (default: 22)
typeNoFile type: f=file, d=directory, l=symlink
newerNoReference file path -- find matches files modified more recently than this file
maxsizeNoMaximum file size (e.g. '10M', '500k')
minsizeNoMinimum file size (e.g. '1M', '100k')
timeoutNoCommand timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately.
maxdepthNoMaximum directory depth to search (0 = the path itself only)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and network profile is known. The description adds that the operation runs remotely via a wrapped find, but says nothing about result shape, permission failures, partial output, or how the timeout/pool behavior (documented only in the schema) affects the call.

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?

Two front-loaded sentences with no filler; the purpose arrives first and the rationale second. It is efficient, though it leaves the description thin relative to a 13-parameter tool.

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?

With full schema coverage and read-only annotations, the description is minimally sufficient to invoke the tool correctly. However, for a search tool with no output schema, it omits the return format (matched paths? metadata?) and gives no guidance relative to the many sibling listing/inspection tools.

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 every one of the 13 parameters is already documented in structured data, including wildcard syntax, size units, and the timeout/pool note. The description adds no parameter-level meaning beyond that, which is the expected baseline.

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 and resource ('Search for files on a remote host') plus the underlying mechanism ('wraps the find command'), which separates it from siblings like ssh_ls or ssh_stat. It never names a sibling explicitly, so the differentiation is inferred rather than stated.

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 phrase 'so you don't have to construct find syntax manually' implies when this tool is preferable to raw ssh_exec, but there are no explicit when-to-use/when-not rules, no mention of ssh_ls as the lighter alternative for simple listing, and no prerequisites or exclusions.

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

ssh_git_checkA

Test Git-over-SSH authentication to a hosting provider (GitHub, GitLab, Bitbucket, etc). Verifies your SSH key is registered and working. Use this when git clone/pull/push fails with SSH errors.

NameRequiredDescriptionDefault
hostNoGit hosting hostname (default: "github.com"). Omit for the default; an empty string is rejected.
userNoSSH user for the git host (default: "git"). Omit for the default; an empty string is rejected.

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 must carry the behavioral disclosure burden. It accurately conveys that the tool performs a test/verification of SSH authentication, implying a non-destructive diagnostic. However, it does not explicitly state the absence of side effects, potential prerequisites (e.g., key loaded via ssh_agent_ensure), or failure modes. This is adequate but not comprehensive.

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, both information-dense without redundancy. The primary action and purpose are front-loaded, followed by a concrete usage condition. No filler words; every phrase contributes to the agent's understanding. This is a model of conciseness.

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 tool with two optional parameters and no output schema, the description covers the purpose, when to use it, and what it verifies. The only gap is the lack of explicit return-value specification, but given the diagnostic nature, the outcome (success/failure) is implied. The description is complete enough for an agent to select and invoke it correctly.

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 descriptions for both parameters (host and user), including defaults and constraints. With 100% schema description coverage, the description adds no additional parameter detail, which is acceptable. The baseline of 3 applies because the schema sufficiently documents the parameters without needing extra elaboration.

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 states a specific action ('Test Git-over-SSH authentication') and clearly identifies the resource (hosting providers like GitHub, GitLab, Bitbucket). It is unambiguous and distinct from generic SSH tools by focusing on Git-over-SSH. The mention of verifying the SSH key registration and working status adds actionable clarity.

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 gives an explicit trigger: 'Use this when git clone/pull/push fails with SSH errors.' This clearly indicates the intended scenario. It does not explicitly state when not to use it or name alternatives, but the specific use case distinguishes it from siblings like ssh_test without requiring further detail. A stronger exclusion clause would elevate this to 5.

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

ssh_key_listA
Read-only

List all SSH private keys in ~/.ssh/ with their type, fingerprint, and whether they are loaded in the agent. Use this to find which keys are available and which ones need to be loaded. Reports isError only when ~/.ssh exists but could not be read -- an absent or empty ~/.ssh is a successful answer with a ssh-keygen hint.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

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

Adds genuinely non-obvious behavior beyond the readOnlyHint/openWorldHint annotations: isError is raised only when ~/.ssh exists but is unreadable, while a missing or empty directory is a successful result with a ssh-keygen hint. That error semantics is valuable, though file permissions, symlink handling, and public-key visibility are unstated.

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 tight sentences: what it returns first, then when to use it, then error semantics. Every sentence carries information and nothing is repeated from structured fields.

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?

A zero-parameter read tool with no output schema, and the description covers the returned fields plus the success/failure boundary. Nothing an agent needs in order to call it and interpret the result is missing.

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 no parameters, so there is nothing for the description to document and the baseline of 4 applies. The description does not need to compensate for any schema gap.

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 (list) plus resource (SSH private keys) plus scope (~/.ssh/), and it names the returned fields: type, fingerprint, agent-loaded status. This is clearly distinguishable from ssh_key_load, which it implicitly signals as the follow-up action.

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?

States an explicit usage context: find which keys are available and which need loading, which routes the agent toward ssh_key_load for the second step. It doesn't state any when-not conditions or name the sibling tool outright, 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_key_loadA

Load an SSH private key into the running agent. Ensures the agent is running first. Use this after ssh_key_list shows a key that is not loaded.

NameRequiredDescriptionDefault
keyPathYesPath to the SSH private key to load (e.g. ~/.ssh/id_ed25519)

TDQS

A4/5.0
Behavior3/5

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

No annotations are present, so the description carries the behavioral burden. It adds useful context by noting 'Ensures the agent is running first', but it does not disclose error handling, idempotency, or permission needs. Minimum viable for a simple load operation.

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, both earning their place. The main action is front-loaded, the prerequisite and usage condition are stated succinctly, 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 simple one-parameter tool with no output schema, this description provides enough to invoke correctly: what it does, a key prerequisite, and the condition for use. It is slightly incomplete in not mentioning return values or error scenarios, but these are minor for this operation.

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 the single parameter keyPath, and the description does not add meaning beyond what the schema already provides. 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 clearly states the action ('Load an SSH private key'), the target ('into the running agent'), and differentiates from siblings by referencing ssh_key_list. It is specific and unambiguous.

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 provides a condition for use ('after ssh_key_list shows a key that is not loaded'), but does not mention when not to use it or compare with sibling ssh_agent_ensure, which also handles agent startup. Lacks explicit alternatives.

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

ssh_known_hosts_fixA

Remove a stale host key from known_hosts and re-scan the host to add the current key. Use this when you see 'Host key verification failed' errors, typically after a server has been recreated or reprovisioned.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
portNoSSH port (default: 22)

TDQS

A4.2/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 clearly discloses the mutating behavior: removal of a stale key followed by a re-scan to add the current key. It goes beyond the tool name by specifying the action sequence and trigger, although it doesn't mention the affected known_hosts path or 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?

Two brief sentences: the first describes the action, the second the trigger. No waste and front-loaded with the primary behavior.

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?

Adequate for a two-parameter tool with no output schema: an agent knows what it does and when to invoke it. It could note that this modifies the local user's known_hosts file, but the action is clear from the phrase 'remove a stale host key from known_hosts'.

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 host and port each described. The description adds no extra parameter detail beyond the schema, so baseline 3 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?

States a specific sequence (remove stale key, re-scan host) on a specific resource (known_hosts), and explicitly names the error condition it addresses. This differentiates it from sibling ssh tools that execute, read, or list remote files.

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 when to use: upon 'Host key verification failed' errors after server recreate/reprovision. Does not name alternatives or exclude cases such as using ssh_diagnose for broader connectivity checks, so one point off.

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

ssh_lsA
Read-only

List files in a directory on a remote host via SFTP. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
pathYesAbsolute path to the remote directory. Must start with /.
portNoSSH port (default: 22)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A3.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered; the description adds genuinely new behavioral context by disclosing the connection-pool limit (SSH_MCP_MAX_POOL_SIZE, default 100) and a 30s wait before starting, which tells the agent this call can block. It stops short of stating result shape, whether listing is recursive, or whether hidden files are included.

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, zero filler, and the core operation is front-loaded ahead of the secondary pool-exhaustion caveat. Every clause carries information an agent can act on.

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?

With no output schema, the description is the only place to learn what a listing returns (entry names only? metadata? symlink handling?), and it says nothing about that. The blocking/pool behavior is covered well, but for a read/list tool the return semantics gap is a real omission.

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 all six parameters (including the plaintext-password warning and default port/user) are already documented in the schema. The description adds no parameter-level meaning beyond what the schema provides, 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 and resource ('List files in a directory on a remote host') plus the transport ('via SFTP'), so the agent knows exactly what operation this performs. It does not, however, distinguish itself from close siblings like ssh_find or ssh_stat, which also touch remote paths.

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?

The second sentence describes pool-exhaustion behavior, not when to choose this tool over alternatives. There is no guidance on when to use ssh_ls versus ssh_find (search), ssh_stat (metadata), or ssh_read_file (contents), and no stated prerequisites beyond the implied SSH connection.

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

ssh_mkdirA

Create a directory on a remote host via SFTP. Set recursive: true to create parent directories as needed (like mkdir -p). Existing intermediate dirs are tolerated; an existing leaf path is still an error. Unlike the other SFTP tools, the path may be relative. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting. NOT gated by SSH_MCP_COMMAND_WHITELIST / SSH_MCP_COMMAND_BLACKLIST: command policy applies only to ssh_exec and ssh_multi_exec, so a blacklist such as ^rm does NOT block this tool.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
pathYesPath of the directory to create. Absolute (starting with /) is recommended and unambiguous. A relative path is also accepted and resolves against the SFTP working directory, which is normally the remote user's home. ~ is NOT expanded — SFTP has no shell to expand it.
portNoSSH port (default: 22)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
recursiveNoCreate parent directories as needed (default: false). Like `mkdir -p`.
privateKeyPathNoPath to SSH private key

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure and does so richly. It documents error semantics ('existing leaf path is still an error'), waiting behavior ('waits up to 30s for a free slot'), and a major security/policy exception ('NOT gated by SSH_MCP_COMMAND_WHITELIST / BLACKLIST'). These exceed basic expectations and give the agent concrete expectations beyond just 'creates a directory.'

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 and front-loaded: it opens with the core purpose, then immediately covers recursive behavior, then path relativity, then connection pool, then command policy. Every sentence earns its place; there is no fluff or redundancy. It packs a lot of important detail into a compact paragraph without being verbose.

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 (mkdir) and a fully documented schema, the description covers the key contextual gaps: error behavior, wait timeout, and command policy interplay. It does not explicitly state what happens after the 30s wait exceeds or what the success return value is, but these are minor for this operation. The description is largely complete for an agent to invoke the tool correctly.

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. The description adds meaningful semantics beyond the schema, particularly for `recursive`: it explains the behavior of existing intermediate dirs vs. an existing leaf path, and the `~` expansion caveat for `path` (though that is also in the schema). This adds value beyond the raw property definitions, justifying a 4.

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 opens with a specific verb+resource: 'Create a directory on a remote host via SFTP.' This clearly states the tool's action and domain, and it distinguishes itself from siblings by noting 'Unlike the other SFTP tools, the path may be relative,' which helps an agent tell it apart from other SFTP operations like ssh_write_file or ssh_ls.

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

Usage Guidelines4/5

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

The description provides clear context about when to use the tool, such as supporting relative paths and the recursive flag behavior, but it stops short of explicitly naming alternatives or saying 'use this instead of ssh_exec for mkdir.' It includes a relevant exclusion about command policy (not gated by whitelist/blacklist), which is an implicit usage condition, but no direct when-not statements.

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

ssh_multi_execA

Execute a command on multiple remote hosts in parallel. Runs at most SSH_MCP_MAX_POOL_SIZE hosts at once (default 100) and works through a longer list as slots free up. timeout is per host: it bounds each host's command, not the whole call. Each parallel slot works through its share of the list one host at a time, so with the pool to itself a call can take up to about ceil(hosts / SSH_MCP_MAX_POOL_SIZE) x (timeout + connect time). The connection pool is shared with every other tool; when it is full this call waits for slots instead of failing, and gives up only when none of its own hosts holds a slot and a full timeout has passed with none of them starting or finishing. The hosts waiting at that point (up to one per parallel slot) and every host still queued then report Connection pool is full; the queued ones are never attempted. Rerun those hosts once the other calls finish, or raise SSH_MCP_MAX_POOL_SIZE. Returns results per host. Use this instead of calling ssh_exec multiple times — it's faster and shows results side by side. Use env to set environment variables for this call without modifying the command string. Subject to SSH_MCP_COMMAND_WHITELIST / SSH_MCP_COMMAND_BLACKLIST if configured (policy is checked once, against the env-prefixed command, before fan-out).

NameRequiredDescriptionDefault
envNoEnvironment variables to set for this command. Injected as a `KEY='value' ...` prefix; works on any sshd regardless of AcceptEnv config. VALUES are POSIX-single-quoted, so any byte is safe in a value. KEYS cannot be quoted (a shell assignment prefix requires a bare name), so each key must match /^[A-Za-z_][A-Za-z0-9_]*$/ (the POSIX name grammar) — a key outside that grammar is rejected and the call fails before anything is sent to a host. Command policy is checked against the PREFIXED command, so a `^`-anchored whitelist pattern stops matching once this is set.
portNoSSH port (default: 22)
hostsYesList of SSH hostnames or IPs
commandYesShell command to execute on all hosts
timeoutNoPer-host command timeout in milliseconds (default: 30000): bounds each host's command, not the whole call. Also the call's no-progress budget on a full pool (see the tool description).
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4.5/5.0
Behavior5/5

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

With zero annotations, the description carries the full burden and does so thoroughly: it discloses the shared connection pool, queueing rather than failing, the exact no-progress give-up condition, which hosts get reported as 'Connection pool is full', and that whitelist/blacklist policy is evaluated once against the env-prefixed command before fan-out. These are non-obvious behaviors an agent could not infer from the schema.

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

Conciseness4/5

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

The operation and its primary use case are front-loaded, and the dense middle is warranted by genuinely complex pool semantics. It is longer than ideal — the pool-exhaustion paragraph is a single hard-to-parse sentence — but almost every clause carries operational information rather than 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?

Concurrency, timeout, policy, and failure behavior are all covered for an 8-parameter tool with no annotations. The one gap is the return value: 'Returns results per host' does not say whether each entry carries exit status, stdout/stderr separation, or how failed hosts are represented, and there is no output schema to fall back on.

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 baseline is 3. The description reinforces the important `timeout` scoping (per host, not whole call) and the env-prefix interaction with `^`-anchored whitelists, but those details are already present in the schema, so it adds little beyond structured data.

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, resource, and concurrency mode ('Execute a command on multiple remote hosts in parallel') and explicitly distinguishes itself from the sibling ssh_exec by naming the alternative pattern to avoid. An agent can select this over ssh_exec without opening either schema.

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?

Gives an explicit routing rule ('Use this instead of calling ssh_exec multiple times — it's faster and shows results side by side'), plus remedial guidance for the failure path (rerun the reported hosts or raise SSH_MCP_MAX_POOL_SIZE) and a note on when to prefer `env` over command-string manipulation.

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 file from a remote host via SFTP. A whole-file read is limited to 10 MB. For a large file -- or behind a proxy that caps results, such as Yaw MCP at about 100 KB -- read it in pages with offset and length (bytes): a paged read returns a status block first ([bytes A-B of SIZE] and the next offset) and then the text. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
pathYesAbsolute path to the remote file. Must start with /.
portNoSSH port (default: 22)
lengthNoNumber of bytes to read (default: the rest of the file, up to 10 MB). Behind Yaw MCP keep it at or under about 90000 so the page is not cut. A page boundary can split a multi-byte UTF-8 character.
offsetNoByte offset to start reading at (default 0). Setting offset or length switches to a paged read.
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the readOnly and openWorld annotations, the description discloses important behavioral traits: the 10 MB whole-file limit, proxy result caps, paged-read status output, UTF-8 boundary splitting, and a 30-second wait when the SSH connection pool is exhausted. These are exactly the operational constraints an agent needs before invoking the tool.

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 compact and front-loaded: the core action and size limit appear first, followed by paging guidance and pool-wait behavior. Every sentence carries useful operational information with no filler.

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?

With no output schema, the description compensates by explaining paged-read return behavior, size limits, proxy caps, and pool timeouts. Combined with the fully described input schema, an agent has enough context to call this tool correctly and understand its key constraints.

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 schema already documents host, path, port, length, offset, auth fields, and pagination behavior in detail. The description adds useful paging context but largely repeats what the schema already conveys about offset and length, so it does not substantially add parameter-level meaning beyond the structured fields.

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: reading a remote file via SFTP. It is clearly about file reading, but it does not explicitly differentiate itself from sibling tools such as ssh_download or ssh_tail, which also retrieve remote file content.

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?

It gives concrete invocation guidance: whole-file reads are capped at 10 MB, and large files or proxy-capped environments should use paged reads with offset and length. It does not explicitly say when to choose this tool over alternatives like ssh_download or ssh_tail, so it stops short of full when/when-not guidance.

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

ssh_service_statusA
Read-only

Check the status of a systemd service on a remote host. Returns whether it's active, its PID, uptime, and description. Use this instead of ssh_exec with systemctl.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
portNoSSH port (default: 22)
serviceYesSystemd service name (e.g. nginx, sshd, docker)
timeoutNoCommand timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately.
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint and openWorldHint, so the safety profile is covered. The description adds value by disclosing the return payload (active state, PID, uptime, description), which is meaningful since there is no output schema. It doesn't mention failure behavior for an unreachable host or unknown unit, keeping it at 4.

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 with no filler: purpose first, return contents second, sibling routing third. 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?

With no output schema, the description usefully summarizes the returned fields, and the schema carries auth and timeout detail. Minor gaps on error/edge behavior (host unreachable, service not found) keep it just short of complete.

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 every parameter — including the plaintext-password warning and timeout/pool-slot semantics — is documented in the schema itself. The description adds nothing about the 'service' or 'host' arguments, so the baseline 3 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?

States a specific verb and resource ('Check the status of a systemd service on a remote host') and immediately distinguishes itself from the generic sibling by saying to use it instead of ssh_exec with systemctl. An agent can select it over the 20 siblings without opening the 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 names the alternative it replaces ('Use this instead of ssh_exec with systemctl'), which is the key routing decision. It stops short of covering edge cases — e.g. non-systemd hosts or when ssh_exec would still be appropriate — so it 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_statA
Read-only

Get metadata for a file or directory on a remote host via SFTP. Returns size, permissions (octal), uid/gid, mtime/atime, and the path type. Symlinks are reported as symlink -> <target kind>: the type describes the link itself while size/mode/mtime describe its TARGET, and a dangling symlink is reported rather than erroring. Use this instead of parsing ls -la output. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
pathYesAbsolute path to the remote file or directory. Must start with /.
portNoSSH port (default: 22)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4.5/5.0
Behavior5/5

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

Annotations only declare readOnly and openWorld; the description goes further with concrete behavior: symlink type describes the link while size/mode/mtime describe the target, dangling symlinks are reported rather than erroring, and pool saturation causes up to a 30s wait (with the SSH_MCP_MAX_POOL_SIZE knob named). That is exactly the kind of context annotations cannot convey.

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 sentences, front-loaded with purpose, then the non-obvious symlink semantics, then the pool-wait caveat. Every sentence carries information an agent would otherwise have to guess.

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?

With no output schema, the description supplies the return fields (size, octal permissions, uid/gid, mtime/atime, path type) and the symlink edge case, plus latency behavior under pool pressure. Nothing critical for correct invocation is missing.

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 host, path, port, credentials and key path are all documented in the schema, including a strong warning about plaintext passwords. The description adds no parameter-level detail beyond the return-field discussion, so baseline 3 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?

States a specific verb and resource ('Get metadata for a file or directory on a remote host via SFTP') and names the mechanism, immediately distinguishing it from listing tools. The 'instead of parsing ls -la output' line further separates it from ssh_ls-style siblings.

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 says to use this rather than parsing `ls -la` output, giving a clear usage condition. It does not, however, route against the actual sibling tools (ssh_ls, ssh_find, ssh_read_file) or state when-not-to-use beyond that one comparison.

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

ssh_tailA
Read-only

Read the last N lines of a file on a remote host, optionally filtering by a grep pattern. Use this for reading log files instead of ssh_exec with manual tail/grep commands.

NameRequiredDescriptionDefault
grepNoCase-insensitive pattern to filter lines
hostYesSSH hostname or IP address
pathYesAbsolute path to the file to tail
portNoSSH port (default: 22)
linesNoNumber of lines to read from the end (default: 100). Must be a positive integer.
timeoutNoCommand timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately.
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and openWorldHint=true, so the safety and environment profile is known. The description adds the intended use case context but says nothing about auth requirements, what happens on a missing file or unreachable host, or whether the connection pool/timeout behavior is shared with ssh_exec; the pool caveat lives only in the schema.

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

Conciseness5/5

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

Two short sentences: the first defines the operation, the second gives the routing advice. Nothing redundant, and the purpose is front-loaded.

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 9 parameters, full schema coverage, and annotations covering safety, the description is nearly sufficient for correct invocation. The remaining gap is that it never states what comes back (raw lines? exit status? error message on missing file), which matters slightly more because no output schema exists.

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 every parameter (host, path, lines, grep, timeout, auth fields) is already documented in structured data. The description mentions line count and grep filtering only in passing and adds no syntax 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.

Purpose5/5

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

States a specific verb and resource ('Read the last N lines of a file on a remote host') plus the optional filter, which is a precise and non-tautological statement of what the tool does. It is clearly distinguishable from generic execution siblings like ssh_exec or ssh_multi_exec.

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 away from the obvious alternative: 'Use this for reading log files instead of ssh_exec with manual tail/grep commands.' It doesn't mention ssh_read_file, which is arguably the closest sibling for plain file reads, so a small differentiation gap remains.

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

ssh_testA

Quick connectivity test to an SSH host. Reports success/failure with timing and actionable error details. Lighter and faster than ssh_diagnose — use this for a quick check before running operations.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
portNoSSH port (default: 22)

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the tool reports success/failure with timing and actionable error details, which informs the agent about the return type and content. It does not mention authentication or potential side effects, but 'test' implies a non-destructive operation. The description adds meaningful context beyond the bare name, so a 4 is appropriate.

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: two sentences that front-load the core purpose, then immediately state the differentiation and usage context. Every sentence earns its place, with no redundant phrasing or 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?

Given the simple two-parameter schema and absence of an output schema, the description covers the essential aspects: what it does, what it returns (success/failure, timing, error details), and when to use it. It lacks precise output formatting details, but it provides enough for an agent to invoke it correctly and interpret the result. This is nearly complete for such a lightweight tool.

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 already covers 100% of parameter descriptions (host and port). The description adds no additional meaning about parameters—it does not explain expected formats, defaults, or how the port is used beyond the schema's basic default of 22. Therefore, the baseline of 3 is appropriate; the description adds no extra value here.

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: a quick connectivity test to an SSH host, reporting success/failure with timing and error details. It explicitly distinguishes itself from the sibling ssh_diagnose by being lighter and faster, so an agent can easily tell them apart without examining schemas.

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?

It explicitly states when to use this tool ('use this for a quick check before running operations') and contrasts it with ssh_diagnose ('lighter and faster'). This gives clear context and implies when not to use it (when a deeper diagnostic is needed). The guidance is direct and actionable.

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

ssh_uploadA

Upload a local file to a remote host via SFTP. Reads an arbitrary local file at an agent-chosen localPath -- any file readable by this process leaves the machine toward the remote host (the mirror direction of ssh_download's local write). If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting. NOT gated by SSH_MCP_COMMAND_WHITELIST / SSH_MCP_COMMAND_BLACKLIST: command policy applies only to ssh_exec and ssh_multi_exec, so a blacklist such as ^rm does NOT block this tool.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
portNoSSH port (default: 22)
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
localPathYesPath to the local file to upload
remotePathYesAbsolute path on the remote host. Must start with /.
privateKeyPathNoPath to SSH private key

TDQS

A3.8/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 substantial work: it discloses that any process-readable file leaves the machine, the 30s pool-wait behavior under SSH_MCP_MAX_POOL_SIZE, and the important exemption from SSH_MCP_COMMAND_WHITELIST/BLACKLIST with a concrete `^rm` example. It does not say whether an existing remote file is overwritten or the call fails, nor what the tool returns, which is a meaningful gap for a write operation.

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?

Front-loaded with the action, then the security and concurrency constraints in descending priority, with no filler. The final policy-exemption sentence is long but earns its length by preventing a real mistaken assumption about blacklists.

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 7-parameter mutation tool with no annotations and no output schema, the description covers the safety surface, concurrency behavior, and policy scope well. The remaining gap is overwrite/failure semantics and what a successful call reports, which an agent would want before re-uploading to an existing path.

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; the description rises above it by scoping `localPath` as "agent-chosen" and emphasizing that any readable file is exfiltrated, which is security-relevant meaning the schema's neutral one-liner does not convey. It adds no new detail on `remotePath`, `port`, or auth parameters, but those are already fully documented.

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 opening sentence gives a specific verb and resource ("Upload a local file to a remote host via SFTP") and explicitly positions it as the mirror direction of ssh_download. However, it never distinguishes itself from ssh_write_file, the closest sibling, so an agent must infer the boundary between uploading a local file and writing remote content.

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 through the ssh_download comparison and by naming ssh_exec/ssh_multi_exec as the tools governed by command policy. There is no explicit "use ssh_upload when X, use ssh_write_file when Y" guidance, leaving the most ambiguous sibling relationship unresolved.

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 host via SFTP. Creates or overwrites the file. If the connection pool is full (SSH_MCP_MAX_POOL_SIZE, default 100), waits up to 30s for a free slot before starting. NOT gated by SSH_MCP_COMMAND_WHITELIST / SSH_MCP_COMMAND_BLACKLIST: command policy applies only to ssh_exec and ssh_multi_exec, so a blacklist such as ^rm does NOT block this tool.

NameRequiredDescriptionDefault
hostYesSSH hostname or IP address
pathYesAbsolute path to the remote file. Must start with /.
portNoSSH port (default: 22)
contentYesFile content to write
passwordNoSSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process.
usernameNoSSH username (default: current user)
privateKeyPathNoPath to SSH private key

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and openWorldHint=true, and the description adds real value on top: it makes explicit that existing file contents are overwritten, discloses the pool-exhaustion wait (up to 30s, gated by SSH_MCP_MAX_POOL_SIZE, default 100), and clarifies that command blacklists do not protect against it. It omits failure behavior (permission denied, missing parent directory) and whether the write is atomic, which are the remaining gaps for a destructive mutation.

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?

Front-loaded with purpose and overwrite semantics before the operational caveats, and every sentence carries information. The blacklist sentence is long and tool-specific but earns its place by preventing a false safety assumption.

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 destructive 7-parameter write with full schema coverage, no output schema, and safety hints already in annotations, the description covers purpose, overwrite risk, throughput limits, and a misleading policy assumption. Nothing essential to calling it correctly is missing.

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 the schema already documents host, path, port, content, credentials, and key path with guidance (password plaintext warning, absolute-path requirement). The description adds no parameter-level detail beyond what the schema provides, 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 (write), resource (remote file), and transport (SFTP), plus the create-or-overwrite semantics. It does not explicitly distinguish itself from ssh_upload, the other obvious write-path sibling, so an agent must infer that ssh_upload takes a local source path while this takes inline content.

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?

Gives clear operating context: the tool bypasses SSH_MCP_COMMAND_WHITELIST/BLACKLIST, which is exactly the kind of pre-call assumption an agent might get wrong, and names the sibling tools (ssh_exec, ssh_multi_exec) where policy does apply. It stops short of stating when to prefer ssh_upload or ssh_delete over this tool, so no direct alternative routing is 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. 3 tool updatesv0.18.1
    • Changedssh_find4 fields changed
      • changedInput schema / properties / maxdepth / description
        Previous value: -"Maximum directory depth to search"New value: +"Maximum directory depth to search (0 = the path itself only)"
      • addedInput schema / properties / maxdepth / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / maxdepth / minimum
        Added value: +0
      • changedInput schema / properties / maxdepth / type
        Previous value: -"number"New value: +"integer"
    • Changedssh_multi_exec1 field changed
      • addedInput schema / properties / hosts / minItems
        Added value: +1
    • Changedssh_read_file2 fields changed
      • addedInput schema / properties / length
        Added value: +{
        +  "description": "Number of bytes to read (default: the rest of the file, up to 10 MB). Behind Yaw MCP keep it at or under about 90000 so the page is not cut. A page boundary can split a multi-byte UTF-8 character.",
        +  "exclusiveMinimum": 0,
        +  "maximum": 10485760,
        +  "type": "integer"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "description": "Byte offset to start reading at (default 0). Setting offset or length switches to a paged read.",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
  2. 13 tool updatesv0.17.0
    • Changedssh_delete1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path of the file or empty directory to delete"New value: +"Absolute path of the file or empty directory to delete. Must start with /."
    • Changedssh_download1 field changed
      • changedInput schema / properties / remotePath / description
        Previous value: -"Absolute path to the remote file"New value: +"Absolute path to the remote file. Must start with /."
    • Changedssh_exec2 fields changed
      • changedInput schema / properties / env / description
        Previous value: -"Environment variables to set for this command. Injected as a `KEY='value' ...` prefix; works on any sshd regardless of AcceptEnv config. Values are POSIX-single-quoted, so any byte is safe."New value: +"Environment variables to set for this command. Injected as a `KEY='value' ...` prefix; works on any sshd regardless of AcceptEnv config. VALUES are POSIX-single-quoted, so any byte is safe in a value. KEYS cannot be quoted (a shell assignment prefix requires a bare name), so each key must match /^[A-Za-z_][A-Za-z0-9_]*$/ (the POSIX name grammar) — a key outside that grammar is rejected and the call fails before anything is sent to a host. Command policy is checked against the PREFIXED command, so a `^`-anchored whitelist pattern stops matching once this is set."
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in milliseconds (default: 30000)"New value: +"Command timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately."
    • Changedssh_find1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in milliseconds (default: 30000)"New value: +"Command timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately."
    • Changedssh_git_check4 fields changed
      • changedInput schema / properties / host / description
        Previous value: -"Git hosting hostname (default: \"github.com\")"New value: +"Git hosting hostname (default: \"github.com\"). Omit for the default; an empty string is rejected."
      • addedInput schema / properties / host / minLength
        Added value: +1
      • changedInput schema / properties / user / description
        Previous value: -"SSH user for the git host (default: \"git\")"New value: +"SSH user for the git host (default: \"git\"). Omit for the default; an empty string is rejected."
      • addedInput schema / properties / user / minLength
        Added value: +1
    • Changedssh_ls1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to the remote directory"New value: +"Absolute path to the remote directory. Must start with /."
    • Changedssh_mkdir1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path of the directory to create"New value: +"Path of the directory to create. Absolute (starting with /) is recommended and unambiguous. A relative path is also accepted and resolves against the SFTP working directory, which is normally the remote user's home. ~ is NOT expanded — SFTP has no shell to expand it."
    • Changedssh_multi_exec2 fields changed
      • addedInput schema / properties / env
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "description": "Environment variables to set for this command. Injected as a `KEY='value' ...` prefix; works on any sshd regardless of AcceptEnv config. VALUES are POSIX-single-quoted, so any byte is safe in a value. KEYS cannot be quoted (a shell assignment prefix requires a bare name), so each key must match /^[A-Za-z_][A-Za-z0-9_]*$/ (the POSIX name grammar) — a key outside that grammar is rejected and the call fails before anything is sent to a host. Command policy is checked against the PREFIXED command, so a `^`-anchored whitelist pattern stops matching once this is set.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in milliseconds (default: 30000)"New value: +"Per-host command timeout in milliseconds (default: 30000): bounds each host's command, not the whole call. Also the call's no-progress budget on a full pool (see the tool description)."
    • Changedssh_service_status1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in milliseconds (default: 30000)"New value: +"Command timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately."
    • Changedssh_stat1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to the remote file or directory"New value: +"Absolute path to the remote file or directory. Must start with /."
    • Changedssh_tail1 field changed
      • changedInput schema / properties / timeout / description
        Previous value: -"Command timeout in milliseconds (default: 30000)"New value: +"Command timeout in milliseconds (default: 30000). Also the longest the call waits for a free connection-pool slot (SSH_MCP_MAX_POOL_SIZE, default 100) before the command starts; the wait and the command are bounded separately."
    • Changedssh_upload1 field changed
      • changedInput schema / properties / remotePath / description
        Previous value: -"Absolute path on the remote host"New value: +"Absolute path on the remote host. Must start with /."
    • Changedssh_write_file1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to the remote file"New value: +"Absolute path to the remote file. Must start with /."
  3. 1 tool updatev0.11.7
    • Changedssh_read_file1 field changed
      • changedInput schema / properties / path / description
        Previous value: -"Absolute path to the remote file"New value: +"Absolute path to the remote file. Must start with /."
  4. 6 tool updatesv0.11.0
    • Addedssh_delete
    • Changedssh_exec1 field changed
      • addedInput schema / properties / env
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "description": "Environment variables to set for this command. Injected as a `KEY='value' ...` prefix; works on any sshd regardless of AcceptEnv config. Values are POSIX-single-quoted, so any byte is safe.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
    • Changedssh_find1 field changed
      • addedInput schema / properties / newer
        Added value: +{
        +  "description": "Reference file path -- find matches files modified more recently than this file",
        +  "type": "string"
        +}
    • Addedssh_mkdir
    • Addedssh_stat
    • Changedssh_tail4 fields changed
      • changedInput schema / properties / lines / description
        Previous value: -"Number of lines to read from the end (default: 100)"New value: +"Number of lines to read from the end (default: 100). Must be a positive integer."
      • addedInput schema / properties / lines / exclusiveMinimum
        Added value: +0
      • addedInput schema / properties / lines / maximum
        Added value: +9007199254740991
      • changedInput schema / properties / lines / type
        Previous value: -"number"New value: +"integer"
  5. 18 tool updatesv0.9.1
    • Addedssh_agent_ensure
    • Addedssh_config_lookup
    • Changedssh_diagnose4 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
    • Changedssh_download5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / password / description
        Previous value: -"SSH password (prefer keys)"New value: +"SSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process."
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
    • Changedssh_exec9 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / command / description
        Previous value: -"Shell command to execute on the remote host"New value: +"Shell command to execute on the remote host (interpreted by the remote login shell)"
      • changedInput schema / properties / password / description
        Previous value: -"SSH password (prefer keys)"New value: +"SSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process."
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
      • addedInput schema / properties / timeout / exclusiveMinimum
        Added value: +0
      • addedInput schema / properties / timeout / maximum
        Added value: +9007199254740991
      • changedInput schema / properties / timeout / type
        Previous value: -"number"New value: +"integer"
    • Addedssh_find
    • Addedssh_git_check
    • Addedssh_key_list
    • Addedssh_key_load
    • Addedssh_known_hosts_fix
    • Changedssh_ls5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / password / description
        Previous value: -"SSH password (prefer keys)"New value: +"SSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process."
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
    • Addedssh_multi_exec
    • Changedssh_read_file5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / password / description
        Previous value: -"SSH password (prefer keys)"New value: +"SSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process."
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
    • Addedssh_service_status
    • Addedssh_tail
    • Addedssh_test
    • Changedssh_upload5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / password / description
        Previous value: -"SSH password (prefer keys)"New value: +"SSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process."
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
    • Changedssh_write_file5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / password / description
        Previous value: -"SSH password (prefer keys)"New value: +"SSH password. STRONGLY prefer key-based auth (privateKeyPath or ssh-agent). Passwords pass through MCP protocol frames as plaintext and may be logged by the transport or host process."
      • addedInput schema / properties / port / maximum
        Added value: +65535
      • addedInput schema / properties / port / minimum
        Added value: +1
      • changedInput schema / properties / port / type
        Previous value: -"number"New value: +"integer"
  6. 7 tool updatesv0.2.0
    • First observedssh_diagnose
    • First observedssh_download
    • First observedssh_exec
    • First observedssh_ls
    • First observedssh_read_file
    • First observedssh_upload
    • First observedssh_write_file

TDQS

A3.8/5.0

Scored across 21 tools

Disambiguation4/5

Every tool targets a clearly distinct operation (exec, file read/write, upload/download, ls/stat/delete/mkdir, key management, diagnostics), and the descriptions explicitly disambiguate close pairs like ssh_test vs ssh_diagnose and ssh_write_file vs ssh_upload. Minor overlap remains: ssh_tail and ssh_find are convenience wrappers around what ssh_exec could do, and ssh_agent_ensure vs ssh_diagnose overlap on agent troubleshooting.

Naming Consistency4/5

All 21 tools share a predictable `ssh_` namespace and are readable at a glance. There is a near-even split between verb_noun (ssh_read_file, ssh_mkdir, ssh_multi_exec) and noun_verb ordering (ssh_key_list, ssh_config_lookup, ssh_git_check, ssh_known_hosts_fix), plus a special case ssh_ls, which is a small but real deviation.

Tool Count3/5

21 tools is on the heavy side for this domain, with several thin convenience wrappers (ssh_tail, ssh_find, ssh_service_status, ssh_test) that could be expressed via ssh_exec. Each earns some place, but the surface feels broader than the core task strictly requires.

Completeness4/5

Strong lifecycle coverage: exec, multi-host exec, full SFTP file operations, directory creation, stat/metadata, key listing/loading, config lookup, known_hosts repair, and diagnostics. Gaps are moderate: no rename/move, chmod/chown, symlink creation, or key generation tool, forcing fallbacks to ssh_exec (or leaving no clean path for keygen).

Maintenance

ActivityActive
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables seamless SSH operations including secure connections, file transfers, interactive shell sessions, and Docker container management on remote servers. Supports both password and SSH key authentication with credential management and connection pooling.
    18
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables remote file operations and command execution across multiple machines via SSH. Supports reading files, listing directories, and running commands on any host configured in your SSH config.
    -
  • A
    license
    A
    quality
    D
    maintenance
    Enables secure SSH connections to multiple remote servers with support for command execution, file transfers (SFTP), directory listing, and both password and key-based authentication.
    7
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables executing commands on remote SSH hosts, with full support for bastion/jump hosts and ~/.ssh/config, plus Slurm job management and rsync.
    4
    MIT