Skip to content

MCP Server

Eric Kochen edited this page Apr 7, 2026 · 5 revisions

What is MCP?

MCP (Model Context Protocol) is a standard for connecting AI coding assistants to external tools. purple implements an MCP server so AI agents like Claude Code, Cursor and Windsurf can query your SSH hosts, run commands and manage containers programmatically.

Starting the server

purple mcp

The AI client spawns purple mcp automatically as a child process. You do not need to start it manually. Just add the config below and restart your AI client.

With a custom config:

purple --config ~/other/ssh_config mcp

Available tools

Tool Description
list_hosts List all SSH hosts. Optional tag filter (fuzzy match)
get_host Detailed info for one host: provider, tags, metadata, tunnels, askpass
run_command Run a command on a remote host via SSH. Configurable timeout (default 30s)
list_containers List Docker/Podman containers on a remote host
container_action Start, stop or restart a container

Client setup

Claude Code

Add to ~/.claude/settings.json:

{
  "mcpServers": {
    "purple": {
      "command": "purple",
      "args": ["mcp"]
    }
  }
}

Restart Claude Code. The purple tools appear automatically.

Cursor

Add to your MCP configuration (Settings > MCP Servers):

{
  "purple": {
    "command": "purple",
    "args": ["mcp"]
  }
}

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "purple": {
      "command": "purple",
      "args": ["mcp"]
    }
  }
}

Custom SSH config path

If you use a non-default SSH config, pass --config before mcp:

{
  "mcpServers": {
    "purple": {
      "command": "purple",
      "args": ["--config", "/path/to/ssh_config", "mcp"]
    }
  }
}

Other MCP clients

Any MCP-compatible client that supports stdio transport can use purple. Point it to the purple mcp command.

Security

The MCP server validates every alias against the SSH config before executing SSH commands. Only hosts in your config can be targeted. Container IDs are validated with an ASCII alphanumeric allowlist to prevent injection. All SSH operations use BatchMode=yes (no interactive prompts) and timeouts.

Purple does not implement its own approval gate. Approval behavior depends on your AI client. Claude Code prompts for approval on tool calls by default. Verify your client's settings before enabling run_command in production.

Example session

What the AI client sends and receives:

→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"claude","version":"1.0"}}}
← {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"purple","version":"2.30.1"}}}

→ {"jsonrpc":"2.0","method":"notifications/initialized"}
(no response)

→ {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_hosts","arguments":{"tag":"prod"}}}
← {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"[{\"alias\":\"web-1\",\"hostname\":\"10.0.1.5\", ...}]"}]}}

→ {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"run_command","arguments":{"alias":"web-1","command":"uptime"}}}
← {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"{\"exit_code\":0,\"stdout\":\" 14:32 up 42 days\",\"stderr\":\"\"}"}]}}

Troubleshooting

"No such file or directory" on startup

MCP clients spawn purple as a child process with a minimal PATH (typically /usr/local/bin, /opt/homebrew/bin, /usr/bin, /bin). If you installed purple via curl the binary lives in ~/.local/bin which is not in that PATH.

Fix: use the full path in your MCP config:

{
  "mcpServers": {
    "purple": {
      "command": "/Users/you/.local/bin/purple",
      "args": ["mcp"]
    }
  }
}

Find your path with which purple.

Homebrew installs (/opt/homebrew/bin/purple) are usually found automatically.

Limitations

  • Stdio transport only. No HTTP or SSE
  • Read and execute only. No host mutations (add, edit, delete) in this version
  • No provider sync, tunnel management or file transfer via MCP
  • Single-threaded, blocking. One request at a time

Clone this wiki locally