The connector asked for a sudo password on every privileged call and failed whenever nobody answered it, which is every unattended run. - Always probe `sudo -n` first, even for aliases set to sudo="prompt". `_sudo_prefix` used to elicit unconditionally, so a host granting this user NOPASSWD still opened an Agent Inbox prompt; with no human there it hit the client's 300s ELICITATION_DEADLINE, got back `cancel`, and surfaced as "sudo password required (user declined or timed out)". sudo refuses before running anything when it wants a password, so the probe is side-effect free. - Strip a leading `sudo` from `command` and turn it into sudo=true. Agents write `exec(command="sudo systemctl restart x")`: with sudo=false that ran a tty-less sudo, with sudo=true it nested `sudo -S ... sudo ...` whose inner prompt had no tty either. Handles -u/-n/-S/-E/-H/-i/-k/-p/--; an unknown flag leaves the command alone. sudo_user now implies sudo=true. - Run privileged commands as `sh -c '<command>'`, so `&&`, pipes and redirections are elevated too instead of only the first word. - Add SSH_MCP_SUDO_PASSWORD (optional, secret) for unattended runs. It is consulted only after `sudo -n` proved a password is needed, so on a NOPASSWD host it never lands in the command's own stdin. - Actionable errors for every sudo failure mode, and a `hint` on a nested sudo we could not peel off. General review of the same server: - Drain stdout and stderr together and make timeout_sec a real wall-clock deadline. Both streams share one SSH channel window, so reading stdout to EOF first stalled once a chatty stderr filled it. Command stdin is now closed after the optional password. - Queue messages that arrive while awaiting an elicitation reply instead of discarding them, so a concurrent tools/call is not lost. - Record the client's `elicitation` capability at initialize and fail fast when it is absent rather than blocking on a prompt nobody can answer. - Tolerate null/string integer arguments (depth, max_results, context_lines, timeout_sec). - Realign the version across both manifests: fragment.json said 5/1.0.4 while connector.json said 2/1.0.1, so the feed was permanently ahead of the installed version and offered an update forever. Also lands the pending docs work: CONNECTOR_MANIFEST_GUIDE.md as the single source of truth, docs/connector.manifest_guide.md retired to a pointer, CLAUDE.md audited against the repo, compile.py docstring fixed, and an opencode.json config.
27 lines
603 B
JSON
27 lines
603 B
JSON
{
|
|
"id": "ssh",
|
|
"name": "SSH Remote Access",
|
|
"type": "mcp_local",
|
|
"scope": "user",
|
|
"icon_small": "ssh/icon_sm.svg",
|
|
"icon_large": "ssh/icon_lg.svg",
|
|
"user_description": "Full SSH remote server access \u2014 files, commands, systemd, upload/download. Aliases manage host config; auth via key/agent or elicited password.",
|
|
"requires": [
|
|
"PYTHON"
|
|
],
|
|
"tags": [
|
|
"ssh",
|
|
"mcp",
|
|
"local",
|
|
"remote",
|
|
"server",
|
|
"sysadmin"
|
|
],
|
|
"auth": {
|
|
"type": "none"
|
|
},
|
|
"folder": "ssh",
|
|
"version": 6,
|
|
"version_string": "1.1.0",
|
|
"version_release_date": "2026-09-03"
|
|
} |