@@ -19,6 +19,7 @@ import ResourcesTab, { Resource } from "./components/ResourcesTab";
19
19
import NotificationsTab from "./components/NotificationsTab" ;
20
20
import PromptsTab , { Prompt } from "./components/PromptsTab" ;
21
21
import ToolsTab , { Tool as ToolType } from "./components/ToolsTab" ;
22
+ import CommandHistory from "./components/CommandHistory" ;
22
23
23
24
const App = ( ) => {
24
25
const [ socket , setSocket ] = useState < WebSocket | null > ( null ) ;
@@ -39,6 +40,9 @@ const App = () => {
39
40
"/Users/ashwin/code/example-servers/build/everything/index.js" ,
40
41
) ;
41
42
const [ mcpConnected , setMcpConnected ] = useState < boolean > ( false ) ;
43
+ const [ commandHistory , setCommandHistory ] = useState <
44
+ Array < { command : string ; response : string | null } >
45
+ > ( [ ] ) ;
42
46
43
47
useEffect ( ( ) => {
44
48
const ws = new WebSocket ( "ws://localhost:3000" ) ;
@@ -55,25 +59,33 @@ const App = () => {
55
59
if ( message . type === "resources" ) {
56
60
setResources ( message . data . resources ) ;
57
61
setError ( null ) ;
62
+ updateCommandHistory ( message ) ;
58
63
} else if ( message . type === "resource" ) {
59
64
setResourceContent ( JSON . stringify ( message . data , null , 2 ) ) ;
60
65
setError ( null ) ;
66
+ updateCommandHistory ( message ) ;
61
67
} else if ( message . type === "prompts" ) {
62
68
setPrompts ( message . data . prompts ) ;
63
69
setError ( null ) ;
70
+ updateCommandHistory ( message ) ;
64
71
} else if ( message . type === "prompt" ) {
65
72
setPromptContent ( JSON . stringify ( message . data , null , 2 ) ) ;
66
73
setError ( null ) ;
74
+ updateCommandHistory ( message ) ;
67
75
} else if ( message . type === "tools" ) {
68
76
setTools ( message . data . tools ) ;
69
77
setError ( null ) ;
78
+ updateCommandHistory ( message ) ;
70
79
} else if ( message . type === "toolResult" ) {
71
80
setToolResult ( JSON . stringify ( message . data , null , 2 ) ) ;
72
81
setError ( null ) ;
82
+ updateCommandHistory ( message ) ;
73
83
} else if ( message . type === "error" ) {
74
84
setError ( message . message ) ;
85
+ updateCommandHistory ( message ) ;
75
86
} else if ( message . type === "connected" ) {
76
87
setMcpConnected ( true ) ;
88
+ updateCommandHistory ( message ) ;
77
89
}
78
90
} ;
79
91
@@ -89,10 +101,29 @@ const App = () => {
89
101
return ( ) => ws . close ( ) ;
90
102
} , [ ] ) ;
91
103
104
+ const updateCommandHistory = ( response : unknown ) => {
105
+ setCommandHistory ( ( prev ) => {
106
+ const lastCommand = prev [ prev . length - 1 ] ;
107
+ if ( lastCommand && lastCommand . response === null ) {
108
+ const updatedHistory = [ ...prev ] ;
109
+ updatedHistory [ updatedHistory . length - 1 ] = {
110
+ ...lastCommand ,
111
+ response : JSON . stringify ( response ) ,
112
+ } ;
113
+ return updatedHistory ;
114
+ }
115
+ return prev ;
116
+ } ) ;
117
+ } ;
118
+
92
119
const sendWebSocketMessage = ( message : object ) => {
93
120
if ( socket ) {
94
121
console . log ( "Sending WebSocket message:" , message ) ;
95
122
socket . send ( JSON . stringify ( message ) ) ;
123
+ setCommandHistory ( ( prev ) => [
124
+ ...prev ,
125
+ { command : JSON . stringify ( message ) , response : null } ,
126
+ ] ) ;
96
127
}
97
128
} ;
98
129
@@ -136,97 +167,100 @@ const App = () => {
136
167
< Sidebar connectionStatus = { connectionStatus } />
137
168
< div className = "flex-1 flex flex-col overflow-hidden" >
138
169
< h1 className = "text-2xl font-bold p-4" > MCP Inspector</ h1 >
139
- < div className = "flex-1 overflow-auto" >
140
- < div className = "p-4 bg-white shadow-md m-4 rounded-md" >
141
- < h2 className = "text-lg font-semibold mb-2" > Connect MCP Server</ h2 >
142
- < div className = "flex space-x-2 mb-2" >
143
- < Input
144
- placeholder = "Command"
145
- value = { command }
146
- onChange = { ( e ) => setCommand ( e . target . value ) }
147
- />
148
- < Input
149
- placeholder = "Arguments (space-separated)"
150
- value = { args }
151
- onChange = { ( e ) => setArgs ( e . target . value ) }
152
- />
153
- < Button onClick = { connectMcpServer } >
154
- < Play className = "w-4 h-4 mr-2" />
155
- Connect
156
- </ Button >
157
- </ div >
158
- </ div >
159
- { mcpConnected ? (
160
- < Tabs defaultValue = "resources" className = "w-full p-4" >
161
- < TabsList className = "mb-4 p-0" >
162
- < TabsTrigger value = "resources" >
163
- < Files className = "w-4 h-4 mr-2" />
164
- Resources
165
- </ TabsTrigger >
166
- < TabsTrigger value = "prompts" >
167
- < MessageSquare className = "w-4 h-4 mr-2" />
168
- Prompts
169
- </ TabsTrigger >
170
- < TabsTrigger value = "requests" disabled >
171
- < Send className = "w-4 h-4 mr-2" />
172
- Requests
173
- </ TabsTrigger >
174
- < TabsTrigger value = "notifications" disabled >
175
- < Bell className = "w-4 h-4 mr-2" />
176
- Notifications
177
- </ TabsTrigger >
178
- < TabsTrigger value = "tools" disabled >
179
- < Hammer className = "w-4 h-4 mr-2" />
180
- Tools
181
- </ TabsTrigger >
182
- < TabsTrigger value = "console" disabled >
183
- < Terminal className = "w-4 h-4 mr-2" />
184
- Console
185
- </ TabsTrigger >
186
- </ TabsList >
187
-
188
- < div className = "w-full" >
189
- < ResourcesTab
190
- resources = { resources }
191
- listResources = { listResources }
192
- readResource = { readResource }
193
- selectedResource = { selectedResource }
194
- setSelectedResource = { setSelectedResource }
195
- resourceContent = { resourceContent }
196
- error = { error }
170
+ < div className = "flex-1 overflow-auto flex" >
171
+ < div className = "flex-1" >
172
+ < div className = "p-4 bg-white shadow-md m-4 rounded-md" >
173
+ < h2 className = "text-lg font-semibold mb-2" > Connect MCP Server</ h2 >
174
+ < div className = "flex space-x-2 mb-2" >
175
+ < Input
176
+ placeholder = "Command"
177
+ value = { command }
178
+ onChange = { ( e ) => setCommand ( e . target . value ) }
197
179
/>
198
- < NotificationsTab />
199
- < PromptsTab
200
- prompts = { prompts }
201
- listPrompts = { listPrompts }
202
- getPrompt = { getPrompt }
203
- selectedPrompt = { selectedPrompt }
204
- setSelectedPrompt = { setSelectedPrompt }
205
- promptContent = { promptContent }
206
- error = { error }
180
+ < Input
181
+ placeholder = "Arguments (space-separated)"
182
+ value = { args }
183
+ onChange = { ( e ) => setArgs ( e . target . value ) }
207
184
/>
208
- < RequestsTab />
209
- < ToolsTab
210
- tools = { tools }
211
- listTools = { listTools }
212
- callTool = { callTool }
213
- selectedTool = { selectedTool }
214
- setSelectedTool = { setSelectedTool }
215
- toolResult = { toolResult }
216
- error = { error }
217
- />
218
- < ConsoleTab />
185
+ < Button onClick = { connectMcpServer } >
186
+ < Play className = "w-4 h-4 mr-2" />
187
+ Connect
188
+ </ Button >
219
189
</ div >
220
- </ Tabs >
221
- ) : (
222
- < div className = "flex items-center justify-center h-full" >
223
- < p className = "text-lg text-gray-500" >
224
- Connect to an MCP server to start inspecting
225
- </ p >
226
190
</ div >
227
- ) }
191
+ { mcpConnected ? (
192
+ < Tabs defaultValue = "resources" className = "w-full p-4" >
193
+ < TabsList className = "mb-4 p-0" >
194
+ < TabsTrigger value = "resources" >
195
+ < Files className = "w-4 h-4 mr-2" />
196
+ Resources
197
+ </ TabsTrigger >
198
+ < TabsTrigger value = "prompts" >
199
+ < MessageSquare className = "w-4 h-4 mr-2" />
200
+ Prompts
201
+ </ TabsTrigger >
202
+ < TabsTrigger value = "requests" disabled >
203
+ < Send className = "w-4 h-4 mr-2" />
204
+ Requests
205
+ </ TabsTrigger >
206
+ < TabsTrigger value = "notifications" disabled >
207
+ < Bell className = "w-4 h-4 mr-2" />
208
+ Notifications
209
+ </ TabsTrigger >
210
+ < TabsTrigger value = "tools" disabled >
211
+ < Hammer className = "w-4 h-4 mr-2" />
212
+ Tools
213
+ </ TabsTrigger >
214
+ < TabsTrigger value = "console" disabled >
215
+ < Terminal className = "w-4 h-4 mr-2" />
216
+ Console
217
+ </ TabsTrigger >
218
+ </ TabsList >
219
+
220
+ < div className = "w-full" >
221
+ < ResourcesTab
222
+ resources = { resources }
223
+ listResources = { listResources }
224
+ readResource = { readResource }
225
+ selectedResource = { selectedResource }
226
+ setSelectedResource = { setSelectedResource }
227
+ resourceContent = { resourceContent }
228
+ error = { error }
229
+ />
230
+ < NotificationsTab />
231
+ < PromptsTab
232
+ prompts = { prompts }
233
+ listPrompts = { listPrompts }
234
+ getPrompt = { getPrompt }
235
+ selectedPrompt = { selectedPrompt }
236
+ setSelectedPrompt = { setSelectedPrompt }
237
+ promptContent = { promptContent }
238
+ error = { error }
239
+ />
240
+ < RequestsTab />
241
+ < ToolsTab
242
+ tools = { tools }
243
+ listTools = { listTools }
244
+ callTool = { callTool }
245
+ selectedTool = { selectedTool }
246
+ setSelectedTool = { setSelectedTool }
247
+ toolResult = { toolResult }
248
+ error = { error }
249
+ />
250
+ < ConsoleTab />
251
+ </ div >
252
+ </ Tabs >
253
+ ) : (
254
+ < div className = "flex items-center justify-center h-full" >
255
+ < p className = "text-lg text-gray-500" >
256
+ Connect to an MCP server to start inspecting
257
+ </ p >
258
+ </ div >
259
+ ) }
260
+ </ div >
228
261
</ div >
229
262
</ div >
263
+ < CommandHistory commandHistory = { commandHistory } />
230
264
</ div >
231
265
) ;
232
266
} ;
0 commit comments