From b30d04f3e794aba7fd701df4f7ce6f6f4a6f4d47 Mon Sep 17 00:00:00 2001 From: localai-bot Date: Fri, 6 Mar 2026 16:01:30 +0000 Subject: [PATCH] Add SHELL_TIMEOUT_DISABLED environment variable to disable timeout - Add getTimeoutDisabled() function to check for SHELL_TIMEOUT_DISABLED env var - When SHELL_TIMEOUT_DISABLED=true, bypass timeout completely using context.Background() - Maintain backward compatibility with existing SHELL_TIMEOUT functionality - Update documentation in README.md to include new environment variable - Update shell/Dockerfile with SHELL_TIMEOUT default and SHELL_TIMEOUT_DISABLED documentation This allows users to disable the 30-second timeout entirely when needed for long-running scripts. --- README.md | 10 +++++++--- shell/Dockerfile | 2 ++ shell/main.go | 34 +++++++++++++++++++++++++++------- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3796bbc..1ff2ca4 100644 --- a/README.md +++ b/README.md @@ -527,6 +527,8 @@ A shell script execution server that allows AI models to execute shell scripts a **Configuration:** - `SHELL_CMD` - Environment variable to set the shell command to use (default: `sh -c`). Can include arguments, e.g., `bash -x` or `zsh` +- `SHELL_TIMEOUT_DISABLED` - Set to `true` to disable the timeout completely (default: timeout is 30 seconds) +- `SHELL_TIMEOUT` - Environment variable to set the timeout in seconds (default: 30 seconds) - `SHELL_WORKING_DIR` - Environment variable to set the working directory for script execution (default: current directory) **Input Format:** @@ -546,14 +548,16 @@ A shell script execution server that allows AI models to execute shell scripts a "exit_code": 0, "success": true, "error": "" -} -``` - **Docker Image:** ```bash docker run -e SHELL_CMD=bash ghcr.io/mudler/mcps/shell:latest ``` +With timeout disabled: +```bash +docker run -e SHELL_CMD=bash -e SHELL_TIMEOUT_DISABLED=true ghcr.io/mudler/mcps/shell:latest +``` + With custom working directory: ```bash docker run -e SHELL_CMD=bash -e SHELL_WORKING_DIR=/workspace ghcr.io/mudler/mcps/shell:latest diff --git a/shell/Dockerfile b/shell/Dockerfile index b1f84a3..adbe417 100644 --- a/shell/Dockerfile +++ b/shell/Dockerfile @@ -45,6 +45,8 @@ RUN mkdir -p /tmp/shell-sessions # Set environment variables ENV SHELL_CMD="bash -c" ENV SHELL_WORKING_DIR="/root" +ENV SHELL_TIMEOUT="30" +# Set SHELL_TIMEOUT_DISABLED=true to disable timeout completely ENV TOOL_NAME=execute_command # Run the MCP server diff --git a/shell/main.go b/shell/main.go index 9fcead6..b819d82 100644 --- a/shell/main.go +++ b/shell/main.go @@ -45,6 +45,12 @@ func getWorkingDirectory() string { return os.Getenv("SHELL_WORKING_DIR") } +// getTimeoutDisabled returns whether timeout is disabled via SHELL_TIMEOUT_DISABLED env var +func getTimeoutDisabled() bool { + timeoutDisabled := os.Getenv("SHELL_TIMEOUT_DISABLED") + return strings.ToLower(timeoutDisabled) == "true" +} + // getTimeout returns the default timeout from SHELL_TIMEOUT env var, // or 30 seconds if not set or invalid func getTimeout() int { @@ -65,14 +71,28 @@ func ExecuteCommand(ctx context.Context, req *mcp.CallToolRequest, input Execute ExecuteCommandOutput, error, ) { - // Set default timeout if not provided - timeout := input.Timeout - if timeout <= 0 { - timeout = getTimeout() + // Determine timeout based on whether it's disabled + var timeout int + if getTimeoutDisabled() { + // Timeout is disabled - use 0 to indicate no timeout + timeout = 0 + } else { + // Set default timeout if not provided + timeout = input.Timeout + if timeout <= 0 { + timeout = getTimeout() + } } - // Create a context with timeout - cmdCtx, cancel := context.WithTimeout(ctx, time.Duration(timeout)*time.Second) + // Create a context with timeout (or no timeout if disabled) + var cmdCtx context.Context + var cancel context.CancelFunc + if timeout > 0 { + cmdCtx, cancel = context.WithTimeout(ctx, time.Duration(timeout)*time.Second) + } else { + cmdCtx = ctx + cancel = func() {} + } defer cancel() // Get shell command from environment variable (default: "sh -c") @@ -181,7 +201,7 @@ func main() { // Add tool for executing shell scripts mcp.AddTool(server, &mcp.Tool{ Name: configurableName, - Description: "Execute a shell script and return the output, exit code, and any errors. The shell command can be configured via SHELL_CMD environment variable (default: 'sh -c'). The working directory can be set via SHELL_WORKING_DIR environment variable. The default timeout can be configured via SHELL_TIMEOUT environment variable (default: 30 seconds). An initialization script can be run before server startup via SHELL_INIT_SCRIPT environment variable.", + Description: "Execute a shell script and return the output, exit code, and any errors. The shell command can be configured via SHELL_CMD environment variable (default: 'sh -c'). The working directory can be set via SHELL_WORKING_DIR environment variable. The default timeout can be configured via SHELL_TIMEOUT environment variable (default: 30 seconds). Timeout can be disabled by setting SHELL_TIMEOUT_DISABLED=true. An initialization script can be run before server startup via SHELL_INIT_SCRIPT environment variable.", }, ExecuteCommand) // Run the server