fix: register worker presence BEFORE server.connect, not after

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) <noreply@anthropic.com>
This commit is contained in:
Janpeter Visser 2026-05-01 19:51:40 +02:00
parent f01fab8c38
commit 89f4674fd2

View file

@ -61,14 +61,19 @@ async function main() {
registerCleanupMyWorktreesTool(server) registerCleanupMyWorktreesTool(server)
registerImplementNextStoryPrompt(server) registerImplementNextStoryPrompt(server)
const transport = new StdioServerTransport() // Presence bootstrap MUST run before server.connect — the stdio transport
await server.connect(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() const auth = await getAuth()
await registerWorker({ userId: auth.userId, tokenId: auth.tokenId }) await registerWorker({ userId: auth.userId, tokenId: auth.tokenId })
const { stop: stopHeartbeat } = startHeartbeat({ tokenId: auth.tokenId }) const { stop: stopHeartbeat } = startHeartbeat({ tokenId: auth.tokenId })
registerShutdownHandlers({ userId: auth.userId, tokenId: auth.tokenId, stopHeartbeat }) registerShutdownHandlers({ userId: auth.userId, tokenId: auth.tokenId, stopHeartbeat })
const transport = new StdioServerTransport()
await server.connect(transport)
console.error(`scrum4me-mcp ${VERSION} running on stdio`) console.error(`scrum4me-mcp ${VERSION} running on stdio`)
} }