Skip to content

fix: non-blocking stdio startup and --no-cache flag#277

Open
mustafa89 wants to merge 1 commit intokorotovsky:masterfrom
mustafa89:fix/non-blocking-stdio-startup
Open

fix: non-blocking stdio startup and --no-cache flag#277
mustafa89 wants to merge 1 commit intokorotovsky:masterfrom
mustafa89:fix/non-blocking-stdio-startup

Conversation

@mustafa89
Copy link
Copy Markdown

Summary

Fixes #271 — the stdio transport blocks the MCP initialize response until users/channels caches are fully loaded. On large workspaces (12k+ users, 43k+ channels) this takes 3-5 minutes, causing MCP clients with connection timeouts to drop the server.

Changes

1. Non-blocking stdio startup (default behavior change)

Removed the busy-wait loop in main.go that blocked stdio from starting until IsReady() returned true:

// BEFORE — blocks until caches are loaded
case "stdio":
    for {
        if ready, _ := p.IsReady(); ready {
            break
        }
        time.Sleep(100 * time.Millisecond)
    }
    s.ServeStdio()
// AFTER — starts immediately, caches load in background
case "stdio":
    if ready, _ := p.IsReady(); !ready && !noCache {
        logger.Info("Slack MCP Server is still warming up caches, starting server anyway")
    }
    s.ServeStdio()

This matches the existing SSE/HTTP behavior, which already starts serving before caches are ready. Tool calls made before caches load return a graceful "not ready" error via the existing buildErrorRecoveryMiddleware, allowing the LLM to retry.

2. --no-cache CLI flag (opt-in)

For environments that only use channel/user IDs (never #channel-name or @username lookups), the --no-cache flag skips cache loading entirely:

slack-mcp-server --no-cache --transport stdio

This marks both usersReady and channelsReady as true immediately via a new SkipCache() method on ApiProvider, without loading any data. Startup is instant regardless of workspace size.

Files changed

File Change
cmd/slack-mcp-server/main.go Add --no-cache flag, remove stdio busy-wait loop, add warm-up log message
pkg/provider/api.go Add SkipCache() method

Testing

Tested on a workspace with 823 users and 1,418 channels:

Mode Startup time Notes
--no-cache <1s Instant, no cache loading
Default (no flag) <1s MCP handshake immediate, caches load in background
Original (upstream) 30s+ timeout Blocked on channel cache refresh

Remove the busy-wait loop that blocks the stdio transport from
responding to MCP initialize until users/channels caches are fully
loaded. On large workspaces this causes MCP clients with connection
timeouts (e.g. 30-60s) to drop the server.

Changes:
- stdio transport now starts the MCP server immediately, matching the
  existing SSE/HTTP behavior. Caches continue loading in a background
  goroutine. Tool calls made before caches are ready return a graceful
  "not ready" error (already handled by the error recovery middleware).
- Add --no-cache CLI flag to skip cache loading entirely for
  environments that only use channel/user IDs (never #name or @name
  lookups). This makes startup instant regardless of workspace size.
- Add SkipCache() method on ApiProvider that marks both caches as
  ready without loading data.

Fixes korotovsky#271
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server blocks MCP initialize response while caching users/channels on startup

1 participant