From 733d2a6e6ecb325729d7b2258da4b7285b8bcebe Mon Sep 17 00:00:00 2001 From: Justin Spahr-Summers Date: Tue, 12 Nov 2024 13:32:12 +0000 Subject: [PATCH] Separate error states per tab Resolves #40. --- client/src/App.tsx | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/client/src/App.tsx b/client/src/App.tsx index e90090f..33e2726 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -79,7 +79,11 @@ const App = () => { const [tools, setTools] = useState([]); const [toolResult, setToolResult] = useState(null); - const [error, setError] = useState(null); + const [errors, setErrors] = useState>({ + resources: null, + prompts: null, + tools: null, + }); const [command, setCommand] = useState(() => { return localStorage.getItem("lastCommand") || "mcp-server-everything"; }); @@ -175,17 +179,19 @@ const App = () => { const makeRequest = async >( request: ClientRequest, schema: T, + tabKey: keyof typeof errors ) => { if (!mcpClient) { throw new Error("MCP client not connected"); } - + try { const response = await mcpClient.request(request, schema); pushHistory(request, response); + setErrors(prev => ({ ...prev, [tabKey]: null })); return response; } catch (e: unknown) { - setError((e as Error).message); + setErrors(prev => ({ ...prev, [tabKey]: (e as Error).message })); throw e; } }; @@ -211,11 +217,12 @@ const App = () => { params: nextResourceCursor ? { cursor: nextResourceCursor } : {}, }, ListResourcesResultSchema, + 'resources' ); setResources(resources.concat(response.resources ?? [])); setNextResourceCursor(response.nextCursor); }; - + const listResourceTemplates = async () => { const response = await makeRequest( { @@ -225,13 +232,14 @@ const App = () => { : {}, }, ListResourceTemplatesResultSchema, + 'resources' ); setResourceTemplates( resourceTemplates.concat(response.resourceTemplates ?? []), ); setNextResourceTemplateCursor(response.nextCursor); }; - + const readResource = async (uri: string) => { const response = await makeRequest( { @@ -239,6 +247,7 @@ const App = () => { params: { uri }, }, ReadResourceResultSchema, + 'resources' ); setResourceContent(JSON.stringify(response, null, 2)); }; @@ -250,11 +259,12 @@ const App = () => { params: nextPromptCursor ? { cursor: nextPromptCursor } : {}, }, ListPromptsResultSchema, + 'prompts' ); setPrompts(response.prompts); setNextPromptCursor(response.nextCursor); }; - + const getPrompt = async (name: string, args: Record = {}) => { const response = await makeRequest( { @@ -262,6 +272,7 @@ const App = () => { params: { name, arguments: args }, }, GetPromptResultSchema, + 'prompts' ); setPromptContent(JSON.stringify(response, null, 2)); }; @@ -273,11 +284,12 @@ const App = () => { params: nextToolCursor ? { cursor: nextToolCursor } : {}, }, ListToolsResultSchema, + 'tools' ); setTools(response.tools); setNextToolCursor(response.nextCursor); }; - + const callTool = async (name: string, params: Record) => { const response = await makeRequest( { @@ -291,6 +303,7 @@ const App = () => { }, }, CompatibilityCallToolResultSchema, + 'tools' ); setToolResult(response); }; @@ -515,7 +528,7 @@ const App = () => { resourceContent={resourceContent} nextCursor={nextResourceCursor} nextTemplateCursor={nextResourceTemplateCursor} - error={error} + error={errors.resources} /> { setSelectedPrompt={setSelectedPrompt} promptContent={promptContent} nextCursor={nextPromptCursor} - error={error} + error={errors.prompts} /> - { }} toolResult={toolResult} nextCursor={nextToolCursor} - error={error} + error={errors.tools} />