diff --git a/cmd/anvilmcp/execute.go b/cmd/anvilmcp/execute.go index e5bdbdd..4838a0d 100644 --- a/cmd/anvilmcp/execute.go +++ b/cmd/anvilmcp/execute.go @@ -85,6 +85,15 @@ func recordValidationFailure() { } } +func isPermissionError(err error) bool { + if err == nil { + return false + } + msg := strings.ToLower(err.Error()) + return strings.Contains(msg, "permission denied") || + strings.Contains(msg, "no such file or directory") +} + func validateCode(code string) error { if err := checkRateLimit(); err != nil { return err diff --git a/cmd/anvilmcp/main.go b/cmd/anvilmcp/main.go index 9234976..ba6e3de 100644 --- a/cmd/anvilmcp/main.go +++ b/cmd/anvilmcp/main.go @@ -134,6 +134,7 @@ func handleToolCall(req MCPRequest) { timeout = int(t) } sandbox, _ := params.Arguments["sandbox"].(string) + sandboxExplicit := sandbox != "" if sandbox == "" { sandbox = "anvilmcp" } @@ -145,6 +146,12 @@ func handleToolCall(req MCPRequest) { fmt.Fprintf(os.Stderr, "[anvilmcp] Executing bash code (timeout: %ds, sandbox: %s)\n", timeout, sandbox) result, err := executeCode(code, language, timeout, sandbox) + // Fallback to default sandbox on permission errors (only if sandbox wasn't explicit) + if err != nil && !sandboxExplicit && isPermissionError(err) { + fmt.Fprintf(os.Stderr, "[anvilmcp] Permission error in %s sandbox, falling back to default\n", sandbox) + result, err = executeCode(code, language, timeout, "default") + } + // Log token comparison codeTokens := estimateTokens(code) outputTokens := estimateTokens(result)