#293
fix: make server command timeout configurable
Problem
Every tool command is killed after 300 seconds because COMMAND_TIMEOUT is hardcoded in hexstrike_server.py. Long nuclei, amass or nmap scans can never finish (#84).
Passing --timeout 3600 to hexstrike_mcp.py doesn't help (#107). That flag only sets how long the MCP client waits for the HTTP response. The server still terminates the command at 300s.
Changes
- Configurable server timeout: use the
HEXSTRIKE_COMMAND_TIMEOUTenv var or the new--timeoutserver flag. The default stays 300s. - Startup override now takes effect:
EnhancedCommandExecutor.__init__tooktimeout: int = COMMAND_TIMEOUT. Python evaluates default arguments once, at import time, so changing the global at startup would have had no effect. The default is now resolved when the executor is created. - Per-request timeout on
/api/command: an optionaltimeoutfield (positive integer, in seconds). Anything else returns a 400. - Timed-out output is no longer cached: a timed-out run that printed something counts as
success, so its truncated output used to be cached. Running the same command again withinCACHE_TTL(1h) returned the truncated result without running anything. - README: the new flag is listed under "Start the Server", and Troubleshooting now explains the server timeout vs. the MCP client timeout.
All tool endpoints still call execute_command() without a timeout, so they pick up the server-wide setting automatically.
Testing
I ran these checks through the real __main__ path (--timeout 2) and with HEXSTRIKE_COMMAND_TIMEOUT=3, using Flask's test client so no port was opened. All 24 passed:
- the flag and the env var set
COMMAND_TIMEOUT, and new executors use it - a command longer than the server timeout is terminated on time (2.0s and 3.0s)
- a per-request
timeoutboth shortens and extends the limit "abc",-1,0,trueand1.5are rejected with a 400- timed-out partial results are not cached, and successful results still are
Fixes #84 Fixes #107