11import { Client } from "@modelcontextprotocol/sdk/client/index.js" ;
22import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js" ;
33import {
4- CompatibilityCallToolResultSchema ,
4+ ClientNotification ,
55 ClientRequest ,
6+ CompatibilityCallToolResult ,
7+ CompatibilityCallToolResultSchema ,
68 CreateMessageRequestSchema ,
79 CreateMessageResult ,
810 EmptyResultSchema ,
@@ -19,8 +21,6 @@ import {
1921 Root ,
2022 ServerNotification ,
2123 Tool ,
22- CompatibilityCallToolResult ,
23- ClientNotification ,
2424} from "@modelcontextprotocol/sdk/types.js" ;
2525import { useCallback , useEffect , useRef , useState } from "react" ;
2626// Add dark mode class based on system preference
@@ -32,21 +32,21 @@ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
3232import {
3333 Bell ,
3434 Files ,
35+ FolderTree ,
3536 Hammer ,
3637 Hash ,
3738 MessageSquare ,
3839 Send ,
3940 Terminal ,
40- FolderTree ,
4141} from "lucide-react" ;
4242
43+ import { toast } from "react-toastify" ;
4344import { ZodType } from "zod" ;
4445import "./App.css" ;
4546import ConsoleTab from "./components/ConsoleTab" ;
4647import HistoryAndNotifications from "./components/History" ;
4748import PingTab from "./components/PingTab" ;
4849import PromptsTab , { Prompt } from "./components/PromptsTab" ;
49- import RequestsTab from "./components/RequestsTabs" ;
5050import ResourcesTab from "./components/ResourcesTab" ;
5151import RootsTab from "./components/RootsTab" ;
5252import SamplingTab , { PendingRequest } from "./components/SamplingTab" ;
@@ -67,7 +67,11 @@ const App = () => {
6767 const [ tools , setTools ] = useState < Tool [ ] > ( [ ] ) ;
6868 const [ toolResult , setToolResult ] =
6969 useState < CompatibilityCallToolResult | null > ( null ) ;
70- const [ error , setError ] = useState < string | null > ( null ) ;
70+ const [ errors , setErrors ] = useState < Record < string , string | null > > ( {
71+ resources : null ,
72+ prompts : null ,
73+ tools : null ,
74+ } ) ;
7175 const [ command , setCommand ] = useState < string > ( ( ) => {
7276 return localStorage . getItem ( "lastCommand" ) || "mcp-server-everything" ;
7377 } ) ;
@@ -202,9 +206,14 @@ const App = () => {
202206 ] ) ;
203207 } ;
204208
209+ const clearError = ( tabKey : keyof typeof errors ) => {
210+ setErrors ( ( prev ) => ( { ...prev , [ tabKey ] : null } ) ) ;
211+ } ;
212+
205213 const makeRequest = async < T extends ZodType < object > > (
206214 request : ClientRequest ,
207215 schema : T ,
216+ tabKey ?: keyof typeof errors ,
208217 ) => {
209218 if ( ! mcpClient ) {
210219 throw new Error ( "MCP client not connected" ) ;
@@ -213,9 +222,19 @@ const App = () => {
213222 try {
214223 const response = await mcpClient . request ( request , schema ) ;
215224 pushHistory ( request , response ) ;
225+
226+ if ( tabKey !== undefined ) {
227+ clearError ( tabKey ) ;
228+ }
229+
216230 return response ;
217231 } catch ( e : unknown ) {
218- setError ( ( e as Error ) . message ) ;
232+ if ( tabKey === undefined ) {
233+ toast . error ( ( e as Error ) . message ) ;
234+ } else {
235+ setErrors ( ( prev ) => ( { ...prev , [ tabKey ] : ( e as Error ) . message } ) ) ;
236+ }
237+
219238 throw e ;
220239 }
221240 } ;
@@ -229,7 +248,7 @@ const App = () => {
229248 await mcpClient . notification ( notification ) ;
230249 pushHistory ( notification ) ;
231250 } catch ( e : unknown ) {
232- setError ( ( e as Error ) . message ) ;
251+ toast . error ( ( e as Error ) . message ) ;
233252 throw e ;
234253 }
235254 } ;
@@ -241,6 +260,7 @@ const App = () => {
241260 params : nextResourceCursor ? { cursor : nextResourceCursor } : { } ,
242261 } ,
243262 ListResourcesResultSchema ,
263+ "resources" ,
244264 ) ;
245265 setResources ( resources . concat ( response . resources ?? [ ] ) ) ;
246266 setNextResourceCursor ( response . nextCursor ) ;
@@ -255,6 +275,7 @@ const App = () => {
255275 : { } ,
256276 } ,
257277 ListResourceTemplatesResultSchema ,
278+ "resources" ,
258279 ) ;
259280 setResourceTemplates (
260281 resourceTemplates . concat ( response . resourceTemplates ?? [ ] ) ,
@@ -269,6 +290,7 @@ const App = () => {
269290 params : { uri } ,
270291 } ,
271292 ReadResourceResultSchema ,
293+ "resources" ,
272294 ) ;
273295 setResourceContent ( JSON . stringify ( response , null , 2 ) ) ;
274296 } ;
@@ -280,6 +302,7 @@ const App = () => {
280302 params : nextPromptCursor ? { cursor : nextPromptCursor } : { } ,
281303 } ,
282304 ListPromptsResultSchema ,
305+ "prompts" ,
283306 ) ;
284307 setPrompts ( response . prompts ) ;
285308 setNextPromptCursor ( response . nextCursor ) ;
@@ -292,6 +315,7 @@ const App = () => {
292315 params : { name, arguments : args } ,
293316 } ,
294317 GetPromptResultSchema ,
318+ "prompts" ,
295319 ) ;
296320 setPromptContent ( JSON . stringify ( response , null , 2 ) ) ;
297321 } ;
@@ -303,6 +327,7 @@ const App = () => {
303327 params : nextToolCursor ? { cursor : nextToolCursor } : { } ,
304328 } ,
305329 ListToolsResultSchema ,
330+ "tools" ,
306331 ) ;
307332 setTools ( response . tools ) ;
308333 setNextToolCursor ( response . nextCursor ) ;
@@ -321,6 +346,7 @@ const App = () => {
321346 } ,
322347 } ,
323348 CompatibilityCallToolResultSchema ,
349+ "tools" ,
324350 ) ;
325351 setToolResult ( response ) ;
326352 } ;
@@ -445,39 +471,66 @@ const App = () => {
445471 < ResourcesTab
446472 resources = { resources }
447473 resourceTemplates = { resourceTemplates }
448- listResources = { listResources }
449- listResourceTemplates = { listResourceTemplates }
450- readResource = { readResource }
474+ listResources = { ( ) => {
475+ clearError ( "resources" ) ;
476+ listResources ( ) ;
477+ } }
478+ listResourceTemplates = { ( ) => {
479+ clearError ( "resources" ) ;
480+ listResourceTemplates ( ) ;
481+ } }
482+ readResource = { ( uri ) => {
483+ clearError ( "resources" ) ;
484+ readResource ( uri ) ;
485+ } }
451486 selectedResource = { selectedResource }
452- setSelectedResource = { setSelectedResource }
487+ setSelectedResource = { ( resource ) => {
488+ clearError ( "resources" ) ;
489+ setSelectedResource ( resource ) ;
490+ } }
453491 resourceContent = { resourceContent }
454492 nextCursor = { nextResourceCursor }
455493 nextTemplateCursor = { nextResourceTemplateCursor }
456- error = { error }
494+ error = { errors . resources }
457495 />
458496 < PromptsTab
459497 prompts = { prompts }
460- listPrompts = { listPrompts }
461- getPrompt = { getPrompt }
498+ listPrompts = { ( ) => {
499+ clearError ( "prompts" ) ;
500+ listPrompts ( ) ;
501+ } }
502+ getPrompt = { ( name , args ) => {
503+ clearError ( "prompts" ) ;
504+ getPrompt ( name , args ) ;
505+ } }
462506 selectedPrompt = { selectedPrompt }
463- setSelectedPrompt = { setSelectedPrompt }
507+ setSelectedPrompt = { ( prompt ) => {
508+ clearError ( "prompts" ) ;
509+ setSelectedPrompt ( prompt ) ;
510+ } }
464511 promptContent = { promptContent }
465512 nextCursor = { nextPromptCursor }
466- error = { error }
513+ error = { errors . prompts }
467514 />
468- < RequestsTab />
469515 < ToolsTab
470516 tools = { tools }
471- listTools = { listTools }
472- callTool = { callTool }
517+ listTools = { ( ) => {
518+ clearError ( "tools" ) ;
519+ listTools ( ) ;
520+ } }
521+ callTool = { ( name , params ) => {
522+ clearError ( "tools" ) ;
523+ callTool ( name , params ) ;
524+ } }
473525 selectedTool = { selectedTool }
474526 setSelectedTool = { ( tool ) => {
527+ clearError ( "tools" ) ;
475528 setSelectedTool ( tool ) ;
476529 setToolResult ( null ) ;
477530 } }
478531 toolResult = { toolResult }
479532 nextCursor = { nextToolCursor }
480- error = { error }
533+ error = { errors . tools }
481534 />
482535 < ConsoleTab />
483536 < PingTab
0 commit comments