{"id":51744614,"url":"https://github.com/developerz-ai/mcp-ssh","last_synced_at":"2026-07-18T17:35:23.199Z","repository":{"id":367654801,"uuid":"1281697373","full_name":"developerz-ai/mcp-ssh","owner":"developerz-ai","description":"Remote shell + file access for AI agents over authenticated MCP-HTTP — an ssh replacement you talk to over /mcp. Single Rust binary, OAuth 2.1 + Basic auth, auto-backgrounding jobs with paginated logs.","archived":false,"fork":false,"pushed_at":"2026-07-02T19:06:19.000Z","size":412,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-18T17:35:14.568Z","etag":null,"topics":["ai-agents","axum","claude","devops","llm-tools","mcp","model-context-protocol","oauth2","remote-shell","rust","self-hosted","tokio"],"latest_commit_sha":null,"homepage":"https://github.com/developerz-ai/mcp-ssh#readme","language":"Rust","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/developerz-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-26T20:35:16.000Z","updated_at":"2026-07-02T19:06:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/developerz-ai/mcp-ssh","commit_stats":null,"previous_names":["developerz-ai/mcp-ssh"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/developerz-ai/mcp-ssh","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerz-ai%2Fmcp-ssh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerz-ai%2Fmcp-ssh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerz-ai%2Fmcp-ssh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerz-ai%2Fmcp-ssh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/developerz-ai","download_url":"https://codeload.github.com/developerz-ai/mcp-ssh/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/developerz-ai%2Fmcp-ssh/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35626138,"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-18T02:00:07.223Z","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":["ai-agents","axum","claude","devops","llm-tools","mcp","model-context-protocol","oauth2","remote-shell","rust","self-hosted","tokio"],"created_at":"2026-07-18T17:35:21.310Z","updated_at":"2026-07-18T17:35:23.191Z","avatar_url":"https://github.com/developerz-ai.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔌 mcp-ssh\n\n\u003e **ssh, but you talk to it over `/mcp` from any MCP client.**\n\u003e A single Rust binary that gives an AI agent a remote shell + file access to **one host — the box it runs on.** No SSH client, no multi-server fan-out, no gateway. It runs commands **locally**, as the service user, and speaks MCP over HTTP.\n\nYou point Claude (or any MCP client) at `https://your-host/mcp`, it authenticates, and now the agent can `bash`, read/write files, and supervise long-running jobs on that machine — from anywhere.\n\n## 🚗 The story\n\nYou're in your car. From your phone, you point Claude at `https://your-vps/mcp` and say *\"run the deploy.\"*\n\n- Claude calls `bash(\"./deploy.sh\")`.\n- The deploy takes 20 minutes — so it **auto-backgrounds** and hands back a job id instead of blocking.\n- Claude polls `job(action=\"poll\", id)` **page by page**, watching progress a few hundred lines at a time, so a 20-minute build never floods its context window.\n- It finishes. Claude tells you it's done. You never touched a keyboard.\n\nWant to go further? Run `bash(\"claude -p 'fix the failing test and push'\")` — **one agent supervising another agent** on your VPS. mcp-ssh is just the shell; what you run through it is up to you.\n\n## ⚡ Quickstart\n\n**One-liner (Debian/Ubuntu)** — downloads the latest release, asks for a username + password, installs the service, and starts it:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/developerz-ai/mcp-ssh/main/deploy/install.sh | sudo bash\n```\n\n\u003cdetails\u003e\u003csummary\u003eOr do it by hand\u003c/summary\u003e\n\n```bash\n# 1. install (Debian/Ubuntu — grab the .deb from releases)\nsudo dpkg -i mcp-ssh_*.deb\n\n# 2. set the single username/password (prompts for the password)\nmcp-ssh set-auth admin\n\n# 3. start it as a systemd service\nsudo systemctl enable --now mcp-ssh\n\n# 4. verify it's up on loopback\ncurl -fsS http://127.0.0.1:1337/.well-known/oauth-authorization-server\n```\n\n\u003c/details\u003e\n\nThen put TLS in front (see [docs/deploy.md](docs/deploy.md)) and connect from Claude.\n\nmcp-ssh now listens on `127.0.0.1:1337` at `/mcp`. Expose it as `https://your-host/mcp` with a reverse proxy → **[docs/deploy.md](docs/deploy.md)**.\n\n## 🧰 The tools\n\nA small, heavily-parametrized surface — **three resource-oriented tools**, composition pushed into params. Everything runs locally as the service user.\n\n| Tool | Params | What it does |\n|---|---|---|\n| `bash` | `cmd`, `cwd?`, `timeout?`, `bg?`, `interactive?`, `title?` | Run a shell command. Returns output inline if it finishes within the inline window (default 2s), else a **job id** to monitor with `job`. `timeout` overrides the inline window; `bg=true` backgrounds immediately; `interactive=true` sources `~/.bashrc`; `title` labels the job id (`\u003ctitle\u003e-HH-MM-SS`). Output is byte/line-capped per page. |\n| `job` | `action`, `id?`, `cursor?`, `limit?` | Manage jobs. `action=\"poll\"` → status + **one page** of merged stdout+stderr (default 200 lines, byte-capped, with `next_cursor`/`has_more`); `action=\"list\"` → all jobs + status; `action=\"kill\"` → kill running job `id`. |\n| `file` | `action`, `path?`, `content?`, `pattern?`, `recursive?`, `src?`, `dest?`, `cursor?`, `limit?` | File operations by `action`: `read` (paginated), `write`, `append`, `delete`, `list` (`recursive` for the tree), `grep` (`pattern`, `recursive` under a dir), `move` (`src`→`dest`). |\n\nFull reference with examples → **[docs/usage.md](docs/usage.md)**.\n\n## 🔗 Connect from Claude\n\n1. Deploy mcp-ssh behind TLS so it's reachable at `https://your-host/mcp`.\n2. In Claude, add a remote MCP server with URL `https://your-host/mcp`.\n3. Claude runs the **OAuth 2.1** flow (the spec-compliant auth GUI clients use); log in with the username/password you set via `mcp-ssh set-auth`.\n4. The tools above appear. Say *\"run the deploy.\"*\n\nHeadless client (the `claude` CLI, curl) with no browser? Mint a bearer with [`bin/mcp-token`](bin/mcp-token) and pass it as `Authorization: Bearer …` → **[docs/deploy.md](docs/deploy.md#-connect-a-client)**.\n\n## 🔐 Auth\n\n`/mcp` is **bearer-only** — all MCP clients must authenticate via OAuth 2.1. Claude and every\nspec-compliant GUI client run this flow automatically; you just log in with the username/password\nyou set via `mcp-ssh set-auth`. Tokens (and job history) are persisted to a bundled SQLite database,\nso **logins and job history survive a service restart** — handy since the agent can self-update and\nrestart itself.\n\nSet the credentials once:\n\n```bash\nmcp-ssh set-auth admin     # prompts for the password\n```\n\n## 🖥️ CLI\n\n```bash\nmcp-ssh serve              # run the server (this is the default)\nmcp-ssh set-auth \u003cuser\u003e    # configure the username/password\n\nmcp-ssh jobs               # list running jobs (--all includes finished ones)\nmcp-ssh job kill \u003cid\u003e      # SIGTERM then SIGKILL a job's process group\nmcp-ssh sessions           # summarise OAuth logins (token counts + next expiry)\n```\n\n`jobs`/`job kill`/`sessions` read the same SQLite state the server uses, so they\nwork from any shell on the host (no auth needed); `sessions` never prints token\nvalues.\n\n## ⚠️ Security\n\n**This gives an agent full shell access — with `sudo` (root) by default.** The\nunit ships `NoNewPrivileges=false` and the installer grants the run user\n`NOPASSWD:ALL`, so the agent can self-manage the host (update + restart itself,\nmanage services). Anyone who authenticates to `/mcp` can run anything as root.\nTreat it accordingly:\n\n- Run it as a **dedicated user** (the installer defaults to `mcp-ssh`), not your login account.\n- Always put it **behind TLS** (reverse proxy). Never expose `:1337` directly.\n- Use a **strong password** — it's the only thing between the internet and root.\n- Set `MCP_SSH_ALLOWED_HOSTS` to your public hostname — it's the DNS-rebinding guard.\n- Don't want root? [Lock it down](docs/deploy.md#self-management-the-agent-has-sudo-by-default) — remove the sudoers file + set `NoNewPrivileges=true`.\n\n## 📦 Install\n\n| Method | How |\n|---|---|\n| **One-liner** | `curl -fsSL https://raw.githubusercontent.com/developerz-ai/mcp-ssh/main/deploy/install.sh \\| sudo bash` — latest release, prompts for creds, installs + starts the service |\n| **Debian/Ubuntu** | download `mcp-ssh_*.deb` from [releases](https://github.com/developerz-ai/mcp-ssh/releases) → `sudo dpkg -i mcp-ssh_*.deb` |\n| **Docker** | pull the image and run it (see [docs/deploy.md](docs/deploy.md)) |\n| **From source** | `cargo build --release` → binary at `target/release/mcp-ssh` |\n\n## 📚 Docs\n\n| Doc | What's in it |\n|---|---|\n| [docs/connect-claude.md](docs/connect-claude.md) | Connect from Claude Desktop \u0026 mobile — custom-connector setup, OAuth login, troubleshooting |\n| [docs/usage.md](docs/usage.md) | Every tool with params + examples, the execution \u0026 pagination model, config \u0026 env vars |\n| [docs/architecture.md](docs/architecture.md) | Module map, auto-backgrounding execution, the auth middleware, the stack |\n| [docs/deploy.md](docs/deploy.md) | systemd, Caddy \u0026 nginx+certbot TLS, Docker, hardening |\n| [docs/prompts/system-prompt.md](docs/prompts/system-prompt.md) | Ready-to-paste system prompt for driving the server from a chat LLM |\n| [docs/prompts/skill.md](docs/prompts/skill.md) | Claude Code skill for autonomous server-side work |\n| [`.coderabbit.yaml`](.coderabbit.yaml) | CodeRabbit AI review config; install the [GitHub App](https://github.com/apps/coderabbitai) on the repo |\n\n## 🧬 Stack\n\nRust 2024 · tokio · axum 0.8 · [rmcp](https://github.com/modelcontextprotocol/rust-sdk) 1.7 (MCP Streamable HTTP) · [rusqlite](https://github.com/rusqlite/rusqlite) (bundled SQLite — durable state, no system libsqlite).\n\n## 📄 License\n\nMIT. Repository: \u003chttps://github.com/developerz-ai/mcp-ssh\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloperz-ai%2Fmcp-ssh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeveloperz-ai%2Fmcp-ssh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeveloperz-ai%2Fmcp-ssh/lists"}