Commit e876a55

mo khan <mo@mokhan.ca>
2025-06-22 14:58:03
docs: add design doc for bash MCP
1 parent d8b2cda
Changed files (1)
cmd
cmd/bash/DESIGN.md
@@ -0,0 +1,215 @@
+# MCP Bash Server โ€“ DESIGN.md
+
+## ๐Ÿ“Œ Overview
+
+This server is part of the [Model Context Protocol (MCP)](https://github.com/xlgmokha/mcp) ecosystem. It exposes a safe and sandboxed Bash shell environment over HTTP so that AI agents can run shell commands, receive outputs, and reason about systems programmatically without unrestricted access to the host system.
+
+---
+
+## ๐Ÿงฑ Goals
+
+- Accept Bash command requests from agents
+- Run them in a sandboxed, time-limited environment
+- Return structured results: stdout, stderr, exit code, and duration
+- Be safe by default, and extensible for future improvements (containers, persistent sessions)
+
+---
+
+## ๐Ÿ“ Directory Structure
+
+```
+
+mcp/
+โ”œโ”€โ”€ cmd/
+โ”‚   โ””โ”€โ”€ bash/
+โ”‚       โ””โ”€โ”€ main.go          # Entrypoint HTTP server
+โ”œโ”€โ”€ pkg/
+โ”‚   โ””โ”€โ”€ bash/
+โ”‚       โ””โ”€โ”€ server.go        # Handles command execution
+โ””โ”€โ”€ go.mod
+````
+
+---
+
+## ๐ŸŒ HTTP API
+
+### POST `/run`
+
+#### Request
+
+```json
+{
+  "command": "ls -al",
+  "timeout_seconds": 5
+}
+````
+
+* `command` (string): Shell command to run.
+* `timeout_seconds` (int): Optional. Max seconds to allow execution. Default: 5.
+
+#### Response
+
+```json
+{
+  "stdout": "total 0\n-rw-r--r-- file1\n",
+  "stderr": "",
+  "exit_code": 0,
+  "duration_ms": 13
+}
+```
+
+---
+
+## ๐Ÿง  Internal API
+
+```go
+type CommandRequest struct {
+    Command       string
+    TimeoutSeconds int
+}
+
+type CommandResult struct {
+    Stdout     string
+    Stderr     string
+    ExitCode   int
+    DurationMs int64
+}
+
+func RunCommand(ctx context.Context, req CommandRequest) (CommandResult, error)
+```
+
+* Executes a shell command using Go's `os/exec`.
+* Handles timeout using `context.WithTimeout`.
+* Returns captured output and metadata.
+
+---
+
+## ๐Ÿ” Security & Sandbox Plan
+
+**Initial Implementation (MVP):**
+
+* Use a per-request working directory under a configured root (e.g. `/tmp/mcp/bash-<uuid>`)
+* Timeout enforcement
+* Drop privileges by running under a non-root user
+* Optional input validation for dangerous commands
+
+**Future Options:**
+
+* Use `nsjail`, `firejail`, or containers (`podman`, `docker`)
+* CPU and memory limits
+* Disk quotas and file write limits
+* Per-agent execution UID
+
+---
+
+## โš™๏ธ Configuration
+
+| Method           | Variable/Flag            | Description                                    | Default         |
+| ---------------- | ------------------------ | ---------------------------------------------- | --------------- |
+| CLI flag         | `--workdir=/path/to/dir` | Root directory for sandboxed command execution | `/tmp/mcp/bash` |
+| Environment var  | `MCP_BASH_ROOT_DIR`      | Fallback if flag not provided                  | `/tmp/mcp/bash` |
+| Internal default | (hardcoded fallback)     | Used if neither flag nor env var is set        | `/tmp/mcp/bash` |
+
+> **Note:** The CLI flag takes precedence over the environment variable.
+
+---
+
+## โœ… MVP Checklist
+
+* [ ] Basic HTTP server using `net/http`
+* [ ] POST `/run` endpoint
+* [ ] Timeout via `context.WithTimeout`
+* [ ] Use `exec.CommandContext` to run the command
+* [ ] Capture and return stdout, stderr, exit code, and timing
+* [ ] Create temporary working directory per request under the configured root
+* [ ] Add unit and integration tests
+* [ ] Support `--workdir` CLI flag and `MCP_BASH_ROOT_DIR` env var
+
+---
+
+## ๐Ÿงช Testing
+
+**Unit Tests:**
+
+* Mock command runner
+* Validate request parsing, output formatting
+
+**Integration Tests:**
+
+* Execute safe commands (`echo`, `ls`)
+* Validate timeout behavior
+* Capture output correctness
+
+**Security Tests:**
+
+* Try `yes > /dev/null`
+* Try fork bomb: `:(){ :|:& };:`
+* Try `rm -rf /` (should be blocked or jailed)
+
+---
+
+## ๐Ÿ“ฆ Dependencies
+
+* Go stdlib:
+
+  * `os/exec`, `context`, `net/http`, `encoding/json`, `time`, `io/ioutil`, `flag`
+* Optional:
+
+  * `github.com/google/uuid`
+  * `github.com/gorilla/mux` (for extensible routing)
+
+---
+
+## ๐Ÿงฌ Future Work
+
+* [ ] Persistent shell sessions (`cd`, variables, etc.)
+* [ ] Command history and working memory
+* [ ] Streaming I/O for interactive commands
+* [ ] File upload API to allow scripts/data to be passed in
+* [ ] gRPC API
+
+---
+
+## โœจ Example Usage
+
+Start server with flag:
+
+```bash
+go run ./cmd/bash --workdir=/home/mokhax/src
+```
+
+Or using environment variable:
+
+```bash
+export MCP_BASH_ROOT_DIR=/srv/mcp/tmp
+go run ./cmd/bash
+```
+
+Run a command:
+
+```bash
+curl -X POST http://localhost:8080/run \
+  -H "Content-Type: application/json" \
+  -d '{"command": "ls -al", "timeout_seconds": 3}'
+```
+
+---
+
+## ๐Ÿง  Why Bash?
+
+* Ideal for scripting, file system exploration, automation
+* Agents can use familiar Unix semantics
+* Can be secured and sandboxed effectively
+* Supports future composability (e.g., running other MCP servers via CLI tools)
+
+---
+
+## ๐Ÿงฉ Integration Notes
+
+This server can be coordinated with other `mcp` services (e.g. `git`, `fs`, `edit`) via a central orchestrator or CLI client. Each server is standalone, stateless, and focused on one domain of control.
+
+---
+
+**Author:** [mo khan](https://github.com/xlgmokha)
+**Project:** [MCP](https://github.com/xlgmokha/mcp)
+**License:** MIT