A FastMCP implementation for secure SSH connections with read-only command execution
Server has 5 tools with complete schemas and descriptions, but quality is inconsistent. Tool names follow verb_noun convention (ssh_connect, ssh_execute, ssh_disconnect, ssh_list_connections, ssh_get_allowed_commands). Descriptions are present but generic (avg ~80 chars, below 194-char baseline). Parameters have types and descriptions, but lack constraints (enums, ranges, patterns). No output schemas documented. Error handling returns plain text without recovery guidance. Security model is sound (read-only enforcement via allowlist), but no audit logging or permission gates. No tool annotations (readOnlyHint, destructiveHint). Composition is reasonable, tools chain logically (connect → execute → disconnect), but ssh_execute requires pre-connection state, creating implicit dependencies not documented in descriptions.
Establish SSH connection to a remote machine (read-only access only).
Disconnect from the remote machine.
Execute a read-only command on the connected remote machine.
Get the list of allowed read-only commands.
List all active SSH connections.
No output schemas documented. Tools return plain text strings; LLMs cannot parse structured results or chain downstream calls. ssh_list_connections and ssh_get_allowed_commands return formatted text instead of JSON arrays.
Implicit state dependency not documented. ssh_execute requires prior ssh_connect call with same host/username/port, but descriptions do not state this prerequisite. LLMs may attempt execute without connecting.
Error responses lack recovery guidance. Errors return plain messages ('Connection failed: ...', 'Command not allowed...') without suggesting next steps. LLMs cannot self-correct or retry intelligently.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 49 | <=2025-11-25 | v2 |
No tool annotations. Tools lack readOnlyHint, destructiveHint, or idempotentHint metadata. ssh_connect and ssh_disconnect modify state (connection pool) but are not marked as such.
Parameter constraints missing. 'port' accepts any integer; should be constrained to 1 - 65535. 'command' is free-form string; allowlist validation happens at runtime, not declared in schema. No enum or pattern constraints.