Summary
The mcp__ruvector__hooks_route_enhanced MCP tool always returns {"success": false, "error": "spawnSync /bin/sh ETIMEDOUT"} for any input. The equivalent CLI subcommand ruvector hooks route-enhanced "<task>" succeeds in ~182ms, so the regression is inside the MCP server's shell-out path, not the underlying routing code.
Environment
ruvector version: 0.2.25 (latest on npm at time of report)
- Node: v20.19.6
- OS: Linux 6.6.87.2-microsoft-standard-WSL2 (Ubuntu, WSL2)
- MCP client: Claude Code (claude-flow integration)
- Server config:
.mcp.json → ruvector mcp start (default, no env overrides)
Reproduction
- Start the ruvector MCP server (
ruvector mcp start) and connect from any MCP client.
- Call the
hooks_route_enhanced tool with any task:
{ "task": "test routing" }
- Observe response.
Actual
{
"success": false,
"error": "spawnSync /bin/sh ETIMEDOUT"
}
The error is reproducible on every call, including immediately after server start (so it is not a warm-up / first-call issue).
Expected
A routing decision similar to what the CLI returns:
$ time ruvector hooks route-enhanced "test routing"
{"success":true,"agent":"coder","confidence":0.5,"reason":"default mapping","signals":[],"coverageWeight":null,"complexity":null}
real 0m0.182s
Comparison: same input through CLI vs MCP
| Path |
Result |
Time |
ruvector hooks route-enhanced "test" (CLI) |
success, returns routing JSON |
~180ms |
mcp__ruvector__hooks_route_enhanced { "task": "test" } (MCP) |
spawnSync /bin/sh ETIMEDOUT |
~immediate fail |
mcp__ruvector__hooks_diff_analyze, mcp__ruvector__hooks_trajectory_step and other ruvector MCP tools all work in the same MCP server session, so the MCP transport itself is fine — the issue is specific to hooks_route_enhanced.
Likely cause
Looks like the MCP handler for hooks_route_enhanced is shelling out via child_process.spawnSync('/bin/sh', ...) with a timeout that is set too low (or set to 0 and rounded), so the child process is killed before it can boot. The other ruvector MCP hooks that work (diff_analyze, etc.) appear to call the underlying logic in-process, which would explain why only this one fails.
If the in-process path exists, switching hooks_route_enhanced to use it (the same code path the CLI command exercises) should fix it. If a shell-out is genuinely required, raising/removing the spawnSync timeout would unblock it.
Impact
In Claude Code, this hook is wired into the PreToolUse: Task hook chain (see .claude/settings.json from claude-flow's defaults) for enhanced agent routing. Because the MCP call always errors, this routing tier is silently disabled. The fallback mcp__claude-flow__hooks_route still works, so Task spawns are still routed — just without ruvector's AST/coverage/diff signals.
Workaround
Replace the MCP-tool hook with a command hook that calls the CLI directly:
This bypasses the broken MCP handler and uses the working CLI path.
Summary
The
mcp__ruvector__hooks_route_enhancedMCP tool always returns{"success": false, "error": "spawnSync /bin/sh ETIMEDOUT"}for any input. The equivalent CLI subcommandruvector hooks route-enhanced "<task>"succeeds in ~182ms, so the regression is inside the MCP server's shell-out path, not the underlying routing code.Environment
ruvectorversion: 0.2.25 (latest on npm at time of report).mcp.json→ruvector mcp start(default, no env overrides)Reproduction
ruvector mcp start) and connect from any MCP client.hooks_route_enhancedtool with any task:{ "task": "test routing" }Actual
{ "success": false, "error": "spawnSync /bin/sh ETIMEDOUT" }The error is reproducible on every call, including immediately after server start (so it is not a warm-up / first-call issue).
Expected
A routing decision similar to what the CLI returns:
Comparison: same input through CLI vs MCP
ruvector hooks route-enhanced "test"(CLI)mcp__ruvector__hooks_route_enhanced { "task": "test" }(MCP)spawnSync /bin/sh ETIMEDOUTmcp__ruvector__hooks_diff_analyze,mcp__ruvector__hooks_trajectory_stepand other ruvector MCP tools all work in the same MCP server session, so the MCP transport itself is fine — the issue is specific tohooks_route_enhanced.Likely cause
Looks like the MCP handler for
hooks_route_enhancedis shelling out viachild_process.spawnSync('/bin/sh', ...)with a timeout that is set too low (or set to0and rounded), so the child process is killed before it can boot. The other ruvector MCP hooks that work (diff_analyze, etc.) appear to call the underlying logic in-process, which would explain why only this one fails.If the in-process path exists, switching
hooks_route_enhancedto use it (the same code path the CLI command exercises) should fix it. If a shell-out is genuinely required, raising/removing the spawnSync timeout would unblock it.Impact
In Claude Code, this hook is wired into the
PreToolUse: Taskhook chain (see.claude/settings.jsonfrom claude-flow's defaults) for enhanced agent routing. Because the MCP call always errors, this routing tier is silently disabled. The fallbackmcp__claude-flow__hooks_routestill works, so Task spawns are still routed — just without ruvector's AST/coverage/diff signals.Workaround
Replace the MCP-tool hook with a
commandhook that calls the CLI directly:{ "type": "command", "command": "ruvector hooks route-enhanced \"\${tool_input.description}\" 2>/dev/null || true", "timeout": 2000 }This bypasses the broken MCP handler and uses the working CLI path.