diff --git a/autogpt_platform/frontend/src/app/(platform)/build/components/MCPToolDialog.tsx b/autogpt_platform/frontend/src/app/(platform)/build/components/MCPToolDialog.tsx index 7d2283f7fd..35dff1b6f3 100644 --- a/autogpt_platform/frontend/src/app/(platform)/build/components/MCPToolDialog.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/build/components/MCPToolDialog.tsx @@ -21,8 +21,13 @@ import { Label } from "@/components/__legacy__/ui/label"; import { LoadingSpinner } from "@/components/__legacy__/ui/loading"; import { Badge } from "@/components/__legacy__/ui/badge"; import { ScrollArea } from "@/components/__legacy__/ui/scroll-area"; -import { useBackendAPI } from "@/lib/autogpt-server-api/context"; -import type { CredentialsMetaInput, MCPTool } from "@/lib/autogpt-server-api"; +import type { CredentialsMetaInput } from "@/lib/autogpt-server-api"; +import type { MCPToolResponse } from "@/app/api/__generated__/models/mCPToolResponse"; +import { + postV2DiscoverAvailableToolsOnAnMcpServer, + postV2InitiateOauthLoginForAnMcpServer, + postV2ExchangeOauthCodeForMcpTokens, +} from "@/app/api/__generated__/endpoints/mcp/mcp"; import { CaretDown } from "@phosphor-icons/react"; import { openOAuthPopup } from "@/lib/oauth-popup"; import { CredentialsProvidersContext } from "@/providers/agent-credentials/credentials-provider"; @@ -50,12 +55,11 @@ export function MCPToolDialog({ onClose, onConfirm, }: MCPToolDialogProps) { - const api = useBackendAPI(); const allProviders = useContext(CredentialsProvidersContext); const [step, setStep] = useState("url"); const [serverUrl, setServerUrl] = useState(""); - const [tools, setTools] = useState([]); + const [tools, setTools] = useState([]); const [serverName, setServerName] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); @@ -63,7 +67,7 @@ export function MCPToolDialog({ const [oauthLoading, setOauthLoading] = useState(false); const [showManualToken, setShowManualToken] = useState(false); const [manualToken, setManualToken] = useState(""); - const [selectedTool, setSelectedTool] = useState(null); + const [selectedTool, setSelectedTool] = useState(null); const [credentials, setCredentials] = useState( null, ); @@ -105,9 +109,13 @@ export function MCPToolDialog({ setLoading(true); setError(null); try { - const result = await api.mcpDiscoverTools(url, authToken); - setTools(result.tools); - setServerName(result.server_name); + const response = + await postV2DiscoverAvailableToolsOnAnMcpServer({ + server_url: url, + auth_token: authToken || null, + }); + setTools(response.data.tools); + setServerName(response.data.server_name ?? null); setAuthRequired(false); setShowManualToken(false); setStep("tool"); @@ -130,7 +138,7 @@ export function MCPToolDialog({ setLoading(false); } }, - [api], + [], ); const handleDiscoverTools = useCallback(() => { @@ -148,9 +156,10 @@ export function MCPToolDialog({ setOauthLoading(true); try { - const { login_url, state_token } = await api.mcpOAuthLogin( - serverUrl.trim(), - ); + const loginResponse = await postV2InitiateOauthLoginForAnMcpServer({ + server_url: serverUrl.trim(), + }); + const { login_url, state_token } = loginResponse.data; const { promise, cleanup } = openOAuthPopup(login_url, { stateToken: state_token, @@ -165,9 +174,19 @@ export function MCPToolDialog({ setOauthLoading(false); const mcpProvider = allProviders?.["mcp"]; - const callbackResult = mcpProvider - ? await mcpProvider.mcpOAuthCallback(result.code, state_token) - : await api.mcpOAuthCallback(result.code, state_token); + let callbackResult; + if (mcpProvider) { + callbackResult = await mcpProvider.mcpOAuthCallback( + result.code, + state_token, + ); + } else { + const cbResponse = await postV2ExchangeOauthCodeForMcpTokens({ + code: result.code, + state_token, + }); + callbackResult = cbResponse.data; + } setCredentials({ id: callbackResult.id, @@ -178,9 +197,12 @@ export function MCPToolDialog({ setAuthRequired(false); // Discover tools now that we're authenticated - const toolsResult = await api.mcpDiscoverTools(serverUrl.trim()); - setTools(toolsResult.tools); - setServerName(toolsResult.server_name); + const toolsResponse = + await postV2DiscoverAvailableToolsOnAnMcpServer({ + server_url: serverUrl.trim(), + }); + setTools(toolsResponse.data.tools); + setServerName(toolsResponse.data.server_name ?? null); setStep("tool"); } catch (e: any) { // If server doesn't support OAuth → show manual token entry @@ -210,7 +232,7 @@ export function MCPToolDialog({ setLoading(false); oauthAbortRef.current = null; } - }, [api, serverUrl, allProviders]); + }, [serverUrl, allProviders]); // Auto-start OAuth sign-in when server returns 401/403 useEffect(() => { @@ -398,7 +420,7 @@ function MCPToolCard({ selected, onSelect, }: { - tool: MCPTool; + tool: MCPToolResponse; selected: boolean; onSelect: () => void; }) { diff --git a/autogpt_platform/frontend/src/components/contextual/CredentialsInput/useCredentialsInput.ts b/autogpt_platform/frontend/src/components/contextual/CredentialsInput/useCredentialsInput.ts index 715c6fbe60..a9d8fbde91 100644 --- a/autogpt_platform/frontend/src/components/contextual/CredentialsInput/useCredentialsInput.ts +++ b/autogpt_platform/frontend/src/components/contextual/CredentialsInput/useCredentialsInput.ts @@ -5,6 +5,7 @@ import { BlockIOCredentialsSubSchema, CredentialsMetaInput, } from "@/lib/autogpt-server-api/types"; +import { postV2InitiateOauthLoginForAnMcpServer } from "@/app/api/__generated__/endpoints/mcp/mcp"; import { openOAuthPopup } from "@/lib/oauth-popup"; import { useQueryClient } from "@tanstack/react-query"; import { useEffect, useRef, useState } from "react"; @@ -183,9 +184,11 @@ export function useCredentialsInput({ let state_token: string; if (isMCP) { - ({ login_url, state_token } = await api.mcpOAuthLogin( - discriminatorValue!, - )); + const mcpLoginResponse = + await postV2InitiateOauthLoginForAnMcpServer({ + server_url: discriminatorValue!, + }); + ({ login_url, state_token } = mcpLoginResponse.data); } else { ({ login_url, state_token } = await api.oAuthLogin( provider, diff --git a/autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts b/autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts index 119f424ad0..e58b5f6020 100644 --- a/autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts +++ b/autogpt_platform/frontend/src/lib/autogpt-server-api/client.ts @@ -33,7 +33,6 @@ import type { GraphMeta, GraphUpdateable, HostScopedCredentials, - MCPDiscoverToolsResponse, LibraryAgent, LibraryAgentID, LibraryAgentPreset, @@ -793,38 +792,6 @@ export default class BackendAPI { return this._request("POST", "/otto/ask", query); } - //////////////////////////////////////// - ///////////// MCP FUNCTIONS //////////// - //////////////////////////////////////// - - async mcpDiscoverTools( - serverUrl: string, - authToken?: string, - ): Promise { - return this._request("POST", "/mcp/discover-tools", { - server_url: serverUrl, - auth_token: authToken || null, - }); - } - - async mcpOAuthLogin( - serverUrl: string, - ): Promise<{ login_url: string; state_token: string }> { - return this._request("POST", "/mcp/oauth/login", { - server_url: serverUrl, - }); - } - - async mcpOAuthCallback( - code: string, - stateToken: string, - ): Promise { - return this._request("POST", "/mcp/oauth/callback", { - code, - state_token: stateToken, - }); - } - //////////////////////////////////////// ////////// INTERNAL FUNCTIONS ////////// //////////////////////////////////////// diff --git a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts b/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts index f3702d58d0..ffc21269e6 100644 --- a/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts +++ b/autogpt_platform/frontend/src/lib/autogpt-server-api/types.ts @@ -759,18 +759,6 @@ export enum SpecialBlockID { OUTPUT = "363ae599-353e-4804-937e-b2ee3cef3da4", } -export type MCPTool = { - name: string; - description: string; - input_schema: Record; -}; - -export type MCPDiscoverToolsResponse = { - tools: MCPTool[]; - server_name: string | null; - protocol_version: string | null; -}; - export type AnalyticsMetrics = { metric_name: string; metric_value: number; diff --git a/autogpt_platform/frontend/src/providers/agent-credentials/credentials-provider.tsx b/autogpt_platform/frontend/src/providers/agent-credentials/credentials-provider.tsx index 3ea7f32377..75dcab3618 100644 --- a/autogpt_platform/frontend/src/providers/agent-credentials/credentials-provider.tsx +++ b/autogpt_platform/frontend/src/providers/agent-credentials/credentials-provider.tsx @@ -8,6 +8,7 @@ import { HostScopedCredentials, UserPasswordCredentials, } from "@/lib/autogpt-server-api"; +import { postV2ExchangeOauthCodeForMcpTokens } from "@/app/api/__generated__/endpoints/mcp/mcp"; import { useBackendAPI } from "@/lib/autogpt-server-api/context"; import { useSupabase } from "@/lib/supabase/hooks/useSupabase"; import { toDisplayName } from "@/providers/agent-credentials/helper"; @@ -125,14 +126,18 @@ export default function CredentialsProvider({ [api, addCredentials, onFailToast], ); - /** Wraps `BackendAPI.mcpOAuthCallback`, and adds the result to the internal credentials store. */ + /** Exchanges an MCP OAuth code for tokens and adds the result to the internal credentials store. */ const mcpOAuthCallback = useCallback( async ( code: string, state_token: string, ): Promise => { try { - const credsMeta = await api.mcpOAuthCallback(code, state_token); + const response = await postV2ExchangeOauthCodeForMcpTokens({ + code, + state_token, + }); + const credsMeta = response.data; addCredentials("mcp", credsMeta); return credsMeta; } catch (error) { @@ -140,7 +145,7 @@ export default function CredentialsProvider({ throw error; } }, - [api, addCredentials, onFailToast], + [addCredentials, onFailToast], ); /** Wraps `BackendAPI.createAPIKeyCredentials`, and adds the result to the internal credentials store. */