Skip to content

Silent process.exit(1) in main() makes Claude Desktop on Windows fail with no diagnostic #18

@DarkBoow

Description

@DarkBoow

Summary

When @vapi-ai/mcp-server is launched by Claude Desktop on Windows, the server starts, receives the initialize JSON-RPC message from the client, and then dies ~3-4s later with zero output on stderr/stdout. The catch (err) { process.exit(1); } in dist/index.js swallows the actual error and makes any user-side diagnosis impossible.

The same package works perfectly in Claude Code (CLI) on the same machine, with the same VAPI_TOKEN, on the same Node version ? so it is not a setup issue.

Environment

  • OS: Windows 11 Home (10.0.26200)
  • Node: v24.13, npm 11.6
  • @vapi-ai/mcp-server: 0.0.9 (latest at time of writing)
  • Embedded @modelcontextprotocol/sdk: 1.29.0
  • Claude Desktop: Claude_1.8555.2.0_x64__pzs8sxrjxfjjc (Windows Store)
  • Claude Code: 2.x (works fine, same machine)

Reproduction

Add this to claude_desktop_config.json and restart Claude Desktop:

{
  "mcpServers": {
    "vapi": {
      "command": "powershell",
      "args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command",
               "$env:VAPI_TOKEN = '<token>'; node '<path>\\@vapi-ai\\mcp-server\\dist\\index.js'"]
    }
  }
}

Or any equivalent wrapper that provides VAPI_TOKEN and launches the server. Then go to Settings ? MCP and see vapi: failed.

Observed behavior (Claude Desktop log)

[vapi] [info] Server started and connected successfully
[vapi] [info] Message from client: {"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{"extensions":{"io.modelcontextprotocol/ui":{"mimeTypes":["text/html;profile=mcp-app"]}}},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}
[vapi] [info] Server transport closed
[vapi] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr ... and it will appear in this log.
[vapi] [error] Server disconnected.

Note that:

  • The server never sends an initialize response back to the client.
  • No "Message to client" line is ever logged.
  • Stderr is empty.
  • Time between init RX and transport close is consistently ~3-4 seconds.

The same workflow on Claude Code (which spawns the server with a roughly equivalent JSON-RPC initialize payload, but presumably without the io.modelcontextprotocol/ui capability extension) succeeds: all 13 tools are listed and usable.

Root cause hypothesis

Looking at dist/index.js:

async function main() {
    try {
        const mcpServer = createMcpServer();
        const transport = new StdioServerTransport();
        await mcpServer.connect(transport);
        setupShutdownHandler(mcpServer);
    }
    catch (err) {
        process.exit(1);   // ? swallows the error
    }
}
// ...
main().catch((err) => {
    process.exit(1);       // ? also swallows
});

These silent exits prevent any user-side debugging. The actual exception is probably thrown by mcpServer.connect(transport) or during message handling, possibly because the SDK doesn't know how to handle the io.modelcontextprotocol/ui capability extension that Claude Desktop announces (Claude Code presumably doesn't send this extension).

Suggested fix

Even if the underlying SDK issue can't be fixed in this repo, please at minimum log the error before exiting so users can diagnose:

async function main() {
    try {
        const mcpServer = createMcpServer();
        const transport = new StdioServerTransport();
        await mcpServer.connect(transport);
        setupShutdownHandler(mcpServer);
    }
    catch (err) {
        console.error('[vapi-mcp] fatal error during startup:', err);
        process.exit(1);
    }
}

main().catch((err) => {
    console.error('[vapi-mcp] uncaught error in main:', err);
    process.exit(1);
});

This 4-line change would have saved me ~2 hours of debugging tonight, and would let other Windows + Claude Desktop users immediately see the real error.

Workarounds for users hitting this

  • Claude Code works fine ? use the remote HTTP variant (mcp-remote against https://mcp.vapi.ai/mcp) or the stdio local variant, both work.
  • Claude Desktop on Windows: no known workaround at time of writing. Bug needs to be fixed either in this repo (better error handling) or upstream in the SDK / Claude Desktop's MCP client.

Related upstream issues

Both report the same "Server transport closed unexpectedly" pattern with no stderr ? but for other MCP servers, suggesting it's a Claude Desktop / Windows pipe handling issue that affects many MCP servers, not just @vapi-ai/mcp-server.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions