PrometheusGroup/filemaster-control-panel
0
1 2const TOOLS = [3 { value: 'list_files', label: 'List Files', description: 'Lists files and directories in a given path.', params: [{ name: 'path', type: 'text', label: 'Directory Path' }] },4 { value: 'read_file', label: 'Read File', description: 'Reads the content of a specific file.', params: [{ name: 'path', type: 'text', label: 'File Path' }] },5 { value: 'create_file', label: 'Create File', description: 'Creates a new file with optional content.', params: [{ name: 'path', type: 'text', label: 'New File Path' }, { name: 'content', type: 'textarea', label: 'Initial Content (optional)' }] },6 { value: 'write_file', label: 'Write to File', description: 'Writes content to a file, creating a backup first.', params: [{ name: 'path', type: 'text', label: 'File Path' }, { name: 'content', type: 'textarea', label: 'New Content' }] },7 { value: 'delete_file', label: 'Delete File', description: 'Deletes a specific file.', params: [{ name: 'path', type: 'text', label: 'File to Delete' }] },8 { value: 'identify_log_errors', label: 'Identify Log Errors', description: 'Scans a log file for common error messages.', params: [{ name: 'log_file_path', type: 'text', label: 'Log File Path' }] },9];10 11function App() {12 const [selectedTool, setSelectedTool] = React.useState(TOOLS[0].value);13 const [parameters, setParameters] = React.useState({ path: 'C:\\temp' });14 const [isLoading, setIsLoading] = React.useState(false);15 const [response, setResponse] = React.useState(null);16 const [error, setError] = React.useState('');17 18 const currentTool = React.useMemo(() => TOOLS.find(t => t.value === selectedTool), [selectedTool]);19 20 const handleToolChange = (e) => {21 const newToolName = e.target.value;22 setSelectedTool(newToolName);23 setParameters({});24 setResponse(null);25 setError('');26 };27 28 const handleParamChange = (name, value) => {29 setParameters(prev => ({ ...prev, [name]: value }));30 };31 32 const handleSubmit = async (e) => {33 e.preventDefault();34 setIsLoading(true);35 setResponse(null);36 setError('');37 38 const invocation_id = `mcp-ui-${Date.now()}`;39 const endpoint = `http://127.0.0.1:8000/mcp/invoke/${selectedTool}`;40 41 try {42 const res = await fetch(endpoint, {43 method: 'POST',44 headers: { 'Content-Type': 'application/json' },45 body: JSON.stringify({46 tool_name: selectedTool,47 invocation_id,48 parameters,49 }),50 });51 52 const data = await res.json();53 if (!res.ok || data.result?.status === 'error') {54 throw new Error(data.result?.message || `Server responded with status: ${res.status}`);55 }56 setResponse(data);57 } catch (err) {58 setError(err instanceof Error ? err.message : 'An unknown error occurred.');59 } finally {60 setIsLoading(false);61 }62 };63 64 return (65 <div className="container">66 <header>67 <h1>MCP Toolkit Control Panel</h1>68 <p>A client to interact with the Maintenance & Control Program toolkit server.</p>69 </header>70 71 <main>72 <div className="card form-card">73 <h2>Select a Tool</h2>74 <form onSubmit={handleSubmit}>75 <div className="form-group">76 <label htmlFor="tool-select">Tool</label>77 <select id="tool-select" value={selectedTool} onChange={handleToolChange}>78 {TOOLS.map(tool => (79 <option key={tool.value} value={tool.value}>{tool.label}</option>80 ))}81 </select>82 <p>{currentTool.description}</p>83 </div>84 85 {currentTool.params.map(param => (86 <div className="form-group" key={param.name}>87 <label htmlFor={param.name}>{param.label}</label>88 {param.type === 'textarea' ? (89 <textarea90 id={param.name}91 value={parameters[param.name] || ''}92 onChange={(e) => handleParamChange(param.name, e.target.value)}93 required94 />95 ) : (96 <input97 id={param.name}98 type="text"99 value={parameters[param.name] || ''}100 onChange={(e) => handleParamChange(param.name, e.target.value)}101 required102 />103 )}104 </div>105 ))}106 107 <button type="submit" disabled={isLoading}>108 {isLoading ? 'Running...' : `Run: ${currentTool.label}`}109 </button>110 </form>111 </div>112 113 {isLoading && (114 <div className="card status-card">115 <div className="loader">116 <span></span>117 <span></span>118 <span></span>119 </div>120 <p>Communicating with MCP Server...</p>121 </div>122 )}123 124 {error && (125 <div className="card result-card error">126 <h2>Error</h2>127 <pre>{error}</pre>128 </div>129 )}130 131 {response && (132 <div className="card result-card success">133 <h2>Result for Invocation: {response.invocation_id}</h2>134 <pre>{JSON.stringify(response.result, null, 2)}</pre>135 </div>136 )}137 </main>138 </div>139 );140}141 142const root = ReactDOM.createRoot(document.getElementById('root'));143root.render(<App />);144 145 146 