2
2
3
3
import { useState } from 'react' ;
4
4
import { useMCP } from '@/contexts/MCPContext' ;
5
+ import { MCPMessageMonitor } from './MCPMessageMonitor' ;
5
6
6
7
export function MCPTab ( ) {
7
8
const { connections, addMcpServer, removeMcpServer, reconnectServer, isLoading } = useMCP ( ) ;
8
9
const [ showAddForm , setShowAddForm ] = useState ( false ) ;
9
10
const [ newServerName , setNewServerName ] = useState ( '' ) ;
10
11
const [ newServerUrl , setNewServerUrl ] = useState ( '' ) ;
11
12
const [ authType , setAuthType ] = useState < 'none' | 'oauth' > ( 'none' ) ;
13
+
14
+ // Collapsible section states
15
+ const [ showSummary , setShowSummary ] = useState ( true ) ;
16
+ const [ showAddServers , setShowAddServers ] = useState ( true ) ;
17
+ const [ showServerList , setShowServerList ] = useState ( true ) ;
12
18
13
19
const handleAddExampleServer = async ( ) => {
14
20
try {
@@ -73,50 +79,75 @@ export function MCPTab() {
73
79
const allTools = connections . flatMap ( conn => conn . tools ) ;
74
80
75
81
return (
76
- < div className = "flex-1 flex flex-col overflow-hidden" >
82
+ < div className = "h-full flex flex-col overflow-hidden" >
77
83
{ /* Summary */ }
78
- < div className = "p-4 border-b border-gray-200 dark:border-gray-700" >
79
- < div className = "bg-gray-50 dark:bg-gray-700 rounded-lg p-3" >
80
- < h3 className = "font-medium text-gray-900 dark:text-white mb-2" >
81
- MCP Summary
82
- </ h3 >
83
- < div className = "text-sm space-y-1 " >
84
- < p className = "text-gray-700 dark:text-gray-300 " >
85
- < span className = "font-medium" > { connectedServers . length } </ span > servers connected
86
- </ p >
87
- < p className = "text-gray-700 dark:text-gray-300 " >
88
- < span className = "font-medium" > { allTools . length } </ span > tools available
89
- </ p >
84
+ < div className = "border-b border-gray-200 dark:border-gray-700" >
85
+ < button
86
+ onClick = { ( ) => setShowSummary ( ! showSummary ) }
87
+ className = "w-full p-4 text-left hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors"
88
+ >
89
+ < div className = "flex items-center justify-between " >
90
+ < h3 className = "font-medium text-gray-900 dark:text-white " >
91
+ MCP Summary
92
+ </ h3 >
93
+ < span className = "text-gray-500 dark:text-gray-400 " >
94
+ { showSummary ? '−' : '+' }
95
+ </ span >
90
96
</ div >
91
- </ div >
97
+ </ button >
98
+ { showSummary && (
99
+ < div className = "px-4 pb-4" >
100
+ < div className = "bg-gray-50 dark:bg-gray-700 rounded-lg p-3" >
101
+ < div className = "text-sm space-y-1" >
102
+ < p className = "text-gray-700 dark:text-gray-300" >
103
+ < span className = "font-medium" > { connectedServers . length } </ span > servers connected
104
+ </ p >
105
+ < p className = "text-gray-700 dark:text-gray-300" >
106
+ < span className = "font-medium" > { allTools . length } </ span > tools available
107
+ </ p >
108
+ </ div >
109
+ </ div >
110
+ </ div >
111
+ ) }
92
112
</ div >
93
113
94
114
{ /* Add Servers Section */ }
95
- < div className = "p-4 border-b border-gray-200 dark:border-gray-700" >
96
- < h3 className = "font-medium text-gray-900 dark:text-white mb-3" >
97
- Add Servers
98
- </ h3 >
99
-
100
- { /* Example Server Button */ }
115
+ < div className = "border-b border-gray-200 dark:border-gray-700" >
101
116
< button
102
- onClick = { handleAddExampleServer }
103
- disabled = { isLoading || connections . some ( conn => conn . name === 'Example Server' ) }
104
- className = "w-full mb-3 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
117
+ onClick = { ( ) => setShowAddServers ( ! showAddServers ) }
118
+ className = "w-full p-4 text-left hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors"
105
119
>
106
- { connections . some ( conn => conn . name === 'Example Server' ) ? 'Example Server Added' : 'Add Example Server' }
120
+ < div className = "flex items-center justify-between" >
121
+ < h3 className = "font-medium text-gray-900 dark:text-white" >
122
+ Add Servers
123
+ </ h3 >
124
+ < span className = "text-gray-500 dark:text-gray-400" >
125
+ { showAddServers ? '−' : '+' }
126
+ </ span >
127
+ </ div >
107
128
</ button >
129
+ { showAddServers && (
130
+ < div className = "px-4 pb-4 space-y-3" >
131
+ { /* Example Server Button */ }
132
+ < button
133
+ onClick = { handleAddExampleServer }
134
+ disabled = { isLoading || connections . some ( conn => conn . name === 'Example Server' ) }
135
+ className = "w-full px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
136
+ >
137
+ { connections . some ( conn => conn . name === 'Example Server' ) ? 'Example Server Added' : 'Add Example Server' }
138
+ </ button >
108
139
109
- { /* Custom Server Form Toggle */ }
110
- < button
111
- onClick = { ( ) => setShowAddForm ( ! showAddForm ) }
112
- className = "w-full px-4 py-2 text-sm bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors"
113
- >
114
- { showAddForm ? 'Cancel' : 'Add Custom Server' }
115
- </ button >
140
+ { /* Custom Server Form Toggle */ }
141
+ < button
142
+ onClick = { ( ) => setShowAddForm ( ! showAddForm ) }
143
+ className = "w-full px-4 py-2 text-sm bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors"
144
+ >
145
+ { showAddForm ? 'Cancel' : 'Add Custom Server' }
146
+ </ button >
116
147
117
- { /* Custom Server Form */ }
118
- { showAddForm && (
119
- < form onSubmit = { handleAddCustomServer } className = "mt-3 space-y-3" >
148
+ { /* Custom Server Form */ }
149
+ { showAddForm && (
150
+ < form onSubmit = { handleAddCustomServer } className = "space-y-3" >
120
151
< div >
121
152
< label className = "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1" >
122
153
Server Name
@@ -168,15 +199,27 @@ export function MCPTab() {
168
199
</ button >
169
200
</ form >
170
201
) }
202
+ </ div >
203
+ ) }
171
204
</ div >
172
205
173
206
{ /* Server List */ }
174
- < div className = "flex-1 overflow-y-auto p-4" >
175
- < div className = "flex items-center justify-between mb-3" >
176
- < h3 className = "font-medium text-gray-900 dark:text-white" >
177
- Servers ({ connections . length } )
178
- </ h3 >
179
- </ div >
207
+ < div className = "flex-shrink-0" >
208
+ < button
209
+ onClick = { ( ) => setShowServerList ( ! showServerList ) }
210
+ className = "w-full p-4 text-left hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors border-b border-gray-200 dark:border-gray-700"
211
+ >
212
+ < div className = "flex items-center justify-between" >
213
+ < h3 className = "font-medium text-gray-900 dark:text-white" >
214
+ Servers ({ connections . length } )
215
+ </ h3 >
216
+ < span className = "text-gray-500 dark:text-gray-400" >
217
+ { showServerList ? '−' : '+' }
218
+ </ span >
219
+ </ div >
220
+ </ button >
221
+ { showServerList && (
222
+ < div className = "max-h-60 overflow-y-auto p-4" >
180
223
181
224
{ connections . length === 0 ? (
182
225
< p className = "text-sm text-gray-500 dark:text-gray-400" >
@@ -258,7 +301,12 @@ export function MCPTab() {
258
301
) ) }
259
302
</ div >
260
303
) }
304
+ </ div >
305
+ ) }
261
306
</ div >
307
+
308
+ { /* Message Monitor */ }
309
+ < MCPMessageMonitor />
262
310
</ div >
263
311
) ;
264
312
}
0 commit comments