fix: 800ms delay before first inbound notification
Race observed on first turn: ClaudePlugin emits notifications/claude/channel before Claude Code finishes registering the channel handler internally. Claude logs "MCP server synthesis: Channel notifications registered" ~25ms AFTER hello_ack arrives. Notifications that arrive earlier are silently dropped — observed empty session, no turn, curl hangs until timeout. Fix: on first `inbound` frame after WS hello, wait 800ms before emitting the MCP notification. Subsequent inbounds skip the wait. End-to-end verified twice on laptop. Cold-start ~10s, hot path 2-3s.
This commit is contained in:
11
server.ts
11
server.ts
@@ -98,6 +98,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async req => {
|
||||
let ws: WebSocket | null = null
|
||||
let backoff = 1000
|
||||
const outbox: unknown[] = []
|
||||
let firstInboundDelivered = false
|
||||
|
||||
function bridgeSend(frame: unknown): void {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
@@ -147,6 +148,16 @@ async function handleBridge(frame: any): Promise<void> {
|
||||
log(`hello_ack received`)
|
||||
return
|
||||
case 'inbound':
|
||||
// Race guard: Claude Code's internal "Channel notifications registered"
|
||||
// log line appears ~25ms AFTER we send hello_ack — if we push the
|
||||
// notification before then, claude silently drops it. Buffer the
|
||||
// first inbound briefly to dodge this. Subsequent inbounds don't
|
||||
// need the wait (channel is registered for the lifetime of the
|
||||
// session).
|
||||
if (!firstInboundDelivered) {
|
||||
await new Promise(r => setTimeout(r, 800))
|
||||
firstInboundDelivered = true
|
||||
}
|
||||
await mcp.notification({
|
||||
method: 'notifications/claude/channel',
|
||||
params: {
|
||||
|
||||
Reference in New Issue
Block a user