/ migrations / migrateEnableAllProjectMcpServersToSettings.ts
migrateEnableAllProjectMcpServersToSettings.ts
  1  import { logEvent } from 'src/services/analytics/index.js'
  2  import {
  3    getCurrentProjectConfig,
  4    saveCurrentProjectConfig,
  5  } from '../utils/config.js'
  6  import { logError } from '../utils/log.js'
  7  import {
  8    getSettingsForSource,
  9    updateSettingsForSource,
 10  } from '../utils/settings/settings.js'
 11  
 12  /**
 13   * Migration: Move MCP server approval fields from project config to local settings
 14   * This migrates both enableAllProjectMcpServers and enabledMcpjsonServers to the
 15   * settings system for better management and consistency.
 16   */
 17  export function migrateEnableAllProjectMcpServersToSettings(): void {
 18    const projectConfig = getCurrentProjectConfig()
 19  
 20    // Check if any field exists in project config
 21    const hasEnableAll = projectConfig.enableAllProjectMcpServers !== undefined
 22    const hasEnabledServers =
 23      projectConfig.enabledMcpjsonServers &&
 24      projectConfig.enabledMcpjsonServers.length > 0
 25    const hasDisabledServers =
 26      projectConfig.disabledMcpjsonServers &&
 27      projectConfig.disabledMcpjsonServers.length > 0
 28  
 29    if (!hasEnableAll && !hasEnabledServers && !hasDisabledServers) {
 30      return
 31    }
 32  
 33    try {
 34      const existingSettings = getSettingsForSource('localSettings') || {}
 35      const updates: Partial<{
 36        enableAllProjectMcpServers: boolean
 37        enabledMcpjsonServers: string[]
 38        disabledMcpjsonServers: string[]
 39      }> = {}
 40      const fieldsToRemove: Array<
 41        | 'enableAllProjectMcpServers'
 42        | 'enabledMcpjsonServers'
 43        | 'disabledMcpjsonServers'
 44      > = []
 45  
 46      // Migrate enableAllProjectMcpServers if it exists and hasn't been migrated
 47      if (
 48        hasEnableAll &&
 49        existingSettings.enableAllProjectMcpServers === undefined
 50      ) {
 51        updates.enableAllProjectMcpServers =
 52          projectConfig.enableAllProjectMcpServers
 53        fieldsToRemove.push('enableAllProjectMcpServers')
 54      } else if (hasEnableAll) {
 55        // Already migrated, just mark for removal
 56        fieldsToRemove.push('enableAllProjectMcpServers')
 57      }
 58  
 59      // Migrate enabledMcpjsonServers if it exists
 60      if (hasEnabledServers && projectConfig.enabledMcpjsonServers) {
 61        const existingEnabledServers =
 62          existingSettings.enabledMcpjsonServers || []
 63        // Merge the servers (avoiding duplicates)
 64        updates.enabledMcpjsonServers = [
 65          ...new Set([
 66            ...existingEnabledServers,
 67            ...projectConfig.enabledMcpjsonServers,
 68          ]),
 69        ]
 70        fieldsToRemove.push('enabledMcpjsonServers')
 71      }
 72  
 73      // Migrate disabledMcpjsonServers if it exists
 74      if (hasDisabledServers && projectConfig.disabledMcpjsonServers) {
 75        const existingDisabledServers =
 76          existingSettings.disabledMcpjsonServers || []
 77        // Merge the servers (avoiding duplicates)
 78        updates.disabledMcpjsonServers = [
 79          ...new Set([
 80            ...existingDisabledServers,
 81            ...projectConfig.disabledMcpjsonServers,
 82          ]),
 83        ]
 84        fieldsToRemove.push('disabledMcpjsonServers')
 85      }
 86  
 87      // Update settings if there are any updates
 88      if (Object.keys(updates).length > 0) {
 89        updateSettingsForSource('localSettings', updates)
 90      }
 91  
 92      // Remove migrated fields from project config
 93      if (
 94        fieldsToRemove.includes('enableAllProjectMcpServers') ||
 95        fieldsToRemove.includes('enabledMcpjsonServers') ||
 96        fieldsToRemove.includes('disabledMcpjsonServers')
 97      ) {
 98        saveCurrentProjectConfig(current => {
 99          const {
100            enableAllProjectMcpServers: _enableAll,
101            enabledMcpjsonServers: _enabledServers,
102            disabledMcpjsonServers: _disabledServers,
103            ...configWithoutFields
104          } = current
105          return configWithoutFields
106        })
107      }
108  
109      // Log the migration event
110      logEvent('tengu_migrate_mcp_approval_fields_success', {
111        migratedCount: fieldsToRemove.length,
112      })
113    } catch (e: unknown) {
114      // Log migration failure but don't throw to avoid breaking startup
115      logError(e)
116      logEvent('tengu_migrate_mcp_approval_fields_error', {})
117    }
118  }