|
|
@@ -7,7 +7,12 @@ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/
|
|
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"
|
|
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
|
|
|
import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js"
|
|
|
-import { type Tool as MCPToolDef, ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"
|
|
|
+import {
|
|
|
+ type LoggingMessageNotification,
|
|
|
+ LoggingMessageNotificationSchema,
|
|
|
+ type Tool as MCPToolDef,
|
|
|
+ ToolListChangedNotificationSchema,
|
|
|
+} from "@modelcontextprotocol/sdk/types.js"
|
|
|
import { Config } from "@/config/config"
|
|
|
import { ConfigMCPV1 } from "@opencode-ai/core/v1/config/mcp"
|
|
|
import { NamedError } from "@opencode-ai/core/util/error"
|
|
|
@@ -391,6 +396,10 @@ export const layer = Layer.effect(
|
|
|
)
|
|
|
|
|
|
function watch(s: State, name: string, client: MCPClient, bridge: EffectBridge.Shape, timeout?: number) {
|
|
|
+ client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) =>
|
|
|
+ bridge.promise(serverLog(name, notification.params)),
|
|
|
+ )
|
|
|
+
|
|
|
if (!client.getServerCapabilities()?.tools) return
|
|
|
client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
|
|
|
if (s.clients[name] !== client || s.status[name]?.status !== "connected") return
|
|
|
@@ -404,6 +413,24 @@ export const layer = Layer.effect(
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ function serverLog(name: string, params: LoggingMessageNotification["params"]) {
|
|
|
+ const fields = { server: name, logger: params.logger, level: params.level, data: params.data }
|
|
|
+ switch (params.level) {
|
|
|
+ case "debug":
|
|
|
+ return Effect.logDebug("MCP server log", fields)
|
|
|
+ case "info":
|
|
|
+ case "notice":
|
|
|
+ return Effect.logInfo("MCP server log", fields)
|
|
|
+ case "warning":
|
|
|
+ return Effect.logWarning("MCP server log", fields)
|
|
|
+ case "error":
|
|
|
+ case "critical":
|
|
|
+ case "alert":
|
|
|
+ case "emergency":
|
|
|
+ return Effect.logError("MCP server log", fields)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
const state = yield* InstanceState.make<State>(
|
|
|
Effect.fn("MCP.state")(function* () {
|
|
|
const cfg = yield* cfgSvc.get()
|