(s: State, name: string, client: MCPClient, bridge: EffectBridge.Shape, timeout?: number)
| 432 | ) |
| 433 | |
| 434 | function watch(s: State, name: string, client: MCPClient, bridge: EffectBridge.Shape, timeout?: number) { |
| 435 | client.onclose = () => { |
| 436 | if (s.clients[name] !== client) return |
| 437 | delete s.clients[name] |
| 438 | delete s.defs[name] |
| 439 | delete s.instructions[name] |
| 440 | s.status[name] = { status: "failed", error: "Connection closed" } |
| 441 | bridge.fork( |
| 442 | Effect.logWarning("MCP connection closed", { server: name }).pipe( |
| 443 | Effect.andThen(events.publish(ToolsChanged, { server: name })), |
| 444 | Effect.ignore, |
| 445 | ), |
| 446 | ) |
| 447 | } |
| 448 | |
| 449 | client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => |
| 450 | bridge.promise(serverLog(name, notification.params)), |
| 451 | ) |
| 452 | |
| 453 | if (!client.getServerCapabilities()?.tools) return |
| 454 | client.setNotificationHandler(ToolListChangedNotificationSchema, async () => { |
| 455 | if (s.clients[name] !== client || s.status[name]?.status !== "connected") return |
| 456 | |
| 457 | const listed = await bridge.promise(McpCatalog.defs(client, timeout)) |
| 458 | if (!listed) return |
| 459 | if (s.clients[name] !== client || s.status[name]?.status !== "connected") return |
| 460 | |
| 461 | s.defs[name] = listed |
| 462 | await bridge.promise(events.publish(ToolsChanged, { server: name }).pipe(Effect.ignore)) |
| 463 | }) |
| 464 | } |
| 465 | |
| 466 | function serverLog(name: string, params: LoggingMessageNotification["params"]) { |
| 467 | const fields = { server: name, logger: params.logger, level: params.level, data: params.data } |
no test coverage detected