@@ -30,6 +30,7 @@ import {
3030} from "../../shared/mcp"
3131import { fileExistsAtPath } from "../../utils/fs"
3232import { arePathsEqual } from "../../utils/path"
33+ import { PEARAI_URL } from "../../shared/api"
3334
3435export type McpConnection = {
3536 server : McpServer
@@ -106,11 +107,13 @@ export class McpHub {
106107 private isDisposed : boolean = false
107108 connections : McpConnection [ ] = [ ]
108109 isConnecting : boolean = false
110+ private context : vscode . ExtensionContext
109111
110- constructor ( provider : ClineProvider ) {
112+ constructor ( provider : ClineProvider , context : vscode . ExtensionContext ) {
111113 this . providerRef = new WeakRef ( provider )
112114 this . watchMcpSettingsFile ( )
113115 this . initializeMcpServers ( )
116+ this . context = context
114117 }
115118
116119 /**
@@ -259,6 +262,33 @@ export class McpHub {
259262 )
260263 }
261264
265+ private async fetchDefaultSettings ( ) : Promise < Record < string , any > > {
266+ try {
267+ const response = await fetch ( `${ PEARAI_URL } /getDefaultAgentMCPSettings` )
268+ if ( ! response . ok ) {
269+ throw new Error ( `HTTP error! status: ${ response . status } ` )
270+ }
271+ const data = await response . json ( )
272+ if ( data && data . mcpServers ) {
273+ return data . mcpServers
274+ }
275+ return { }
276+ } catch ( error ) {
277+ console . error ( "Failed to fetch default MCP settings:" , error )
278+ return { }
279+ }
280+ }
281+
282+ private async getPearAiApiKey ( ) : Promise < string | null > {
283+ try {
284+ const token = await this . context . secrets . get ( "pearaiApiKey" )
285+ return token || null
286+ } catch ( error ) {
287+ console . error ( "Failed to get PearAI token from secrets:" , error )
288+ return null
289+ }
290+ }
291+
262292 private async initializeMcpServers ( ) : Promise < void > {
263293 try {
264294 const settingsPath = await this . getMcpSettingsFilePath ( )
@@ -274,8 +304,36 @@ export class McpHub {
274304 return
275305 }
276306
307+ // Fetch default settings
308+ const defaultSettings = await this . fetchDefaultSettings ( )
309+ // Only add new servers from default settings that don't exist in current settings
310+ const mergedServers = { ...( config . mcpServers || { } ) }
311+ for ( const [ serverName , serverConfig ] of Object . entries ( defaultSettings ) ) {
312+ if ( ! mergedServers [ serverName ] ) {
313+ mergedServers [ serverName ] = serverConfig
314+ }
315+
316+ // If this is the pearai server, check login status and update API key
317+ if ( serverName === "pearai" ) {
318+ const apiKey = await this . getPearAiApiKey ( )
319+ if ( apiKey ) {
320+ mergedServers [ serverName ] = {
321+ ...serverConfig ,
322+ args : [ "pearai-mcp" , apiKey ] ,
323+ }
324+ }
325+ }
326+ }
327+
328+ // Update mcpServers while preserving config structure
329+ config . mcpServers = mergedServers
330+
331+ // Write updated config back to file
332+ await fs . writeFile ( settingsPath , JSON . stringify ( config , null , 2 ) )
333+
277334 // Validate the config using McpSettingsSchema
278335 const result = McpSettingsSchema . safeParse ( config )
336+ console . log ( "IM HERE 10101" , result )
279337 if ( result . success ) {
280338 await this . updateServerConnections ( result . data . mcpServers || { } )
281339 } else {
@@ -920,4 +978,50 @@ export class McpHub {
920978 }
921979 this . disposables . forEach ( ( d ) => d . dispose ( ) )
922980 }
981+
982+ public async clearPearAiApiKey ( ) : Promise < void > {
983+ try {
984+ const settingsPath = await this . getMcpSettingsFilePath ( )
985+ const content = await fs . readFile ( settingsPath , "utf-8" )
986+ const config = JSON . parse ( content )
987+
988+ if ( config . mcpServers ?. pearai ) {
989+ config . mcpServers . pearai = {
990+ ...config . mcpServers . pearai ,
991+ args : [ "pearai-mcp" , "<PEARAI_API_KEY>" ] ,
992+ }
993+
994+ await fs . writeFile ( settingsPath , JSON . stringify ( config , null , 2 ) )
995+ await this . updateServerConnections ( config . mcpServers )
996+ vscode . window . showInformationMessage ( "PearAI API key cleared successfully" )
997+ }
998+ } catch ( error ) {
999+ console . error ( "Failed to clear PearAI API key:" , error )
1000+ vscode . window . showErrorMessage ( "Failed to clear PearAI API key" )
1001+ throw error
1002+ }
1003+ }
1004+
1005+ public async updatePearAiApiKey ( apiKey : string ) : Promise < void > {
1006+ try {
1007+ const settingsPath = await this . getMcpSettingsFilePath ( )
1008+ const content = await fs . readFile ( settingsPath , "utf-8" )
1009+ const config = JSON . parse ( content )
1010+
1011+ if ( config . mcpServers ?. pearai ) {
1012+ config . mcpServers . pearai = {
1013+ ...config . mcpServers . pearai ,
1014+ args : [ "pearai-mcp" , apiKey ] ,
1015+ }
1016+
1017+ await fs . writeFile ( settingsPath , JSON . stringify ( config , null , 2 ) )
1018+ await this . updateServerConnections ( config . mcpServers )
1019+ vscode . window . showInformationMessage ( "PearAI API key updated successfully" )
1020+ }
1021+ } catch ( error ) {
1022+ console . error ( "Failed to update PearAI API key:" , error )
1023+ vscode . window . showErrorMessage ( "Failed to update PearAI API key" )
1024+ throw error
1025+ }
1026+ }
9231027}
0 commit comments