{"id":51526588,"url":"https://github.com/oaslananka/ssh-mcp-pro","last_synced_at":"2026-07-08T22:00:59.691Z","repository":{"id":368950126,"uuid":"1283304039","full_name":"oaslananka/ssh-mcp-pro","owner":"oaslananka","description":"TypeScript MCP server for controlled SSH operations, remote host workflows, command execution guardrails, and infrastructure automation.","archived":false,"fork":false,"pushed_at":"2026-07-02T23:24:24.000Z","size":555,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T00:22:44.223Z","etag":null,"topics":["automation","devops","infrastructure","linux","mcp","model-context-protocol","nodejs","operations","remote-automation","security","ssh","terminal","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oaslananka.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":"GOVERNANCE.md","roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":"MAINTAINERS.md","copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["oaslananka"],"buy_me_a_coffee":"oaslananka"}},"created_at":"2026-06-28T19:23:10.000Z","updated_at":"2026-07-02T23:24:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/oaslananka/ssh-mcp-pro","commit_stats":null,"previous_names":["oaslananka/ssh-mcp-pro"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/oaslananka/ssh-mcp-pro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oaslananka%2Fssh-mcp-pro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oaslananka%2Fssh-mcp-pro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oaslananka%2Fssh-mcp-pro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oaslananka%2Fssh-mcp-pro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oaslananka","download_url":"https://codeload.github.com/oaslananka/ssh-mcp-pro/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oaslananka%2Fssh-mcp-pro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35279442,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-08T02:00:06.796Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","devops","infrastructure","linux","mcp","model-context-protocol","nodejs","operations","remote-automation","security","ssh","terminal","typescript"],"created_at":"2026-07-08T22:00:58.373Z","updated_at":"2026-07-08T22:00:59.684Z","avatar_url":"https://github.com/oaslananka.png","language":"TypeScript","funding_links":["https://github.com/sponsors/oaslananka","https://buymeacoffee.com/oaslananka","https://www.buymeacoffee.com/oaslananka","https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee\u0026emoji=%E2%98%95\u0026slug=oaslananka\u0026button_colour=FFDD00\u0026font_colour=000000\u0026font_family=Arial\u0026outline_colour=000000\u0026coffee_colour=ffffff"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003essh-mcp-pro\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/ssh-mcp-pro\"\u003e\u003cimg alt=\"npm version\" src=\"https://img.shields.io/npm/v/ssh-mcp-pro.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/ssh-mcp-pro\"\u003e\u003cimg alt=\"npm downloads\" src=\"https://img.shields.io/npm/dt/ssh-mcp-pro.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"license\" src=\"https://img.shields.io/badge/license-MIT-blue.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/oaslananka/ssh-mcp-pro/actions/workflows/ci.yml\"\u003e\u003cimg alt=\"CI\" src=\"https://github.com/oaslananka/ssh-mcp-pro/actions/workflows/ci.yml/badge.svg\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://oaslananka.github.io/ssh-mcp-pro/\"\u003e\u003cimg alt=\"API Docs\" src=\"https://github.com/oaslananka/ssh-mcp-pro/actions/workflows/docs.yml/badge.svg\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.buymeacoffee.com/oaslananka\"\u003e\n    \u003cimg src=\"https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20coffee\u0026emoji=%E2%98%95\u0026slug=oaslananka\u0026button_colour=FFDD00\u0026font_colour=000000\u0026font_family=Arial\u0026outline_colour=000000\u0026coffee_colour=ffffff\" alt=\"Buy me a coffee\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nssh-mcp-pro is a secure Model Context Protocol (MCP) server for SSH automation. It lets MCP-capable clients open SSH sessions, inspect hosts, run guarded commands, manage files, transfer artifacts, create tunnels, and perform idempotent package or service work through policy-controlled tools.\n\n## Prerequisites\n\n- Node.js `\u003e=22.22.2` or `\u003e=24.15.0` or `\u003e=26.3.0`\n- pnpm `\u003e=11.0.9`\n- SSH access to the target hosts\n- Docker, only for local integration tests and container image builds\n\n## Installation\n\nInstall globally with pnpm:\n\n```bash\npnpm add --global ssh-mcp-pro\nssh-mcp-pro --version\n```\n\nRun without a global install:\n\n```bash\nnpx ssh-mcp-pro\n```\n\nFor pnpm-only environments, use:\n\n```bash\npnpm dlx ssh-mcp-pro\n```\n\nContainer images are published to GitHub Container Registry for release tags:\n\n```bash\ndocker run --rm ghcr.io/oaslananka/ssh-mcp-pro:1.0.0 --version\n```\n\nImages are published for `linux/amd64` and `linux/arm64` with exact semver and\nGit tag aliases. Production deployments should prefer the digest-pinned\nreference recorded by the release workflow. See [Docker Usage](docs/docker.md)\nfor the tag policy, digest-pinned examples, and registry verification steps.\n\n## Quickstart\n\nGeneric stdio MCP config:\n\n```json\n{\n  \"name\": \"ssh-mcp-pro\",\n  \"command\": \"ssh-mcp-pro\",\n  \"type\": \"stdio\"\n}\n```\n\nVS Code settings style:\n\n```json\n{\n  \"mcp.servers\": {\n    \"ssh-mcp-pro\": {\n      \"type\": \"stdio\",\n      \"command\": \"ssh-mcp-pro\",\n      \"args\": []\n    }\n  }\n}\n```\n\nClaude Desktop style:\n\n```json\n{\n  \"mcpServers\": {\n    \"ssh-mcp-pro\": {\n      \"command\": \"ssh-mcp-pro\",\n      \"args\": []\n    }\n  }\n}\n```\n\nAfter registration, start with discovery and a strict host-key policy:\n\n```text\nList configured SSH hosts, open a session to bastion.example.com as deploy with hostKeyPolicy=strict, then run os_detect.\n```\n\n## Usage\n\nUse ssh-mcp-pro from an MCP client over stdio, or run the HTTP transport for\nremote-safe connector profiles. Start with read-only discovery tools, inspect\nthe active policy, and create explicit sessions before running remote commands:\n\n```text\nList configured SSH hosts, explain the active SSH policy, connect to the selected host, then report its operating system and disk usage.\n```\n\nSee [examples/README.md](examples/README.md) for additional workflows and\n[INSTALL.md](INSTALL.md) for client-specific setup.\n\n## Configuration\n\nAll `SSH_MCP_*` environment variables parsed by `src/config.ts` are listed below. Comma-separated settings also accept newline-separated values.\n\n| Variable | Default | Purpose |\n| --- | --- | --- |\n| `SSH_MCP_MAX_SESSIONS` | `20` | Maximum concurrent SSH sessions. |\n| `SSH_MCP_SESSION_TTL` | `900000` | Session time-to-live in milliseconds. |\n| `SSH_MCP_COMMAND_TIMEOUT` | `30000` | Default remote command timeout in milliseconds. |\n| `SSH_MCP_MAX_COMMAND_OUTPUT_BYTES` | `1048576` | Maximum buffered stdout/stderr bytes per command result. |\n| `SSH_MCP_MAX_STREAM_CHUNKS` | `4096` | Maximum retained streaming chunks. |\n| `SSH_MCP_MAX_FILE_SIZE` | `10485760` | Maximum bytes returned by text-focused file reads. |\n| `SSH_MCP_MAX_FILE_WRITE_BYTES` | `10485760` | Maximum accepted write payload before buffering. |\n| `SSH_MCP_MAX_TRANSFER_BYTES` | `52428800` | Maximum upload or download transfer size. |\n| `SSH_MCP_DEBUG` | `false` | Enables debug-oriented configuration behavior. |\n| `SSH_MCP_RATE_LIMIT` | `true` | Enables the global MCP request rate limiter. |\n| `SSH_MCP_RATE_LIMIT_MAX` | `100` | Maximum requests per rate-limit window. |\n| `SSH_MCP_RATE_LIMIT_PER_SESSION` | `true` | Enables per-session MCP request rate limiting when tool arguments include `sessionId`. |\n| `SSH_MCP_RATE_LIMIT_PER_SESSION_MAX` | `50` | Maximum requests per SSH session per rate-limit window. |\n| `SSH_MCP_RATE_LIMIT_PER_SESSION_WINDOW_MS` | `60000` | Per-session rate-limit window in milliseconds. |\n| `SSH_MCP_RATE_LIMIT_WINDOW_MS` | `60000` | Rate-limit window in milliseconds. |\n| `SSH_MCP_STRICT_HOST_KEY` | unset | Legacy boolean alias for strict vs insecure host-key checking. |\n| `SSH_MCP_HOST_KEY_POLICY` | `strict` | Host-key mode: `strict`, `accept-new`, or `insecure`. |\n| `SSH_MCP_KNOWN_HOSTS_PATH` | `~/.ssh/known_hosts` | Known hosts file used for strict host-key verification. |\n| `SSH_MCP_ALLOW_ROOT_LOGIN` | `false` | Allows SSH login as root and mirrors into policy. |\n| `SSH_MCP_ALLOWED_CIPHERS` | empty | Optional SSH cipher allowlist. |\n| `SSH_MCP_POLICY_FILE` | unset | JSON file containing partial policy overrides. |\n| `SSH_MCP_POLICY_MODE` | `enforce` | Policy decision mode: `enforce` or `explain`. |\n| `SSH_MCP_ALLOW_RAW_SUDO` | `false` | Allows raw `proc_sudo`; prefer `ensure_*` tools. |\n| `SSH_MCP_ALLOW_DESTRUCTIVE_COMMANDS` | `false` | Allows commands matching destructive command policy. |\n| `SSH_MCP_ALLOW_DESTRUCTIVE_FS` | `false` | Allows destructive filesystem operations such as `fs_rmrf`. |\n| `SSH_MCP_ALLOWED_HOSTS` | empty | Host allowlist for policy and remote connector safety checks. |\n| `SSH_MCP_COMMAND_ALLOW` | empty | Command allow patterns. |\n| `SSH_MCP_COMMAND_DENY` | empty | Command deny patterns. |\n| `SSH_MCP_PATH_ALLOW_PREFIXES` | `/tmp,/var/tmp,/home,/Users` | Remote path prefixes allowed by filesystem policy. |\n| `SSH_MCP_PATH_DENY_PREFIXES` | `/etc/sudoers,/etc/shadow,/etc/passwd,/boot,/dev,/proc` | Remote path prefixes denied by filesystem policy. |\n| `SSH_MCP_LOCAL_PATH_ALLOW_PREFIXES` | OS temp directory | Local paths allowed for transfer operations. |\n| `SSH_MCP_LOCAL_PATH_DENY_PREFIXES` | empty | Local paths denied for transfer operations. |\n| `SSH_MCP_TUNNEL_ALLOW_BIND_HOSTS` | `127.0.0.1,localhost,::1` | Local bind hosts allowed for tunnels. |\n| `SSH_MCP_TUNNEL_DENY_BIND_HOSTS` | `0.0.0.0,::` | Local bind hosts denied for tunnels. |\n| `SSH_MCP_TUNNEL_ALLOW_REMOTE_HOSTS` | empty | Optional remote tunnel target host allowlist. |\n| `SSH_MCP_TUNNEL_DENY_REMOTE_HOSTS` | empty | Optional remote tunnel target host denylist. |\n| `SSH_MCP_TUNNEL_ALLOW_PORTS` | empty | Optional tunnel port allowlist. |\n| `SSH_MCP_TUNNEL_DENY_PORTS` | empty | Optional tunnel port denylist. |\n| `SSH_MCP_HTTP_HOST` | `127.0.0.1` | Streamable HTTP bind host. |\n| `SSH_MCP_HTTP_PORT` | `3000` | Streamable HTTP bind port. |\n| `SSH_MCP_HTTP_ALLOWED_ORIGINS` | `http://127.0.0.1,http://localhost` | Browser origins allowed for HTTP clients. |\n| `SSH_MCP_HTTP_BEARER_TOKEN_FILE` | unset | Bearer token file for HTTP transport. Required for non-loopback bearer deployments. |\n| `SSH_MCP_ENABLE_LEGACY_SSE` | `false` | Enables legacy SSE compatibility. |\n| `SSH_MCP_HTTP_MAX_REQUEST_BODY_BYTES` | `1048576` | Maximum HTTP request body size. |\n| `SSH_MCP_HTTP_MAX_SESSIONS` | `20` | Maximum active Streamable HTTP MCP sessions. Expired sessions are cleaned first; if capacity is still full, the oldest idle session is evicted so abandoned clients do not cause persistent 502s. Use `100` for ChatGPT/Cloudflare production deployments. |\n| `SSH_MCP_HTTP_SESSION_IDLE_TTL_MS` | `900000` | HTTP MCP session idle timeout in milliseconds. Use `300000` for ChatGPT/Cloudflare production deployments where clients may abandon sessions without DELETE. |\n| `SSH_MCP_HTTP_PUBLIC_URL` | unset | Stable public HTTPS MCP URL for protected resource metadata. |\n| `SSH_MCP_HTTP_TRUST_PROXY` | `false` | Trust reverse proxy forwarded headers. |\n| `SSH_MCP_TOOL_PROFILE` | `full` | Active tool exposure profile. |\n| `SSH_MCP_CONNECTOR_PROFILE` | `full` | Alias for `SSH_MCP_TOOL_PROFILE`. |\n| `SSH_MCP_CONNECTOR_CREDENTIAL_PROVIDER` | `none` | Credential provider: `none`, `agent`, or `command`. |\n| `SSH_MCP_CONNECTOR_CREDENTIAL_COMMAND` | unset | External credential command when provider is `command`. |\n| `SSH_MCP_CONNECTOR_CREDENTIAL_COMMAND_ARGS` | empty | Arguments passed to the external credential command. |\n| `SSH_MCP_CONNECTOR_CREDENTIAL_COMMAND_TIMEOUT_MS` | `5000` | Credential command timeout in milliseconds. |\n| `SSH_MCP_CONNECTOR_DEFAULT_USERNAME` | unset | Default username for connector broker flows. |\n| `SSH_MCP_HTTP_AUTH_MODE` | `bearer` | HTTP auth mode: `bearer` or `oauth`. |\n| `SSH_MCP_OAUTH_ISSUER` | unset | Expected OAuth issuer. |\n| `SSH_MCP_OAUTH_AUDIENCE` | unset | Expected OAuth audience. |\n| `SSH_MCP_OAUTH_JWKS_URL` | unset | OAuth JWKS URL. |\n| `SSH_MCP_OAUTH_RESOURCE` | unset | OAuth protected resource identifier. |\n| `SSH_MCP_OAUTH_REQUIRED_SCOPES` | `ssh-mcp-pro.read` | Required OAuth scopes. |\n| `SSH_MCP_OAUTH_ALLOWED_ALGORITHMS` | unset | Optional comma-separated JWT algorithm allowlist, for example `RS256,ES256`. When unset, the built-in OAuth verifier defaults are used. |\n| `SSH_MCP_REMOTE_AGENT_MCP_PASSTHROUGH` | unset | When enabled with `1`, `true`, `yes`, or `on`, lets `/mcp` requests bypass the remote control plane and reach the Streamable HTTP MCP handler. Use only for connector routing migrations. |\n\nThe parser also accepts non-`SSH_MCP_*` compatibility aliases `PORT`, `KNOWN_HOSTS_PATH`, and `STRICT_HOST_KEY_CHECKING`.\n\n## Tool Profiles\n\n`full` exposes every registered tool, resource, and prompt. Every other profile uses an explicit per-profile allowset. `chatgpt` and `claude` currently expose the same baseline connector tools as `remote-safe`, with empty client-specific extension sets reserved for future additions.\n\n| Profile | Exposed tools | Exposed resources | Exposed prompts |\n| --- | --- | --- | --- |\n| `full` | All SSH, process, filesystem, transfer, ensure, tunnel, connector, and system tools. | All runtime resources. | All prompts. |\n| `remote-safe` | `connector_status`, `ssh_hosts_list`, `ssh_policy_explain`, `ssh_host_inspect`, `ssh_mutation_plan`. | `ssh-mcp-pro://capabilities/support-matrix`. | `inspect-host-capabilities`, `plan-mutation`. |\n| `chatgpt` | Baseline remote connector tools plus an empty ChatGPT extension set. | Same remote connector subset as `remote-safe`. | Same remote connector subset as `remote-safe`. |\n| `claude` | Baseline remote connector tools plus an empty Claude extension set. | Same remote connector subset as `remote-safe`. | Same remote connector subset as `remote-safe`. |\n| `remote-readonly` | Same remote connector subset as `remote-safe`. | Same remote connector subset as `remote-safe`. | Same remote connector subset as `remote-safe`. |\n| `remote-broker` | Same remote connector subset as `remote-safe`. | Same remote connector subset as `remote-safe`. | Same remote connector subset as `remote-safe`. |\n\n## Security Defaults\n\nssh-mcp-pro starts with strict SSH host-key verification, denies root login, denies raw sudo, blocks destructive commands and filesystem operations unless policy allows them, and refuses non-loopback HTTP startup unless authentication, origins, public HTTPS URL, strict host-key verification, a remote-safe tool profile, and host allowlists are configured. See [SECURITY.md](SECURITY.md) for vulnerability reporting and [SECURITY_DECISIONS.md](SECURITY_DECISIONS.md) for the design rationale behind these defaults.\n\n## More Documentation\n\n- [INSTALL.md](INSTALL.md) covers full client setup and troubleshooting.\n- [API reference](https://oaslananka.github.io/ssh-mcp-pro/) is generated from the published TypeScript entry points.\n- [CHANGELOG.md](CHANGELOG.md) records release history in Keep a Changelog format.\n- [AGENTS.md](AGENTS.md) describes agent-facing operational guidance.\n- [examples/README.md](examples/README.md) contains workflow examples.\n- [ARCHITECTURE.md](ARCHITECTURE.md) explains the major subsystems and ADRs.\n- [REGISTRY_SUBMISSION.md](REGISTRY_SUBMISSION.md) tracks MCP Registry submission readiness.\n- [docs/tutorials/getting-started.md](docs/tutorials/getting-started.md),\n  [docs/how-to/](docs/how-to/README.md), [docs/reference/](docs/reference/README.md),\n  and [docs/explanation/](docs/explanation/architecture.md) organize the docs above by\n  task (tutorial, how-to, reference, explanation).\n- [docs/troubleshooting.md](docs/troubleshooting.md) covers common failure modes.\n\n## Project Health \u0026 Governance\n\n- [GOVERNANCE.md](GOVERNANCE.md) describes how decisions are made today.\n- [MAINTAINERS.md](MAINTAINERS.md) lists current maintainers.\n- [ROADMAP.md](ROADMAP.md) tracks known process gaps and what's planned to close them.\n- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) sets community expectations.\n- [docs/repo-maturity-report.md](docs/repo-maturity-report.md) is an evidence-based\n  audit of this repository's open-source and OpenSSF maturity, including what's not\n  yet in place.\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for setup, quality gates, commit rules,\nand pull request expectations. Participation is governed by the\n[Code of Conduct](CODE_OF_CONDUCT.md).\n\n## License\n\nssh-mcp-pro is available under the [MIT License](LICENSE).\n\n## Agent plugin and runtime configuration\n\nThis repository owns the product-level agent plugin, MCP runtime configuration, and product-specific skills for `ssh-mcp-pro`. The central [`agent-tools`](https://github.com/oaslananka/agent-tools) repository should catalog this plugin, but the manifest and workflow instructions live here so they stay synchronized with the actual MCP server package.\n\n| File | Purpose |\n| --- | --- |\n| [`.claude-plugin/plugin.json`](.claude-plugin/plugin.json) | Claude Code-valid product plugin manifest. |\n| [`.mcp.json`](.mcp.json) | Claude Code project-local MCP server configuration. |\n| [`.codex/config.example.toml`](.codex/config.example.toml) | Codex CLI MCP configuration example. |\n| [`.vscode/mcp.example.json`](.vscode/mcp.example.json) | VS Code / GitHub Copilot workspace MCP configuration example. |\n| [`opencode.example.jsonc`](opencode.example.jsonc) | OpenCode project MCP configuration example. |\n| `.opencode/skills/` | OpenCode-native mirrored skill definitions. |\n| [`docs/agent-runtime-config.md`](docs/agent-runtime-config.md) | Agent runtime setup and validation notes. |\n\nValidate plugin packaging locally:\n\n```bash\nclaude plugin validate .\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foaslananka%2Fssh-mcp-pro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foaslananka%2Fssh-mcp-pro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foaslananka%2Fssh-mcp-pro/lists"}