Skip to content

MCP Server returns HTTP 500 in WSL 2 Mirror networking mode #163

@zen010101

Description

@zen010101

Problem Description

Happy MCP Server fails to start properly in WSL 2 with Mirror networking mode, returning HTTP 500 errors when Claude Code attempts to connect. This prevents the automatic chat title functionality from working, though core Happy features (real-time sync, mobile access) remain unaffected.

Environment

  • OS: WSL 2 (Windows Subsystem for Linux)
  • WSL Network Mode: Mirror mode
  • Distribution: Linux 6.6.87.2-microsoft-standard-WSL2
  • Node.js: v22.21.1
  • Happy Version: 0.12.0
  • Claude Code Version: 2.1.34

Error Details

When Claude Code starts with Happy MCP integration, it displays:

Happy MCP Server
Status: ✘ failed
Auth: ✘ not authenticated
URL: http://127.0.0.1:45733/
Error: HTTP 500 trying to load OAuth metadata from http://127.0.0.1:45733/.well-known/oauth-authorization-server

Reproduction Steps

  1. Install Happy on WSL 2 with Mirror networking mode
  2. Run happy in a project directory
  3. Observe Claude Code starting with MCP configuration
  4. Claude Code attempts to discover OAuth metadata from the MCP server
  5. Server returns HTTP 500 with empty response body

Testing Results

Manual testing of the MCP server endpoints:

# Root endpoint
curl -v http://127.0.0.1:45733/
# Returns: HTTP 500 Internal Server Error (empty body)

# OAuth metadata endpoint
curl -v http://127.0.0.1:45733/.well-known/oauth-authorization-server
# Returns: HTTP 500 Internal Server Error (empty body)

Root Cause Analysis

After investigating the source code, the issue appears to be in the error handling of the MCP server:

// In dist/index-DMBGazgc.mjs around line 4722
const server = createServer(async (req, res) => {
  try {
    await transport.handleRequest(req, res);
  } catch (error) {
    logger.debug("Error handling request:", error);
    if (!res.headersSent) {
      res.writeHead(500).end();  // ← Returns empty 500 response
    }
  }
});

The StreamableHTTPServerTransport.handleRequest() method throws an exception, which is caught but only logged to debug level (invisible to users) and returns an empty 500 response without any error details.

Impact Assessment

Working Features ✅:

  • Real-time sync via Socket.IO
  • Mobile app access and control
  • End-to-end encryption
  • All core Happy functionality
  • Other MCP servers (Serena, Context7, etc.)

Broken Features ❌:

  • Automatic chat title updates via mcp__happy__change_title tool
  • Web browser authentication (OAuth callback)

Workaround: Users can manually set chat titles in the Happy mobile app.

Hypothesis

This issue is likely specific to WSL Mirror networking mode, which changes how the network stack handles localhost/127.0.0.1 connections. The StreamableHTTPServerTransport from @modelcontextprotocol/sdk may expect certain network behaviors that differ in WSL Mirror mode.

Evidence:

  1. All HTTP-based features fail (MCP Server + OAuth callback)
  2. Socket.IO-based features work fine (uses different transport)
  3. Server binds to 127.0.0.1 successfully but fails on request handling
  4. Same code likely works on standard Linux/macOS

Suggested Improvements

  1. Better Error Logging:
} catch (error) {
  logger.error("MCP request failed:", error);  // Use error level, not debug
  if (!res.headersSent) {
    res.writeHead(500, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
      error: error.message,
      stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
    }));
  }
}
  1. Add Diagnostic Mode:

    • Provide --debug flag to show detailed errors
    • Add network environment detection
    • Special handling for WSL environments
  2. Test in WSL Mirror Mode:

    • Verify compatibility with WSL Mirror networking
    • May need to adjust StreamableHTTPServerTransport usage
    • Consider alternative approaches for WSL environments

Additional Context

  • User is in China, which may have additional network constraints in WSL
  • The issue does NOT prevent Happy's core value proposition (mobile access to local Claude Code sessions)
  • Happy logs show successful server startup but immediate closure on errors
  • Other developers using standard Linux/macOS likely haven't encountered this

Logs

Happy successfully starts the MCP server:

[10:42:07.778] [START] Happy MCP server started at http://127.0.0.1:45583/

But the server lifecycle is short-lived due to errors.


Note: Despite this issue, Happy remains incredibly useful for accessing Claude Code from mobile devices. The automatic title feature is a nice-to-have, not a critical function. Thank you for building such a great tool! 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions