Remote HTTP MCP (Slack): cohort with tengu_mcp_retry_failed_remote=false forces frequent re-OAuth despite valid refresh tokens
Summary
The Slack MCP plugin (claude-plugins-official/slack) requires re-OAuth frequently across sessions even though refresh tokens ARE being saved correctly. Investigation points to the GrowthBook feature flag tengu_mcp_retry_failed_remote being false for my account — when any transient MCP connection failure occurs, Claude Code flips a cached needs-auth state instead of retrying the refresh-token flow, and that state sticks across sessions.
Environment
- Claude Code: 2.1.110
- OS: macOS (Darwin 25.4.0)
- Node: v24.3.0
- MCP plugin:
claude-plugins-official/slack1.0.0 →https://mcp.slack.com/mcp - Transport: remote HTTP, OAuth 2.0 + PKCE, redirect port 3118
- Cohort flag:
.cachedGrowthBookFeatures.tengu_mcp_retry_failed_remote = false
Evidence (log analysis)
Across all ~/Library/Caches/claude-cli-nodejs/*/mcp-logs-plugin-slack-slack/*.jsonl:
| Event | Count |
|---|---|
| Has refresh token: true | 305 |
| Returning tokens | 300 |
| Token length: 180 | 300 |
| Token expired without refresh token | 252 |
| Skipping connection (cached needs-auth) | 492 |
| Cleared stored tokens | multiple |
Refresh tokens are being persisted and retrieved correctly most of the time (305 successful reads). Slack is returning refresh tokens on every auth (Has refresh token: true). The failure mode fires when:
- A session's refresh attempt hits any transient issue
- Claude Code flips a
needs-authcached state instead of retrying (consistent withtengu_mcp_retry_failed_remote = false) - That state persists across sessions — next startup logs
Skipping connection (cached needs-auth)before even trying the stored tokens - User is forced through full OAuth flow to recover
Ruled out (per the Anthropic troubleshooting docs)
- ❌ Clock drift — 73ms skew vs
time.apple.com, well within OAuth tolerance - ❌ Locked/out-of-sync keychain — login keychain status
no-timeout, Claude Code credentials entry present and writable - ❌ Refresh token never persisted — 305 successful retrievals in the logs disprove this
- ❌ Stale CLI version — running current 2.1.110
Cohort-stickiness test (done)
- Removed
tengu_mcp_retry_failed_remotefrom~/.claude.json - Spawned a fresh
claude -psubprocess - GrowthBook re-fetched the flag with the same value (
false) - Confirmed: it's a stable cohort assignment, not local cache corruption. Flipping/clearing the local value alone can't resolve this.
Reproduction
- Be in the GrowthBook cohort where
tengu_mcp_retry_failed_remote = false(checkjq '.cachedGrowthBookFeatures.tengu_mcp_retry_failed_remote' ~/.claude.json) - Authenticate a remote HTTP MCP plugin (Slack is the clearest repro but any remote HTTP OAuth MCP should hit it)
- Work normally — at some point the MCP connection hits a transient failure
- Next session: forced through full re-OAuth despite a valid refresh token in the keychain
Requested fix
One of:
- A. Flip the flag default / reassign cohorts so
tengu_mcp_retry_failed_remote = trueis the norm (simplest) - B. Decouple the "no retry" behaviour from persistent state — the flag could reasonably govern retry-within-a-single-attempt, but the
needs-authcache shouldn't survive across sessions when a valid refresh token is present in the keychain. On reconnect, try the stored refresh token first regardless of any prior failure flag - C. Expose a user-level override (env var or
settings.jsonkey) so affected users can opt out of the flag locally
Impact
Happens multiple times per day, blocking agentic workflows that rely on Slack MCP (sending DMs, reading channels). The user-visible symptom is misleading — the OAuth URL prompt suggests a stored-token failure, but the tokens are fine. Problem will affect any user in this cohort using any remote HTTP MCP server that can have transient connection issues.
---
Happy to share sanitised log files, run additional probes, or test a fixed build. Investigation session conducted 2026-04-16 using Context7 against /ericbuess/claude-code-docs and /websites/slack_dev for docs verification.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗