Share a chosen workspace folder and stop with the window
run.sh asks which host folder Claude may access, using the desktop's folder picker (zenity, or kdialog on KDE; terminal prompt otherwise), and mounts it read-write at /workspace. It opens at the last folder used, refuses / and $HOME, and can be skipped with --workspace DIR. The image creates /workspace and a ~/workspace symlink to it. Closing Claude Desktop's window only hides the app, which left the container running invisibly. The new entrypoint launch-claude.sh watches the app's X windows and quits it once none is open or minimized, so the container exits with it. run.sh adds --init for signal handling and reaping. Also add .gitignore for workspace/ and .env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -38,13 +38,14 @@ The repo is at an early stage (no code yet). The layout below is the **intended*
|
||||
## Architecture
|
||||
|
||||
- **One service per container.** Claude Desktop, Ghidra and the RE MCP server each get their own image, connected on one compose network.
|
||||
- **Shared workspace volume.** Every container mounts `./workspace` at the same path (e.g. `/workspace`), so a file path means the same thing to Claude, Ghidra and the RE MCP.
|
||||
- **Shared workspace volume.** Every container mounts the workspace at `/workspace`, so a file path means the same thing to Claude, Ghidra and the RE MCP. `run.sh` asks for the host folder on each start in the desktop's folder picker (`zenity`, or `kdialog` on KDE; terminal prompt if neither exists), opening at the last folder used, else `./workspace`. Skip it with `--workspace DIR` or `WORKSPACE=DIR`. It refuses `/` and `$HOME`. The image symlinks `~/workspace` to `/workspace` for Claude Desktop's file picker.
|
||||
- **GUI forwarding.** Claude Desktop and Ghidra are GUI apps. Default to X11 forwarding (`/tmp/.X11-unix` + `DISPLAY`). Support Wayland through XWayland. Keep a noVNC/VNC fallback in mind for headless hosts. Never solve display access with a blanket `xhost +`. Scope it (`xhost +local:docker` or `+SI:localuser:...`).
|
||||
- **GhidraMCP wiring.** GhidraMCP has two parts:
|
||||
- a Ghidra plugin that runs an HTTP server inside Ghidra (default port `8080`), and
|
||||
- a Python MCP bridge (`bridge_mcp_ghidra.py`) that speaks MCP to Claude and forwards calls to that HTTP server.
|
||||
|
||||
The bridge is configured with the Ghidra server URL (e.g. `http://ghidra:8080/`). The plugin must be enabled in the CodeBrowser and a program must be open, or the bridge has nothing to talk to.
|
||||
- **Container lifetime follows the window.** Closing Claude Desktop's window only hides the app (GNOME shows no tray icon to bring it back). The image's entrypoint `launch-claude.sh` watches the app's X windows: when none is open or minimized for ~3 s, it quits the app and the container exits. `run.sh` uses `--init` so signals and zombie processes are handled.
|
||||
- **MCP transport between containers.** Claude Desktop starts local MCP servers as stdio subprocesses. Because the servers live in other containers, pick one approach and apply it consistently:
|
||||
- *Preferred:* run the MCP servers with an HTTP/SSE transport in their own containers. Bridge them into Claude Desktop's stdio config with a small proxy (e.g. `mcp-remote` or `mcp-proxy`) installed in the Claude Desktop image.
|
||||
- *Alternative:* install the bridges inside the Claude Desktop image and point them at the other containers over the network. This works well for the GhidraMCP bridge, which is just Python + HTTP.
|
||||
|
||||
Reference in New Issue
Block a user