Summary
mcp__ruvector__hooks_route_enhanced deterministically fails with spawnSync /bin/sh ETIMEDOUT, while the equivalent direct CLI invocation returns in ~500 ms with valid JSON.
The sibling mcp__ruvector__hooks_route (without _enhanced) works correctly via MCP with the same input shape — so the bug is specific to the _enhanced wrapper, not to the MCP layer in general.
Reproduction
# Direct CLI — works in ~500 ms
$ ruvector hooks route-enhanced "review pull request" \
--file "/home/user/site360/CLAUDE.md"
ONNX initialization failed, using fallback embeddings
{"success":true,"agent":"documentation-specialist","confidence":0.5,"reason":"default mapping","signals":[],"coverageWeight":null,"complexity":null}
Via MCP from Claude Code (any client speaking MCP to the bundled ruvector server):
The error reproduces deterministically across:
- Different
task strings (short and long).
- Real file paths AND non-existent file paths.
- Multiple back-to-back MCP server reconnects (
/mcp reload in Claude Code).
The sibling mcp__ruvector__hooks_route (same input shape) returns:
{ "success": true, "agent": "documentation-specialist", "confidence": 0.5,
"reason": "default mapping", "alternates": [], "sonaPatterns": 0, "engineRouted": true }
…in <1 s. So the divergence is in the _enhanced code path.
Hypothesis
spawnSync /bin/sh ETIMEDOUT strongly suggests the MCP server is wrapping the underlying analyzer with child_process.spawnSync(..., { timeout: N }) and either:
- The
_enhanced path eagerly initializes AST + coverage + diff analyzers and exceeds the configured timeout, even though the same operation completes in <1 s when invoked directly from the parent shell — perhaps because the MCP server's child shell has a different working directory / env that re-runs an initialization step (ruvector hooks init, etc.).
- The
_enhanced path has a deadlock against a resource that hooks_route doesn't touch (e.g., a lock file in the intelligence store).
Suggested debug steps
- Diff the spawn invocation between
mcp__ruvector__hooks_route (works) and mcp__ruvector__hooks_route_enhanced (hangs). The two MCP tool definitions appear adjacent in the server registration.
- Increase the spawnSync
timeout option in the _enhanced path (or remove it) and re-run; if it then returns successfully, the fix is to bump the timeout to cover AST/coverage warm-up.
- Confirm whether the MCP server passes the same
cwd and env to the child shell that the parent process uses; if not, the child may be initializing pi-brain or another component from scratch on each call.
Environment
- ruvector:
0.2.25 (which ruvector → /home/user/.nvm/versions/node/v20.19.6/bin/ruvector)
- Node: v20.19.6
- OS: Linux WSL2 (Ubuntu) on Windows 11
- Same machine:
mcp__ruvector__hooks_route works → CLI itself works → bug is in the _enhanced MCP wrapper specifically.
Workaround for callers (until fixed)
Use the unenhanced mcp__ruvector__hooks_route (loses AST/coverage/diff signals[] enrichment), or shell out to ruvector hooks route-enhanced "<task>" --file <file> and parse the JSON yourself.
Summary
mcp__ruvector__hooks_route_enhanceddeterministically fails withspawnSync /bin/sh ETIMEDOUT, while the equivalent direct CLI invocation returns in ~500 ms with valid JSON.The sibling
mcp__ruvector__hooks_route(without_enhanced) works correctly via MCP with the same input shape — so the bug is specific to the_enhancedwrapper, not to the MCP layer in general.Reproduction
Via MCP from Claude Code (any client speaking MCP to the bundled ruvector server):
The error reproduces deterministically across:
taskstrings (short and long)./mcpreload in Claude Code).The sibling
mcp__ruvector__hooks_route(same input shape) returns:{ "success": true, "agent": "documentation-specialist", "confidence": 0.5, "reason": "default mapping", "alternates": [], "sonaPatterns": 0, "engineRouted": true }…in <1 s. So the divergence is in the
_enhancedcode path.Hypothesis
spawnSync /bin/sh ETIMEDOUTstrongly suggests the MCP server is wrapping the underlying analyzer withchild_process.spawnSync(..., { timeout: N })and either:_enhancedpath eagerly initializes AST + coverage + diff analyzers and exceeds the configured timeout, even though the same operation completes in <1 s when invoked directly from the parent shell — perhaps because the MCP server's child shell has a different working directory / env that re-runs an initialization step (ruvector hooks init, etc.)._enhancedpath has a deadlock against a resource thathooks_routedoesn't touch (e.g., a lock file in the intelligence store).Suggested debug steps
mcp__ruvector__hooks_route(works) andmcp__ruvector__hooks_route_enhanced(hangs). The two MCP tool definitions appear adjacent in the server registration.timeoutoption in the_enhancedpath (or remove it) and re-run; if it then returns successfully, the fix is to bump the timeout to cover AST/coverage warm-up.cwdandenvto the child shell that the parent process uses; if not, the child may be initializing pi-brain or another component from scratch on each call.Environment
0.2.25(which ruvector→/home/user/.nvm/versions/node/v20.19.6/bin/ruvector)mcp__ruvector__hooks_routeworks → CLI itself works → bug is in the_enhancedMCP wrapper specifically.Workaround for callers (until fixed)
Use the unenhanced
mcp__ruvector__hooks_route(loses AST/coverage/diffsignals[]enrichment), or shell out toruvector hooks route-enhanced "<task>" --file <file>and parse the JSON yourself.