Skip to content

MCP Server stdout pollution prevents JSON-RPC communication #179

@spinbased

Description

@spinbased

Issue Description

The ruv-swarm MCP server outputs logging messages on stdout, which prevents proper JSON-RPC communication with MCP clients.

Problem

When running npx ruv-swarm mcp start, the server outputs various logs to stdout:

[ERROR] Failed to initialize pooled persistence {...}
[ca426a4e...] [INFO] ruv-swarm MCP server starting in stdio mode
[ca426a4e...] [INFO] Connection established {...}
🧠 Initializing ruv-swarm with WASM capabilities...
✅ WASM bindings loaded successfully
📊 Features: {...}

MCP Protocol Requirements:

  • stdin/stdout must be dedicated to JSON-RPC messages
  • All logging should go to stderr or log files
  • stdout pollution breaks message parsing

Impact

MCP clients (like ABRAXAS v4.0) timeout after 10 seconds trying to parse tools/list responses because:

  1. Send JSON-RPC request to stdin: {"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
  2. Expected response on stdout: {"jsonrpc":"2.0","id":1,"result":{...}}
  3. Actual response: Mixed with log messages, unparseable

Expected Behavior

// stdout: ONLY JSON-RPC messages
{"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}

// stderr: ALL logging
[INFO] ruv-swarm MCP server starting...
 WASM bindings loaded successfully

Reproduction Steps

# Terminal 1: Start MCP server
npx ruv-swarm mcp start

# Terminal 2: Send JSON-RPC message
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | nc localhost 3000

# Result: Timeout or mixed output

Suggested Fix

Option 1: Separate Channels

// Route all logging to stderr
console.error('[INFO] Server starting...');  // Not console.log()

// Keep stdout clean for JSON-RPC
process.stdout.write(JSON.stringify(response) + '\n');

Option 2: Quiet Mode

npx ruv-swarm mcp start --quiet  # No logs on stdout
npx ruv-swarm mcp start --log-file=/tmp/ruv-swarm.log

Option 3: Configuration

{
  "mcp": {
    "protocol": "stdio",
    "logging": {
      "channel": "stderr",
      "level": "error"
    }
  }
}

Environment

  • ruv-swarm version: 1.0.20
  • Node.js: v22.18.0
  • Platform: Windows 11 / Linux
  • Used in: ABRAXAS v4.0 MCP integration

Related

This affects all MCP client integrations, including:

  • Claude Code
  • Claude Desktop
  • ABRAXAS
  • Any custom MCP clients

References

Workaround

Until fixed, users can interact via CLI instead of MCP:

# Instead of MCP auto-connect
npx ruv-swarm init hierarchical 8
npx ruv-swarm orchestrate "task description"

Priority

High - Blocks MCP integration for all clients expecting clean stdio protocol.

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