1- import { useState } from 'react' ;
2- import { useRegistry } from './hooks/useRegistry' ;
1+ import { useState , useEffect } from 'react' ;
32import { ServerCard } from './components/ServerCard' ;
4- import { PRESETS } from './presets' ;
53import './App.css' ;
64
75export default function App ( ) {
8- const [ activePreset , setActivePreset ] = useState ( PRESETS [ 0 ] ) ;
9- const [ customQuery , setCustomQuery ] = useState ( '' ) ;
6+ const [ servers , setServers ] = useState ( [ ] ) ;
7+ const [ loading , setLoading ] = useState ( true ) ;
8+ const [ error , setError ] = useState ( null ) ;
109
11- const search = customQuery . trim ( ) || activePreset . search ;
10+ const load = ( ) => {
11+ setLoading ( true ) ;
12+ setError ( null ) ;
13+ fetch ( './allowed-servers' )
14+ . then ( ( r ) => { if ( ! r . ok ) throw new Error ( `HTTP ${ r . status } ` ) ; return r . json ( ) ; } )
15+ . then ( ( d ) => setServers ( d . servers ?? [ ] ) )
16+ . catch ( ( e ) => setError ( e . message ) )
17+ . finally ( ( ) => setLoading ( false ) ) ;
18+ } ;
1219
13- const { servers , loading , error , refetch } = useRegistry ( search ) ;
20+ useEffect ( ( ) => { load ( ) ; } , [ ] ) ;
1421
1522 return (
1623 < div className = "app" >
1724 < header className = "app-header" >
1825 < div className = "header-content" >
1926 < div >
20- < h1 > MCP Registry Explorer </ h1 >
21- < p className = "subtitle" > Browse filtered MCP servers from the official registry </ p >
27+ < h1 > MCP Registry</ h1 >
28+ < p className = "subtitle" > Allowed MCP servers for this organization </ p >
2229 </ div >
2330 < a
2431 href = "https://registry.modelcontextprotocol.io"
@@ -32,51 +39,19 @@ export default function App() {
3239 </ header >
3340
3441 < main className = "app-main" >
35- < section className = "filter-section" >
36- < div className = "preset-tabs" >
37- { PRESETS . map ( ( preset ) => (
38- < button
39- key = { preset . id }
40- className = { `preset-tab ${ activePreset . id === preset . id && ! customQuery ? 'active' : '' } ` }
41- onClick = { ( ) => {
42- setActivePreset ( preset ) ;
43- setCustomQuery ( '' ) ;
44- } }
45- >
46- { preset . label }
47- </ button >
48- ) ) }
49- </ div >
50-
51- < div className = "custom-filter" >
52- < input
53- type = "text"
54- placeholder = "Custom search…"
55- value = { customQuery }
56- onChange = { ( e ) => setCustomQuery ( e . target . value ) }
57- />
58- </ div >
59-
60- < p className = "filter-description" >
61- { customQuery . trim ( ) ? `Searching for: "${ customQuery . trim ( ) } "` : activePreset . description }
62- </ p >
63- </ section >
64-
6542 { loading && (
66- < div className = "status" >
67- < span className = "spinner" /> Searching registry…
68- </ div >
43+ < div className = "status" > < span className = "spinner" /> Loading…</ div >
6944 ) }
7045
7146 { error && (
7247 < div className = "status error" >
73- Error: { error } — < button onClick = { refetch } > Retry</ button >
48+ Error: { error } — < button onClick = { load } > Retry</ button >
7449 </ div >
7550 ) }
7651
7752 { ! loading && ! error && (
7853 < div className = "results-header" >
79- < span > { servers . length } server{ servers . length !== 1 ? 's' : '' } found </ span >
54+ < span > { servers . length } allowed server{ servers . length !== 1 ? 's' : '' } </ span >
8055 </ div >
8156 ) }
8257
@@ -85,10 +60,6 @@ export default function App() {
8560 < ServerCard key = { `${ entry . server . name } :${ entry . server . version } ` } entry = { entry } />
8661 ) ) }
8762 </ div >
88-
89- { ! loading && ! error && servers . length === 0 && (
90- < div className = "empty" > No servers matched the current filter.</ div >
91- ) }
9263 </ main >
9364 </ div >
9465 ) ;
0 commit comments