diff --git a/autogpt_platform/backend/backend/api/features/mcp/routes.py b/autogpt_platform/backend/backend/api/features/mcp/routes.py index 230eb517eb..4be050d267 100644 --- a/autogpt_platform/backend/backend/api/features/mcp/routes.py +++ b/autogpt_platform/backend/backend/api/features/mcp/routes.py @@ -193,7 +193,7 @@ async def mcp_oauth_login( metadata: dict[str, Any] | None = None - if protected_resource and "authorization_servers" in protected_resource: + if protected_resource and protected_resource.get("authorization_servers"): auth_server_url = protected_resource["authorization_servers"][0] resource_url = protected_resource.get("resource", request.server_url) @@ -216,7 +216,11 @@ async def mcp_oauth_login( except Exception: pass - if not metadata or "authorization_endpoint" not in metadata: + if ( + not metadata + or "authorization_endpoint" not in metadata + or "token_endpoint" not in metadata + ): raise fastapi.HTTPException( status_code=400, detail="This MCP server does not advertise OAuth support. " diff --git a/autogpt_platform/backend/backend/integrations/credentials_store.py b/autogpt_platform/backend/backend/integrations/credentials_store.py index a0cfb03133..3e79a6c047 100644 --- a/autogpt_platform/backend/backend/integrations/credentials_store.py +++ b/autogpt_platform/backend/backend/integrations/credentials_store.py @@ -23,7 +23,7 @@ from backend.util.settings import Settings settings = Settings() -def _provider_matches(stored: str, expected: str) -> bool: +def provider_matches(stored: str, expected: str) -> bool: """Compare provider strings, handling Python 3.13 ``str(StrEnum)`` bug. On Python 3.13, ``str(ProviderName.MCP)`` returns ``"ProviderName.MCP"`` @@ -410,7 +410,7 @@ class IntegrationCredentialsStore: self, user_id: str, provider: str ) -> list[Credentials]: credentials = await self.get_all_creds(user_id) - return [c for c in credentials if _provider_matches(c.provider, provider)] + return [c for c in credentials if provider_matches(c.provider, provider)] async def get_authorized_providers(self, user_id: str) -> list[str]: credentials = await self.get_all_creds(user_id) @@ -531,7 +531,7 @@ class IntegrationCredentialsStore: state for state in oauth_states if secrets.compare_digest(state.token, token) - and _provider_matches(state.provider, provider) + and provider_matches(state.provider, provider) and state.expires_at > now.timestamp() ), None, diff --git a/autogpt_platform/backend/backend/integrations/creds_manager.py b/autogpt_platform/backend/backend/integrations/creds_manager.py index bd5203eaeb..fb1dbda8ba 100644 --- a/autogpt_platform/backend/backend/integrations/creds_manager.py +++ b/autogpt_platform/backend/backend/integrations/creds_manager.py @@ -9,7 +9,10 @@ from redis.asyncio.lock import Lock as AsyncRedisLock from backend.data.model import Credentials, OAuth2Credentials from backend.data.redis_client import get_redis_async -from backend.integrations.credentials_store import IntegrationCredentialsStore +from backend.integrations.credentials_store import ( + IntegrationCredentialsStore, + provider_matches, +) from backend.integrations.oauth import CREDENTIALS_BY_PROVIDER, HANDLERS_BY_NAME from backend.integrations.providers import ProviderName from backend.util.exceptions import MissingConfigError @@ -137,7 +140,7 @@ class IntegrationCredentialsManager: self, user_id: str, credentials: OAuth2Credentials, lock: bool = True ) -> OAuth2Credentials: async with self._locked(user_id, credentials.id, "refresh"): - if credentials.provider == ProviderName.MCP.value: + if provider_matches(credentials.provider, ProviderName.MCP.value): oauth_handler = _create_mcp_oauth_handler(credentials) else: oauth_handler = await _get_provider_oauth_handler(credentials.provider) diff --git a/docs/integrations/block-integrations/mcp/block.md b/docs/integrations/block-integrations/mcp/block.md index ae97ba1a23..6858e42e94 100644 --- a/docs/integrations/block-integrations/mcp/block.md +++ b/docs/integrations/block-integrations/mcp/block.md @@ -1,6 +1,6 @@ # Mcp Block -_Add a description of this category of blocks._ +Blocks for connecting to and executing tools on MCP (Model Context Protocol) servers. ## MCP Tool @@ -10,7 +10,9 @@ Connect to any MCP server and execute its tools. Provide a server URL, select a ### How it works -_Add technical explanation here._ +The block uses JSON-RPC 2.0 over HTTP to communicate with MCP servers. When configuring, it sends an `initialize` request followed by `tools/list` to discover available tools and their input schemas. On execution, it calls `tools/call` with the selected tool name and arguments, then extracts text, image, or resource content from the response. + +Authentication is handled via OAuth 2.0 when the server requires it. The block supports optional credentials — public servers work without authentication, while protected servers trigger a standard OAuth flow with PKCE. Tokens are automatically refreshed when they expire. ### Inputs @@ -30,7 +32,9 @@ _Add technical explanation here._ ### Possible use case -_Add practical use case examples here._ +- **Connecting to third-party APIs**: Use an MCP server like Sentry or Linear to query issues, create tickets, or manage projects without building custom integrations. +- **AI-powered tool execution**: Chain MCP tool calls with AI blocks to let agents dynamically discover and use external tools based on task requirements. +- **Data retrieval from knowledge bases**: Connect to MCP servers like DeepWiki to search documentation, retrieve code context, or query structured knowledge bases. ---