An open API service indexing awesome lists of open source software.

https://github.com/developerz-ai/mcp-ssh

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.
https://github.com/developerz-ai/mcp-ssh

ai-agents axum claude devops llm-tools mcp model-context-protocol oauth2 remote-shell rust self-hosted tokio

Last synced: 22 days ago
JSON representation

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.

Awesome Lists containing this project

README

          

# ๐Ÿ”Œ mcp-ssh

> **ssh, but you talk to it over `/mcp` from any MCP client.**
> 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.

You 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.

## ๐Ÿš— The story

You're in your car. From your phone, you point Claude at `https://your-vps/mcp` and say *"run the deploy."*

- Claude calls `bash("./deploy.sh")`.
- The deploy takes 20 minutes โ€” so it **auto-backgrounds** and hands back a job id instead of blocking.
- 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.
- It finishes. Claude tells you it's done. You never touched a keyboard.

Want 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.

## โšก Quickstart

**One-liner (Debian/Ubuntu)** โ€” downloads the latest release, asks for a username + password, installs the service, and starts it:

```bash
curl -fsSL https://raw.githubusercontent.com/developerz-ai/mcp-ssh/main/deploy/install.sh | sudo bash
```

Or do it by hand

```bash
# 1. install (Debian/Ubuntu โ€” grab the .deb from releases)
sudo dpkg -i mcp-ssh_*.deb

# 2. set the single username/password (prompts for the password)
mcp-ssh set-auth admin

# 3. start it as a systemd service
sudo systemctl enable --now mcp-ssh

# 4. verify it's up on loopback
curl -fsS http://127.0.0.1:1337/.well-known/oauth-authorization-server
```

Then put TLS in front (see [docs/deploy.md](docs/deploy.md)) and connect from Claude.

mcp-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)**.

## ๐Ÿงฐ The tools

A small, heavily-parametrized surface โ€” **three resource-oriented tools**, composition pushed into params. Everything runs locally as the service user.

| Tool | Params | What it does |
|---|---|---|
| `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 (`-HH-MM-SS`). Output is byte/line-capped per page. |
| `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`. |
| `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`). |

Full reference with examples โ†’ **[docs/usage.md](docs/usage.md)**.

## ๐Ÿ”— Connect from Claude

1. Deploy mcp-ssh behind TLS so it's reachable at `https://your-host/mcp`.
2. In Claude, add a remote MCP server with URL `https://your-host/mcp`.
3. 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`.
4. The tools above appear. Say *"run the deploy."*

Headless 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)**.

## ๐Ÿ” Auth

`/mcp` is **bearer-only** โ€” all MCP clients must authenticate via OAuth 2.1. Claude and every
spec-compliant GUI client run this flow automatically; you just log in with the username/password
you set via `mcp-ssh set-auth`. Tokens (and job history) are persisted to a bundled SQLite database,
so **logins and job history survive a service restart** โ€” handy since the agent can self-update and
restart itself.

Set the credentials once:

```bash
mcp-ssh set-auth admin # prompts for the password
```

## ๐Ÿ–ฅ๏ธ CLI

```bash
mcp-ssh serve # run the server (this is the default)
mcp-ssh set-auth # configure the username/password

mcp-ssh jobs # list running jobs (--all includes finished ones)
mcp-ssh job kill # SIGTERM then SIGKILL a job's process group
mcp-ssh sessions # summarise OAuth logins (token counts + next expiry)
```

`jobs`/`job kill`/`sessions` read the same SQLite state the server uses, so they
work from any shell on the host (no auth needed); `sessions` never prints token
values.

## โš ๏ธ Security

**This gives an agent full shell access โ€” with `sudo` (root) by default.** The
unit ships `NoNewPrivileges=false` and the installer grants the run user
`NOPASSWD:ALL`, so the agent can self-manage the host (update + restart itself,
manage services). Anyone who authenticates to `/mcp` can run anything as root.
Treat it accordingly:

- Run it as a **dedicated user** (the installer defaults to `mcp-ssh`), not your login account.
- Always put it **behind TLS** (reverse proxy). Never expose `:1337` directly.
- Use a **strong password** โ€” it's the only thing between the internet and root.
- Set `MCP_SSH_ALLOWED_HOSTS` to your public hostname โ€” it's the DNS-rebinding guard.
- 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`.

## ๐Ÿ“ฆ Install

| Method | How |
|---|---|
| **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 |
| **Debian/Ubuntu** | download `mcp-ssh_*.deb` from [releases](https://github.com/developerz-ai/mcp-ssh/releases) โ†’ `sudo dpkg -i mcp-ssh_*.deb` |
| **Docker** | pull the image and run it (see [docs/deploy.md](docs/deploy.md)) |
| **From source** | `cargo build --release` โ†’ binary at `target/release/mcp-ssh` |

## ๐Ÿ“š Docs

| Doc | What's in it |
|---|---|
| [docs/connect-claude.md](docs/connect-claude.md) | Connect from Claude Desktop & mobile โ€” custom-connector setup, OAuth login, troubleshooting |
| [docs/usage.md](docs/usage.md) | Every tool with params + examples, the execution & pagination model, config & env vars |
| [docs/architecture.md](docs/architecture.md) | Module map, auto-backgrounding execution, the auth middleware, the stack |
| [docs/deploy.md](docs/deploy.md) | systemd, Caddy & nginx+certbot TLS, Docker, hardening |
| [docs/prompts/system-prompt.md](docs/prompts/system-prompt.md) | Ready-to-paste system prompt for driving the server from a chat LLM |
| [docs/prompts/skill.md](docs/prompts/skill.md) | Claude Code skill for autonomous server-side work |
| [`.coderabbit.yaml`](.coderabbit.yaml) | CodeRabbit AI review config; install the [GitHub App](https://github.com/apps/coderabbitai) on the repo |

## ๐Ÿงฌ Stack

Rust 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).

## ๐Ÿ“„ License

MIT. Repository: .