From 89f4674fd2cf7dac914106d97b0c9b9423f5278f Mon Sep 17 00:00:00 2001 From: janpeter visser Date: Fri, 1 May 2026 19:51:40 +0200 Subject: [PATCH] fix: register worker presence BEFORE server.connect, not after MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit server.connect(transport) on the stdio transport awaits the first MCP handshake from the client. If that handshake stalls (or the await keeps the process pinned to the stdio event loop), the lines that follow never run — registerWorker / startHeartbeat / shutdown-handlers are silently skipped. Symptom: NavBar shows 'Geen agent' while jobs are claiming and running (observed in production after the M13 worker-presence release). ClaudeWorker count stays at 0 even though tools are responding. Fix: do the presence bootstrap before opening the transport. Tools are already registered at this point — connecting the transport just makes them reachable. Delaying the connect by ~10ms (one DB upsert + one pg_notify) is harmless to the client handshake. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/index.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2059b32..58c185a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -61,14 +61,19 @@ async function main() { registerCleanupMyWorktreesTool(server) registerImplementNextStoryPrompt(server) - const transport = new StdioServerTransport() - await server.connect(transport) - + // Presence bootstrap MUST run before server.connect — the stdio transport + // can stall the await on incoming messages, so anything after server.connect + // may never execute reliably. Registering the worker + starting the + // heartbeat first guarantees the UI sees the agent as soon as the process + // is up, regardless of when the MCP client sends its first request. const auth = await getAuth() await registerWorker({ userId: auth.userId, tokenId: auth.tokenId }) const { stop: stopHeartbeat } = startHeartbeat({ tokenId: auth.tokenId }) registerShutdownHandlers({ userId: auth.userId, tokenId: auth.tokenId, stopHeartbeat }) + const transport = new StdioServerTransport() + await server.connect(transport) + console.error(`scrum4me-mcp ${VERSION} running on stdio`) }