Skip to content

fix(oauth): clean up orphaned tokens on server removal and startup#288

Merged
Dumbris merged 1 commit intomainfrom
fix/oauth-token-cleanup
Jan 31, 2026
Merged

fix(oauth): clean up orphaned tokens on server removal and startup#288
Dumbris merged 1 commit intomainfrom
fix/oauth-token-cleanup

Conversation

@Dumbris
Copy link
Contributor

@Dumbris Dumbris commented Jan 31, 2026

Summary

  • Clean up orphaned OAuth tokens when servers are removed
  • Add startup cleanup for tokens of servers no longer in configuration
  • Notify RefreshManager to stop tracking removed servers

Problem

OAuth tokens were accumulating in the database for servers that had been removed, causing:

  • Unnecessary token refresh attempts on startup
  • Confusing error messages: "OAuth token refresh failed - token expired too long ago"
  • Database bloat with orphaned records

Evidence from investigation:

Before cleanup: 11 tokens
- autorag-cf (ORPHANED, expired 217 hours ago)
- bindings-cloudflare (ORPHANED, expired 481 hours ago)
- cloudflare-builds (ORPHANED, expired 73 hours ago)
- cloudflare-dns-analytics (ORPHANED, expired 73 hours ago)
- cloudflare-logs (ORPHANED, expired 73 hours ago)
- oauth-test-server (ORPHANED, expired 1339 hours ago)
- runlayer-mock (ORPHANED)
- ... plus 4 valid tokens

After cleanup: 4 tokens (only for servers in config)

Root Cause

RemoveServer() was not calling ClearOAuthState() to remove OAuth tokens when a server was deleted, and there was no startup cleanup for tokens of servers removed while mcpproxy was not running.

Changes

1. internal/server/server.go

  • Added ClearOAuthState() call in RemoveServer() to clean up OAuth tokens
  • Added RefreshManager.OnTokenCleared() notification to stop refresh scheduling

2. internal/storage/manager.go

  • Added CleanupOrphanedOAuthTokens(validServerNames []string) method
  • Removes tokens for servers not in the provided list of valid server names

3. internal/runtime/lifecycle.go

  • Added startup cleanup: calls CleanupOrphanedOAuthTokens() before starting RefreshManager
  • Collects valid server names from configuration

4. internal/storage/manager_oauth_test.go

  • Added TestManager_CleanupOrphanedOAuthTokens test

Storage Key Design (already correct)

Tokens use serverName_hash(serverName|serverURL) as storage key, ensuring:

  • ✓ Multiple servers with same URL (different names) → different keys
  • ✓ Same server with different URL (URL changed) → different keys
  • ClearOAuthState(serverName) removes all tokens with serverName_ prefix

Test plan

  • Unit test for CleanupOrphanedOAuthTokens passes
  • Build succeeds
  • Linter passes
  • Verified cleanup works with real database (7 orphaned tokens cleaned up)
  • CI passes

🤖 Generated with Claude Code

This fixes the issue where OAuth tokens accumulate in the database for
servers that have been removed, causing unnecessary refresh attempts and
confusing error messages like "OAuth token refresh failed - token expired
too long ago".

Changes:
1. RemoveServer() now calls ClearOAuthState() to remove OAuth tokens
   when a server is deleted
2. RemoveServer() notifies RefreshManager to stop tracking the removed
   server's token refresh schedule
3. Added CleanupOrphanedOAuthTokens() to storage manager that removes
   tokens for servers no longer in configuration
4. Startup now cleans up orphaned tokens before starting RefreshManager

Key storage design notes:
- Tokens use serverName_hash(serverName|serverURL) as storage key
- This ensures multiple servers can share the same URL (different names)
- URL changes for a server name are properly handled via ClearOAuthState
  which deletes all tokens with the serverName_ prefix

Tested: Verified 7 orphaned tokens were cleaned up on startup

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7af5775
Status: ✅  Deploy successful!
Preview URL: https://8de25c32.mcpproxy-docs.pages.dev
Branch Preview URL: https://fix-oauth-token-cleanup.mcpproxy-docs.pages.dev

View logs

@github-actions
Copy link

📦 Build Artifacts

Workflow Run: View Run
Branch: fix/oauth-token-cleanup

Available Artifacts

  • archive-darwin-amd64 (23 MB)
  • archive-darwin-arm64 (21 MB)
  • archive-linux-amd64 (12 MB)
  • archive-linux-arm64 (11 MB)
  • archive-windows-amd64 (23 MB)
  • archive-windows-arm64 (20 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (26 MB)
  • installer-dmg-darwin-arm64 (23 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 21545962892 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

@Dumbris Dumbris merged commit 55b0861 into main Jan 31, 2026
23 checks passed
@Dumbris Dumbris deleted the fix/oauth-token-cleanup branch January 31, 2026 14:45
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.

1 participant