Debugging MCP Servers with File Logging and Stdio Workarounds

Fazm Team··2 min read

Debugging MCP Servers with File Logging and Stdio Workarounds

Debugging MCP servers is painful, and the stdio transport is the main reason. When your server communicates over stdin/stdout, you cannot just add print statements - any stray output corrupts the JSON-RPC stream and kills the connection.

The Stdio Problem

MCP servers using stdio transport have a strict contract: stdout is exclusively for JSON-RPC messages. Every byte that goes to stdout must be valid protocol. This means your normal debugging workflow - sprinkling print statements everywhere - is completely off limits.

This is especially frustrating when writing MCP servers in Swift. Swift's print() goes to stdout by default. One forgotten debug print and your server silently breaks. No error message. The client just stops receiving valid responses.

The File Logging Solution

The simplest workaround is logging everything to a file in /tmp and tailing it in a separate terminal:

let logFile = "/tmp/mcp-server-debug.log"

func debugLog(_ message: String) {
    let timestamp = ISO8601DateFormatter().string(from: Date())
    let line = "[\(timestamp)] \(message)\n"
    if let data = line.data(using: .utf8) {
        let handle = FileHandle(forWritingAtPath: logFile)
        handle?.seekToEndOfFile()
        handle?.write(data)
        handle?.closeFile()
    }
}

Then in another terminal: tail -f /tmp/mcp-server-debug.log

What to Log

Log more than you think you need:

  • Every incoming request - the full JSON-RPC method and params
  • Every outgoing response - including the response ID matching
  • Tool execution start and end - with timing information
  • Errors with full context - not just the error message but the state that caused it

Stderr Is Your Friend

One often overlooked option: stderr is not part of the MCP protocol. You can safely write debug output to stderr without breaking the connection. In Swift, use FileHandle.standardError instead of print(). Most MCP clients ignore stderr, so your debug output flows freely.

The debugging experience is rough but manageable once you set up proper file logging. Do it before you need it.

Fazm is an open source macOS AI agent. Open source on GitHub.

More on This Topic

Related Posts