feat(core): log mcp server messages (#34529)
This commit is contained in:
parent
d66c5f3bfa
commit
931323005c
2 changed files with 32 additions and 0 deletions
|
|
@ -11,6 +11,8 @@ import {
|
|||
CallToolResultSchema,
|
||||
ListRootsRequestSchema,
|
||||
ListToolsResultSchema,
|
||||
type LoggingMessageNotification,
|
||||
LoggingMessageNotificationSchema,
|
||||
ToolListChangedNotificationSchema,
|
||||
ToolSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js"
|
||||
|
|
@ -54,6 +56,12 @@ export interface CallToolResult {
|
|||
readonly content: ReadonlyArray<CallToolContent>
|
||||
}
|
||||
|
||||
export interface LogMessage {
|
||||
readonly level: LoggingMessageNotification["params"]["level"]
|
||||
readonly logger: LoggingMessageNotification["params"]["logger"]
|
||||
readonly data: LoggingMessageNotification["params"]["data"]
|
||||
}
|
||||
|
||||
/** Handle over a connected MCP server that keeps the SDK `Client` out of the rest of core. */
|
||||
export interface Connection {
|
||||
/** Server-supplied usage instructions from the initialize result, if any. */
|
||||
|
|
@ -66,6 +74,8 @@ export interface Connection {
|
|||
readonly args?: Record<string, unknown>
|
||||
}) => Effect.Effect<CallToolResult, Error>
|
||||
readonly onClose: (callback: () => void) => void
|
||||
/** Registers a callback fired when the server emits an MCP logging notification. */
|
||||
readonly onLog: (callback: (message: LogMessage) => void) => void
|
||||
/** Registers a callback fired when the server announces its tool list changed; no-op if unsupported. */
|
||||
readonly onToolsChanged: (callback: () => void) => void
|
||||
}
|
||||
|
|
@ -186,6 +196,9 @@ export const connect = Effect.fnUntraced(function* (
|
|||
onClose: (callback) => {
|
||||
client.onclose = callback
|
||||
},
|
||||
onLog: (callback) => {
|
||||
client.setNotificationHandler(LoggingMessageNotificationSchema, (notification) => callback(notification.params))
|
||||
},
|
||||
onToolsChanged: (callback) => {
|
||||
if (!client.getServerCapabilities()?.tools?.listChanged) return
|
||||
client.setNotificationHandler(ToolListChangedNotificationSchema, async () => callback())
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ export const layer = Layer.effect(
|
|||
entry.status = { status: "failed", error: "Connection closed" }
|
||||
fork(events.publish(McpEvent.ToolsChanged, { server: name }).pipe(Effect.ignore))
|
||||
})
|
||||
connection.onLog((message) => fork(serverLog(name, message).pipe(Effect.ignore)))
|
||||
connection.onToolsChanged(() => {
|
||||
fork(
|
||||
refreshTools(name, entry, connection).pipe(
|
||||
|
|
@ -261,6 +262,24 @@ export const layer = Layer.effect(
|
|||
})
|
||||
}
|
||||
|
||||
const serverLog = (server: ServerName, message: MCPClient.LogMessage) => {
|
||||
const fields = { server, logger: message.logger, level: message.level, data: message.data }
|
||||
switch (message.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 startServer = (name: ServerName, entry: ServerEntry) =>
|
||||
Effect.gen(function* () {
|
||||
const scope = yield* Scope.fork(root)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue