Skip to content

Commit 7a3e64c

Browse files
author
User
committed
lint: ruff clean on src/ and webapp/
1 parent 4fe96e5 commit 7a3e64c

32 files changed

Lines changed: 151 additions & 86 deletions

docs/specifications/sandboxing_technologies.md

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,19 +173,87 @@ docker run -p 4000:80 myapp
173173
- CI/CD pipelines
174174
- Multi-service applications
175175

176+
## Docker Sandbox (docker sandbox + docker agent)
177+
178+
*Added 2026-05-06 for future reference.*
179+
180+
Docker Desktop v0.12+ ships two AI-agent-oriented commands:
181+
182+
### docker sandbox
183+
Creates VM-based isolated sandbox environments for AI agents. Built-in agent templates:
184+
185+
| Subcommand | Template |
186+
|---|---|
187+
| `opencode` | Pre-configured for our fleet CLI tool |
188+
| `claude` | Claude Code |
189+
| `codex` | Terminal AI coding agent |
190+
| `copilot` | GitHub Copilot |
191+
| `gemini` | Google Gemini CLI |
192+
| `cagent` | Docker's agent runner (v1.44.0) |
193+
| `kiro` | Terminal agent |
194+
| `shell` | Plain shell |
195+
196+
```bash
197+
# Create a sandbox for opencode
198+
docker sandbox create opencode --name my-sandbox
199+
200+
# List running sandboxes
201+
docker sandbox ls
202+
203+
# Exec into a sandbox
204+
docker sandbox exec my-sandbox -- bash
205+
206+
# Snapshot and restore
207+
docker sandbox save my-sandbox --template my-template
208+
docker sandbox create opencode --template my-template
209+
210+
# Clean up
211+
docker sandbox rm my-sandbox
212+
```
213+
214+
### docker agent (cagent)
215+
Docker's AI Agent Runner (internal name: `cagent`, v1.44.0). Runs agents from YAML configs:
216+
217+
```bash
218+
# Create a new agent config
219+
docker agent new my-agent --model gemini-2.0-flash
220+
221+
# Run an agent
222+
docker agent run my-agent
223+
224+
# Run from a YAML file
225+
docker agent run ./agent.yaml
226+
227+
# Expose as MCP server
228+
docker agent serve my-agent
229+
```
230+
231+
### vs. virtualization-mcp sandbox_management
232+
| Aspect | Docker Sandbox | virtualization-mcp sandbox_management |
233+
|---|---|---|
234+
| Isolation | VM-level (full OS) | Container-level (Docker) |
235+
| Agent support | 8 built-in templates (opencode, claude, etc.) | Custom Python/JS/bash images |
236+
| Integration | Standalone CLI | MCP tool, fleet-integrated |
237+
| Snapshot | `docker sandbox save` | `session_destroy` + recreate |
238+
| Networking | Managed via `docker sandbox network` | `--network` flag |
239+
240+
**Note**: Docker Sandbox overlaps with our existing `sandbox_management` tool but adds VM-level isolation and multi-agent templates. Worth watching for fleet-specific features; not a replacement for our MCP-integrated approach.
241+
176242
## Comparison Table
177243

178-
| Feature | venv | Conda (cenv) | Docker |
179-
|------------------------|-------------------|-------------------|-------------------|
180-
| Isolation Level | Python packages | Python + system | OS-level |
181-
| Package Management | pip | conda | apt/yum/apk/etc. |
182-
| Dependencies | Python only | Multi-language | System-wide |
183-
| Performance | Very fast | Fast | Slight overhead |
184-
| Size | Small | Medium | Larger |
185-
| Startup Time | Instant | Fast | Slower |
186-
| Cross-platform | Yes | Yes | Yes (with Docker) |
187-
| System Requirements | Python only | Conda installed | Docker installed |
188-
| Use Case | Python projects | Data science | Deployment |
244+
| Feature | venv | Conda (cenv) | Docker Containers | Docker Sandbox* |
245+
|------------------------|-------------------|-------------------|-------------------|-------------------|
246+
| Isolation Level | Python packages | Python + system | Container-level | VM-level (full OS) |
247+
| Package Management | pip | conda | apt/yum/apk/etc. | Template images |
248+
| Dependencies | Python only | Multi-language | System-wide | Full OS stack |
249+
| Performance | Very fast | Fast | Slight overhead | VM overhead |
250+
| Size | Small | Medium | Larger | Largest |
251+
| Startup Time | Instant | Fast | Slower | Slowest |
252+
| Cross-platform | Yes | Yes | Yes (with Docker) | Yes (Docker Desktop)|
253+
| System Requirements | Python only | Conda installed | Docker installed | Docker Desktop v0.12+|
254+
| Use Case | Python projects | Data science | Deployment | AI agent sandboxing |
255+
256+
*\*Docker Sandbox (`docker sandbox` + `docker agent`) added in Docker Desktop v0.12. See section below.*
189257

190258
## Integration with virtualization-mcp
191259

src/virtualization_mcp/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
]
2525

2626
# Lazy imports to avoid circular imports
27-
import importlib # noqa: E402
2827

2928

3029
def _lazy_import():

src/virtualization_mcp/all_tools_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def main() -> int:
8484
parser.add_argument(
8585
"--http", action="store_const", const="http", dest="transport", help="Alias for --transport http"
8686
)
87-
parser.add_argument("--host", default="0.0.0.0", help="HTTP host")
87+
parser.add_argument("--host", default="0.0.0.0", help="HTTP host") # noqa: S104
8888
parser.add_argument("--port", type=int, default=10702, help="HTTP port")
8989
args = parser.parse_args()
9090

src/virtualization_mcp/api/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
"""
77

88
import logging
9-
import time
109
from collections.abc import Callable
1110
from functools import wraps
12-
from typing import Any, Optional, TypeVar, cast
11+
from typing import Any
1312

1413
from fastmcp import FastMCP
1514

@@ -19,7 +18,6 @@
1918
from ..utils.rate_limiter import RateLimiter
2019

2120
# Import API modules
22-
from . import documentation
2321
from .documentation import register_documentation_routes
2422

2523
logger = logging.getLogger(__name__)

src/virtualization_mcp/config.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import sys
1010
from datetime import datetime
1111
from pathlib import Path
12+
from typing import ClassVar
1213

1314
from pydantic import BaseModel, ConfigDict, Field, field_validator
1415

@@ -22,7 +23,7 @@
2223
class BaseSettings(BaseModel):
2324
debug: bool = False
2425
log_level: str = "INFO"
25-
host: str = "0.0.0.0"
26+
host: str = "0.0.0.0" # noqa: S104
2627
port: int = 10702
2728

2829

@@ -54,7 +55,7 @@ class Settings(BaseSettings):
5455
DEBUG: bool = False
5556

5657
# Server configuration (MCP HTTP/SSE: use 10700-10800 per SOTA; 10702 avoids webapp 10700/10701)
57-
HOST: str = "0.0.0.0"
58+
HOST: str = "0.0.0.0" # noqa: S104
5859
PORT: int = Field(default=10702, validation_alias="VIRTUALIZATION_MCP_PORT", description="MCP HTTP/SSE port")
5960
WEB_PORT: int = 3080 # FastAPI web server port
6061
WORKERS: int = 1
@@ -210,7 +211,7 @@ def setup_console_handler() -> logging.Handler:
210211

211212
# Color formatter for console
212213
class ColorFormatter(logging.Formatter):
213-
COLORS = {
214+
COLORS: ClassVar[dict[str, str]] = {
214215
"WARNING": "\033[93m", # Yellow
215216
"INFO": "\033[92m", # Green
216217
"DEBUG": "\033[96m", # Cyan

src/virtualization_mcp/dual_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def run_web_server():
4545
configure_logging()
4646

4747
port = int(os.getenv("WEB_PORT", getattr(settings, "WEB_PORT", 3080)))
48-
host = os.getenv("WEB_HOST", "0.0.0.0")
48+
host = os.getenv("WEB_HOST", "0.0.0.0") # noqa: S104
4949

5050
logger.info(f"Starting FastAPI web server on http://{host}:{port}")
5151
logger.info(f"Web interface: http://localhost:{port}")

src/virtualization_mcp/json_encoder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from collections.abc import Callable
1010
from datetime import datetime
1111
from enum import Enum
12-
from typing import Any, TypeVar
12+
from typing import Any, ClassVar, TypeVar
1313

1414
logger = logging.getLogger(__name__)
1515

@@ -21,7 +21,7 @@ class VBoxJSONEncoder(json.JSONEncoder):
2121
"""Custom JSON encoder that handles VirtualBox objects and other non-serializable types."""
2222

2323
# Cache for type handlers to improve performance
24-
_type_handlers: dict[type, Callable[[Any], Any]] = {}
24+
_type_handlers: ClassVar[dict[type, Callable[[Any], Any]]] = {}
2525

2626
def __init__(self, *args, **kwargs):
2727
super().__init__(*args, **kwargs)

src/virtualization_mcp/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def parse_arguments() -> argparse.Namespace:
2323
"""Parse command line arguments."""
2424
parser = argparse.ArgumentParser(description="VirtualBox MCP Server")
2525
parser.add_argument("--debug", action="store_true", default=DEBUG, help="Enable debug logging")
26-
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to bind the server to")
26+
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to bind the server to") # noqa: S104
2727
parser.add_argument(
2828
"--port",
2929
type=int,

src/virtualization_mcp/plugins/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"""
66

77
import logging
8-
from typing import Optional
98

109
from fastmcp import FastMCP
1110

src/virtualization_mcp/server_v2/plugins/hyperv_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ async def shutdown(self) -> None:
432432
try:
433433
await websocket.close()
434434
except Exception:
435-
pass
435+
logger.debug("Websocket close failed during shutdown")
436436

437437
await super().shutdown()
438438
logger.info("Hyper-V Manager plugin stopped")

0 commit comments

Comments
 (0)