diff --git a/web-app/src/containers/SettingsMenu.tsx b/web-app/src/containers/SettingsMenu.tsx index 7a543b03f..da0e94870 100644 --- a/web-app/src/containers/SettingsMenu.tsx +++ b/web-app/src/containers/SettingsMenu.tsx @@ -104,7 +104,7 @@ const SettingsMenu = () => { title: 'common:mcp-servers', route: route.settings.mcp_servers, hasSubMenu: false, - isEnabled: PlatformFeatures[PlatformFeature.MCP_SERVERS], + isEnabled: PlatformFeatures[PlatformFeature.MCP_SERVERS_SETTINGS], }, { title: 'common:local_api_server', @@ -122,7 +122,7 @@ const SettingsMenu = () => { title: 'common:extensions', route: route.settings.extensions, hasSubMenu: false, - isEnabled: PlatformFeatures[PlatformFeature.EXTENSION_MANAGEMENT], + isEnabled: PlatformFeatures[PlatformFeature.EXTENSIONS_SETTINGS], }, ] diff --git a/web-app/src/hooks/useToolApproval.ts b/web-app/src/hooks/useToolApproval.ts index 5edc5dddc..13529115d 100644 --- a/web-app/src/hooks/useToolApproval.ts +++ b/web-app/src/hooks/useToolApproval.ts @@ -1,6 +1,8 @@ import { create } from 'zustand' import { persist, createJSONStorage } from 'zustand/middleware' import { localStorageKey } from '@/constants/localStorage' +import { PlatformFeatures } from '@/lib/platform/const' +import { PlatformFeature } from '@/lib/platform/types' export type ToolApprovalModalProps = { toolName: string @@ -32,7 +34,7 @@ export const useToolApproval = create()( persist( (set, get) => ({ approvedTools: {}, - allowAllMCPPermissions: false, + allowAllMCPPermissions: PlatformFeatures[PlatformFeature.MCP_AUTO_APPROVE_TOOLS], isModalOpen: false, modalProps: null, @@ -55,6 +57,12 @@ export const useToolApproval = create()( showApprovalModal: (toolName: string, threadId: string, toolParameters?: object) => { return new Promise((resolve) => { + // Auto-approve MCP tools when feature is enabled + if (PlatformFeatures[PlatformFeature.MCP_AUTO_APPROVE_TOOLS]) { + resolve(true) + return + } + // Check if tool is already approved for this thread const state = get() if (state.isToolApproved(threadId, toolName)) { diff --git a/web-app/src/lib/platform/const.ts b/web-app/src/lib/platform/const.ts index f761b30f1..5192a6d1e 100644 --- a/web-app/src/lib/platform/const.ts +++ b/web-app/src/lib/platform/const.ts @@ -14,15 +14,9 @@ export const PlatformFeatures: Record = { // Hardware monitoring and GPU usage [PlatformFeature.HARDWARE_MONITORING]: isPlatformTauri(), - // Extension installation/management - [PlatformFeature.EXTENSION_MANAGEMENT]: true, - // Local model inference (llama.cpp) [PlatformFeature.LOCAL_INFERENCE]: isPlatformTauri(), - // MCP (Model Context Protocol) servers - [PlatformFeature.MCP_SERVERS]: true, - // Local API server [PlatformFeature.LOCAL_API_SERVER]: isPlatformTauri(), @@ -46,4 +40,13 @@ export const PlatformFeatures: Record = { // Model provider settings page management - disabled for web only [PlatformFeature.MODEL_PROVIDER_SETTINGS]: isPlatformTauri(), + + // Auto-enable MCP tool permissions - enabled for web platform + [PlatformFeature.MCP_AUTO_APPROVE_TOOLS]: !isPlatformTauri(), + + // MCP servers settings page - disabled for web + [PlatformFeature.MCP_SERVERS_SETTINGS]: isPlatformTauri(), + + // Extensions settings page - disabled for web + [PlatformFeature.EXTENSIONS_SETTINGS]: isPlatformTauri(), } \ No newline at end of file diff --git a/web-app/src/lib/platform/types.ts b/web-app/src/lib/platform/types.ts index 5aa0fe7f4..48d917cab 100644 --- a/web-app/src/lib/platform/types.ts +++ b/web-app/src/lib/platform/types.ts @@ -16,15 +16,9 @@ export enum PlatformFeature { // Hardware monitoring and GPU usage HARDWARE_MONITORING = 'hardwareMonitoring', - // Extension installation/management - EXTENSION_MANAGEMENT = 'extensionManagement', - // Local model inference (llama.cpp) LOCAL_INFERENCE = 'localInference', - // MCP (Model Context Protocol) servers - MCP_SERVERS = 'mcpServers', - // Local API server LOCAL_API_SERVER = 'localApiServer', @@ -48,4 +42,13 @@ export enum PlatformFeature { // Model provider settings page management MODEL_PROVIDER_SETTINGS = 'modelProviderSettings', + + // Auto-enable MCP tool permissions without approval + MCP_AUTO_APPROVE_TOOLS = 'mcpAutoApproveTools', + + // MCP servers settings page management + MCP_SERVERS_SETTINGS = 'mcpServersSettings', + + // Extensions settings page management + EXTENSIONS_SETTINGS = 'extensionsSettings', } diff --git a/web-app/src/routes/settings/extensions.tsx b/web-app/src/routes/settings/extensions.tsx index 9843d48b0..f278a44b2 100644 --- a/web-app/src/routes/settings/extensions.tsx +++ b/web-app/src/routes/settings/extensions.tsx @@ -18,7 +18,7 @@ export const Route = createFileRoute(route.settings.extensions as any)({ function Extensions() { return ( - + ) diff --git a/web-app/src/routes/settings/mcp-servers.tsx b/web-app/src/routes/settings/mcp-servers.tsx index 0eaa61696..0b95cf7ce 100644 --- a/web-app/src/routes/settings/mcp-servers.tsx +++ b/web-app/src/routes/settings/mcp-servers.tsx @@ -23,8 +23,6 @@ import { useTranslation } from '@/i18n/react-i18next-compat' import { useAppState } from '@/hooks/useAppState' import { PlatformGuard } from '@/lib/platform/PlatformGuard' import { PlatformFeature } from '@/lib/platform' -import { isPlatformTauri } from '@/lib/platform/utils' -import { MCPTool } from '@janhq/core' // Function to mask sensitive values const maskSensitiveValue = (value: string) => { @@ -92,118 +90,12 @@ export const Route = createFileRoute(route.settings.mcp_servers as any)({ function MCPServers() { return ( - - {isPlatformTauri() ? : } + + ) } -// Web version of MCP servers - simpler UI without server management -function MCPServersWeb() { - const { t } = useTranslation() - const serviceHub = useServiceHub() - const { allowAllMCPPermissions, setAllowAllMCPPermissions } = useToolApproval() - - const [webMcpTools, setWebMcpTools] = useState([]) - const [webMcpServers, setWebMcpServers] = useState([]) - const [webMcpLoading, setWebMcpLoading] = useState(true) - - useEffect(() => { - async function loadWebMcpData() { - setWebMcpLoading(true) - try { - const [tools, servers] = await Promise.all([ - serviceHub.mcp().getTools(), - serviceHub.mcp().getConnectedServers(), - ]) - setWebMcpTools(tools) - setWebMcpServers(servers) - } catch (error) { - console.error('Failed to load web MCP data:', error) - setWebMcpTools([]) - setWebMcpServers([]) - } finally { - setWebMcpLoading(false) - } - } - loadWebMcpData() - }, [serviceHub]) - - return ( -
- -

{t('common:settings')}

-
-
- -
-
- -

- {t('mcp-servers:title')} -

-

- MCP tools are automatically available in your chat sessions -

-
- } - > - - -
- } - /> - - - - 0 - ? `Connected to ${webMcpServers.join(', ')}. ${webMcpTools.length} tools available.` - : "MCP service not connected" - } - descriptionOutside={ - webMcpTools.length > 0 && !webMcpLoading && ( -
-

Available Tools:

-
- {webMcpTools.map((tool) => ( -
-
-
{tool.name}
-
{tool.description}
- {tool.server && ( -
Server: {tool.server}
- )} -
-
- ))} -
-
- ) - } - /> -
-
-
- - - ) -} - -// Desktop version of MCP servers - full server management capabilities function MCPServersDesktop() { const { t } = useTranslation() const serviceHub = useServiceHub() @@ -351,10 +243,12 @@ function MCPServersDesktop() { setLoadingServers((prev) => ({ ...prev, [serverKey]: true })) const config = getServerConfig(serverKey) if (active && config) { - serviceHub.mcp().activateMCPServer(serverKey, { - ...(config ?? (mcpServers[serverKey] as MCPServerConfig)), - active, - }) + serviceHub + .mcp() + .activateMCPServer(serverKey, { + ...(config ?? (mcpServers[serverKey] as MCPServerConfig)), + active, + }) .then(() => { // Save single server editServer(serverKey, { @@ -388,10 +282,13 @@ function MCPServersDesktop() { active, }) syncServers() - serviceHub.mcp().deactivateMCPServer(serverKey).finally(() => { - serviceHub.mcp().getConnectedServers().then(setConnectedServers) - setLoadingServers((prev) => ({ ...prev, [serverKey]: false })) - }) + serviceHub + .mcp() + .deactivateMCPServer(serverKey) + .finally(() => { + serviceHub.mcp().getConnectedServers().then(setConnectedServers) + setLoadingServers((prev) => ({ ...prev, [serverKey]: false })) + }) } } } diff --git a/web-app/src/test/setup.ts b/web-app/src/test/setup.ts index a542ffec9..9fb6d928d 100644 --- a/web-app/src/test/setup.ts +++ b/web-app/src/test/setup.ts @@ -11,17 +11,18 @@ expect.extend(matchers) vi.mock('@/lib/platform/const', () => ({ PlatformFeatures: { hardwareMonitoring: true, - extensionManagement: true, localInference: true, - mcpServers: true, localApiServer: true, modelHub: true, systemIntegrations: true, httpsProxy: true, defaultProviders: true, analytics: true, - webAutoModelSelection: true, + webAutoModelSelection: false, modelProviderSettings: true, + mcpAutoApproveTools: false, + mcpServersSettings: true, + extensionsSettings: true, } }))