// MCP Manager View // Renders the MCP server management interface async function renderMcpManager() { const container = document.getElementById('mainContent'); if (!container) return; // Hide stats grid and search for MCP view const statsGrid = document.getElementById('statsGrid'); const searchInput = document.getElementById('searchInput'); if (statsGrid) statsGrid.style.display = 'none'; if (searchInput) searchInput.parentElement.style.display = 'none'; // Load MCP config if not already loaded if (!mcpConfig) { await loadMcpConfig(); } const currentPath = projectPath.replace(/\//g, '\\'); const projectData = mcpAllProjects[currentPath] || {}; const projectServers = projectData.mcpServers || {}; const disabledServers = projectData.disabledMcpServers || []; // Get all available servers from all projects const allAvailableServers = getAllAvailableMcpServers(); // Separate current project servers and available servers const currentProjectServerNames = Object.keys(projectServers); // Separate global servers and project servers that are not in current project const globalServerEntries = Object.entries(mcpGlobalServers) .filter(([name]) => !currentProjectServerNames.includes(name)); const otherProjectServers = Object.entries(allAvailableServers) .filter(([name, info]) => !currentProjectServerNames.includes(name) && !info.isGlobal); container.innerHTML = `

Current Project MCP Servers

${currentProjectServerNames.length} servers configured
${currentProjectServerNames.length === 0 ? `
🔌

No MCP servers configured for this project

Add servers from the available list below

` : `
${currentProjectServerNames.map(serverName => { const serverConfig = projectServers[serverName]; const isEnabled = !disabledServers.includes(serverName); return renderMcpServerCard(serverName, serverConfig, isEnabled, true); }).join('')}
`}
${globalServerEntries.length > 0 ? `
🌐

Global MCP Servers

${globalServerEntries.length} servers from ~/.claude/settings
${globalServerEntries.map(([serverName, serverConfig]) => { return renderGlobalServerCard(serverName, serverConfig); }).join('')}
` : ''}

Available from Other Projects

${otherProjectServers.length} servers available
${otherProjectServers.length === 0 ? `

No additional MCP servers found in other projects

` : `
${otherProjectServers.map(([serverName, serverInfo]) => { return renderAvailableServerCard(serverName, serverInfo); }).join('')}
`}

All Projects MCP Overview

${Object.keys(mcpAllProjects).length} projects
${Object.entries(mcpAllProjects).map(([path, config]) => { const servers = config.mcpServers || {}; const projectDisabled = config.disabledMcpServers || []; const serverNames = Object.keys(servers); const isCurrentProject = path === currentPath; const enabledCount = serverNames.filter(s => !projectDisabled.includes(s)).length; return ` `; }).join('')}
Project MCP Servers Status
${isCurrentProject ? '📍' : '📁'}
${escapeHtml(path.split('\\').pop() || path)} ${isCurrentProject ? '(Current)' : ''}
${escapeHtml(path)}
${serverNames.length === 0 ? 'No MCP servers' : serverNames.map(serverName => { const isEnabled = !projectDisabled.includes(serverName); return ` ${escapeHtml(serverName)} `; }).join('') }
${enabledCount}/${serverNames.length}
`; // Attach event listeners for toggle switches attachMcpEventListeners(); } function renderMcpServerCard(serverName, serverConfig, isEnabled, isInCurrentProject) { const command = serverConfig.command || 'N/A'; const args = serverConfig.args || []; const hasEnv = serverConfig.env && Object.keys(serverConfig.env).length > 0; return `
${isEnabled ? '🟢' : '🔴'}

${escapeHtml(serverName)}

cmd ${escapeHtml(command)}
${args.length > 0 ? `
args ${escapeHtml(args.slice(0, 3).join(' '))}${args.length > 3 ? '...' : ''}
` : ''} ${hasEnv ? `
env ${Object.keys(serverConfig.env).length} variables
` : ''}
${isInCurrentProject ? `
` : ''}
`; } function renderAvailableServerCard(serverName, serverInfo) { const serverConfig = serverInfo.config; const usedIn = serverInfo.usedIn || []; const command = serverConfig.command || 'N/A'; return `

${escapeHtml(serverName)}

cmd ${escapeHtml(command)}
Used in ${usedIn.length} project${usedIn.length !== 1 ? 's' : ''}
`; } function renderGlobalServerCard(serverName, serverConfig) { const command = serverConfig.command || 'N/A'; const args = serverConfig.args || []; const hasEnv = serverConfig.env && Object.keys(serverConfig.env).length > 0; return `
🌐

${escapeHtml(serverName)}

Global
cmd ${escapeHtml(command)}
${args.length > 0 ? `
args ${escapeHtml(args.slice(0, 3).join(' '))}${args.length > 3 ? '...' : ''}
` : ''} ${hasEnv ? `
env ${Object.keys(serverConfig.env).length} variables
` : ''}
Available to all projects from ~/.claude/settings
`; } function attachMcpEventListeners() { // Toggle switches document.querySelectorAll('.mcp-server-card input[data-action="toggle"]').forEach(input => { input.addEventListener('change', async (e) => { const serverName = e.target.dataset.serverName; const enable = e.target.checked; await toggleMcpServer(serverName, enable); }); }); // Add buttons document.querySelectorAll('.mcp-server-card button[data-action="add"]').forEach(btn => { btn.addEventListener('click', async (e) => { const serverName = e.target.dataset.serverName; const serverConfig = JSON.parse(e.target.dataset.serverConfig); await copyMcpServerToProject(serverName, serverConfig); }); }); // Remove buttons document.querySelectorAll('.mcp-server-card button[data-action="remove"]').forEach(btn => { btn.addEventListener('click', async (e) => { const serverName = e.target.dataset.serverName; if (confirm(`Remove MCP server "${serverName}" from this project?`)) { await removeMcpServerFromProject(serverName); } }); }); }