mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-10 01:48:40 +00:00
feat(mcp): support server log notifications (#31752)
This commit is contained in:
parent
c51a1588c7
commit
07b983e82f
2 changed files with 30 additions and 2 deletions
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { expect, mock, beforeEach } from "bun:test"
|
||||
import { ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"
|
||||
import { Cause, Effect, Exit } from "effect"
|
||||
import type { MCP as MCPNS } from "../../src/mcp/index"
|
||||
import { testEffect } from "../lib/effect"
|
||||
|
|
@ -394,7 +395,7 @@ it.instance(
|
|||
{ name: "next_tool", description: "next", inputSchema: { type: "object", properties: {} } },
|
||||
]
|
||||
|
||||
const handler = Array.from(serverState.notificationHandlers.values())[0]
|
||||
const handler = serverState.notificationHandlers.get(ToolListChangedNotificationSchema)
|
||||
expect(handler).toBeDefined()
|
||||
yield* Effect.promise(() => handler?.())
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue