Skip to content

Handle missing hosted OAuth refresh tokens#1911

Merged
chelojimenez merged 1 commit intomainfrom
codex/investigate-reconnect-token-error
Apr 24, 2026
Merged

Handle missing hosted OAuth refresh tokens#1911
chelojimenez merged 1 commit intomainfrom
codex/investigate-reconnect-token-error

Conversation

@chelojimenez
Copy link
Copy Markdown
Contributor

@chelojimenez chelojimenez commented Apr 24, 2026

Summary

  • Treat the hosted OAuth missing-refresh-token error as a reauth signal during reconnect
  • Add a regression test covering the fallback from stored credential lookup to interactive OAuth

Testing

  • Added unit coverage in use-server-state.hosted-oauth.test.tsx
  • Not run (not requested)

Note

Low Risk
Low risk: small change to error-string detection for hosted OAuth reconnect plus a focused regression test; main risk is false-positive matching if backend error text changes.

Overview
Hosted OAuth reconnect now treats the backend error Stored hosted OAuth credential is missing refresh_token as a reauth required signal, triggering the interactive OAuth fallback instead of failing the reconnect.

Adds a regression test in use-server-state.hosted-oauth.test.tsx to verify handleReconnect calls ensureAuthorizedForReconnect when this missing-refresh-token error is returned.

Reviewed by Cursor Bugbot for commit 8fd2e0d. Bugbot is set up for automated code reviews on this repo. Configure here.

@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Apr 24, 2026
@chelojimenez
Copy link
Copy Markdown
Contributor Author

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@dosubot dosubot Bot added the enhancement New feature or request label Apr 24, 2026
@github-actions
Copy link
Copy Markdown

Internal preview

Preview URL: https://mcp-inspector-pr-1911.up.railway.app
Deployed commit: a066a54
PR head commit: 8fd2e0d
Backend target: staging fallback.
Health: ❌ Convex unreachable — see upsert-preview job logs (staging may need convex deploy)
Access is employee-only in non-production environments.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

Walkthrough

The pull request adds coverage and logic for handling hosted OAuth reconnection when a stored credential lacks a refresh_token. A new unit test verifies that the ensureAuthorizedForReconnect flow is invoked with appropriate OAuth configuration and callbacks. Concurrently, the requiresFreshOAuthAuthorization predicate is extended to recognize this missing refresh token condition, causing hosted-mode reconnection failures to trigger a fresh OAuth flow rather than being treated as non-refresh-needed errors.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@mcpjam-inspector/client/src/hooks/use-server-state.ts`:
- Around line 133-135: The predicate currently matches the literal string
"stored hosted oauth credential is missing refresh_token" inline
(normalized.includes(...)) which couples the reconnect flow to a fragile error
wording; extract that literal into a shared constant (e.g.
MISSING_REFRESH_TOKEN_ERROR) and replace the inline normalized.includes(...)
with a reference to that constant, and similarly extract the other two error
predicates used in the same function in use-server-state.ts for consistency so
all three checks use named constants rather than hardcoded strings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a84757ca-ce33-4772-9540-5b684d63ead5

📥 Commits

Reviewing files that changed from the base of the PR and between 52b1f4a and 8fd2e0d.

📒 Files selected for processing (2)
  • mcpjam-inspector/client/src/hooks/__tests__/use-server-state.hosted-oauth.test.tsx
  • mcpjam-inspector/client/src/hooks/use-server-state.ts

Comment on lines +133 to +135
normalized.includes(
"stored hosted oauth credential is missing refresh_token",
) ||
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -nP -C2 'missing\s+refresh[_ ]token' --iglob '!**/node_modules/**'

Repository: MCPJam/inspector

Length of output: 1587


🏁 Script executed:

#!/bin/bash
# Find backend code that might emit this error
find . -type f \( -name "*.py" -o -name "*.go" -o -name "*.rs" -o -name "*.ts" -o -name "*.tsx" \) | head -20 | xargs rg -l "missing refresh" --max-count 1

Repository: MCPJam/inspector

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Check if there's an SDK or backend module
fd -t f -e ts -e tsx -e py -e go -e rs | grep -E "(sdk|backend|server)" | head -20

Repository: MCPJam/inspector

Length of output: 681


🏁 Script executed:

#!/bin/bash
# Search for where mockReconnectServer might be defined or what it represents
rg -n "mockReconnectServer\|reconnectServer" mcpjam-inspector/client/ -A 3 | head -30

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Check if error constants/enums are used elsewhere in the codebase
rg -n "const.*ERROR|const.*MESSAGE" mcpjam-inspector/client/src/ | head -20

Repository: MCPJam/inspector

Length of output: 2279


🏁 Script executed:

#!/bin/bash
# Check what error constants exist in use-hosted-oauth-gate.ts
cat mcpjam-inspector/client/src/hooks/hosted/use-hosted-oauth-gate.ts | head -100

Repository: MCPJam/inspector

Length of output: 3462


🏁 Script executed:

#!/bin/bash
# Search for the error message in SDK code
fd -t f \( -name "*.ts" -o -name "*.tsx" \) sdk/ | xargs rg -l "missing refresh" --max-count 5

Repository: MCPJam/inspector

Length of output: 446


🏁 Script executed:

#!/bin/bash
# Look at the full use-server-state.ts around the error checks to understand context
sed -n '125,145p' mcpjam-inspector/client/src/hooks/use-server-state.ts

Repository: MCPJam/inspector

Length of output: 724


🏁 Script executed:

#!/bin/bash
# Search for where the error is generated in SDK
rg "Stored hosted OAuth credential is missing refresh_token" --iglob '!**/node_modules/**'

Repository: MCPJam/inspector

Length of output: 215


🏁 Script executed:

#!/bin/bash
# Look at the test file to understand the source of the error
sed -n '430,450p' mcpjam-inspector/client/src/hooks/__tests__/use-server-state.hosted-oauth.test.tsx

Repository: MCPJam/inspector

Length of output: 663


🏁 Script executed:

#!/bin/bash
# Search for similar error message patterns in SDK to understand where they originate
rg "stored.*oauth.*credential|oauth.*credential" --iglob '!**/node_modules/**' -i

Repository: MCPJam/inspector

Length of output: 6357


🏁 Script executed:

#!/bin/bash
# Find the definition/setup of mockReconnectServer
rg "mockReconnectServer\s*=" mcpjam-inspector/client/src/hooks/__tests__/use-server-state.hosted-oauth.test.tsx -B 5 -A 5 | head -30

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for any backend or server implementation that might emit this error
find . -type f \( -name "*.py" -o -name "*.go" -o -name "*.rs" \) 2>/dev/null | head -10

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Search for error handling in the entire codebase related to reconnect
rg "refresh_token|reconnect" --iglob '!**/node_modules/**' | grep -i error | head -15

Repository: MCPJam/inspector

Length of output: 1980


🏁 Script executed:

#!/bin/bash
# Look for reconnectServer implementation/definition
rg "reconnectServer.*=" mcpjam-inspector/client/ -B 3 -A 3 | head -40

Repository: MCPJam/inspector

Length of output: 3616


🏁 Script executed:

#!/bin/bash
# Check if there's an API call or service that provides reconnectServer
rg "function.*reconnect|const.*reconnect" mcpjam-inspector/client/src/lib/ -i | head -20

Repository: MCPJam/inspector

Length of output: 174


🏁 Script executed:

#!/bin/bash
# Find where the error string originates by checking for API responses
sed -n '1,50p' mcpjam-inspector/client/src/test/mocks/mcp-api.ts

Repository: MCPJam/inspector

Length of output: 1573


🏁 Script executed:

#!/bin/bash
# Find the actual reconnectServer implementation
rg "export.*reconnectServer|const reconnectServer" mcpjam-inspector/client/src/state/ -A 10

Repository: MCPJam/inspector

Length of output: 820


🏁 Script executed:

#!/bin/bash
# Check mcp-api.ts file
cat mcpjam-inspector/client/src/state/mcp-api.ts | head -150

Repository: MCPJam/inspector

Length of output: 4209


🏁 Script executed:

#!/bin/bash
# Look for the server backend that returns the error
find . -type f -name "*.ts" | xargs rg -l "refresh_token.*missing|missing.*refresh" --max-count 5 | grep -v node_modules | grep -v test

Repository: MCPJam/inspector

Length of output: 116


🏁 Script executed:

#!/bin/bash
# Look at servers-api.ts to see how validateHostedServer is implemented
cat mcpjam-inspector/client/src/lib/apis/web/servers-api.ts | head -200

Repository: MCPJam/inspector

Length of output: 1398


🏁 Script executed:

#!/bin/bash
# Check the backend server code for the error message
find . -path ./node_modules -prune -o -type f \( -name "*.ts" -o -name "*.tsx" \) -print | xargs rg "Stored.*OAuth\|refresh_token.*credential" | head -20

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look at the test to see exactly how the error is used
sed -n '428,460p' mcpjam-inspector/client/src/hooks/__tests__/use-server-state.hosted-oauth.test.tsx

Repository: MCPJam/inspector

Length of output: 961


🏁 Script executed:

#!/bin/bash
# Search for where the backend might be generating this error
find . -type f -name "*.ts" -o -name "*.tsx" | xargs rg -l "api.*servers.*validate|Stored.*OAuth" | grep -v node_modules | grep -v test

Repository: MCPJam/inspector

Length of output: 475


🏁 Script executed:

#!/bin/bash
# Check if there's a backend implementation in the server directory
ls -la mcpjam-inspector/server/

Repository: MCPJam/inspector

Length of output: 1141


🏁 Script executed:

#!/anbin/bash
# Look at the server code for validation
find mcpjam-inspector/server -name "*.ts" -type f | xargs rg -l "oauth\|credential" | head -10

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look at server routes
ls -la mcpjam-inspector/server/routes/

Repository: MCPJam/inspector

Length of output: 387


🏁 Script executed:

#!/bin/bash
# Search for web routes specifically
find mcpjam-inspector/server/routes -type f -name "*.ts" | head -20

Repository: MCPJam/inspector

Length of output: 1294


🏁 Script executed:

#!/bin/bash
# Search for the specific error message in the entire server codebase
rg "Stored.*OAuth\|missing.*refresh" mcpjam-inspector/server/ --type ts

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look for web routes validation
find mcpjam-inspector/server/routes/web -type f -name "*.ts" 2>/dev/null | head -20

Repository: MCPJam/inspector

Length of output: 1313


🏁 Script executed:

#!/an/bin/bash
# Search more broadly for the error message in all TypeScript files
rg "missing refresh" . --type ts --type tsx | grep -v node_modules | grep -v ".next"

Repository: MCPJam/inspector

Length of output: 88


🏁 Script executed:

#!/bin/bash
# Look at the services directory
find mcpjam-inspector/server/services -type f -name "*.ts" | head -20

Repository: MCPJam/inspector

Length of output: 1384


🏁 Script executed:

#!/bin/bash
# Search for where this specific error is generated or mocked
rg "Stored hosted OAuth credential" . --max-count 10

Repository: MCPJam/inspector

Length of output: 217


🏁 Script executed:

#!/bin/bash
# Look for web/servers routes specifically
cat mcpjam-inspector/server/routes/web/servers.ts 2>/dev/null | head -150

Repository: MCPJam/inspector

Length of output: 4242


🏁 Script executed:

#!/bin/bash
# Check if this is an external service call by looking for fetch/axios calls
rg "reconnect|validate.*server" mcpjam-inspector/server/routes/web/ --type ts -A 5 | head -40

Repository: MCPJam/inspector

Length of output: 2564


🏁 Script executed:

#!/bin/bash
# Check if there are other similar hardcoded error checks in the file
sed -n '125,160p' mcpjam-inspector/client/src/hooks/use-server-state.ts

Repository: MCPJam/inspector

Length of output: 987


🏁 Script executed:

#!/bin/bash
# Look at all the error checks to understand the pattern
sed -n '128,142p' mcpjam-inspector/client/src/hooks/use-server-state.ts

Repository: MCPJam/inspector

Length of output: 479


🏁 Script executed:

#!/bin/bash
# Verify whether there is a constant file or shared errors module
find mcpjam-inspector/client/src -name "*constant*" -o -name "*error*" -o -name "*message*" | grep -v test | head -20

Repository: MCPJam/inspector

Length of output: 980


🏁 Script executed:

#!/bin/bash
# Check OAuth constants
cat mcpjam-inspector/client/src/lib/oauth/constants.ts

Repository: MCPJam/inspector

Length of output: 1870


🏁 Script executed:

#!/bin/bash
# Check error guidance
cat mcpjam-inspector/client/src/lib/xaa/error-guidance.ts

Repository: MCPJam/inspector

Length of output: 13862


🏁 Script executed:

#!/bin/bash
# Look for where shouldRetriggerHostedReauth is called
rg "shouldRetriggerHostedReauth" mcpjam-inspector/client/ -B 5 -A 5

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Search for the function that contains the hardcoded string
rg "shouldRetriggerHostedReauth" . --max-count 10

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Look at context around where the error message is checked
sed -n '120,180p' mcpjam-inspector/client/src/hooks/use-server-state.ts

Repository: MCPJam/inspector

Length of output: 1657


🏁 Script executed:

#!/bin/bash
# Find where this function is defined
ast-grep --pattern 'function shouldRetriggerHostedReauth' mcpjam-inspector/client/src/

Repository: MCPJam/inspector

Length of output: 42


🏁 Script executed:

#!/bin/bash
# Find the function that contains this error check
rg -B 10 'stored hosted oauth credential is missing refresh_token' mcpjam-inspector/client/src/hooks/use-server-state.ts | head -30

Repository: MCPJam/inspector

Length of output: 331


🏁 Script executed:

#!/bin/bash
# Look at the test to understand expectations and confirm the string is stable
sed -n '428,465p' mcpjam-inspector/client/src/hooks/__tests__/use-server-state.hosted-oauth.test.tsx

Repository: MCPJam/inspector

Length of output: 971


🏁 Script executed:

#!/bin/bash
# Check if there are any other files that reference this exact error string
rg -r 'Stored hosted OAuth credential' . --max-count 10

Repository: MCPJam/inspector

Length of output: 50375


Extract the error string to a constant.

The predicate relies on matching "stored hosted oauth credential is missing refresh_token" after lowercasing. If the backend or external service that emits this error ever rewords it—adding punctuation, changing refresh_token to refresh token, or localizing—the reconnect flow will silently fail, leaving users with an error toast instead of an OAuth redirect. Creating a shared constant makes this coupling explicit and easier to maintain.

const MISSING_REFRESH_TOKEN_ERROR = 
  "stored hosted oauth credential is missing refresh_token";

Consider extracting all three error predicates in that function to constants for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcpjam-inspector/client/src/hooks/use-server-state.ts` around lines 133 -
135, The predicate currently matches the literal string "stored hosted oauth
credential is missing refresh_token" inline (normalized.includes(...)) which
couples the reconnect flow to a fragile error wording; extract that literal into
a shared constant (e.g. MISSING_REFRESH_TOKEN_ERROR) and replace the inline
normalized.includes(...) with a reference to that constant, and similarly
extract the other two error predicates used in the same function in
use-server-state.ts for consistency so all three checks use named constants
rather than hardcoded strings.

@chelojimenez chelojimenez merged commit 469c1cd into main Apr 24, 2026
12 checks passed
@chelojimenez chelojimenez deleted the codex/investigate-reconnect-token-error branch April 24, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant