Summary
The mcp-proxy-all.jar silently drops JSON-RPC messages (including initialize) that arrive on stdin before the SSE connection to the Burp MCP Server is fully established. This causes MCP clients like Claude Code to fail to connect, as the initialize response is never received.
This is distinct from the SDK version mismatch fixed in commit 0a5ce34 (#53, #55) — the proxy now connects to the correct endpoint, but there is a ~3 second window during startup where stdin messages are lost.
Root Cause
The proxy JAR begins reading stdin on the main thread while the SSE connection is still being established asynchronously on the DefaultDispatcher thread. Messages received during this window are processed but have no active SSE session to forward to, so they are silently dropped with no error on stderr or stdout.
Startup sequence (observed via stderr logs):
T+0.000s Starting Burp MCP proxy with SSE URL: http://127.0.0.1:9876
T+0.001s No explicit authentication configured (will auto-detect OAuth 2.1)
T+0.017s No authentication configured, checking if server supports OAuth 2.1...
T+0.162s Using insecure HTTP for OAuth endpoints (OAuth probe)
T+0.244s Using non-OAuth authentication for SSE connection
T+0.301s Successfully connected to SSE server ← stdin is only safe AFTER this
An MCP client that sends initialize at any point before ~T+0.3s will have its message dropped.
Reproduction
# ❌ FAILS: message sent immediately (how Claude Code invokes it)
echo '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}' \
| java -jar libs/mcp-proxy-all.jar --sse-url http://127.0.0.1:9876
# Result: proxy connects, reads the message, outputs nothing, exits on stdin EOF
# ✅ WORKS: message sent after SSE handshake (3s delay)
python3 -c "
import subprocess, time, json
proc = subprocess.Popen(
['java', '-jar', 'libs/mcp-proxy-all.jar', '--sse-url', 'http://127.0.0.1:9876'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
time.sleep(3) # wait for SSE
proc.stdin.write(json.dumps({'jsonrpc':'2.0','method':'initialize','params':{'protocolVersion':'2024-11-05','capabilities':{},'clientInfo':{'name':'test','version':'1.0'}},'id':1}) + '\n')
proc.stdin.flush()
time.sleep(2)
print(proc.stdout.readline()) # prints valid initialize response
proc.kill()
"
Suggested Fix
Buffer stdin messages in the proxy until the SSE connection is established, then replay them in order. Alternatively, block the stdin reader thread until the SSE session ID is received.
Pseudocode:
// Current (broken): reads stdin immediately
launch { readStdin() }
launch { connectSse() }
// Fixed: gate stdin on SSE readiness
val sseReady = CompletableDeferred<Unit>()
launch { connectSse(); sseReady.complete(Unit) }
launch { sseReady.await(); readStdin() }
Workaround
Wrap the proxy JAR in a script that monitors stderr for "Successfully connected" before forwarding stdin:
#!/usr/bin/env python3
"""Buffer stdin until proxy's SSE connection is ready."""
import subprocess, sys, threading
proc = subprocess.Popen(
["java", "-jar", "libs/mcp-proxy-all.jar", "--sse-url", "http://127.0.0.1:9876"],
stdin=subprocess.PIPE, stdout=sys.stdout.buffer, stderr=subprocess.PIPE)
# Wait for readiness signal on stderr
while True:
line = proc.stderr.readline()
if not line:
break
sys.stderr.buffer.write(line)
sys.stderr.buffer.flush()
if b"Successfully connected" in line:
break
# Drain remaining stderr
threading.Thread(target=lambda: [sys.stderr.buffer.write(l) or sys.stderr.buffer.flush()
for l in proc.stderr], daemon=True).start()
# Forward stdin
try:
for line in sys.stdin.buffer:
proc.stdin.write(line)
proc.stdin.flush()
except (BrokenPipeError, IOError):
pass
finally:
proc.stdin.close()
sys.exit(proc.wait())
Environment
- Burp Suite Professional, MCP Server extension loaded from local build (repo HEAD
77c423b)
mcp-proxy-all.jar from commit 0a5ce34 (Feb 18 update)
- macOS Darwin 25.3.0, Java 21
- Claude Code (MCP client, stdio transport)
Related Issues
Summary
The
mcp-proxy-all.jarsilently drops JSON-RPC messages (includinginitialize) that arrive on stdin before the SSE connection to the Burp MCP Server is fully established. This causes MCP clients like Claude Code to fail to connect, as theinitializeresponse is never received.This is distinct from the SDK version mismatch fixed in commit
0a5ce34(#53, #55) — the proxy now connects to the correct endpoint, but there is a ~3 second window during startup where stdin messages are lost.Root Cause
The proxy JAR begins reading stdin on the main thread while the SSE connection is still being established asynchronously on the
DefaultDispatcherthread. Messages received during this window are processed but have no active SSE session to forward to, so they are silently dropped with no error on stderr or stdout.Startup sequence (observed via stderr logs):
An MCP client that sends
initializeat any point before ~T+0.3s will have its message dropped.Reproduction
Suggested Fix
Buffer stdin messages in the proxy until the SSE connection is established, then replay them in order. Alternatively, block the stdin reader thread until the SSE session ID is received.
Pseudocode:
Workaround
Wrap the proxy JAR in a script that monitors stderr for
"Successfully connected"before forwarding stdin:Environment
77c423b)mcp-proxy-all.jarfrom commit0a5ce34(Feb 18 update)Related Issues
/ssevs/) — fixed