diff --git a/examples/inspector/src/components/McpServers.tsx b/examples/inspector/src/components/McpServers.tsx index 25a486d..7f0d28e 100644 --- a/examples/inspector/src/components/McpServers.tsx +++ b/examples/inspector/src/components/McpServers.tsx @@ -58,7 +58,7 @@ export function McpServers({ clearStorage: () => {}, }) const [toolForms, setToolForms] = useState>>({}) - const [executionLog, setExecutionLog] = useState('') + const [toolExecutionLogs, setToolExecutionLogs] = useState>({}) const logRef = useRef(null) const executionLogRef = useRef(null) @@ -218,27 +218,32 @@ export function McpServers({ // Add execution start message const startMessage = `Calling ${tool.name}(${argsStr})\n` - setExecutionLog(prev => prev + startMessage) + setToolExecutionLogs(prev => ({ + ...prev, + [tool.name]: (prev[tool.name] || '') + startMessage + })) try { const result = await connectionData.callTool(tool.name, args) const resultStr = typeof result === 'string' ? result : JSON.stringify(result, null, 2) - setExecutionLog(prev => prev + `${resultStr}\n\n`) + setToolExecutionLogs(prev => ({ + ...prev, + [tool.name]: (prev[tool.name] || '') + `${resultStr}\n\n` + })) } catch (error) { - setExecutionLog(prev => prev + `Error: ${error}\n\n`) + setToolExecutionLogs(prev => ({ + ...prev, + [tool.name]: (prev[tool.name] || '') + `Error: ${error}\n\n` + })) } - - // Auto-scroll to bottom - setTimeout(() => { - if (executionLogRef.current) { - executionLogRef.current.scrollTop = executionLogRef.current.scrollHeight - } - }, 0) } - // Clear execution log - const clearExecutionLog = () => { - setExecutionLog('') + // Clear execution log for specific tool + const clearExecutionLog = (toolName: string) => { + setToolExecutionLogs(prev => ({ + ...prev, + [toolName]: '' + })) } // Render form field based on schema @@ -249,13 +254,15 @@ export function McpServers({ return ( handleFormChange(toolName, fieldName, - schema.type === 'integer' ? parseInt(e.target.value) || 0 : parseFloat(e.target.value) || 0 - )} + onChange={(e) => { + const newValue = e.target.value === '' ? '' : + (schema.type === 'integer' ? parseInt(e.target.value) || 0 : parseFloat(e.target.value) || 0) + handleFormChange(toolName, fieldName, newValue) + }} /> ) } else if (schema.type === 'boolean') { @@ -272,7 +279,7 @@ export function McpServers({ return ( ) : ( -
+
{tools.map((tool: Tool, index: number) => ( -
-
+
+ {/* Tool title outside the card */} +

{tool.name} -

- {tool.description && ( -

- {tool.description} -

- )} + - {/* Form for tool parameters */} - {tool.inputSchema && tool.inputSchema.properties && ( -
- {Object.entries(tool.inputSchema.properties).map(([fieldName, schema]: [string, any]) => { - const isRequired = tool.inputSchema.required?.includes(fieldName) || false - return ( -
-
- - {schema.description && ( -
- -
- {schema.description} +
+ {tool.description && ( +

+ {tool.description} +

+ )} + + {/* Form for tool parameters */} + {tool.inputSchema && tool.inputSchema.properties && ( +
+ {Object.entries(tool.inputSchema.properties).map(([fieldName, schema]: [string, any]) => { + const isRequired = tool.inputSchema.required?.includes(fieldName) || false + return ( +
+
+ + {schema.description && ( +
+ +
+ {schema.description} +
-
- )} + )} +
+
+ {renderFormField(tool.name, fieldName, schema, isRequired)} +
-
- {renderFormField(tool.name, fieldName, schema, isRequired)} -
-
- ) - })} + ) + })} +
+ )} + + {/* Run button */} + + + {/* Per-tool execution log */} +
+
+
Execution Log
+ +
+