feat: spec-based proxy server logging

This commit is contained in:
justin 2025-05-07 01:03:47 -04:00
parent 5c71b26869
commit e642a56563
3 changed files with 36 additions and 0 deletions

View file

@ -1,4 +1,5 @@
import { EventEmitter } from 'events'
import { LoggingLevel } from '@modelcontextprotocol/sdk/types.js'
/**
* Options for creating an OAuth client provider
@ -33,3 +34,12 @@ export interface OAuthCallbackServerOptions {
/** Event emitter to signal when auth code is received */
events: EventEmitter
}
/*
* Message sending helper type
*/
export interface MCPLogMessageParams {
level: LoggingLevel
logger: string
data: Record<string, any>
}

View file

@ -3,6 +3,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js'
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'
import type { MCPLogMessageParams } from './types'
// Connection constants
export const REASON_AUTH_NEEDED = 'authentication-needed'
@ -487,3 +488,19 @@ export function setupSignalHandlers(cleanup: () => Promise<void>) {
export function getServerUrlHash(serverUrl: string): string {
return crypto.createHash('md5').update(serverUrl).digest('hex')
}
/**
* Helper function to send log messages through stdio MCP transport, for proxy logging purposes
* @param transport The transport to send the message through
* @param params Message parameters including level, logger name, and data
*
* In accordance with the official MCP specification
* @see https://modelcontextprotocol.io/specification/2025-03-26/server/utilities/logging#log-message-notifications
*/
export function sendLog(transport: Transport, params: MCPLogMessageParams) {
return transport.send({
jsonrpc: '2.0',
method: 'notifications/message',
params: { ...params },
})
}

View file

@ -20,6 +20,7 @@ import {
getServerUrlHash,
MCP_REMOTE_VERSION,
TransportStrategy,
sendLog,
} from './lib/utils'
import { NodeOAuthClientProvider } from './lib/node-oauth-client-provider'
import { createLazyAuthCoordinator } from './lib/coordination'
@ -76,6 +77,14 @@ async function runProxy(
}
}
sendLog(localTransport, {
level: 'debug',
logger: 'mcp-remote',
data: {
message: 'Connecting to remote server...',
},
})
try {
// Connect to remote server with lazy authentication
const remoteTransport = await connectToRemoteServer(null, serverUrl, authProvider, headers, authInitializer, transportStrategy)