diff --git a/client/src/App.tsx b/client/src/App.tsx index cff51b4ff..c8692c091 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -119,6 +119,14 @@ const App = () => { return localStorage.getItem("lastHeaderName") || ""; }); + const [oauthClientId, setOauthClientId] = useState(() => { + return localStorage.getItem("lastOauthClientId") || ""; + }); + + const [oauthScope, setOauthScope] = useState(() => { + return localStorage.getItem("lastOauthScope") || ""; + }); + const [pendingSampleRequests, setPendingSampleRequests] = useState< Array< PendingRequest & { @@ -187,6 +195,8 @@ const App = () => { env, bearerToken, headerName, + oauthClientId, + oauthScope, config, onNotification: (notification) => { setNotifications((prev) => [...prev, notification as ServerNotification]); @@ -230,6 +240,14 @@ const App = () => { localStorage.setItem("lastHeaderName", headerName); }, [headerName]); + useEffect(() => { + localStorage.setItem("lastOauthClientId", oauthClientId); + }, [oauthClientId]); + + useEffect(() => { + localStorage.setItem("lastOauthScope", oauthScope); + }, [oauthScope]); + useEffect(() => { saveInspectorConfig(CONFIG_LOCAL_STORAGE_KEY, config); }, [config]); @@ -658,6 +676,10 @@ const App = () => { setBearerToken={setBearerToken} headerName={headerName} setHeaderName={setHeaderName} + oauthClientId={oauthClientId} + setOauthClientId={setOauthClientId} + oauthScope={oauthScope} + setOauthScope={setOauthScope} onConnect={connectMcpServer} onDisconnect={disconnectMcpServer} stdErrNotifications={stdErrNotifications} diff --git a/client/src/components/Sidebar.tsx b/client/src/components/Sidebar.tsx index 938e5b5a3..a41e4bfc7 100644 --- a/client/src/components/Sidebar.tsx +++ b/client/src/components/Sidebar.tsx @@ -56,6 +56,10 @@ interface SidebarProps { setBearerToken: (token: string) => void; headerName?: string; setHeaderName?: (name: string) => void; + oauthClientId: string; + setOauthClientId: (id: string) => void; + oauthScope: string; + setOauthScope: (scope: string) => void; onConnect: () => void; onDisconnect: () => void; stdErrNotifications: StdErrNotification[]; @@ -83,6 +87,10 @@ const Sidebar = ({ setBearerToken, headerName, setHeaderName, + oauthClientId, + setOauthClientId, + oauthScope, + setOauthScope, onConnect, onDisconnect, stdErrNotifications, @@ -95,7 +103,7 @@ const Sidebar = ({ }: SidebarProps) => { const [theme, setTheme] = useTheme(); const [showEnvVars, setShowEnvVars] = useState(false); - const [showBearerToken, setShowBearerToken] = useState(false); + const [showAuthConfig, setShowAuthConfig] = useState(false); const [showConfig, setShowConfig] = useState(false); const [shownEnvVars, setShownEnvVars] = useState>(new Set()); const [copiedServerEntry, setCopiedServerEntry] = useState(false); @@ -308,51 +316,6 @@ const Sidebar = ({ /> )} -
- - {showBearerToken && ( -
- - - setHeaderName && setHeaderName(e.target.value) - } - data-testid="header-input" - className="font-mono" - value={headerName} - /> - - setBearerToken(e.target.value)} - data-testid="bearer-token-input" - className="font-mono" - type="password" - /> -
- )} -
)} @@ -521,6 +484,94 @@ const Sidebar = ({ +
+ + {showAuthConfig && ( + <> + {/* Bearer Token Section */} +
+

+ API Token Authentication +

+
+ + + setHeaderName && setHeaderName(e.target.value) + } + data-testid="header-input" + className="font-mono" + value={headerName} + /> + + setBearerToken(e.target.value)} + data-testid="bearer-token-input" + className="font-mono" + type="password" + /> +
+
+ {transportType !== "stdio" && ( + // OAuth Configuration +
+

+ OAuth 2.0 Flow +

+
+ + setOauthClientId(e.target.value)} + value={oauthClientId} + data-testid="oauth-client-id-input" + className="font-mono" + /> + + + + setOauthScope(e.target.value)} + value={oauthScope} + data-testid="oauth-scope-input" + className="font-mono" + /> +
+
+ )} + + )} +
{/* Configuration */}