diff --git a/README.md b/README.md index 1278d04..4434956 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,23 @@ -## RemoteShell MCP +# ๐Ÿ”— RemoteShell MCP -RemoteShell is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that lets an LLM: +A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that enables LLMs to securely manage and execute commands on remote SSH servers. -- Save SSH server profiles once (so the user doesnโ€™t retype credentials) -- Execute **non-interactive** shell commands remotely -- Upload/download files via SFTP +## โœจ Features -This server is built with [FastMCP](https://gofastmcp.com/) and Paramiko. +- ๐Ÿ” **Secure credential management** - Save SSH server profiles once, no need to retype credentials +- ๐Ÿ’ป **Remote command execution** - Execute non-interactive shell commands remotely +- ๐Ÿ“ **File operations** - Upload/download files via SFTP +- ๐Ÿค– **LLM-powered** - Built with [FastMCP](https://gofastmcp.com/) and Paramiko -## Installation / Client setup (recommended) +## ๐Ÿš€ Installation -Add this to your MCP client config: +### For Claude Code users +```bash +claude mcp add remoteshell --scope user -- uvx remoteshell-mcp +``` + +### For other MCP clients +Add this to your MCP client configuration: ```json { @@ -22,32 +29,43 @@ Add this to your MCP client config: } } ``` +## ๐Ÿ“– Usage + +Getting started is easy! You can either: -## Persistent storage +1. **๐Ÿค– Let the LLM configure for you** - Simply tell the LLM your host, username, password, etc., and ask it to set up the server configuration +2. **โš™๏ธ Manual configuration** - Directly edit the configuration file at `~/.config/remoteshell/hosts.json` -RemoteShell persists servers to: -- `~/.config/remoteshell/hosts.json` +## ๐Ÿ’พ Configuration & Storage -The LLM is expected to manage this file by calling `save_server` / `remove_server`. -You can also edit it manually. +RemoteShell securely stores your server configurations in: + +``` +~/.config/remoteshell/hosts.json +``` -Example `hosts.json`: +### ๐Ÿ”ง Configuration Management + +- **LLM-managed**: The LLM automatically manages this file using `save_server` and `remove_server` tools +- **Manual editing**: You can also directly edit the JSON file for advanced configurations + +### ๐Ÿ“‹ Example Configuration ```json { "version": 1, "servers": { - "srv1": { + "production-server": { "host": "1.2.3.4", "user": "root", "port": 22, "auth_type": "password", - "password": "your_password_here", + "password": "your_secure_password", "last_connected": null }, - "srv2": { - "host": "example.com", + "staging-server": { + "host": "staging.example.com", "user": "ubuntu", "port": 22, "auth_type": "private_key", @@ -58,56 +76,102 @@ Example `hosts.json`: } ``` -On POSIX systems you should protect the file: +### ๐Ÿ”’ Security Note + +On POSIX systems, protect your configuration file: ```bash chmod 600 ~/.config/remoteshell/hosts.json ``` -## Tools +## ๐Ÿ› ๏ธ Available Tools + +RemoteShell provides the following MCP tools for remote server management: + +### ๐Ÿ“‹ `list_servers()` + +**Purpose**: Display all saved server profiles with their connection status and last activity. + +**When to use**: +- User asks to "connect to server" or "show machines" +- No specific `connection_id` is provided +- Need to see available servers + +**Example**: *"Show me which servers I have configured"* โ†’ Returns list of all saved servers with online status + +### ๐Ÿ’พ `save_server(connection_id, host, user, auth_type, credential)` + +**Purpose**: Create or update a server profile with authentication credentials. + +**Parameters**: +- `connection_id`: Unique identifier for the server (e.g., "production", "staging") +- `host`: Server hostname or IP address +- `user`: SSH username +- `auth_type`: `"password"` or `"private_key"` +- `credential`: + - For `password`: Plain text password string + - For `private_key`: File path (e.g., `~/.ssh/id_rsa`) or PEM key content + +**When to use**: +- Adding a new server configuration +- Updating credentials after authentication failure +- Changing server connection details + +### ๐Ÿ—‘๏ธ `remove_server(connection_id)` + +**Purpose**: Permanently delete a server profile from storage. + +**When to use**: +- User explicitly requests to remove or forget a server +- Server is no longer accessible or needed + +โš ๏ธ **Warning**: This action cannot be undone + +### โšก `execute_command(connection_id, command)` + +**Purpose**: Execute non-interactive shell commands remotely and return results. -RemoteShell exposes exactly these tools: +**Returns**: `stdout`, `stderr`, and `exit_code` -### `list_servers()` +**When to use**: +- Running system commands, scripts, or utilities +- Checking server status, disk usage, process lists +- File operations, package management, etc. -- **Purpose**: List saved servers, including cached online status and `last_connected`. -- **When to use**: When the user says โ€œconnect serverโ€, โ€œshow machinesโ€, or did not specify a `connection_id`. -- **Example**: โ€œShow me which servers I have.โ€ +**When NOT to use**: +- Interactive programs (vim, htop, top) +- Commands requiring manual input (`[Y/n]` prompts) - unless using flags like `-y` -### `save_server(connection_id, host, user, auth_type, credential)` +**Example**: `execute_command(connection_id="production", command="df -h")` -- **Purpose**: Create/update a saved server profile. -- **auth_type**: `password` or `private_key` -- **credential**: - - For `password`: the password string - - For `private_key`: either a private key path (e.g. `~/.ssh/id_rsa`) or PEM key text -- **When to use**: New server info, or after `auth_failed` to update credentials. +### ๐Ÿ“ค `upload_file(connection_id, local_path, remote_path)` -### `remove_server(connection_id)` +**Purpose**: Upload files from your local machine to a remote server via SFTP. -- **Purpose**: Permanently delete a saved server profile. -- **When to use**: Only when the user explicitly asks to remove/forget a server. +**Parameters**: +- `local_path`: Path to the file on your local machine +- `remote_path`: Destination path on the remote server -### `execute_command(connection_id, command)` +**Notes**: +- If `remote_path` is a directory, the original filename is preserved +- If `local_path` is omitted, server selects a default and returns it in response -- **Purpose**: Execute a **non-interactive** command remotely and return `stdout`, `stderr`, `exit_code`. -- **When NOT to use**: Interactive programs (vim/htop/top) or commands requiring manual `[Y/n]` prompts (unless you add flags like `-y`). -- **Example**: `execute_command(connection_id="srv1", command="df -h")` +### ๐Ÿ“ฅ `download_file(connection_id, remote_path, local_path)` -### `upload_file(connection_id, local_path, remote_path)` +**Purpose**: Download files from a remote server to your local machine via SFTP. -- **Purpose**: Upload a local file (local to the machine running this MCP server) to the remote. -- **Note**: If `remote_path` is a directory, the local filename is preserved. -- **Auto local_path**: If `local_path` is omitted, the server picks a default path and returns it in the response/error. +**Parameters**: +- `remote_path`: Path to the file on the remote server +- `local_path`: Destination path on your local machine -### `download_file(connection_id, remote_path, local_path)` +**Notes**: +- If `local_path` is omitted, defaults to: `~/.config/remoteshell/downloads//` -- **Purpose**: Download a remote file to a local path (local to the machine running this MCP server). -- **Auto local_path**: If `local_path` is omitted, the server defaults to `~/.config/remoteshell/downloads//`. +## ๐Ÿงช Development -## Claude Code shortcut (local dev) +### Local Development Setup -If you want to run the server from a local checkout: +For local development, use this MCP configuration: ```json { @@ -120,7 +184,7 @@ If you want to run the server from a local checkout: } ``` -## Development +### Running Tests ```bash uv run pytest