Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 76 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
# MCP SSH Wingman

A Model Context Protocol (MCP) server that provides read-only access to Unix shell prompts via tmux. This enables AI assistants like Claude to safely observe terminal environments without executing commands.
A Model Context Protocol (MCP) server that provides read-only access to Unix shell prompts via tmux or GNU screen. This enables AI assistants like Claude to safely observe terminal environments without executing commands.

## Features

- 🔒 **Read-only access** - Observe terminal content without execution risks
- 🖥️ **tmux integration** - Leverages tmux's session management for reliable terminal access
- 🖥️ **tmux & screen integration** - Leverages tmux or GNU screen session management for reliable terminal access
- 📺 **Multiple window support** - Access different windows/panes within your terminal sessions
- 📜 **Scrollback history** - Access historical terminal output
- 📊 **Terminal metadata** - Retrieve dimensions, current path, and session info
- 🔌 **MCP protocol** - Standard protocol for AI assistant integration

## Prerequisites

- Go 1.21 or later
- tmux
- tmux (for tmux support)
- GNU screen (for screen support)

## Installation

Expand Down Expand Up @@ -55,8 +57,14 @@ make install
# Start with default tmux session name (mcp-wingman)
./bin/mcp-ssh-wingman

# Use a custom tmux session name
./bin/mcp-ssh-wingman --session my-session
# Use tmux with a custom session name
./bin/mcp-ssh-wingman --terminal tmux --session my-session

# Use GNU screen with default session name
./bin/mcp-ssh-wingman --terminal screen

# Use GNU screen with custom session name and specific window
./bin/mcp-ssh-wingman --terminal screen --session my-screen --window 2
```

### Integration with Claude Desktop
Expand All @@ -65,12 +73,37 @@ Add the server to your Claude Desktop configuration file:

**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`

**For tmux:**
```json
{
"mcpServers": {
"ssh-wingman": {
"command": "/usr/local/bin/mcp-ssh-wingman",
"args": ["--terminal", "tmux", "--session", "mcp-wingman"]
}
}
}
```

**For GNU screen:**
```json
{
"mcpServers": {
"ssh-wingman": {
"command": "/usr/local/bin/mcp-ssh-wingman",
"args": ["--terminal", "screen", "--session", "mcp-wingman"]
}
}
}
```

**For screen with specific window:**
```json
{
"mcpServers": {
"ssh-wingman": {
"command": "/usr/local/bin/mcp-ssh-wingman",
"args": ["--session", "mcp-wingman"]
"args": ["--terminal", "screen", "--session", "my-screen", "--window", "2"]
}
}
}
Expand All @@ -83,7 +116,7 @@ Restart Claude Desktop after updating the configuration.
The server exposes the following MCP tools:

### `read_terminal`
Read the current terminal content from the tmux session.
Read the current terminal content from the tmux/screen session.

```json
{
Expand All @@ -92,7 +125,7 @@ Read the current terminal content from the tmux session.
```

### `read_scrollback`
Read scrollback history from the tmux session.
Read scrollback history from the tmux/screen session.

```json
{
Expand All @@ -112,6 +145,27 @@ Get information about the terminal (dimensions, current path, etc.).
}
```

### `list_windows`
List all windows/panes in the current session.

```json
{
"name": "list_windows"
}
```

### `set_window`
Set the active window/pane for subsequent operations.

```json
{
"name": "set_window",
"arguments": {
"window_id": "2"
}
}
```

## Available Resources

### `terminal://current`
Expand All @@ -122,12 +176,21 @@ Terminal metadata and information.

## How It Works

The server creates or attaches to a tmux session and uses tmux's built-in commands to safely read terminal content:
The server creates or attaches to a tmux/screen session and uses their built-in commands to safely read terminal content:

1. **Session Management**: Creates/attaches to a detached tmux or screen session
2. **Content Capture**: Uses `tmux capture-pane` or `screen hardcopy` to read visible content
3. **Multiple Windows**: Can switch between different windows/panes within the session
4. **Read-Only**: Never sends keystrokes or commands to the session
5. **MCP Protocol**: Exposes terminal content via standard MCP tools and resources

### Screen-Specific Features

1. **Session Management**: Creates/attaches to a detached tmux session
2. **Content Capture**: Uses `tmux capture-pane` to read visible content
3. **Read-Only**: Never sends keystrokes or commands to the session
4. **MCP Protocol**: Exposes terminal content via standard MCP tools and resources
For GNU screen users, the implementation provides:
- **Existing Session Support**: Attach to your existing screen session with all your windows
- **Window Navigation**: List and switch between different screen windows
- **Backscroll Access**: Access your screen's scrollback buffer history
- **Multi-Window Workflow**: Perfect for users who run local screen with multiple remote connections

## Development

Expand Down
16 changes: 13 additions & 3 deletions cmd/mcp-ssh-wingman/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ var (
commit = "none"
date = "unknown"

sessionName = flag.String("session", "mcp-wingman", "tmux session name to attach to")
sessionName = flag.String("session", "mcp-wingman", "terminal session name to attach to")
terminalType = flag.String("terminal", "tmux", "terminal multiplexer type: tmux or screen")
windowID = flag.String("window", "", "specific window/pane ID to attach to (optional)")
versionFlag = flag.Bool("version", false, "print version and exit")
)

Expand All @@ -35,9 +37,17 @@ func main() {
// Log to stderr so it doesn't interfere with JSON-RPC on stdout
log.SetOutput(os.Stderr)

log.Printf("Starting MCP server for tmux session: %s", *sessionName)
// Validate terminal type
if *terminalType != "tmux" && *terminalType != "screen" {
log.Fatalf("Invalid terminal type: %s. Must be 'tmux' or 'screen'", *terminalType)
}

log.Printf("Starting MCP server for %s session: %s", *terminalType, *sessionName)
if *windowID != "" {
log.Printf("Targeting specific window/pane: %s", *windowID)
}

srv := server.NewServer(*sessionName, os.Stdin, os.Stdout)
srv := server.NewServer(*terminalType, *sessionName, *windowID, os.Stdin, os.Stdout)
if err := srv.Start(); err != nil {
log.Fatalf("Server error: %v", err)
}
Expand Down
86 changes: 86 additions & 0 deletions examples/screen-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Example Claude Desktop Configuration for Screen Users

This directory contains example configuration files for different screen setups.

## Basic Screen Configuration

For users with a single screen session:

```json
{
"mcpServers": {
"ssh-wingman": {
"command": "/usr/local/bin/mcp-ssh-wingman",
"args": ["--terminal", "screen", "--session", "main"]
}
}
}
```

## Multi-Window Screen Configuration

For users who want to target a specific window in their screen session:

```json
{
"mcpServers": {
"ssh-wingman": {
"command": "/usr/local/bin/mcp-ssh-wingman",
"args": ["--terminal", "screen", "--session", "main", "--window", "1"]
}
}
}
```

## Usage Tips for Screen Users

### 1. Find Your Screen Session Name
```bash
screen -ls
```

### 2. List Windows in Your Session
Once connected via MCP, use the `list_windows` tool to see all available windows.

### 3. Switch Between Windows
Use the `set_window` tool to switch to different windows:
```json
{
"name": "set_window",
"arguments": {
"window_id": "2"
}
}
```

### 4. Access Scrollback History
Use the `read_scrollback` tool to access your screen's backscroll:
```json
{
"name": "read_scrollback",
"arguments": {
"lines": 1000
}
}
```

## Screen Session Setup

If you don't have a screen session running, you can create one:

```bash
# Create a new detached screen session
screen -dmS main

# Or attach to create windows
screen -S main
# Then use Ctrl-A c to create new windows
# Use Ctrl-A d to detach
```

## Benefits for Screen Users

- **Preserve Your Workflow**: Use your existing screen setup without changes
- **Multiple Remote Connections**: Perfect for users who connect to multiple servers through screen windows
- **Rich Scrollback**: Access all your historical output stored in screen's backscroll buffer
- **Window Management**: Easily navigate between different terminal environments
Loading