@@ -212,6 +212,19 @@ export class ProxyServer {
212212 return this . getStatus ( ) ;
213213 } ) ;
214214
215+ // MCP Server Management API endpoints for selective restart
216+ this . fastify . post ( '/api/mcp/servers' , async ( request , reply ) => {
217+ await this . handleAddServer ( request , reply ) ;
218+ } ) ;
219+
220+ this . fastify . delete ( '/api/mcp/servers/:serverName' , async ( request , reply ) => {
221+ await this . handleRemoveServer ( request , reply ) ;
222+ } ) ;
223+
224+ this . fastify . post ( '/api/mcp/servers/:serverName/restart' , async ( request , reply ) => {
225+ await this . handleRestartServer ( request , reply ) ;
226+ } ) ;
227+
215228 // Logs streaming endpoint - real-time log streaming via SSE
216229 this . fastify . get ( '/logs/stream' , async ( request , reply ) => {
217230 await this . handleLogsStream ( request , reply ) ;
@@ -1130,4 +1143,181 @@ export class ProxyServer {
11301143 console . error ( chalk . red ( 'Failed to load team MCP configuration:' ) , error ) ;
11311144 }
11321145 }
1146+
1147+ /**
1148+ * Handle adding a new MCP server (selective restart API)
1149+ */
1150+ private async handleAddServer ( request : FastifyRequest , reply : FastifyReply ) : Promise < void > {
1151+ try {
1152+ const body = request . body as any ;
1153+ const config = body . config as MCPServerConfig ;
1154+
1155+ if ( ! config || ! config . installation_name ) {
1156+ reply . code ( 400 ) . send ( {
1157+ error : 'Invalid request' ,
1158+ message : 'Missing server configuration'
1159+ } ) ;
1160+ return ;
1161+ }
1162+
1163+ console . log ( chalk . blue ( `[API] Adding MCP server: ${ config . installation_name } ` ) ) ;
1164+
1165+ // Check if server already exists
1166+ const existingProcess = this . processManager . getProcessByName ( config . installation_name ) ;
1167+ if ( existingProcess && existingProcess . status === 'running' ) {
1168+ reply . code ( 409 ) . send ( {
1169+ error : 'Server already exists' ,
1170+ message : `MCP server ${ config . installation_name } is already running`
1171+ } ) ;
1172+ return ;
1173+ }
1174+
1175+ // Spawn the new process
1176+ const processInfo = await this . processManager . spawnProcess ( config ) ;
1177+
1178+ console . log ( chalk . green ( `[API] Successfully added MCP server: ${ config . installation_name } ` ) ) ;
1179+
1180+ reply . code ( 201 ) . send ( {
1181+ success : true ,
1182+ message : `MCP server ${ config . installation_name } added successfully` ,
1183+ server : {
1184+ name : config . installation_name ,
1185+ status : processInfo . status ,
1186+ pid : processInfo . process . pid
1187+ }
1188+ } ) ;
1189+
1190+ } catch ( error ) {
1191+ console . error ( chalk . red ( `[API] Error adding server:` ) , error ) ;
1192+
1193+ reply . code ( 500 ) . send ( {
1194+ error : 'Internal server error' ,
1195+ message : error instanceof Error ? error . message : String ( error )
1196+ } ) ;
1197+ }
1198+ }
1199+
1200+ /**
1201+ * Handle removing an MCP server (selective restart API)
1202+ */
1203+ private async handleRemoveServer ( request : FastifyRequest , reply : FastifyReply ) : Promise < void > {
1204+ try {
1205+ const params = request . params as any ;
1206+ const serverName = params . serverName ;
1207+
1208+ if ( ! serverName ) {
1209+ reply . code ( 400 ) . send ( {
1210+ error : 'Invalid request' ,
1211+ message : 'Missing server name'
1212+ } ) ;
1213+ return ;
1214+ }
1215+
1216+ console . log ( chalk . blue ( `[API] Removing MCP server: ${ serverName } ` ) ) ;
1217+
1218+ // Find the process
1219+ const processInfo = this . processManager . getProcessByName ( serverName ) ;
1220+ if ( ! processInfo ) {
1221+ reply . code ( 404 ) . send ( {
1222+ error : 'Server not found' ,
1223+ message : `MCP server ${ serverName } not found`
1224+ } ) ;
1225+ return ;
1226+ }
1227+
1228+ // Terminate the process
1229+ await this . processManager . terminateProcess ( processInfo , 10000 ) ;
1230+
1231+ console . log ( chalk . green ( `[API] Successfully removed MCP server: ${ serverName } ` ) ) ;
1232+
1233+ reply . code ( 200 ) . send ( {
1234+ success : true ,
1235+ message : `MCP server ${ serverName } removed successfully`
1236+ } ) ;
1237+
1238+ } catch ( error ) {
1239+ console . error ( chalk . red ( `[API] Error removing server:` ) , error ) ;
1240+
1241+ reply . code ( 500 ) . send ( {
1242+ error : 'Internal server error' ,
1243+ message : error instanceof Error ? error . message : String ( error )
1244+ } ) ;
1245+ }
1246+ }
1247+
1248+ /**
1249+ * Handle restarting an MCP server (selective restart API)
1250+ */
1251+ private async handleRestartServer ( request : FastifyRequest , reply : FastifyReply ) : Promise < void > {
1252+ try {
1253+ const params = request . params as any ;
1254+ const body = request . body as any ;
1255+ const serverName = params . serverName ;
1256+ const config = body . config as MCPServerConfig ;
1257+
1258+ if ( ! serverName ) {
1259+ reply . code ( 400 ) . send ( {
1260+ error : 'Invalid request' ,
1261+ message : 'Missing server name'
1262+ } ) ;
1263+ return ;
1264+ }
1265+
1266+ if ( ! config || ! config . installation_name ) {
1267+ reply . code ( 400 ) . send ( {
1268+ error : 'Invalid request' ,
1269+ message : 'Missing server configuration'
1270+ } ) ;
1271+ return ;
1272+ }
1273+
1274+ console . log ( chalk . blue ( `[API] Restarting MCP server: ${ serverName } ` ) ) ;
1275+
1276+ // Find the existing process
1277+ const existingProcess = this . processManager . getProcessByName ( serverName ) ;
1278+ if ( ! existingProcess ) {
1279+ // Server doesn't exist, just start it
1280+ const processInfo = await this . processManager . spawnProcess ( config ) ;
1281+
1282+ console . log ( chalk . green ( `[API] Started MCP server: ${ serverName } (was not running)` ) ) ;
1283+
1284+ reply . code ( 200 ) . send ( {
1285+ success : true ,
1286+ message : `MCP server ${ serverName } started successfully` ,
1287+ server : {
1288+ name : config . installation_name ,
1289+ status : processInfo . status ,
1290+ pid : processInfo . process . pid
1291+ }
1292+ } ) ;
1293+ return ;
1294+ }
1295+
1296+ // Restart the existing process
1297+ const processInfo = await this . processManager . restartServer ( serverName , {
1298+ timeout : 10000 ,
1299+ showProgress : false
1300+ } ) ;
1301+
1302+ console . log ( chalk . green ( `[API] Successfully restarted MCP server: ${ serverName } ` ) ) ;
1303+
1304+ reply . code ( 200 ) . send ( {
1305+ success : true ,
1306+ message : `MCP server ${ serverName } restarted successfully` ,
1307+ server : {
1308+ name : config . installation_name ,
1309+ status : processInfo . status ,
1310+ pid : processInfo . process . pid
1311+ }
1312+ } ) ;
1313+
1314+ } catch ( error ) {
1315+ console . error ( chalk . red ( `[API] Error restarting server:` ) , error ) ;
1316+
1317+ reply . code ( 500 ) . send ( {
1318+ error : 'Internal server error' ,
1319+ message : error instanceof Error ? error . message : String ( error )
1320+ } ) ;
1321+ }
1322+ }
11331323}
0 commit comments