@@ -133,6 +133,7 @@ import {
133133import { startEventLoopLagMonitor } from './services/infrastructure/EventLoopLagMonitor' ;
134134import { HttpServer } from './services/infrastructure/HttpServer' ;
135135import { clearAutoResumeService } from './services/team/AutoResumeService' ;
136+ import { agentTeamsMcpHttpServer } from './services/team/AgentTeamsMcpHttpServer' ;
136137import { LaunchIoGovernor } from './services/team/LaunchIoGovernor' ;
137138import { OpenCodeBridgeCommandClient } from './services/team/opencode/bridge/OpenCodeBridgeCommandClient' ;
138139import {
@@ -352,6 +353,33 @@ async function createOpenCodeRuntimeAdapterRegistry(
352353 const bridgeEnv = applyOpenCodeAutoUpdatePolicy ( { ...process . env } ) ;
353354 bridgeEnv . CLAUDE_TEAM_APP_INSTANCE_ID = openCodeManagedHostInstanceId ;
354355 bridgeEnv . AGENT_TEAMS_MCP_CLAUDE_DIR = getClaudeBasePath ( ) ;
356+ const applyMcpLaunchSpecEnv = async (
357+ targetEnv : NodeJS . ProcessEnv ,
358+ options : { emitProgress ?: boolean } = { }
359+ ) : Promise < void > => {
360+ try {
361+ if ( options . emitProgress ) {
362+ reportProgress ( 'runtime-mcp' , 'Resolving Agent Teams MCP server...' ) ;
363+ }
364+ const mcpLaunchSpec = await resolveAgentTeamsMcpLaunchSpec ( {
365+ onProgress : options . emitProgress
366+ ? ( { phase, message } ) => reportProgress ( `mcp-${ phase } ` , message )
367+ : undefined ,
368+ } ) ;
369+ const mcpEntry = mcpLaunchSpec . args [ 0 ] ;
370+ if ( mcpEntry ) {
371+ targetEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND = mcpLaunchSpec . command ;
372+ targetEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY = mcpEntry ;
373+ targetEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON = JSON . stringify ( mcpLaunchSpec . args ) ;
374+ }
375+ } catch ( error ) {
376+ logger . warn (
377+ `[OpenCode] Runtime adapter bridge MCP entrypoint unresolved: ${
378+ error instanceof Error ? error . message : String ( error )
379+ } `
380+ ) ;
381+ }
382+ } ;
355383 try {
356384 const appManagedOpenCodeBinary = await resolveVerifiedAppManagedOpenCodeRuntimeBinaryPath ( ) ;
357385 if ( appManagedOpenCodeBinary && ! bridgeEnv . CLAUDE_MULTIMODEL_OPENCODE_BIN_PATH ) {
@@ -381,29 +409,69 @@ async function createOpenCodeRuntimeAdapterRegistry(
381409 ) ;
382410 }
383411 try {
384- reportProgress ( 'runtime-mcp' , 'Resolving Agent Teams MCP server...' ) ;
385- const mcpLaunchSpec = await resolveAgentTeamsMcpLaunchSpec ( {
386- onProgress : ( { phase, message } ) => reportProgress ( `mcp-${ phase } ` , message ) ,
387- } ) ;
388- const mcpEntry = mcpLaunchSpec . args [ 0 ] ;
389- if ( mcpEntry ) {
390- bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND = mcpLaunchSpec . command ;
391- bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY = mcpEntry ;
392- bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON = JSON . stringify ( mcpLaunchSpec . args ) ;
393- }
412+ reportProgress ( 'runtime-mcp-http' , 'Starting Agent Teams MCP server...' ) ;
413+ const mcpHttpServer = await agentTeamsMcpHttpServer . ensureStarted ( ) ;
414+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_URL = mcpHttpServer . url ;
415+ reportProgress ( 'runtime-mcp-http-ready' , 'Agent Teams MCP server is ready...' ) ;
394416 } catch ( error ) {
395417 logger . warn (
396- `[OpenCode] Runtime adapter bridge MCP entrypoint unresolved : ${
418+ `[OpenCode] Runtime adapter bridge MCP HTTP server unavailable : ${
397419 error instanceof Error ? error . message : String ( error )
398420 } `
399421 ) ;
400422 }
423+ if ( ! bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_URL ) {
424+ await applyMcpLaunchSpecEnv ( bridgeEnv , { emitProgress : true } ) ;
425+ }
401426
402427 reportProgress ( 'runtime-bridge' , 'Preparing OpenCode bridge...' ) ;
428+ const resolveBridgeCommandEnv = async ( ) : Promise < NodeJS . ProcessEnv > => {
429+ const nextEnv = { ...bridgeEnv } ;
430+ if ( ! bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_URL ) {
431+ return nextEnv ;
432+ }
433+ try {
434+ const mcpHttpServer = await agentTeamsMcpHttpServer . ensureStarted ( ) ;
435+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_URL = mcpHttpServer . url ;
436+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_URL = mcpHttpServer . url ;
437+ delete nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND ;
438+ delete nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY ;
439+ delete nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON ;
440+ } catch ( error ) {
441+ delete nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_URL ;
442+ if (
443+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND &&
444+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY &&
445+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON
446+ ) {
447+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND =
448+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND ;
449+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY =
450+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY ;
451+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON =
452+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON ;
453+ } else {
454+ await applyMcpLaunchSpecEnv ( nextEnv ) ;
455+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND =
456+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_COMMAND ;
457+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY =
458+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ENTRY ;
459+ bridgeEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON =
460+ nextEnv . CLAUDE_MULTIMODEL_AGENT_TEAMS_MCP_ARGS_JSON ;
461+ }
462+ logger . warn (
463+ `[OpenCode] Runtime adapter bridge MCP HTTP server refresh failed: ${
464+ error instanceof Error ? error . message : String ( error )
465+ } `
466+ ) ;
467+ }
468+ return nextEnv ;
469+ } ;
403470 const bridgeClient = new OpenCodeBridgeCommandClient ( {
404471 binaryPath,
405472 tempDirectory : join ( app . getPath ( 'temp' ) , 'claude-team-opencode-bridge' ) ,
406473 env : bridgeEnv ,
474+ envProvider : resolveBridgeCommandEnv ,
407475 } ) ;
408476 const bridgeControlDir = join ( app . getPath ( 'userData' ) , 'opencode-bridge' ) ;
409477 const clientIdentity = createOpenCodeBridgeClientIdentity ( {
@@ -2081,6 +2149,9 @@ async function shutdownServices(): Promise<void> {
20812149 ( ) => cleanupOpenCodeHostsForLifecycle ( 'shutdown' ) ,
20822150 10_000
20832151 ) ;
2152+ await runShutdownStep ( 'Agent Teams MCP HTTP server cleanup' , ( ) =>
2153+ agentTeamsMcpHttpServer . stop ( )
2154+ ) ;
20842155 await runShutdownStep ( 'tracked CLI subprocess cleanup' , ( ) =>
20852156 killTrackedCliProcesses ( 'SIGKILL' )
20862157 ) ;
0 commit comments