{
  "markdown": "# 🛡️ Agent Workspace MCP Server\n\n[![CI](https://github.com/HrRodan/agent-workspace-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/HrRodan/agent-workspace-mcp/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Python 3.14+](https://img.shields.io/badge/python-3.14+-blue.svg)](https://www.python.org/downloads/release/python-3140/)\n\nA unified Model Context Protocol (MCP) server providing a **highly secure, containerized workspace** for Large Language Models (LLMs). It acts as an isolated \"agentic playground\" where agents can autonomously code, test, and debug without risking the host machine.\n\n---\n\n## ✨ Features\n\n- **🏗️ Full Project Lifecycle**: Bootstrap projects with `uv init`, manage dependencies with `uv add`, and execute via `uv run`.\n- **🐚 Secure Bash Access**: Execute shell commands with mandatory timeouts and merged output streams.\n- **🚀 Token-Optimized Output**: Integrates [RTK (Rust Token Killer)](https://github.com/rtk-ai/rtk) to automatically filter and compress `run_bash` outputs (like `ls`, `git`, and test runners), saving 60-90% of LLM context tokens.\n- **📂 Robust Filesystem**: Path-traversal protected operations for reading, writing, and searching the workspace.\n- **🛡️ Multi-Layer Security**: Non-root execution, dropped capabilities, resource limits, and a read-only root filesystem.\n- ⚡ **Precision Editing**: Advanced `search_and_replace` with **fuzzy whitespace matching**, **indentation preservation**, dry-run support, and syntax validation for Python, JSON, JSONL, TOML, and YAML.\n- **📊 Real-time Observability**: Direct logging to MCP client UI and persistent rotating audit logs.\n\n---\n\n## 🏗️ Architecture\n\n```mermaid\nflowchart TD\n    Client[\"MCP Client (Claude / Cursor)\"] -- \"stdio (JSON-RPC)\" --> FastMCP[\"FastMCP Server\"]\n\n    subgraph Sandbox [\"Docker Sandbox Container (mcpuser)\"]\n        direction TB\n        \n        FastMCP -. \"Intercepts accidental prints\" .-> StdioGuard[\"StdoutRedirector\"]\n        FastMCP -. \"Application Logs\" .-> Logger[\"Dual Logger (stderr & .mcp/server.log)\"]\n        \n        FastMCP -- \"Tool Calls\" --> SecurityGuard[\"Security & Path Validator\"]\n        \n        subgraph Toolset [\"Tool Modules\"]\n            direction TB\n            SecurityGuard --> FSTools[\"Filesystem (read, write, list, search)\"]\n            SecurityGuard --> EditTools[\"Editing (search_and_replace)\"]\n            SecurityGuard --> ExecTools[\"Execution (run_bash)\"]\n        end\n\n        EditTools -- \"AST Verification\" --> Validator[\"Syntax Validations (Python, JSON, JSONL, TOML, YAML)\"]\n        ExecTools -- \"Process Group (Timeout=60s)\" --> Shell[\"/bin/sh Subprocess\"]\n        Shell -- \"Package Mgt & Checks\" --> UV[\"uv Environment / Ruff\"]\n        \n        FSTools -- \"Secure I/O\" --> Workspace[\"/workspace Directory\"]\n        EditTools -- \"Atomic Writes\" --> Workspace\n        Shell -- \"Executes within\" --> Workspace\n    end\n\n    Workspace <--\"Volume Mount\"--> HostFS[\"User Host Filesystem\"]\n```\n\n---\n\n## 📦 Quick Start\n\n### 1. Pull or Build the Docker Image\n```bash\n# Pull from GHCR\ndocker pull ghcr.io/hrrodan/agent-workspace-mcp:latest\n\n# OR: Build locally with your host's UID/GID for optimal permissions\ndocker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) -t agent-workspace-mcp .\n```\n\n### 2. Programmatic Usage (OpenAI Agents SDK)\nHere is a quick boilerplate showing how to use the containerized workspace programmatically using the standard `openai-agents` SDK:\n\n```python\nimport asyncio\nfrom agents import Agent, Runner\nfrom agents.mcp import MCPServerStdio\n\nasync def main():\n    # 1. Configure the MCP Server to run via Docker\n    server = MCPServerStdio(\n        name=\"Sandboxed Workspace\",\n        params={\n            \"command\": \"docker\",\n            \"args\": [\n                \"run\", \"-i\", \"--rm\", \"--init\",\n                # \"--network\", \"none\", # Network Isolation (optional) - see below\n                \"--memory=2g\", \"--cpus=2.0\",\n                \"--pids-limit=256\",\n                \"--cap-drop=ALL\", \"--security-opt=no-new-privileges:true\",\n                \"--read-only\",\n                \"--tmpfs\", \"/tmp:size=64m\",\n                \"--tmpfs\", \"/home/mcpuser/.cache:size=512m\",\n                \"--user\", \"1000:1000\", # Replace with your host UID:GID\n                \"-v\", \"/path/to/your/projects:/workspace\",\n                \"ghcr.io/hrrodan/agent-workspace-mcp:latest\",\n            ],\n        },\n        client_session_timeout_seconds=60.0,\n    )\n\n    # 2. Attach server to the Agent and load the skill instructions (optional)\n    with open(\"skills/agent-workspace-mcp/SKILL.md\", \"r\") as f:\n        skill_instructions = f.read()\n\n    agent = Agent(\n        name=\"WorkspaceAgent\",\n        instructions=f\"You are a coding agent with access to a secure workspace.\\n\\n{skill_instructions}\",\n        mcp_servers=[server],\n    )\n\n    # 3. Execute a workflow\n    async with server:\n        result = await Runner.run(\n            agent, \n            \"Create a python script in the workspace to print the first 10 Fibonacci numbers, then run it.\"\n        )\n        print(f\"Agent's Final Output:\\n{result.final_output}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### 3. Use with MCP Clients (Claude / Cursor)\nAdd the following configuration to your `claude_desktop_config.json` or Cursor settings.\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-workspace-mcp\": {\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\", \"-i\", \"--rm\", \"--init\",\n        // \"--network\", \"none\", // Network Isolation (optional) - see below\n        \"--memory=2g\", \"--cpus=2.0\",\n        \"--pids-limit=256\",\n        \"--cap-drop=ALL\", \"--security-opt=no-new-privileges:true\",\n        \"--read-only\",\n        \"--tmpfs\", \"/tmp:size=64m\",\n        \"--tmpfs\", \"/home/mcpuser/.cache:size=512m\",\n        \"--user\", \"1000:1000\",\n        \"-v\", \"/path/to/your/projects:/workspace\",\n        \"ghcr.io/hrrodan/agent-workspace-mcp:latest\"\n      ]\n    }\n  }\n}\n```\n\n> [!IMPORTANT]\n> **Linux Users:** Replace `1000:1000` with your actual UID:GID (run `id -u` and `id -g`). Claude Desktop does not expand environment variables.\n> **Signal Handling:** The `--init` flag is essential for proper signal forwarding and zombie process reaping.\n\n---\n\n## 🛠️ Tool Reference\n\n| Tool | Description |\n|---|---|\n| `read_file` | Read text files with optional `offset` and `limit` (default: 100 lines). |\n| `write_file` | Create files with **syntax validation** and a **5MB size guard**. Refuses to overwrite existing files by default (`create_only=True`). |\n| `list_directory` | List contents with `[F]`ile and `[D]`irectory prefixes. |\n| `search_workspace` | Find files by glob pattern with support for `exclude_patterns`. |\n| `run_bash` | Execute shell commands in `/workspace` with a 60s timeout. Automatically optimized via RTK to reduce token usage. |\n| `search_and_replace` | Multi-edit tool with **fuzzy whitespace matching**, **indentation preservation**, dry-run mode, and **syntax validation (Python, JSON, JSONL, TOML, YAML)**. |\n\n---\n\n## ⚙️ Configuration\n\nThe server supports the following environment variables (passed via Docker `--env`):\n\n| Variable | Default | Description |\n|---|---|---|\n| `COMMAND_TIMEOUT` | `60` | Default seconds before `run_bash` kills a process. |\n| `MAX_SEARCH_RESULTS` | `50` | Maximum results returned by `search_workspace`. |\n| `MAX_READ_SIZE_BYTES` | `1048576` | Maximum file size for `read_file` (1MB). |\n| `MAX_WRITE_SIZE_BYTES` | `5242880` | Maximum file size for `write_file` (5MB). |\n| `LOG_LEVEL` | `INFO` | Python logging level (DEBUG, INFO, etc.). |\n\n---\n\n## 🛡️ Security & Architecture Model\n\nThis server employs a **defense-in-depth** strategy, explicitly separating strict security boundaries from developer experience and operational reliability features.\n\n### 🔒 Core Security Features\nThese features are designed to protect the host system and enforce strict isolation boundaries.\n\n- **Kernel Hardening**: All Linux capabilities are dropped (`--cap-drop=ALL`), neutralizing privilege escalation vectors.\n- **Immutable Server Code**: The `/app` directory containing the server source and its virtual environment is owned by `root` and read-only for the `mcpuser`. This prevents the server from modifying itself or being tampered with via `run_bash`.\n- **Privilege Lockdown**: Enforces `no-new-privileges:true` to prevent any process from gaining elevated rights.\n- **Immutable System Core**: The container's root filesystem is mounted entirely **read-only**, providing a second layer of defense against OS-level tampering.\n- **Resource Quotas**: Hard limitations on CPU, Memory, and PIDs mitigate denial-of-service (DoS) attempts like fork-bombs and host exhaustion.\n- **Strict Boundary Enforcement**: A robust path validator comprehensively blocks all path traversal attacks outside the designated `/workspace`.\n- **Process & Resource Control**: Mandatory command timeouts (default 60s) and strict process group isolation ensure runaway or malicious processes are killed.\n- **Memory-Overload Protection**: Hard limits on file reads (1MB) and command outputs (50KB) prevent memory exhaustion.\n- **Information Leakage Prevention**: Internal stack traces and system paths are suppressed and sanitized from tool outputs.\n\n### 🛠️ Developer Experience & Convenience\nFeatures focused on seamless integration, usability, and reducing friction during agentic workflows.\n\n- **Host-Aligned Non-Root Identity**: Runs as `mcpuser` with UID/GID [customizable at build time](#1-pull-or-build-the-docker-image), eliminating tedious file permission conflicts on host volume mounts.\n- **Automatic Token Optimization**: Shell commands executed via `run_bash` are transparently rewritten through RTK to provide ultra-compact, LLM-friendly output without altering underlying command behavior.\n- **Intelligent Search Exclusions**: High-noise or sensitive directories (`.git`, `.venv`) are automatically ignored to keep context windows lean and relevant.\n- **Ephemeral Workspaces**: Containers are strictly ephemeral (`--rm`), guaranteeing a clean, predictable slate for every new session without state leaking across connections.\n- **Standardized Discovery**: Complies with the [OCI Image Specification](https://github.com/opencontainers/image-spec) for standardized container ecosystem integration and transparent auditing.\n\n### ⚙️ Reliability & Safety Mechanisms\nFeatures ensuring the structural integrity of the workspace and providing observability.\n\n- **Pre-Write Syntax Validation**: Both `write_file` and `search_and_replace` perform in-memory syntax validation for Python, JSON, JSONL, TOML, and YAML before persisting changes, preventing broken code states.\n- **Fail-Safe Writing**: `write_file` blocks accidental overwrites of existing files by default and enforces a 5MB size guard to prevent workspace flooding.\n- **Atomic File Operations**: Edits utilize temp-and-move logic to guarantee file integrity and prevent corruption, even during unexpected interruptions or crashes.\n- **Transparent Observability**: All tool invocations and state changes are streamed in real-time to the MCP client UI for immediate operator oversight.\n\n### 🌐 Network Isolation (Optional)\n\nBy default, the container has full network access via Docker's `bridge` network. For maximum isolation, you can completely disable the network stack using `--network none`:\n\n```bash\ndocker run -i --rm --init \\\n  --network none \\\n  --memory=2g --cpus=2.0 --pids-limit=256 \\\n  --cap-drop=ALL --security-opt=no-new-privileges:true \\\n  --read-only \\\n  --tmpfs /tmp:size=64m \\\n  --tmpfs /home/mcpuser/.cache:size=512m \\\n  --user 1000:1000 \\\n  -v /path/to/your/projects:/workspace \\\n  ghcr.io/hrrodan/agent-workspace-mcp:latest\n```\n\nThis creates a fully **air-gapped sandbox** — only the loopback interface exists inside the container. All outbound connections (`curl`, DNS, `uv add`, etc.) will fail immediately, eliminating data exfiltration and lateral movement risks entirely.\n\n> [!NOTE]\n> With `--network none`, the agent cannot install packages at runtime. All dependencies must be pre-installed in a custom image or pre-populated in the mounted workspace volume.\n\n---\n\n## 🤝 Contributing\n\n1. **Install Dev Dependencies**: `uv sync`\n2. **Run Linting**: `uv run ruff check .`\n3. **Run Unit Tests**: `uv run pytest tests/ --ignore=tests/integration/`\n4. **Run Integration Tests**: Set `OPENROUTER_API_KEY` and run `uv run pytest tests/integration/`\n\n---\n&copy; 2026 HrRodan. Licensed under [MIT](LICENSE).\n",
  "bytes": 12553,
  "sha": "60cce983b0f0d21ac56bd89c98906633cd24fb137e350ee3a93878761ec1e346",
  "repo_slug": "hrrodan/agent-workspace-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_hrrodan_agent_workspace_mcp_427dd839/readme"
}