Skip to content

Windows: chroma-mcp connection fails - uvx.cmd breaks MCP stdio transport #1190

@CodesHour

Description

@CodesHour

Bug Description

On Windows, the chroma-mcp vector search backend fails to connect with MCP error -32000: Connection closed. The search MCP tool is completely non-functional — every call returns this error or chroma-mcp connection in backoff (Xs remaining).

Environment

  • OS: Windows 11 Pro 10.0.26200
  • claude-mem version: 10.3.1 (main branch, latest as of Feb 20, 2026)
  • Node.js: v24.13.0
  • Bun: installed at ~/.bun/bin/bun.exe
  • Python/uvx: uvx 0.9.28, Python 3.13
  • uvx location: C:\Users\<user>\.local\bin\uvx.exe

Root Cause

In worker-service.cjs, the connectInternal() method spawns chroma-mcp using:

let i = process.platform === "win32" ? "uvx.cmd" : "uvx";

On Windows, uvx.cmd is a batch file wrapper. When StdioClientTransport spawns it as a child process, the .cmd wrapper adds an indirection layer that breaks the stdin/stdout MCP handshake. The connection closes within milliseconds (~4ms) before initialization completes.

Logs

[CHROMA_MCP] Connecting to chroma-mcp via MCP stdio {command=uvx.cmd, args=chroma-mcp --client-type persistent --data-dir C:\Users\<user>\.claude-mem\chroma}
[CHROMA_MCP] Connection failed, killing subprocess to prevent zombie {error=MCP error -32000: Connection closed}
[CHROMA] SDK chroma sync failed, continuing without vector search

This is the same class of bug as #695 (macOS), but with a Windows-specific cause.

Fix / Workaround

Changing uvx.cmd to the full path of uvx.exe resolves the issue completely:

// Before (broken on Windows):
let i = process.platform === "win32" ? "uvx.cmd" : "uvx";

// After (works):
let i = process.platform === "win32" ? "uvx.exe" : "uvx";

Using uvx.exe directly bypasses the .cmd batch wrapper and allows the MCP stdio transport to function correctly. After this one-line change, all search/vector operations work perfectly.

Suggested robust fix:

const { execSync } = require('child_process');

function resolveUvx() {
  if (process.platform !== 'win32') return 'uvx';
  // Prefer .exe directly to avoid .cmd stdio issues
  try {
    const resolved = execSync('where uvx.exe', { encoding: 'utf-8', timeout: 5000 }).trim().split('\n')[0];
    if (resolved) return resolved;
  } catch {}
  return 'uvx.exe'; // fallback — .exe suffix still avoids .cmd
}

Steps to Reproduce

  1. Install claude-mem 10.3.1 on Windows 11
  2. Ensure uvx is installed (via pip install uv or standalone installer)
  3. Use any search MCP tool (e.g., search with any query)
  4. Observe MCP error -32000: Connection closed in response and logs

Related

Impact

All MCP search functionality (semantic/vector search) is broken on Windows. The SQLite FTS fallback doesn't activate for MCP tool calls — they just error out. The worker itself runs fine (/api/health returns OK), but the internal chroma-mcp child process can never connect.

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