1- import { useDraggablePane } from "./lib/hooks/useDraggablePane" ;
2- import { useConnection } from "./lib/hooks/useConnection" ;
31import {
42 ClientRequest ,
53 CompatibilityCallToolResult ,
@@ -10,15 +8,17 @@ import {
108 ListPromptsResultSchema ,
119 ListResourcesResultSchema ,
1210 ListResourceTemplatesResultSchema ,
13- ReadResourceResultSchema ,
1411 ListToolsResultSchema ,
12+ ReadResourceResultSchema ,
1513 Resource ,
1614 ResourceTemplate ,
1715 Root ,
1816 ServerNotification ,
1917 Tool ,
2018} from "@modelcontextprotocol/sdk/types.js" ;
21- import { useEffect , useRef , useState } from "react" ;
19+ import React , { Suspense , useEffect , useRef , useState } from "react" ;
20+ import { useConnection } from "./lib/hooks/useConnection" ;
21+ import { useDraggablePane } from "./lib/hooks/useDraggablePane" ;
2222
2323import { StdErrNotification } from "./lib/notificationTypes" ;
2424
@@ -32,6 +32,7 @@ import {
3232 MessageSquare ,
3333} from "lucide-react" ;
3434
35+ import { toast } from "react-toastify" ;
3536import { z } from "zod" ;
3637import "./App.css" ;
3738import ConsoleTab from "./components/ConsoleTab" ;
@@ -49,6 +50,17 @@ const PROXY_PORT = params.get("proxyPort") ?? "3000";
4950const PROXY_SERVER_URL = `http://localhost:${ PROXY_PORT } ` ;
5051
5152const App = ( ) => {
53+ // Handle OAuth callback route
54+ if ( window . location . pathname === "/oauth/callback" ) {
55+ const OAuthCallback = React . lazy (
56+ ( ) => import ( "./components/OAuthCallback" ) ,
57+ ) ;
58+ return (
59+ < Suspense fallback = { < div > Loading...</ div > } >
60+ < OAuthCallback />
61+ </ Suspense >
62+ ) ;
63+ }
5264 const [ resources , setResources ] = useState < Resource [ ] > ( [ ] ) ;
5365 const [ resourceTemplates , setResourceTemplates ] = useState <
5466 ResourceTemplate [ ]
@@ -71,8 +83,14 @@ const App = () => {
7183 return localStorage . getItem ( "lastArgs" ) || "" ;
7284 } ) ;
7385
74- const [ sseUrl , setSseUrl ] = useState < string > ( "http://localhost:3001/sse" ) ;
75- const [ transportType , setTransportType ] = useState < "stdio" | "sse" > ( "stdio" ) ;
86+ const [ sseUrl , setSseUrl ] = useState < string > ( ( ) => {
87+ return localStorage . getItem ( "lastSseUrl" ) || "http://localhost:3001/sse" ;
88+ } ) ;
89+ const [ transportType , setTransportType ] = useState < "stdio" | "sse" > ( ( ) => {
90+ return (
91+ ( localStorage . getItem ( "lastTransportType" ) as "stdio" | "sse" ) || "stdio"
92+ ) ;
93+ } ) ;
7694 const [ notifications , setNotifications ] = useState < ServerNotification [ ] > ( [ ] ) ;
7795 const [ stdErrNotifications , setStdErrNotifications ] = useState <
7896 StdErrNotification [ ]
@@ -190,6 +208,31 @@ const App = () => {
190208 localStorage . setItem ( "lastArgs" , args ) ;
191209 } , [ args ] ) ;
192210
211+ useEffect ( ( ) => {
212+ localStorage . setItem ( "lastSseUrl" , sseUrl ) ;
213+ } , [ sseUrl ] ) ;
214+
215+ useEffect ( ( ) => {
216+ localStorage . setItem ( "lastTransportType" , transportType ) ;
217+ } , [ transportType ] ) ;
218+
219+ // Auto-connect if serverUrl is provided in URL params (e.g. after OAuth callback)
220+ useEffect ( ( ) => {
221+ const serverUrl = params . get ( "serverUrl" ) ;
222+ if ( serverUrl ) {
223+ setSseUrl ( serverUrl ) ;
224+ setTransportType ( "sse" ) ;
225+ // Remove serverUrl from URL without reloading the page
226+ const newUrl = new URL ( window . location . href ) ;
227+ newUrl . searchParams . delete ( "serverUrl" ) ;
228+ window . history . replaceState ( { } , "" , newUrl . toString ( ) ) ;
229+ // Show success toast for OAuth
230+ toast . success ( "Successfully authenticated with OAuth" ) ;
231+ // Connect to the server
232+ connectMcpServer ( ) ;
233+ }
234+ } , [ ] ) ;
235+
193236 useEffect ( ( ) => {
194237 fetch ( `${ PROXY_SERVER_URL } /config` )
195238 . then ( ( response ) => response . json ( ) )
0 commit comments