From 472117a872e1e1f523b74b92223965a2ee5b573c Mon Sep 17 00:00:00 2001 From: Zamil Majdy Date: Tue, 10 Feb 2026 16:47:36 +0400 Subject: [PATCH] fix(mcp): Handle MCP credential deletion with dynamic OAuth handler MCP credentials use per-server dynamic OAuth handlers, not a static handler registered in HANDLERS_BY_NAME. The delete endpoint now creates a dynamic handler from credential metadata for token revocation instead of failing with "Provider 'mcp' does not support OAuth". --- .../backend/api/features/integrations/router.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/autogpt_platform/backend/backend/api/features/integrations/router.py b/autogpt_platform/backend/backend/api/features/integrations/router.py index f92795366e..8364e01439 100644 --- a/autogpt_platform/backend/backend/api/features/integrations/router.py +++ b/autogpt_platform/backend/backend/api/features/integrations/router.py @@ -39,6 +39,7 @@ from backend.data.onboarding import OnboardingStep, complete_onboarding_step from backend.data.user import get_user_integrations from backend.executor.utils import add_graph_execution from backend.integrations.ayrshare import AyrshareClient, SocialPlatform +from backend.integrations.credentials_store import provider_matches from backend.integrations.creds_manager import IntegrationCredentialsManager from backend.integrations.oauth import CREDENTIALS_BY_PROVIDER, HANDLERS_BY_NAME from backend.integrations.providers import ProviderName @@ -348,7 +349,15 @@ async def delete_credentials( tokens_revoked = None if isinstance(creds, OAuth2Credentials): - handler = _get_provider_oauth_handler(request, provider) + if provider_matches(provider.value, ProviderName.MCP.value): + # MCP uses dynamic per-server OAuth — create handler from metadata + from backend.integrations.creds_manager import ( + _create_mcp_oauth_handler, + ) + + handler = _create_mcp_oauth_handler(creds) + else: + handler = _get_provider_oauth_handler(request, provider) tokens_revoked = await handler.revoke_tokens(creds) return CredentialsDeletionResponse(revoked=tokens_revoked)