diff --git a/client/src/App.tsx b/client/src/App.tsx index 01d5552..313eb80 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -19,6 +19,7 @@ import ResourcesTab, { Resource } from "./components/ResourcesTab"; import NotificationsTab from "./components/NotificationsTab"; import PromptsTab, { Prompt } from "./components/PromptsTab"; import ToolsTab, { Tool as ToolType } from "./components/ToolsTab"; +import CommandHistory from "./components/CommandHistory"; const App = () => { const [socket, setSocket] = useState(null); @@ -39,6 +40,9 @@ const App = () => { "/Users/ashwin/code/example-servers/build/everything/index.js", ); const [mcpConnected, setMcpConnected] = useState(false); + const [commandHistory, setCommandHistory] = useState< + Array<{ command: string; response: string | null }> + >([]); useEffect(() => { const ws = new WebSocket("ws://localhost:3000"); @@ -55,25 +59,33 @@ const App = () => { if (message.type === "resources") { setResources(message.data.resources); setError(null); + updateCommandHistory(message); } else if (message.type === "resource") { setResourceContent(JSON.stringify(message.data, null, 2)); setError(null); + updateCommandHistory(message); } else if (message.type === "prompts") { setPrompts(message.data.prompts); setError(null); + updateCommandHistory(message); } else if (message.type === "prompt") { setPromptContent(JSON.stringify(message.data, null, 2)); setError(null); + updateCommandHistory(message); } else if (message.type === "tools") { setTools(message.data.tools); setError(null); + updateCommandHistory(message); } else if (message.type === "toolResult") { setToolResult(JSON.stringify(message.data, null, 2)); setError(null); + updateCommandHistory(message); } else if (message.type === "error") { setError(message.message); + updateCommandHistory(message); } else if (message.type === "connected") { setMcpConnected(true); + updateCommandHistory(message); } }; @@ -89,10 +101,29 @@ const App = () => { return () => ws.close(); }, []); + const updateCommandHistory = (response: unknown) => { + setCommandHistory((prev) => { + const lastCommand = prev[prev.length - 1]; + if (lastCommand && lastCommand.response === null) { + const updatedHistory = [...prev]; + updatedHistory[updatedHistory.length - 1] = { + ...lastCommand, + response: JSON.stringify(response), + }; + return updatedHistory; + } + return prev; + }); + }; + const sendWebSocketMessage = (message: object) => { if (socket) { console.log("Sending WebSocket message:", message); socket.send(JSON.stringify(message)); + setCommandHistory((prev) => [ + ...prev, + { command: JSON.stringify(message), response: null }, + ]); } }; @@ -136,97 +167,100 @@ const App = () => {

MCP Inspector

-
-
-

Connect MCP Server

-
- setCommand(e.target.value)} - /> - setArgs(e.target.value)} - /> - -
-
- {mcpConnected ? ( - - - - - Resources - - - - Prompts - - - - Requests - - - - Notifications - - - - Tools - - - - Console - - - -
- +
+
+

Connect MCP Server

+
+ setCommand(e.target.value)} /> - - setArgs(e.target.value)} /> - - - +
- - ) : ( -
-

- Connect to an MCP server to start inspecting -

- )} + {mcpConnected ? ( + + + + + Resources + + + + Prompts + + + + Requests + + + + Notifications + + + + Tools + + + + Console + + + +
+ + + + + + +
+
+ ) : ( +
+

+ Connect to an MCP server to start inspecting +

+
+ )} +
+
); }; diff --git a/client/src/components/CommandHistory.tsx b/client/src/components/CommandHistory.tsx new file mode 100644 index 0000000..853c17e --- /dev/null +++ b/client/src/components/CommandHistory.tsx @@ -0,0 +1,94 @@ +import { useState } from "react"; +import { Copy } from "lucide-react"; + +const CommandHistory = ({ + commandHistory, +}: { + commandHistory: Array<{ command: string; response: string | null }>; +}) => { + const [expandedCommands, setExpandedCommands] = useState<{ + [key: number]: boolean; + }>({}); + + const toggleCommandExpansion = (index: number) => { + setExpandedCommands((prev) => ({ ...prev, [index]: !prev[index] })); + }; + + const copyToClipboard = (text: string) => { + navigator.clipboard.writeText(text); + }; + + return ( +
+

Command History

+
    + {commandHistory + .slice() + .reverse() + .map((cmd, index) => ( +
  • +
    + toggleCommandExpansion(commandHistory.length - 1 - index) + } + > + + {commandHistory.length - index}.{" "} + {JSON.parse(cmd.command).type} + + + {expandedCommands[commandHistory.length - 1 - index] + ? "▼" + : "▶"} + +
    + {expandedCommands[commandHistory.length - 1 - index] && ( + <> +
    +
    + + Command: + + +
    +
    +                      {JSON.stringify(JSON.parse(cmd.command), null, 2)}
    +                    
    +
    + {cmd.response && ( +
    +
    + + Response: + + +
    +
    +                        {JSON.stringify(JSON.parse(cmd.response), null, 2)}
    +                      
    +
    + )} + + )} +
  • + ))} +
+
+ ); +}; + +export default CommandHistory;