@@ -95,8 +95,17 @@ export default function App() {
9595 // Initialize apiUrl with default value
9696 const [ apiUrl , setApiUrl ] = useState ( 'https://registry.modelcontextprotocol.io/v0/servers' ) ;
9797
98- // Initialize stack with empty array
99- const [ stack , setStack ] = useState < StackItem [ ] > ( [ ] ) ;
98+ // Initialize stack from localStorage (client-side only) to avoid race
99+ // where the "save" effect would run on mount and overwrite a loaded value.
100+ const [ stack , setStack ] = useState < StackItem [ ] > ( ( ) => {
101+ try {
102+ if ( typeof window === 'undefined' ) return [ ] ;
103+ const saved = localStorage . getItem ( 'mcp-registry-stack' ) ;
104+ return saved ? ( JSON . parse ( saved ) as StackItem [ ] ) : [ ] ;
105+ } catch {
106+ return [ ] ;
107+ }
108+ } ) ;
100109
101110 useEffect ( ( ) => {
102111 // Load from localStorage after component mounts (client-side only)
@@ -109,14 +118,6 @@ export default function App() {
109118 setResultsPerPage ( parsed ) ;
110119 }
111120 }
112- const savedStack = localStorage . getItem ( 'mcp-registry-stack' ) ;
113- if ( savedStack ) {
114- try {
115- setStack ( JSON . parse ( savedStack ) ) ;
116- } catch ( err ) {
117- console . error ( 'Failed to parse saved stack:' , err ) ;
118- }
119- }
120121 // Listen to back/forward navigation and sync `search` with the URL
121122 if ( typeof window === 'undefined' ) return ;
122123 const onPop = ( ) => {
@@ -253,12 +254,6 @@ export default function App() {
253254 setNextCursor ( null ) ;
254255 setCurrentPage ( 1 ) ;
255256 fetchServers ( search , null , filterDate ) ;
256- // // Update URL parameter
257- // if (search) {
258- // setSearchParams({ search });
259- // } else {
260- // setSearchParams({});
261- // }
262257 } , [ search , apiUrl , filterDate , resultsPerPage , fetchServers ] ) ;
263258
264259 const handleNext = ( ) => {
@@ -280,11 +275,10 @@ export default function App() {
280275 }
281276 } ;
282277
283- // NOTE: For cursor-based pagination, we can't jump to arbitrary pages
284- // We can only navigate sequentially
278+ // NOTE: For cursor-based pagination, we can't jump to arbitrary pages, we can only navigate sequentially
285279 const handleGoToPage = ( page : number ) => {
286280 if ( page === 1 ) {
287- // Go to first page
281+ // Only support first page for now
288282 setCurrentCursor ( null ) ;
289283 setPreviousCursors ( [ ] ) ;
290284 setCurrentPage ( 1 ) ;
@@ -300,8 +294,14 @@ export default function App() {
300294 { /* Header */ }
301295 < header className = "sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60" >
302296 < div className = "container flex flex-col sm:flex-row sm:h-16 items-start sm:items-center justify-between gap-3 sm:gap-0 px-4 py-3 sm:py-0 mx-auto max-w-7xl" >
303- < div className = "flex items-center gap-2 flex-shrink-0" >
304- < img src = { McpLogo } alt = "Cursor" className = "h-5 w-5 [filter:invert(0)] dark:[filter:invert(1)]" />
297+ < div
298+ role = "button"
299+ tabIndex = { 0 }
300+ aria-label = "Clear search"
301+ onClick = { ( ) => setSearch ( '' ) }
302+ className = "flex items-center gap-2 flex-shrink-0 cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded"
303+ >
304+ < img src = { McpLogo } alt = "MCP logo" className = "h-5 w-5 [filter:invert(0)] dark:[filter:invert(1)]" />
305305 < h1 className = "text-lg" > MCP Registry</ h1 >
306306 </ div >
307307 < div className = "flex items-center gap-4 flex-1 w-full sm:w-auto justify-end max-w-2xl" >
@@ -353,8 +353,9 @@ export default function App() {
353353 // List servers in the stack, with remove button
354354 < DropdownMenuItem
355355 key = { idx }
356- className = "flex items-center justify-between gap-2 p-3"
356+ className = "flex items-center justify-between gap-2 p-3 cursor-pointer "
357357 onSelect = { ( e ) => e . preventDefault ( ) }
358+ onClick = { ( ) => setSearch ( item . serverName ) }
358359 >
359360 < div className = "flex-1 min-w-0" >
360361 < div className = "font-medium text-xs truncate" > { item . serverName } </ div >
@@ -365,7 +366,11 @@ export default function App() {
365366 </ div >
366367 </ div >
367368 < button
368- onClick = { ( ) => removeFromStack ( item . serverName , item . type , item . index ) }
369+ onClick = { ( e ) => {
370+ e . stopPropagation ( ) ;
371+ e . preventDefault ( ) ;
372+ removeFromStack ( item . serverName , item . type , item . index ) ;
373+ } }
369374 className = "p-1 hover:bg-destructive/10 rounded transition-colors"
370375 >
371376 < Trash2 className = "h-4 w-4 text-destructive" />
@@ -497,7 +502,7 @@ export default function App() {
497502
498503 { /* Loading/Error States */ }
499504 { loading && (
500- < p className = "flex items-center justify-center text-center text-muted-foreground gap-2" >
505+ < p className = "flex mt-4 items-center justify-center text-center text-muted-foreground gap-2" >
501506 < Spinner />
502507 < span > Loading servers...</ span >
503508 </ p >
0 commit comments