import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useMcpTools, useMcpConfig, useExecuteMcpTool } from '@/api/mcp'; import { useMcpServers, useCreateMcpServer, useUpdateMcpServer, useDeleteMcpServer, useMcpServerTools, type McpServerConfigEntry, type McpServerConfigCreate, } from '@/api/mcpClient'; export function SettingsMcpPage() { const { t } = useTranslation(); const { data: toolsData, isLoading: toolsLoading } = useMcpTools(); const { data: config } = useMcpConfig(); const executeMutation = useExecuteMcpTool(); const { data: servers, isLoading: serversLoading } = useMcpServers(); const createMutation = useCreateMcpServer(); const updateMutation = useUpdateMcpServer(); const deleteMutation = useDeleteMcpServer(); const [showAddForm, setShowAddForm] = useState(false); const [editingServer, setEditingServer] = useState(null); const [selectedServerForTools, setSelectedServerForTools] = useState(null); const [formData, setFormData] = useState({ name: '', url: '', api_token: '', enabled: true, description: '' }); const [executeToolName, setExecuteToolName] = useState(''); const [executeArgs, setExecuteArgs] = useState('{}'); const [executeResult, setExecuteResult] = useState(null); const { data: serverTools } = useMcpServerTools(selectedServerForTools); const handleAddServer = async () => { try { await createMutation.mutateAsync(formData); setShowAddForm(false); setFormData({ name: '', url: '', api_token: '', enabled: true, description: '' }); } catch { /* error handled by mutation */ } }; const handleUpdateServer = async () => { if (!editingServer) return; try { await updateMutation.mutateAsync({ id: editingServer.id, payload: { name: formData.name, url: formData.url, api_token: formData.api_token, enabled: formData.enabled, description: formData.description }, }); setEditingServer(null); setShowAddForm(false); setFormData({ name: '', url: '', api_token: '', enabled: true, description: '' }); } catch { /* error handled by mutation */ } }; const handleDeleteServer = async (id: string) => { if (window.confirm(t('mcp.client.deleteConfirm'))) { await deleteMutation.mutateAsync(id); } }; const handleEditServer = (server: McpServerConfigEntry) => { setEditingServer(server); setFormData({ name: server.name, url: server.url, api_token: server.api_token || '', enabled: server.enabled, description: server.description || '' }); setShowAddForm(true); }; const handleExecuteTool = async () => { if (!executeToolName) return; try { const args = JSON.parse(executeArgs); const result = await executeMutation.mutateAsync({ toolName: executeToolName, args }); setExecuteResult(JSON.stringify(result, null, 2)); } catch (e) { setExecuteResult(`Error: ${e}`); } }; return (

{t('mcp.title')}

{/* MCP Server Section */}

{t('mcp.server.title')}

{t('mcp.server.description')}

{config && (
{t('mcp.server.serverName')}: {config.server_name}
{t('mcp.server.serverVersion')}: {config.server_version}
{t('mcp.server.protocolVersion')}: {config.protocol_version}
{t('mcp.server.authMethod')}: {config.auth_method}
{t('mcp.server.availableTools')}: {config.available_tools.join(', ')}
)} {toolsLoading ? (
Loading...
) : toolsData && toolsData.tools.length > 0 ? (
{toolsData.tools.map((tool) => ( ))}
{t('mcp.server.toolName')} {t('mcp.server.toolDescription')} {t('mcp.server.toolCategory')} {t('mcp.server.toolPermission')}
{tool.name} {tool.description} {tool.category} {tool.required_permission || '-'}
) : (
{t('mcp.server.noTools')}
)} {/* Tool Execution */}

{t('mcp.server.executeTool')}

setExecuteArgs(e.target.value)} placeholder={t('mcp.server.arguments')} className="flex-1 border border-secondary-300 rounded px-3 py-1.5 text-sm font-mono" />
{executeResult && (
{executeResult}
)}
{/* MCP Client Section */}

{t('mcp.client.title')}

{t('mcp.client.description')}

{showAddForm && (
setFormData({ ...formData, name: e.target.value })} className="w-full border border-secondary-300 rounded px-3 py-1.5 text-sm" />
setFormData({ ...formData, url: e.target.value })} className="w-full border border-secondary-300 rounded px-3 py-1.5 text-sm" />
setFormData({ ...formData, api_token: e.target.value })} className="w-full border border-secondary-300 rounded px-3 py-1.5 text-sm" />
setFormData({ ...formData, description: e.target.value })} className="w-full border border-secondary-300 rounded px-3 py-1.5 text-sm" />
setFormData({ ...formData, enabled: e.target.checked })} />
)} {serversLoading ? (
Loading...
) : servers && servers.length > 0 ? (
{servers.map((server) => ( ))}
{t('mcp.client.serverName')} {t('mcp.client.serverUrl')} {t('mcp.client.enabled')} {t('mcp.client.lastConnected')} Actions
{server.name} {server.url} {server.enabled ? '✓' : '✗'} {server.last_connected_at || '-'}
) : (
{t('mcp.client.noServers')}
)} {selectedServerForTools && serverTools && (

{t('mcp.client.tools')} ({serverTools.count})

{serverTools.tools.length > 0 ? (
    {serverTools.tools.map((tool) => (
  • {tool.name}: {tool.description}
  • ))}
) : ( {t('mcp.client.noTools')} )}
)}
); }