Skip to content

MCP server hangs on startup in WSL2 + NTFS due to fs.watch #199

@mengfanbo123

Description

@mengfanbo123

Problem

When running codegraph serve --mcp inside opencode on WSL2 with the project on an NTFS mount (/mnt/d), the MCP server fails to start within opencode's 30-second initialization timeout. The same command works fine from a regular terminal (~440ms startup).

Environment

  • OS: WSL2 (Ubuntu) on Windows 11
  • Filesystem: NTFS via /mnt/d mount
  • Node: v24.14.1
  • CodeGraph: v0.7.12 (installed via npx @colbymchenry/codegraph)
  • Harness: opencode (MCP stdio)
  • Project: ~350 source files (Rust), no target/ in index (excluded)

Root Cause

The FileWatcher.start() method in dist/sync/watcher.js calls:

fs.watch(this.projectRoot, { recursive: true }, callback);

On NTFS mounts in WSL2, fs.watch({ recursive: true }) is extremely slow — even with only ~350 tracked source files. This blocks the MCP stdio handshake long enough to trigger opencode's 30s startup timeout.

Notably, this is not a cold-start or large-project issue. The project has no target/, no node_modules/, and only 352 source files. The slowness is intrinsic to recursive fs.watch on NTFS.

Current Workaround

I patched watcher.js to check for a CODEGRAPH_NO_WATCH environment variable:

start() {
    if (process.env.CODEGRAPH_NO_WATCH === '1') {
        console.error('[codegraph] File watching disabled via CODEGRAPH_NO_WATCH=1');
        return false;
    }
    // ... original code
}

And set the env var in opencode config:

"codegraph": {
    "type": "local",
    "command": ["codegraph", "serve", "--mcp"],
    "enabled": true,
    "environment": { "CODEGRAPH_NO_WATCH": "1" }
}

This works perfectly — MCP starts in ~180ms, all tools function normally. The trade-off is no auto-sync on file changes (requires manual codegraph sync).

Suggested Fix

Add official support for disabling the file watcher:

  1. Environment variable: CODEGRAPH_NO_WATCH=1 — skip fs.watch entirely
  2. CLI flag: codegraph serve --mcp --no-watch
  3. Auto-detection: Detect WSL2 + NTFS (/mnt/*) and warn/skip watcher automatically

Option 1 is the least invasive and would solve this for all harness tools, not just opencode.

Related

  • Wrong OpenCode init #186 (opencode init config issues)
  • v0.7.10 changelog mentions WSL2 timeout fix, but that only addressed Claude Code's timeout behavior — the underlying fs.watch slowness on NTFS remains

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions