@@ -27,7 +27,7 @@ import { EventV2Bridge } from "@/event-v2-bridge"
2727import { EventV2 } from "@opencode-ai/core/event"
2828import { TuiEvent } from "@/server/tui-event"
2929import open from "open"
30- import { Effect , Exit , Layer , Option , Context , Schema , Stream } from "effect"
30+ import { Cause , Effect , Exit , Layer , Option , Context , Schema , Stream } from "effect"
3131import { EffectBridge } from "@/effect/bridge"
3232import { InstanceState } from "@/effect/instance-state"
3333import { ChildProcess , ChildProcessSpawner } from "effect/unstable/process"
@@ -446,31 +446,45 @@ export const layer = Layer.effect(
446446 )
447447 } )
448448
449- const create = Effect . fn ( "MCP.create" ) ( function * ( key : string , mcp : ConfigMCPV1 . Info ) {
450- if ( mcp . enabled === false ) {
451- return DISABLED_RESULT
452- }
449+ const create = Effect . fn ( "MCP.create" ) (
450+ function * ( key : string , mcp : ConfigMCPV1 . Info ) {
451+ if ( mcp . enabled === false ) {
452+ return DISABLED_RESULT
453+ }
453454
454- const { client : mcpClient , status } =
455- mcp . type === "remote"
456- ? yield * connectRemote ( key , mcp as ConfigMCPV1 . Info & { type : "remote" } )
457- : yield * connectLocal ( key , mcp as ConfigMCPV1 . Info & { type : "local" } )
455+ const { client : mcpClient , status } =
456+ mcp . type === "remote"
457+ ? yield * connectRemote ( key , mcp as ConfigMCPV1 . Info & { type : "remote" } )
458+ : yield * connectLocal ( key , mcp as ConfigMCPV1 . Info & { type : "local" } )
458459
459- if ( ! mcpClient ) {
460- if ( status . status !== "connected" && status . status !== "disabled" ) {
461- yield * Effect . logWarning ( "server unavailable" , { key, type : mcp . type , status : status . status } )
460+ if ( ! mcpClient ) {
461+ if ( status . status !== "connected" && status . status !== "disabled" ) {
462+ yield * Effect . logWarning ( "server unavailable" , { key, type : mcp . type , status : status . status } )
463+ }
464+ return { status } satisfies CreateResult
462465 }
463- return { status } satisfies CreateResult
464- }
465466
466- const listed = mcpClient . getServerCapabilities ( ) ?. tools ? yield * defs ( mcpClient , mcp . timeout ) : [ ]
467- if ( ! listed ) {
468- yield * Effect . tryPromise ( ( ) => mcpClient . close ( ) ) . pipe ( Effect . ignore )
469- return { status : { status : "failed" , error : "Failed to get tools" } } satisfies CreateResult
470- }
471-
472- return { mcpClient, status, defs : listed } satisfies CreateResult
473- } )
467+ return yield * Effect . gen ( function * ( ) {
468+ const listed = mcpClient . getServerCapabilities ( ) ?. tools ? yield * defs ( mcpClient , mcp . timeout ) : [ ]
469+ if ( ! listed ) {
470+ return yield * Effect . fail ( new Error ( "Failed to get tools" ) )
471+ }
472+ return { mcpClient, status, defs : listed } satisfies CreateResult
473+ } ) . pipe (
474+ Effect . catchCause ( ( cause ) =>
475+ Effect . tryPromise ( ( ) => mcpClient . close ( ) ) . pipe ( Effect . ignore , Effect . andThen ( Effect . failCause ( cause ) ) ) ,
476+ ) ,
477+ )
478+ } ,
479+ Effect . map ( ( result ) : CreateResult => result ) ,
480+ Effect . catchCause ( ( cause ) => {
481+ if ( Cause . hasInterruptsOnly ( cause ) ) return Effect . interrupt
482+ const error = Cause . squash ( cause )
483+ return Effect . succeed < CreateResult > ( {
484+ status : { status : "failed" , error : error instanceof Error ? error . message : String ( error ) } ,
485+ } )
486+ } ) ,
487+ )
474488 const cfgSvc = yield * Config . Service
475489
476490 const descendants = Effect . fnUntraced (
@@ -537,9 +551,7 @@ export const layer = Layer.effect(
537551 return
538552 }
539553
540- const result = yield * create ( key , mcp ) . pipe ( Effect . catch ( ( ) => Effect . void ) )
541- if ( ! result ) return
542-
554+ const result = yield * create ( key , mcp )
543555 s . status [ key ] = result . status
544556 if ( result . mcpClient ) {
545557 s . clients [ key ] = result . mcpClient
0 commit comments